mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-20 22:52:29 +02:00
11 KiB
11 KiB
In [1]:
from operator import itemgetter
from langchain.chat_models.openai import ChatOpenAI
from langchain.prompts import SystemMessagePromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.runnables.openai_functions import OpenAIFunctionsRouter
from permchain.connection_inmemory import InMemoryPubSubConnection
from permchain.pubsub import PubSub
from permchain.topic import TopicIn [3]:
drafter_prompt = (
SystemMessagePromptTemplate.from_template(
"You are an expert on turtles, who likes to write in pirate-speak. You have been tasked by your editor with drafting a 100-word article answering the following question."
)
+ "Question:\n\n{question}"
)
drafter_llm = ChatOpenAI(model="gpt-3.5-turbo")
drafter = drafter_prompt | drafter_llm | StrOutputParser()In [4]:
drafter.invoke({"question": "what is art?"})Out [4]:
"Arrr, matey! What be art, ye be askin'? Well, art be a broad term, encompassin' a vast array o' creative expressions. Be it paintin's, sculptures, music, or even the written word, art be a means o' expressin' oneself and communicatin' emotions. It be a way fer humans to tap into their imagination and create somethin' beautiful or thought-provokin'. Art be subjective, each eye seein' it differently, but it be an important part o' our culture, history, and identity. So, me hearties, let yer creativity run wild, and let art be yer compass on this grand adventure called life!"
In [7]:
editor_prompt = (
SystemMessagePromptTemplate.from_template(
"You are an editor. You have been tasked with editing the following draft, which was written by a non-expert. Please accept the draft if it is good enough to publish, or send it for revision, along with your notes to guide the revision."
)
+ "Draft:\n\n{draft}"
)
editor_llm = ChatOpenAI(model="gpt-4")
functions = [
{
"name": "revise",
"description": "Sends the draft for revision",
"parameters": {
"type": "object",
"properties": {
"notes": {
"type": "string",
"description": "The editor's notes to guide the revision.",
},
},
},
},
{
"name": "accept",
"description": "Accepts the draft",
"parameters": {
"type": "object",
"properties": {"ready": {"const": True}},
},
},
]
editor = editor_prompt | editor_llm.bind(functions=functions)In [8]:
editor.invoke({"draft": "hi!"})Out [8]:
AIMessage(content='', additional_kwargs={'function_call': {'name': 'revise', 'arguments': '{\n"notes": "The draft is too short and lacks content. Please provide a detailed and informative draft for review."\n}'}}, example=False)In [9]:
reviser_prompt = (
SystemMessagePromptTemplate.from_template(
"You are an expert on turtles. You have been tasked by your editor with revising the following draft, which was written by a non-expert. You may follow the editor's notes or not, as you see fit."
)
+ "Draft:\n\n{draft}"
+ "Editor's notes:\n\n{notes}"
)
reviser_llm = ChatOpenAI(model="gpt-3.5-turbo")
reviser = reviser_prompt | reviser_llm | StrOutputParser()In [10]:
reviser.invoke({"draft": "hi!", "notes": "too short"})Out [10]:
'Revised draft:\n\nHello!'
In [12]:
# create topics
editor_inbox = Topic("editor_inbox")
reviser_inbox = Topic("reviser_inbox")In [13]:
draft_chain = (
# Listed in inputs
Topic.IN.subscribe()
| {"draft": drafter}
# The draft always goes to the editors inbox
| editor_inbox.publish()
)In [14]:
editor_chain = (
# Listen for events in the editors inbox
editor_inbox.subscribe()
| editor
# Depending on the output, different things should happen
| OpenAIFunctionsRouter(
{
# If revise is chosen, we send a push to the revisor's inbox
"revise": (
{
"notes": itemgetter("notes"),
"draft": editor_inbox.current() | itemgetter("draft"),
"question": Topic.IN.current() | itemgetter("question"),
}
| reviser_inbox.publish()
),
# If accepted, then we return
"accept": editor_inbox.current() | Topic.OUT.publish(),
},
)
)In [15]:
reviser_chain = (
# Listen for events in the reviser's inbox
reviser_inbox.subscribe()
| {"draft": reviser}
# Publish to the editors inbox
| editor_inbox.publish()
)In [17]:
web_researcher = PubSub(
processes=(draft_chain, editor_chain, reviser_chain),
connection=InMemoryPubSubConnection(),
)In [18]:
web_researcher.invoke({"question": "What food do turtles eat?"})Out [18]:
[{'draft': 'Turtles, fascinating creatures of the sea, are known for their diverse diets. They are omnivorous, meaning they consume both plant matter and small animals. Some turtles prefer a herbivorous diet, feeding on aquatic plants, seaweed, and algae. Others have a more carnivorous appetite, enjoying insects, fish, and crustaceans. Additionally, there are turtles that fall in the middle, being omnivores, and enjoying a variety of foods. So, when it comes to what turtles eat, they can be described as versatile eaters, ready to consume whatever comes their way in their marine habitat!'}]In [ ]: