mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-21 07:02:25 +02:00
84 KiB
84 KiB
In [1]:
!pip install --quiet -U langchain langchain_openai tavily-python[1m[[0m[34;49mnotice[0m[1;39;49m][0m[39;49m A new release of pip is available: [0m[31;49m23.3.1[0m[39;49m -> [0m[32;49m23.3.2[0m [1m[[0m[34;49mnotice[0m[1;39;49m][0m[39;49m To update, run: [0m[32;49mpip install --upgrade pip[0m
In [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 ToolNode
tool_node = ToolNode(tools)In [3]:
from langchain_openai import ChatOpenAI
model = ChatOpenAI(temperature=0)In [4]:
model = model.bind_tools(tools)In [5]:
# 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 not last_message.tool_calls:
return "end"
# Otherwise if there is, we continue
else:
return "continue"In [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", model)
workflow.add_node("action", tool_node)
# 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 [7]:
from langgraph.checkpoint.sqlite import SqliteSaver
memory = SqliteSaver.from_conn_string(":memory:")In [8]:
# 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 [9]:
from IPython.display import Image
Image(app.get_graph().draw_png())Out [9]:
In [10]:
from langchain_core.messages import HumanMessage
thread = {"configurable": {"thread_id": '3'}}
for event in app.stream("hi! I'm bob", thread):
for v in event.values():
print(v)content='Hello Bob! How can I assist you today?' response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 86, 'total_tokens': 97}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_c2295e73ad', 'finish_reason': 'stop', 'logprobs': None} id='run-f36a6fff-7732-43ed-b2a1-4d6cde4c073d-0'
In [11]:
app.get_state(thread).valuesOut [11]:
[HumanMessage(content="hi! I'm bob", id='8b86e367-6571-4333-86db-ed089288fd4f'),
AIMessage(content='Hello Bob! How can I assist you today?', response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 86, 'total_tokens': 97}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_c2295e73ad', 'finish_reason': 'stop', 'logprobs': None}, id='run-f36a6fff-7732-43ed-b2a1-4d6cde4c073d-0')]In [12]:
app.get_state(thread).nextOut [12]:
()
In [13]:
for event in app.stream("what is the weather in sf currently", thread):
for v in event.values():
print(v)content='' additional_kwargs={'tool_calls': [{'id': 'call_S1BSXnmEYRcs1Aed2obUsi4J', 'function': {'arguments': '{"query":"current weather in San Francisco"}', 'name': 'tavily_search_results_json'}, 'type': 'function'}]} response_metadata={'token_usage': {'completion_tokens': 22, 'prompt_tokens': 111, 'total_tokens': 133}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'tool_calls', 'logprobs': None} id='run-3d0caf20-5c92-4dd4-bd55-551d29fe6eb4-0' tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': 'current weather in San Francisco'}, 'id': 'call_S1BSXnmEYRcs1Aed2obUsi4J'}]
[ToolMessage(content='[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'San Francisco\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 37.78, \'lon\': -122.42, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1712938752, \'localtime\': \'2024-04-12 9:19\'}, \'current\': {\'last_updated_epoch\': 1712938500, \'last_updated\': \'2024-04-12 09:15\', \'temp_c\': 12.2, \'temp_f\': 54.0, \'is_day\': 1, \'condition\': {\'text\': \'Partly cloudy\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/116.png\', \'code\': 1003}, \'wind_mph\': 11.9, \'wind_kph\': 19.1, \'wind_degree\': 260, \'wind_dir\': \'W\', \'pressure_mb\': 1008.0, \'pressure_in\': 29.76, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 77, \'cloud\': 75, \'feelslike_c\': 10.5, \'feelslike_f\': 51.0, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 4.0, \'gust_mph\': 12.8, \'gust_kph\': 20.5}}"}]', name='tavily_search_results_json', id='1ab04e35-8850-4a78-a66c-071c83c37e55', tool_call_id='call_S1BSXnmEYRcs1Aed2obUsi4J')]
content='The current weather in San Francisco is as follows:\n- Temperature: 12.2°C (54.0°F)\n- Condition: Partly cloudy\n- Wind: 11.9 mph from the west\n- Humidity: 77%\n- Visibility: 16.0 km (9.0 miles)\n- UV Index: 4.0\n\nIf you need more detailed information or have any other questions, feel free to ask!' response_metadata={'token_usage': {'completion_tokens': 91, 'prompt_tokens': 490, 'total_tokens': 581}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'stop', 'logprobs': None} id='run-0ac4ccf0-e8a9-4e71-9349-0020baa3e266-0'
In [14]:
app_w_interrupt = workflow.compile(checkpointer=memory, interrupt_before=["action"])In [15]:
thread = {"configurable": {"thread_id": '4'}}
for event in app_w_interrupt.stream("what is the weather in sf currently", thread):
for v in event.values():
print(v)content='' additional_kwargs={'tool_calls': [{'id': 'call_ZzRMxOoMFp5ydcbpAQptdHbL', 'function': {'arguments': '{"query":"weather in San Francisco"}', 'name': 'tavily_search_results_json'}, 'type': 'function'}]} response_metadata={'token_usage': {'completion_tokens': 21, 'prompt_tokens': 88, 'total_tokens': 109}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'tool_calls', 'logprobs': None} id='run-1b01c302-8e24-43fe-9324-572d67bc529e-0' tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': 'weather in San Francisco'}, 'id': 'call_ZzRMxOoMFp5ydcbpAQptdHbL'}]
In [16]:
current_values = app_w_interrupt.get_state(thread)
current_values.nextOut [16]:
('action',)In [17]:
current_values.values[-1].tool_callsOut [17]:
[{'name': 'tavily_search_results_json',
'args': {'query': 'weather in San Francisco'},
'id': 'call_ZzRMxOoMFp5ydcbpAQptdHbL'}]In [18]:
current_values.values[-1].tool_calls[0]['args']['query'] = "weather in San Francisco today"In [19]:
app_w_interrupt.update_state(thread, current_values.values)Out [19]:
{'configurable': {'thread_id': '4',
'thread_ts': '2024-04-12T16:19:26.369199+00:00'}}In [20]:
app_w_interrupt.get_state(thread).valuesOut [20]:
[HumanMessage(content='what is the weather in sf currently', id='27b8dc9e-0e43-4c20-bb9f-53ee27c791f1'),
AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_ZzRMxOoMFp5ydcbpAQptdHbL', 'function': {'arguments': '{"query":"weather in San Francisco"}', 'name': 'tavily_search_results_json'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 21, 'prompt_tokens': 88, 'total_tokens': 109}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-1b01c302-8e24-43fe-9324-572d67bc529e-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': 'weather in San Francisco today'}, 'id': 'call_ZzRMxOoMFp5ydcbpAQptdHbL'}])]In [21]:
app_w_interrupt.get_state(thread).nextOut [21]:
('action',)In [22]:
for event in app_w_interrupt.stream(None, thread):
for v in event.values():
print(v)[ToolMessage(content='[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'San Francisco\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 37.78, \'lon\': -122.42, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1712938752, \'localtime\': \'2024-04-12 9:19\'}, \'current\': {\'last_updated_epoch\': 1712938500, \'last_updated\': \'2024-04-12 09:15\', \'temp_c\': 12.2, \'temp_f\': 54.0, \'is_day\': 1, \'condition\': {\'text\': \'Partly cloudy\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/116.png\', \'code\': 1003}, \'wind_mph\': 11.9, \'wind_kph\': 19.1, \'wind_degree\': 260, \'wind_dir\': \'W\', \'pressure_mb\': 1008.0, \'pressure_in\': 29.76, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 77, \'cloud\': 75, \'feelslike_c\': 10.5, \'feelslike_f\': 51.0, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 4.0, \'gust_mph\': 12.8, \'gust_kph\': 20.5}}"}]', name='tavily_search_results_json', id='578c3d3b-f905-412e-992a-4e08c4324f8b', tool_call_id='call_ZzRMxOoMFp5ydcbpAQptdHbL')]
content='The current weather in San Francisco is partly cloudy with a temperature of 12.2°C (54.0°F). The wind speed is 11.9 mph coming from the west. The humidity is at 77%, and the visibility is 16.0 km.' response_metadata={'token_usage': {'completion_tokens': 56, 'prompt_tokens': 466, 'total_tokens': 522}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'stop', 'logprobs': None} id='run-e28b3232-f2a0-4b22-bedd-0738788c9449-0'
In [25]:
for state in app_w_interrupt.get_state_history(thread):
print(state)
print('--')
if len(state.values) == 2:
to_replay = stateStateSnapshot(values=[HumanMessage(content='what is the weather in sf currently', id='06076c4e-40fe-4f44-978a-612fed60849c'), AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{"query":"weather in San Francisco today"}', 'name': 'tavily_search_results_json'}}, response_metadata={'token_usage': {'completion_tokens': 22, 'prompt_tokens': 88, 'total_tokens': 110}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'function_call', 'logprobs': None}, id='run-966f6180-3c8f-42d5-af89-906650c46ab5-0'), FunctionMessage(content='[{\'url\': \'https://weather.com/weather/hourbyhour/l/USCA0987:1:US\', \'content\': "recents\\nSpecialty Forecasts\\nHourly Weather-San Francisco, CA\\nBeach Hazard Statement\\nSaturday, November 25\\n5 pm\\nClear\\n6 pm\\nClear\\n7 pm\\nClear\\n8 pm\\nMostly Clear\\n9 pm\\nPartly Cloudy\\n10 pm\\nPartly Cloudy\\n11 pm\\nPartly Cloudy\\nSunday, November 26\\n12 am\\nPartly Cloudy\\n1 am\\nMostly Cloudy\\n2 am\\nMostly Cloudy\\n3 am\\nMostly Cloudy\\n4 am\\nCloudy\\n5 am\\nCloudy\\n6 am\\nMostly Cloudy\\n7 am\\nMostly Cloudy\\n8 am\\nMostly Cloudy\\n9 am\\nMostly Cloudy\\n10 am\\nPartly Cloudy\\n11 am\\nPartly Cloudy\\n12 pm\\nPartly Cloudy\\n1 pm\\nPartly Cloudy\\n2 pm\\nPartly Cloudy\\n3 pm\\nPartly Cloudy\\n4 pm\\nPartly Cloudy\\n5 pm\\nPartly Cloudy\\n6 pm\\nPartly Cloudy\\n7 pm\\nPartly Cloudy\\n8 pm\\nPartly Cloudy\\n9 pm\\nMostly Clear\\n10 pm\\nMostly Clear\\n11 pm\\nMostly Clear\\nMonday, November 27\\n12 am\\nClear\\n1 am\\nMostly Clear\\n2 am\\nMostly Clear\\n3 am\\nPartly Cloudy\\n4 am\\nMostly Clear\\n5 am\\nMostly Clear\\n6 am\\nClear\\n7 am\\nClear\\n8 am\\nSunny\\n9 am\\nSunny\\n10 am\\nSunny\\n11 am\\nSunny\\n12 pm\\nMostly Sunny\\n1 pm\\nPartly Cloudy\\n2 pm\\nMostly Sunny\\n3 pm\\nMostly Sunny\\n4 pm\\nPartly Cloudy\\nRadar\\nSafety First!\\n Don\'t Miss\\nIrresistible\\nWeather Wonders\\nOur Amazing World\\nCelestial Symphony\\nFried Turkey Fail\\nLook At That!\\n Health & Activities\\nSeasonal Allergies and Pollen Count Forecast\\nNo pollen detected in your area\\nCold & Flu Forecast\\nFlu risk is low in your area\\nWe recognize our responsibility to use data and technology for good. Changes For Critters\\nHurricane Tracker\\nStay Safe\\nAir Quality Index\\nAir quality is considered satisfactory, and air pollution poses little or no risk.\\n Take control of your data.\\n"}]', name='tavily_search_results_json', id='97fa7a07-399e-4c5d-8175-624be906c574'), AIMessage(content='The current weather in San Francisco is partly cloudy. The temperature is expected to remain consistent with partly cloudy conditions throughout the day.', response_metadata={'token_usage': {'completion_tokens': 26, 'prompt_tokens': 661, 'total_tokens': 687}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'stop', 'logprobs': None}, id='run-b99e4fd0-7688-4db7-a677-bf8ba9b8698e-0')], next=(), config={'configurable': {'thread_id': '4', 'thread_ts': '2024-04-02T23:07:42.012426+00:00'}}, parent_config=None)
--
StateSnapshot(values=[HumanMessage(content='what is the weather in sf currently', id='06076c4e-40fe-4f44-978a-612fed60849c'), AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{"query":"weather in San Francisco today"}', 'name': 'tavily_search_results_json'}}, response_metadata={'token_usage': {'completion_tokens': 22, 'prompt_tokens': 88, 'total_tokens': 110}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'function_call', 'logprobs': None}, id='run-966f6180-3c8f-42d5-af89-906650c46ab5-0')], next=('action',), config={'configurable': {'thread_id': '4', 'thread_ts': '2024-04-02T23:05:41.595778+00:00'}}, parent_config=None)
--
StateSnapshot(values=[HumanMessage(content='what is the weather in sf currently', id='06076c4e-40fe-4f44-978a-612fed60849c'), AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{"query":"current weather in San Francisco"}', 'name': 'tavily_search_results_json'}}, response_metadata={'token_usage': {'completion_tokens': 22, 'prompt_tokens': 88, 'total_tokens': 110}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'function_call', 'logprobs': None}, id='run-966f6180-3c8f-42d5-af89-906650c46ab5-0')], next=('action',), config={'configurable': {'thread_id': '4', 'thread_ts': '2024-04-02T23:01:11.296458+00:00'}}, parent_config=None)
--
In [26]:
to_replay.valuesOut [26]:
[HumanMessage(content='what is the weather in sf currently', id='06076c4e-40fe-4f44-978a-612fed60849c'),
AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{"query":"current weather in San Francisco"}', 'name': 'tavily_search_results_json'}}, response_metadata={'token_usage': {'completion_tokens': 22, 'prompt_tokens': 88, 'total_tokens': 110}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'function_call', 'logprobs': None}, id='run-966f6180-3c8f-42d5-af89-906650c46ab5-0')]In [27]:
to_replay.nextOut [27]:
('action',)In [28]:
for event in app_w_interrupt.stream(None, to_replay.config):
for v in event.values():
print(v)content="[{'url': 'https://www.accuweather.com/en/us/san-francisco/94103/current-weather/347629', 'content': 'Get the latest weather conditions and forecast for San Francisco, CA. See the temperature, humidity, wind, pressure, cloud cover, and alerts for the current hour and the next few days.'}]" name='tavily_search_results_json' id='82d6c2ac-260c-4d5d-9541-21ac4fab8916'
content='You can check the current weather conditions and forecast for San Francisco, CA on [AccuWeather](https://www.accuweather.com/en/us/san-francisco/94103/current-weather/347629). It will provide you with information on temperature, humidity, wind, pressure, cloud cover, and alerts for the current hour and the next few days.' response_metadata={'token_usage': {'completion_tokens': 75, 'prompt_tokens': 194, 'total_tokens': 269}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'stop', 'logprobs': None} id='run-b4ab153a-266f-44c2-ad37-5fd2a869003a-0'
In [29]:
branch_config = app_w_interrupt.update_state(to_replay.config, AIMessage(content='All done here!', id=to_replay.values[-1].id))In [30]:
branch_state = app_w_interrupt.get_state(branch_config)In [31]:
branch_state.valuesOut [31]:
[HumanMessage(content='what is the weather in sf currently', id='06076c4e-40fe-4f44-978a-612fed60849c'), AIMessage(content='All done here!', id='run-966f6180-3c8f-42d5-af89-906650c46ab5-0')]
In [32]:
branch_state.nextOut [32]:
()
In [ ]: