RaghuCourage9605's picture
Update app.py
1c12b04 verified
import gradio as gr
from langchain_community.chat_message_histories import Neo4jChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain.prompts import ChatPromptTemplate
from langchain.schema import StrOutputParser
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_core.prompts.chat import MessagesPlaceholder
from langchain_community.vectorstores import Neo4jVector
from langchain_neo4j import Neo4jGraph
from langchain_google_genai import ChatGoogleGenerativeAI
from uuid import uuid4
import os
from dotenv import load_dotenv
import asyncio
# Load environment variables
load_dotenv()
# Initialize variables
SESSION_ID = str(uuid4())
print(f"Session ID: {SESSION_ID}")
# Neo4j graph setup
graph = Neo4jGraph(
url="neo4j+s://6682e6ce.databases.neo4j.io",
username="neo4j",
password=os.getenv("NEO4J_PASSWORD")
)
# HuggingFace embeddings
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2",
model_kwargs={'device': 'cpu'},
encode_kwargs={'normalize_embeddings': False}
)
# Create Neo4j VectorStore
graph_store = Neo4jVector.from_existing_index(
embeddings,
graph=graph,
index_name="vector",
embedding_node_property="Embedding",
text_node_property="text",
retrieval_query="""
// get the document
MATCH (node)-[:PART_OF]->(d:Document)
WITH node, score, d
// get the entities and relationships for the document
MATCH (node)-[:HAS_ENTITY]->(e)
MATCH p = (e)-[r]-(e2)
WHERE (node)-[:HAS_ENTITY]->(e2)
// unwind the path, create a string of the entities and relationships
UNWIND relationships(p) as rels
WITH
node,
score,
d,
collect(apoc.text.join(
[labels(startNode(rels))[0], startNode(rels).id, type(rels), labels(endNode(rels))[0], endNode(rels).id]
," ")) as kg
RETURN
node.text as text, score,
{
document: d.id,
entities: kg
} AS metadata
""")
retriever = graph_store.as_retriever()
# Define Cypher Prompt
CYPHER_PROMPT = """
(
"Use the given context to provide an in-depth and structured response."
"Your answer should include:"
"- A clear and concise introduction to the topic."
"- Detailed explanation or relevant steps to address the query."
"- Practical examples or applications where possible."
"- A conclusion summarizing the main points."
"Format your response in sections with appropriate headings for clarity."
"Context: {context}"
)
"""
prompt = ChatPromptTemplate.from_messages([
("system", CYPHER_PROMPT),
MessagesPlaceholder(variable_name="chat_history"),
("human", "{question}")
])
# Helper function to retrieve context
def get_retrieved_context(query: str) -> str:
retrieved_documents = retriever.get_relevant_documents(query)
context = "\n".join(doc.page_content for doc in retrieved_documents)
return context
def get_memory(session_id):
return Neo4jChatMessageHistory(session_id=session_id, graph=graph)
def ReturnResponse(query: str) -> str:
llm = ChatGoogleGenerativeAI(
model='gemini-2.0-flash-exp',
api_key=os.getenv("GOOGLE_AI_STUDIO_API_KEY")
)
chat_chain = prompt | llm | StrOutputParser()
chat_with_message_history = RunnableWithMessageHistory(
chat_chain,
get_memory,
input_messages_key="question",
history_messages_key="chat_history",
)
context = get_retrieved_context(query)
response = chat_with_message_history.invoke({
"question": query,
"context": context,
}, config={
"configurable": {"session_id": SESSION_ID}
})
return gr.Markdown(response)
iface = gr.Interface(
fn=ReturnResponse,
inputs=gr.Textbox(label="Enter your query:", placeholder="Type your question here..."),
outputs=gr.Markdown(label="Chatbot Response"),
title="GraphRAG with conversational Memory πŸ€–πŸ’¬"
)
iface.launch()