Created
June 20, 2023 09:15
-
-
Save aarushik93/8b979de55d913439e21ac6f3302ec55d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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