Files
langgraph/examples/create-react-agent.ipynb
T
2024-06-17 15:25:47 -04:00

652 lines
32 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "992c4695-ec4f-428d-bd05-fb3b5fbd70f4",
"metadata": {},
"source": [
"# How to create a ReAct agent"
]
},
{
"cell_type": "markdown",
"id": "e0fcced0-9767-412f-90f9-7f3cd618ff90",
"metadata": {},
"source": [
"In this how-to we'll create a simple [ReAct](https://arxiv.org/abs/2210.03629) agent app that can check the weather. The app consists of an agent (LLM) and tools. As we interact with the app, we will first call the agent (LLM) to decide if we should use tools. Then we will run a loop: \n",
"\n",
"1. If the agent said to take an action (i.e. call tool), we'll run the tools and pass the results back to the agent\n",
"2. If the agent did not ask to run tools, we will finish (respond to the user)"
]
},
{
"cell_type": "markdown",
"id": "7be3889f-3c17-4fa1-bd2b-84114a2c7247",
"metadata": {},
"source": [
"## Setup"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "a213e11a-5c62-4ddb-a707-490d91add383",
"metadata": {},
"outputs": [],
"source": [
"%%capture --no-stderr\n",
"%pip install -U langgraph langchain-openai"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "23a1885c-04ab-4750-aefa-105891fddf3e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"OPENAI_API_KEY: ········\n"
]
}
],
"source": [
"import getpass\n",
"import os\n",
"\n",
"\n",
"def _set_env(var: str):\n",
" if not os.environ.get(var):\n",
" os.environ[var] = getpass.getpass(f\"{var}: \")\n",
"\n",
"\n",
"_set_env(\"OPENAI_API_KEY\")\n",
"\n",
"# Recommended\n",
"_set_env(\"LANGCHAIN_API_KEY\")\n",
"os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"os.environ[\"LANGCHAIN_PROJECT\"] = \"Create ReAct Agent Tutorial\""
]
},
{
"cell_type": "markdown",
"id": "03c0f089-070c-4cd4-87e0-6c51f2477b82",
"metadata": {},
"source": [
"## How to create a simple ReAct agent with `create_react_agent`"
]
},
{
"cell_type": "markdown",
"id": "91efaf20-711b-4b94-837e-dcef10d8abdd",
"metadata": {},
"source": [
"In our example we'll use `ChatOpenAI` as our agent and a custom tool that returns pre-defined values for weather in two cities (NYC & SF)"
]
},
{
"cell_type": "markdown",
"id": "6238f7d4-7da1-4e48-bc5e-a592280271e0",
"metadata": {},
"source": [
"### Define model and tools"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "029c838a-c6e7-4679-9a8b-953703fe3041",
"metadata": {},
"outputs": [],
"source": [
"from typing import Literal\n",
"\n",
"from langchain_core.tools import tool\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"model = ChatOpenAI(model=\"gpt-4o\", temperature=0)\n",
"\n",
"\n",
"@tool\n",
"def get_weather(city: Literal[\"nyc\", \"sf\"]):\n",
" \"\"\"Use this to get weather information.\"\"\"\n",
" if city == \"nyc\":\n",
" return \"It might be cloudy in nyc\"\n",
" elif city == \"sf\":\n",
" return \"It's always sunny in sf\"\n",
" else:\n",
" raise AssertionError(\"Unknown city\")\n",
"\n",
"\n",
"tools = [get_weather]"
]
},
{
"cell_type": "markdown",
"id": "47570e6c-655b-45ae-ad4a-b278e58f1b94",
"metadata": {},
"source": [
"### Define the graph"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "3d2df9e7-4c2c-494a-9249-5a2ee32eca3e",
"metadata": {},
"outputs": [],
"source": [
"from langgraph.prebuilt import create_react_agent\n",
"\n",
"graph = create_react_agent(model, tools=tools)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "fa16de4c-aac0-4ff4-ab69-60d399f75423",
"metadata": {},
"outputs": [
{
"data": {
"image/jpeg": "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",
"text/plain": [
"<IPython.core.display.Image object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from IPython.display import Image, display\n",
"\n",
"display(Image(graph.get_graph().draw_mermaid_png()))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "16636975-5f2d-4dc7-ab8e-d0bea0830a28",
"metadata": {},
"outputs": [],
"source": [
"def print_stream(stream):\n",
" for s in stream:\n",
" message = s[\"messages\"][-1]\n",
" if isinstance(message, tuple):\n",
" print(message)\n",
" else:\n",
" message.pretty_print()"
]
},
{
"cell_type": "markdown",
"id": "9d187d6b-0fb6-4860-8771-160c3cf403c6",
"metadata": {},
"source": [
"Let's run the app with an input that needs a tool call"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "9ffff6c3-a4f5-47c9-b51d-97caaee85cd6",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"what is the weather in sf\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"Tool Calls:\n",
" get_weather (call_g6w9lHn3fxYo2ABE3Ihhprbr)\n",
" Call ID: call_g6w9lHn3fxYo2ABE3Ihhprbr\n",
" Args:\n",
" city: sf\n",
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: get_weather\n",
"\n",
"It's always sunny in sf\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The weather in San Francisco is currently sunny.\n"
]
}
],
"source": [
"inputs = {\"messages\": [(\"user\", \"what is the weather in sf\")]}\n",
"print_stream(graph.stream(inputs, stream_mode=\"values\"))"
]
},
{
"cell_type": "markdown",
"id": "838a043f-90ad-4e69-9d1d-6e22db2c346c",
"metadata": {},
"source": [
"Now let's try a question that doesn't need tools"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "187479f9-32fa-4611-9487-cf816ba2e147",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"who built you?\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"I was created by OpenAI, a research organization focused on developing and advancing artificial intelligence technology.\n"
]
}
],
"source": [
"inputs = {\"messages\": [(\"user\", \"who built you?\")]}\n",
"print_stream(graph.stream(inputs, stream_mode=\"values\"))"
]
},
{
"cell_type": "markdown",
"id": "82b06aa3-6414-48e6-ba11-07bf065a316a",
"metadata": {},
"source": [
"## How to add system prompt to `create_react_agent`"
]
},
{
"cell_type": "markdown",
"id": "a3823699-1050-40fc-a8cc-ecbdc03c1cbe",
"metadata": {},
"source": [
"There are several ways to customize prompt, all of which are controlled by `messages_modifier` param. You can pass:\n",
"- system message string / `SystemMessage` that will be prepended to the list of messages\n",
"- a function that takes a list of messages and transforms them into an output that can be passed to the language model"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "23ea0a31-3e6b-433b-a832-036655579ebe",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"What's your name? And what's the weather in SF?\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"Tool Calls:\n",
" get_weather (call_PGwTiytTVAAvNKWp4nznPi4s)\n",
" Call ID: call_PGwTiytTVAAvNKWp4nznPi4s\n",
" Args:\n",
" city: sf\n",
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: get_weather\n",
"\n",
"It's always sunny in sf\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"My name is Fred. The weather in San Francisco is currently sunny.\n"
]
}
],
"source": [
"system_prompt = \"You are a helpful bot named Fred.\"\n",
"graph = create_react_agent(model, tools, messages_modifier=system_prompt)\n",
"\n",
"inputs = {\"messages\": [(\"user\", \"What's your name? And what's the weather in SF?\")]}\n",
"print_stream(graph.stream(inputs, stream_mode=\"values\"))"
]
},
{
"cell_type": "markdown",
"id": "d8e797ce-74bf-4a30-a388-08104138fd52",
"metadata": {},
"source": [
"We can also add a more complex prompt for the LLM:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "23c40ab3-c574-47be-a80f-654e9035cd6d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"What's my name? And what's the weather in SF?\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"Tool Calls:\n",
" get_weather (call_scpzIjdK3l411zcEn2T00Xm0)\n",
" Call ID: call_scpzIjdK3l411zcEn2T00Xm0\n",
" Args:\n",
" city: sf\n",
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: get_weather\n",
"\n",
"It's always sunny in sf\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"Your name is Joe. The weather in San Francisco is always sunny.\n"
]
}
],
"source": [
"from langchain_core.prompts import ChatPromptTemplate\n",
"\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", \"You are a helpful bot named Fred.\"),\n",
" (\"user\", \"My name is Joe\"),\n",
" (\"placeholder\", \"{messages}\"),\n",
" ]\n",
")\n",
"\n",
"\n",
"def modify_messages(messages: list):\n",
" # You can do more complex modifications here\n",
" return prompt.invoke({\"messages\": messages})\n",
"\n",
"\n",
"graph = create_react_agent(model, tools, messages_modifier=modify_messages)\n",
"\n",
"inputs = {\"messages\": [(\"user\", \"What's my name? And what's the weather in SF?\")]}\n",
"print_stream(graph.stream(inputs, stream_mode=\"values\"))"
]
},
{
"cell_type": "markdown",
"id": "0af418b8-bdd3-4e10-a552-9d8d2a409a57",
"metadata": {},
"source": [
"## How to add memory to `create_react_agent`"
]
},
{
"cell_type": "markdown",
"id": "4eef6365-530b-4d33-9874-41273ebee510",
"metadata": {},
"source": [
"We can add \"chat memory\" to the graph with LangGraph's checkpointer, to retain the chat context between interactions"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "c43d071a-a91e-4646-a035-b3fed9cd9f0c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"What's the weather in NYC?\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"Tool Calls:\n",
" get_weather (call_C5yEOD1GhlVPX9Gc5nnqgUXF)\n",
" Call ID: call_C5yEOD1GhlVPX9Gc5nnqgUXF\n",
" Args:\n",
" city: nyc\n",
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: get_weather\n",
"\n",
"It might be cloudy in nyc\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The weather in NYC might be cloudy.\n"
]
}
],
"source": [
"from langgraph.checkpoint import MemorySaver\n",
"\n",
"graph = create_react_agent(model, tools, checkpointer=MemorySaver())\n",
"\n",
"config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
"inputs = {\"messages\": [(\"user\", \"What's the weather in NYC?\")]}\n",
"\n",
"print_stream(graph.stream(inputs, config=config, stream_mode=\"values\"))"
]
},
{
"cell_type": "markdown",
"id": "4541ea58-ee6a-4685-a988-c915a42284e6",
"metadata": {},
"source": [
"Notice that when we pass the same the same thread ID, the chat history is preserved"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "b509417b-70f3-4736-b838-5d1729ed759e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"What's it known for?\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"New York City (NYC) is known for many things, including:\n",
"\n",
"1. **Landmarks and Attractions**: \n",
" - **Statue of Liberty**: A symbol of freedom and democracy.\n",
" - **Times Square**: Known for its bright lights, Broadway theaters, and bustling atmosphere.\n",
" - **Central Park**: A large urban park offering various recreational activities.\n",
" - **Empire State Building**: An iconic skyscraper with an observation deck offering panoramic views of the city.\n",
" - **Brooklyn Bridge**: A historic bridge connecting Manhattan and Brooklyn.\n",
"\n",
"2. **Cultural Diversity**: NYC is a melting pot of cultures, languages, and cuisines, making it one of the most diverse cities in the world.\n",
"\n",
"3. **Arts and Entertainment**: \n",
" - **Broadway**: Renowned for its world-class theater productions.\n",
" - **Museums**: Such as the Metropolitan Museum of Art, the Museum of Modern Art (MoMA), and the American Museum of Natural History.\n",
" - **Music and Nightlife**: A vibrant scene with numerous music venues, bars, and clubs.\n",
"\n",
"4. **Financial Hub**: \n",
" - **Wall Street**: The financial district is home to the New York Stock Exchange and numerous financial institutions.\n",
"\n",
"5. **Fashion and Shopping**: \n",
" - **Fifth Avenue**: Known for its high-end shopping.\n",
" - **Fashion Week**: One of the major fashion events held twice a year.\n",
"\n",
"6. **Cuisine**: \n",
" - **Diverse Food Scene**: From street food like hot dogs and pretzels to fine dining and international cuisines.\n",
" - **Famous Foods**: New York-style pizza, bagels, and cheesecake.\n",
"\n",
"7. **Media and Publishing**: \n",
" - Home to major media companies, newspapers like The New York Times, and numerous publishing houses.\n",
"\n",
"8. **Sports**: \n",
" - Home to several major sports teams, including the New York Yankees (baseball), New York Mets (baseball), New York Knicks (basketball), Brooklyn Nets (basketball), New York Giants (football), and New York Jets (football).\n",
"\n",
"9. **Education and Research**: \n",
" - Prestigious institutions like Columbia University, New York University (NYU), and Rockefeller University.\n",
"\n",
"10. **Public Transportation**: \n",
" - An extensive subway system, buses, and taxis that make getting around the city convenient.\n",
"\n",
"NYC is a city that never sleeps, offering endless opportunities for exploration and experiences.\n"
]
}
],
"source": [
"inputs = {\"messages\": [(\"user\", \"What's it known for?\")]}\n",
"print_stream(graph.stream(inputs, config=config, stream_mode=\"values\"))"
]
},
{
"cell_type": "markdown",
"id": "ef765ab6-3ea0-4de0-8737-de8f9d9add40",
"metadata": {},
"source": [
"And if we pass a different thread ID, the chat history is reset"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "1bb09dbe-bbba-4e8f-b44c-b18bd2ed96ff",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"What's it known for?\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"Could you please specify what \"it\" refers to? Are you asking about a specific city, person, object, or something else?\n"
]
}
],
"source": [
"inputs = {\"messages\": [(\"user\", \"What's it known for?\")]}\n",
"print_stream(\n",
" graph.stream(\n",
" inputs, config={\"configurable\": {\"thread_id\": 2}}, stream_mode=\"values\"\n",
" )\n",
")"
]
},
{
"cell_type": "markdown",
"id": "42e730aa-8fac-48a5-9c67-b51393665469",
"metadata": {},
"source": [
"## How to add human-in-the-loop to `create_react_agent`"
]
},
{
"cell_type": "markdown",
"id": "6314e49c-9143-45a8-871b-8bd3f489425c",
"metadata": {},
"source": [
"Let's add an interrupt to let the user confirm before LLM takes an action:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "8cd2cbcc-8a1f-443e-9cc9-dc18cd0ceac6",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"What's the weather in SF?\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"Tool Calls:\n",
" get_weather (call_I7B9YW4ENth7QXYzDpiIoLCE)\n",
" Call ID: call_I7B9YW4ENth7QXYzDpiIoLCE\n",
" Args:\n",
" city: sf\n"
]
}
],
"source": [
"graph = create_react_agent(\n",
" model, tools, interrupt_before=[\"tools\"], checkpointer=MemorySaver()\n",
")\n",
"\n",
"config = {\"configurable\": {\"thread_id\": \"42\"}}\n",
"inputs = {\"messages\": [(\"user\", \"What's the weather in SF?\")]}\n",
"\n",
"print_stream(graph.stream(inputs, config, stream_mode=\"values\"))"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "493d4963-b27b-46ef-8474-1527b08c1c03",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Next step: ('tools',)\n"
]
}
],
"source": [
"snapshot = graph.get_state(config)\n",
"print(\"Next step: \", snapshot.next)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "7ad01f3a-e838-4230-ab07-2f850bb7e7cb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: get_weather\n",
"\n",
"It's always sunny in sf\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The weather in San Francisco is currently sunny.\n"
]
}
],
"source": [
"print_stream(graph.stream(None, config, stream_mode=\"values\"))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "langgraph-example-dev",
"language": "python",
"name": "langgraph-example-dev"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}