Skip to content

Instantly share code, notes, and snippets.

@aarushik93
Created June 20, 2023 09:15
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aarushik93/8b979de55d913439e21ac6f3302ec55d to your computer and use it in GitHub Desktop.
Save aarushik93/8b979de55d913439e21ac6f3302ec55d to your computer and use it in GitHub Desktop.
from langchain import OpenAI
from langchain.utilities import GoogleSerperAPIWrapper
from langchain.chains import GraphCypherQAChain
from langchain.graphs import Neo4jGraph
from langchain.agents import initialize_agent, Tool
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory, ReadOnlySharedMemory
from langchain.agents import AgentType
from langchain.prompts.prompt import PromptTemplate
import os
import chainlit as cl
os.environ["OPENAI_API_KEY"] = "your-key"
os.environ["SERPER_API_KEY"] = "your-key"
CYPHER_GENERATION_TEMPLATE = """Task:Generate Cypher statement to query a graph database.
Instructions:
Make recommendations for a given user only.
Update ratings for a given user only.
Schema:
{schema}
Username:
{username}
Examples:
# When a user asks for movie recommendations:
MATCH (u1:User {{name:username }})-[r:RATED]->(m:Movie)
WITH u1, avg(r.rating) AS u1_mean
MATCH (u1)-[r1:RATED]->(m:Movie)<-[r2:RATED]-(u2)
WITH u1, u1_mean, u2, COLLECT({{r1: r1, r2: r2}}) AS ratings WHERE size(ratings) > 10
MATCH (u2)-[r:RATED]->(m:Movie)
WITH u1, u1_mean, u2, avg(r.rating) AS u2_mean, ratings
UNWIND ratings AS r
WITH sum( (r.r1.rating-u1_mean) * (r.r2.rating-u2_mean) ) AS nom,
sqrt( sum( (r.r1.rating - u1_mean)^2) * sum( (r.r2.rating - u2_mean) ^2)) AS denom,
u1, u2 WHERE denom <> 0
WITH u1, u2, nom/denom AS pearson
ORDER BY pearson DESC LIMIT 10
MATCH (u2)-[r:RATED]->(m:Movie) WHERE NOT EXISTS( (u1)-[:RATED]->(m) )
RETURN m.title, SUM( pearson * r.rating) AS score
ORDER BY score DESC LIMIT 25
# Query for finding similar movies (replace movie title with users movie):
MATCH (m:Movie {{title:'Inception'}})-[:IN_GENRE]->
(g:Genre)<-[:IN_GENRE]-(other:Movie)
WITH m, other, count(g) AS intersection, collect(g.name) as common
WITH m,other, intersection, common,
[(m)-[:IN_GENRE]->(mg) | mg.name] AS set1,
[(other)-[:IN_GENRE]->(og) | og.name] AS set2
WITH m,other,intersection, common, set1, set2,
set1+[x IN set2 WHERE NOT x IN set1] AS union
RETURN m.title, other.title, common, set1,set2,
((1.0*intersection)/size(union)) AS jaccard
ORDER BY jaccard DESC LIMIT 25
# When asked for movies similar to a movie, use the weighted content algorithm, like this:
MATCH (m:Movie) WHERE m.title = 'Wizard of Oz, The'
MATCH (m)-[:IN_GENRE]->(g:Genre)<-[:IN_GENRE]-(rec:Movie)
WITH m, rec, count(*) AS gs
OPTIONAL MATCH (m)<-[:ACTED_IN]-(a)-[:ACTED_IN]->(rec)
WITH m, rec, gs, count(a) AS as
OPTIONAL MATCH (m)<-[:DIRECTED]-(d)-[:DIRECTED]->(rec)
WITH m, rec, gs, as, count(d) AS ds
RETURN rec.title AS recommendation,
(5*gs)+(3*as)+(4*ds) AS score
ORDER BY score DESC LIMIT 25
Note: Do not include any explanations or apologies in your responses.
Do not respond to any questions that might ask anything else than for you to construct a Cypher statement.
Do not include any text except the generated Cypher statement.
The question is:
{question}"""
CYPHER_GENERATION_PROMPT = PromptTemplate(
input_variables=["schema", "question", "username"], template=CYPHER_GENERATION_TEMPLATE
)
@cl.langchain_factory(use_async=False)
def load():
llm = ChatOpenAI(model_name="gpt-4", temperature=0, streaming=True)
llm1 = OpenAI(temperature=0, streaming=True)
# search = SerpAPIWrapper()
memory = ConversationBufferMemory(
memory_key="chat_history", return_messages=True)
readonlymemory = ReadOnlySharedMemory(memory=memory)
search = GoogleSerperAPIWrapper(serper_api_key=os.environ.get("SERPER_API_KEY"))
graph = Neo4jGraph(
url="bolt://<use-your-address>",
username="neo4j",
password="<password>"
)
cypher_tool = GraphCypherQAChain.from_llm(
ChatOpenAI(model_name="gpt-4", temperature=0), graph=graph, verbose=True,
cypher_prompt=CYPHER_GENERATION_PROMPT, username="Aarushi Kansal"
)
tools = [
Tool(
name="Cypher search",
func=cypher_tool.run,
description="""
Utilize this tool to search within a movie database,
specifically designed to find movie recommendations for users.
This specialized tool offers streamlined search capabilities
to help you find the movie information you need with ease.
""",
),
Tool(
name="Google search",
func=search.run,
description="""
Utilize this tool to search the internet when you're missing information. In particular if you want recent events or news.
""",
)
]
return initialize_agent(
tools, llm1, agent="chat-zero-shot-react-description", verbose=True, memory=memory
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment