mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-31 20:29:46 +02:00
18 KiB
18 KiB
In [ ]:
!pip install --quiet -U langchain langchain_openai tavily-pythonIn [2]:
import os
import getpass
os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")
os.environ["TAVILY_API_KEY"] = getpass.getpass("Tavily API Key:")OpenAI API Key: ········ Tavily API Key: ········
In [ ]:
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = getpass.getpass("LangSmith API Key:")In [1]:
from langchain_community.tools.tavily_search import TavilySearchResults
tools = [TavilySearchResults(max_results=1)]In [2]:
from langgraph.prebuilt import ToolExecutor
tool_executor = ToolExecutor(tools)In [3]:
from langchain_openai import ChatOpenAI
# We will set streaming=True so that we can stream tokens
# See the streaming section for more information on this.
model = ChatOpenAI(temperature=0, streaming=True)In [4]:
from langchain_core.utils.function_calling import convert_to_openai_function
functions = [convert_to_openai_function(t) for t in tools]
model = model.bind_functions(functions)In [5]:
from langgraph.prebuilt import ToolInvocation
import json
from langchain_core.messages import FunctionMessage
# Define the function that determines whether to continue or not
def should_continue(messages):
last_message = messages[-1]
# If there is no function call, then we finish
if "function_call" not in last_message.additional_kwargs:
return "end"
# Otherwise if there is, we continue
else:
return "continue"
# Define the function that calls the model
def call_model(messages):
response = model.invoke(messages)
# We return a list, because this will get added to the existing list
return response
# Define the function to execute tools
def call_tool(messages):
# Based on the continue condition
# we know the last message involves a function call
last_message = messages[-1]
# We construct an ToolInvocation from the function_call
action = ToolInvocation(
tool=last_message.additional_kwargs["function_call"]["name"],
tool_input=json.loads(
last_message.additional_kwargs["function_call"]["arguments"]
),
)
# We call the tool_executor and get back a response
response = tool_executor.invoke(action)
# We use the response to create a FunctionMessage
function_message = FunctionMessage(content=str(response), name=action.tool)
# We return a list, because this will get added to the existing list
return function_messageIn [6]:
from langgraph.graph import MessageGraph, END
# Define a new graph
workflow = MessageGraph()
# Define the two nodes we will cycle between
workflow.add_node("agent", call_model)
workflow.add_node("action", call_tool)
# Set the entrypoint as `agent`
# This means that this node is the first one called
workflow.set_entry_point("agent")
# We now add a conditional edge
workflow.add_conditional_edges(
# First, we define the start node. We use `agent`.
# This means these are the edges taken after the `agent` node is called.
"agent",
# Next, we pass in the function that will determine which node is called next.
should_continue,
# Finally we pass in a mapping.
# The keys are strings, and the values are other nodes.
# END is a special node marking that the graph should finish.
# What will happen is we will call `should_continue`, and then the output of that
# will be matched against the keys in this mapping.
# Based on which one it matches, that node will then be called.
{
# If `tools`, then we call the tool node.
"continue": "action",
# Otherwise we finish.
"end": END,
},
)
# We now add a normal edge from `tools` to `agent`.
# This means that after `tools` is called, `agent` node is called next.
workflow.add_edge("action", "agent")In [ ]:
In [14]:
pool = AsyncConnectionPool(
# Example configuration
conninfo="postgresql://langchain:langchain@localhost:6024/langchain",
max_size=20,
)
In [18]:
await pool.close()In [7]:
from langgraph.checkpoint.sqlite import SqliteSaver
from langchain_postgres import PostgresSaver, PickleCheckpointSerializer
from psycopg_pool import AsyncConnectionPool, ConnectionPool
from langchain_postgres import (
PostgresSaver, PickleCheckpointSerializer
)
# pool = AsyncConnectionPool(
# # Example configuration
# conninfo="postgresql://langchain:langchain@localhost:6024/langc0
# hain",
# max_size=20,
# )
pool = ConnectionPool(
# Example configuration
conninfo="postgresql://langchain:langchain@localhost:6024/langchain",
max_size=20,
)
PostgresSaver.create_tables(pool)
memory = PostgresSaver(
serializer=PickleCheckpointSerializer(),
sync_connection=pool,
)
# memory = SqliteSaver.from_conn_string(":memory:")
# Finally, we compile it!
# This compiles it into a LangChain Runnable,
# meaning you can use it as you would any other runnable
app = workflow.compile(checkpointer=memory)In [8]:
from langchain_core.messages import HumanMessage
thread = {"configurable": {"thread_id": "2"}}
inputs = HumanMessage(content="hi! I'm bob")
for event in app.stream(inputs, thread):
for v in event.values():
print(v)content='Hello Bob! It seems like you mentioned your name twice. How can I assist you today?' response_metadata={'finish_reason': 'stop'} id='run-95013bc6-6893-47bb-9640-c9a32e6213be-0'
In [11]:
eventOut [11]:
{'agent': AIMessage(content="I found a website for toothpaste products. You can visit [Colgate's website](https://www.colgate.com/en-us/products) to explore a range of dental care products, including toothpaste.", response_metadata={'finish_reason': 'stop'}, id='run-4c5770e9-46ef-427a-958b-3453893e87b8-0')}In [9]:
inputs = HumanMessage(content="what is my name?")
for event in app.stream(inputs, thread):
for v in event.values():
print(v)content='Your name is Bob! How can I help you, Bob?' response_metadata={'finish_reason': 'stop'} id='run-7b182ace-d276-48d5-b6f6-037614b4aa8e-0'
In [10]:
inputs = HumanMessage(content="can you find website for toothpaste?")
for event in app.stream(inputs, {"configurable": {"thread_id": "3"}}):
for v in event.values():
print(v)content='' additional_kwargs={'function_call': {'arguments': '{"query":"toothpaste website"}', 'name': 'tavily_search_results_json'}} response_metadata={'finish_reason': 'function_call'} id='run-c24abecf-e217-4553-9d53-a3c8ef258ecd-0'
content="[{'url': 'https://www.colgate.com/en-us/products', 'content': 'Get a brighter, whiter smile when you use Colgate Optic White toothpaste, mouthwash, and toothbrush products during your oral care routine. View Products Colgate Total 360º'}]" name='tavily_search_results_json' id='6ad0fc6f-94e2-449a-92a9-94d26fb444ec'
content="I found a website for toothpaste products. You can visit [Colgate's website](https://www.colgate.com/en-us/products) to explore a range of dental care products, including toothpaste." response_metadata={'finish_reason': 'stop'} id='run-4c5770e9-46ef-427a-958b-3453893e87b8-0'
In [ ]: