From b010ce65446d631abf2562552d821d4abcae4846 Mon Sep 17 00:00:00 2001 From: vbarda Date: Thu, 13 Jun 2024 11:05:14 -0400 Subject: [PATCH 1/7] add create_react_agent how-to notebook --- examples/create-react-agent.ipynb | 734 ++++++++++++++++++++++++++++++ 1 file changed, 734 insertions(+) create mode 100644 examples/create-react-agent.ipynb diff --git a/examples/create-react-agent.ipynb b/examples/create-react-agent.ipynb new file mode 100644 index 000000000..9cd2f13d7 --- /dev/null +++ b/examples/create-react-agent.ipynb @@ -0,0 +1,734 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "992c4695-ec4f-428d-bd05-fb3b5fbd70f4", + "metadata": {}, + "source": [ + "# How to: create a ReAct agent" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "a213e11a-5c62-4ddb-a707-490d91add383", + "metadata": {}, + "outputs": [], + "source": [ + "%%capture --no-stderr\n", + "%pip install -U langgraph langchain-community langchain-openai tavily-python" + ] + }, + { + "cell_type": "markdown", + "id": "7be3889f-3c17-4fa1-bd2b-84114a2c7247", + "metadata": {}, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "23a1885c-04ab-4750-aefa-105891fddf3e", + "metadata": {}, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "OPENAI_API_KEY: ········\n", + "TAVILY_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", + "_set_env(\"TAVILY_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" + ] + }, + { + "cell_type": "markdown", + "id": "f1c8e137-e6e6-4f9f-bd1b-77359a1c4ec5", + "metadata": {}, + "source": [ + "Let's create a simple ReAct agent app that can search the web. 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)\n", + "\n", + "In our example we'll use `ChatOpenAI` as our agent and [Tavily Search API](https://tavily.com/) as our tool." + ] + }, + { + "cell_type": "markdown", + "id": "6238f7d4-7da1-4e48-bc5e-a592280271e0", + "metadata": {}, + "source": [ + "### Define model and tools" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "47726059-e6ea-4c5e-babe-aa5e6bad739f", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_openai import ChatOpenAI" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "ea3a8657-ecb3-42f9-8b94-cd2bbca68055", + "metadata": {}, + "outputs": [], + "source": [ + "model = ChatOpenAI(model=\"gpt-4o\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "98934efd-1b28-4475-af26-b4d55c8eae18", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_community.tools.tavily_search import TavilySearchResults" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "c69aac7b-0053-4c28-8524-1d5d58451a87", + "metadata": {}, + "outputs": [], + "source": [ + "tavily_search_tool = TavilySearchResults(max_results=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "e132bd2c-a98a-46e2-b0a8-02ec4dec4f58", + "metadata": {}, + "outputs": [], + "source": [ + "tools = [tavily_search_tool]" + ] + }, + { + "cell_type": "markdown", + "id": "47570e6c-655b-45ae-ad4a-b278e58f1b94", + "metadata": {}, + "source": [ + "### Define the graph" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "11fa1a0f-b99e-4b39-9827-b191b601e79c", + "metadata": {}, + "outputs": [], + "source": [ + "from langgraph.prebuilt import create_react_agent" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "fe4bc2a0-075d-4042-8bfb-738cbf1f98de", + "metadata": {}, + "outputs": [], + "source": [ + "graph = create_react_agent(model, tools=tools)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "65256d47-2fab-416e-a9d3-4fac25951c0a", + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.display import display, Image" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "7dc12855-2cb4-4f64-80cf-ef3297e6eb96", + "metadata": {}, + "outputs": [ + { + "data": { + "image/jpeg": "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", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(Image(graph.get_graph().draw_mermaid_png()))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "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": 13, + "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", + " tavily_search_results_json (call_3mZvRQf2INoE9kHCtMD7wYXf)\n", + " Call ID: call_3mZvRQf2INoE9kHCtMD7wYXf\n", + " Args:\n", + " query: current weather in San Francisco\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", + "\n", + "[{\"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': 1718290752, 'localtime': '2024-06-13 7:59'}, 'current': {'last_updated_epoch': 1718289900, 'last_updated': '2024-06-13 07:45', 'temp_c': 14.4, 'temp_f': 57.9, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1013.0, 'pressure_in': 29.92, 'precip_mm': 0.01, 'precip_in': 0.0, 'humidity': 84, 'cloud': 75, 'feelslike_c': 13.4, 'feelslike_f': 56.0, 'windchill_c': 10.1, 'windchill_f': 50.1, 'heatindex_c': 11.7, 'heatindex_f': 53.1, 'dewpoint_c': 8.8, 'dewpoint_f': 47.9, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 3.0, 'gust_mph': 12.7, 'gust_kph': 20.4}}\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "The current weather in San Francisco is as follows:\n", + "- **Condition:** Partly cloudy\n", + "- **Temperature:** 14.4°C (57.9°F)\n", + "- **Feels Like:** 13.4°C (56.0°F)\n", + "- **Wind:** 2.2 mph (3.6 kph) from the North\n", + "- **Humidity:** 84%\n", + "- **Pressure:** 1013.0 mb\n", + "- **Visibility:** 16.0 km (9.0 miles)\n", + "- **UV Index:** 3\n", + "\n", + "![Partly cloudy](//cdn.weatherapi.com/weather/64x64/day/116.png)\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": 14, + "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 developed by OpenAI, a research organization focused on artificial intelligence. OpenAI creates and maintains AI models like me to assist with a wide range of tasks and provide information.\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": 15, + "id": "2396d3ac-88f8-4a40-9e97-442173ba843c", + "metadata": {}, + "outputs": [], + "source": [ + "system_prompt = \"You are a helpful bot named Fred.\"\n", + "graph = create_react_agent(model, tools, messages_modifier=system_prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "50d989d5-424e-447e-b70e-931ead21e663", + "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", + "\n", + "My name is Fred. Let me check the current weather in San Francisco for you.\n", + "Tool Calls:\n", + " tavily_search_results_json (call_UuiAgBOpGLekVLNJxwjsTzGY)\n", + " Call ID: call_UuiAgBOpGLekVLNJxwjsTzGY\n", + " Args:\n", + " query: current weather in San Francisco\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", + "\n", + "[{\"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': 1718290752, 'localtime': '2024-06-13 7:59'}, 'current': {'last_updated_epoch': 1718289900, 'last_updated': '2024-06-13 07:45', 'temp_c': 14.4, 'temp_f': 57.9, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1013.0, 'pressure_in': 29.92, 'precip_mm': 0.01, 'precip_in': 0.0, 'humidity': 84, 'cloud': 75, 'feelslike_c': 13.4, 'feelslike_f': 56.0, 'windchill_c': 10.1, 'windchill_f': 50.1, 'heatindex_c': 11.7, 'heatindex_f': 53.1, 'dewpoint_c': 8.8, 'dewpoint_f': 47.9, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 3.0, 'gust_mph': 12.7, 'gust_kph': 20.4}}\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "My name is Fred. The current weather in San Francisco is partly cloudy with a temperature of approximately 14.4°C (57.9°F). The wind is blowing from the north at about 2.2 mph (3.6 kph), and the humidity is around 84%.\n" + ] + } + ], + "source": [ + "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": 17, + "id": "894b9d53-cd99-465c-b183-988f797d6b5b", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_core.prompts import ChatPromptTemplate\n", + "prompt = ChatPromptTemplate.from_messages([\n", + " (\"system\", \"You are a helpful bot named Fred.\"),\n", + " (\"placeholder\", \"{messages}\"),\n", + " (\"user\", \"Remember, always be polite!\"),\n", + "])\n", + "\n", + "def modify_messages(messages: list):\n", + " # You can do more complex modifications here\n", + " return prompt.invoke({\"messages\": messages})\n", + "\n", + "graph = create_react_agent(model, tools, messages_modifier=modify_messages)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "8602282f-72ec-405f-b014-e1e319f73d33", + "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", + "\n", + "Hello! My name is Fred. Let me check the current weather in San Francisco for you.\n", + "Tool Calls:\n", + " tavily_search_results_json (call_QOco9uwxOZaoh9WaSwoMc3eA)\n", + " Call ID: call_QOco9uwxOZaoh9WaSwoMc3eA\n", + " Args:\n", + " query: current weather in San Francisco\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", + "\n", + "HTTPError('502 Server Error: Bad Gateway for url: https://api.tavily.com/search')\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "Of course! I always strive to be polite and helpful. Let's try to find out the current weather in San Francisco again.\n", + "Tool Calls:\n", + " tavily_search_results_json (call_G6x1cxoXQbRBPZ8i18X40j0d)\n", + " Call ID: call_G6x1cxoXQbRBPZ8i18X40j0d\n", + " Args:\n", + " query: current weather in San Francisco\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", + "\n", + "[{\"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': 1718290752, 'localtime': '2024-06-13 7:59'}, 'current': {'last_updated_epoch': 1718289900, 'last_updated': '2024-06-13 07:45', 'temp_c': 14.4, 'temp_f': 57.9, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1013.0, 'pressure_in': 29.92, 'precip_mm': 0.01, 'precip_in': 0.0, 'humidity': 84, 'cloud': 75, 'feelslike_c': 13.4, 'feelslike_f': 56.0, 'windchill_c': 10.1, 'windchill_f': 50.1, 'heatindex_c': 11.7, 'heatindex_f': 53.1, 'dewpoint_c': 8.8, 'dewpoint_f': 47.9, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 3.0, 'gust_mph': 12.7, 'gust_kph': 20.4}}\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "Of course! I always strive to be polite and helpful.\n", + "\n", + "Currently, in San Francisco, it is partly cloudy with a temperature of approximately 14.4°C (57.9°F). The wind is blowing from the north at around 2.2 mph (3.6 kph). The humidity level is quite high at 84%, and visibility is good at 16 km (9 miles).\n", + "\n", + "Is there anything else you would like to know?\n" + ] + } + ], + "source": [ + "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": "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": 19, + "id": "dfd72a3c-3ff9-4bc3-ab51-f3c8424e7932", + "metadata": {}, + "outputs": [], + "source": [ + "from langgraph.checkpoint import MemorySaver\n", + "graph = create_react_agent(model, tools, checkpointer=MemorySaver())" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "3db05867-1ced-402c-b739-72afda037e7f", + "metadata": {}, + "outputs": [], + "source": [ + "config = {\"configurable\": {\"thread_id\": \"1\"}}\n", + "inputs = {\"messages\": [(\"user\", \"What's the weather in SF?\")]}" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "fcf1f692-b437-4f8d-9a75-94a018e90a7c", + "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", + " tavily_search_results_json (call_SQua8Xc6fLjtJlS8CvaCxH2U)\n", + " Call ID: call_SQua8Xc6fLjtJlS8CvaCxH2U\n", + " Args:\n", + " query: current weather in San Francisco\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", + "\n", + "[{\"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': 1718290938, 'localtime': '2024-06-13 8:02'}, 'current': {'last_updated_epoch': 1718290800, 'last_updated': '2024-06-13 08:00', 'temp_c': 14.4, 'temp_f': 57.9, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1013.0, 'pressure_in': 29.92, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 84, 'cloud': 75, 'feelslike_c': 13.4, 'feelslike_f': 56.2, 'windchill_c': 11.1, 'windchill_f': 52.0, 'heatindex_c': 12.5, 'heatindex_f': 54.6, 'dewpoint_c': 8.8, 'dewpoint_f': 47.9, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 4.0, 'gust_mph': 11.3, 'gust_kph': 18.1}}\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "The current weather in San Francisco is partly cloudy with a temperature of 14.4°C (57.9°F). The wind is blowing from the north at 2.2 mph (3.6 kph). Humidity is at 84%, and visibility is 16 km (9 miles). The UV index is 4.\n" + ] + } + ], + "source": [ + "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": 22, + "id": "b509417b-70f3-4736-b838-5d1729ed759e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "How about NYC?\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "Tool Calls:\n", + " tavily_search_results_json (call_s3cYMxsn11IfPxEMsxMp9Ycb)\n", + " Call ID: call_s3cYMxsn11IfPxEMsxMp9Ycb\n", + " Args:\n", + " query: current weather in New York City\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", + "\n", + "[{\"url\": \"https://www.weatherapi.com/\", \"content\": \"{'location': {'name': 'New York', 'region': 'New York', 'country': 'United States of America', 'lat': 40.71, 'lon': -74.01, 'tz_id': 'America/New_York', 'localtime_epoch': 1718290946, 'localtime': '2024-06-13 11:02'}, 'current': {'last_updated_epoch': 1718290800, 'last_updated': '2024-06-13 11:00', 'temp_c': 23.9, 'temp_f': 75.0, 'is_day': 1, 'condition': {'text': 'Sunny', 'icon': '//cdn.weatherapi.com/weather/64x64/day/113.png', 'code': 1000}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1018.0, 'pressure_in': 30.05, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 55, 'cloud': 0, 'feelslike_c': 24.9, 'feelslike_f': 76.7, 'windchill_c': 26.1, 'windchill_f': 78.9, 'heatindex_c': 26.2, 'heatindex_f': 79.2, 'dewpoint_c': 12.5, 'dewpoint_f': 54.6, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 7.0, 'gust_mph': 7.2, 'gust_kph': 11.6}}\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "The current weather in New York City is sunny with a temperature of 23.9°C (75.0°F). The wind is blowing from the north at 2.2 mph (3.6 kph). Humidity is at 55%, and visibility is 16 km (9 miles). The UV index is 7.\n" + ] + } + ], + "source": [ + "inputs = {\"messages\": [(\"user\", \"How about NYC?\")]}\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": 23, + "id": "1bb09dbe-bbba-4e8f-b44c-b18bd2ed96ff", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "How about NYC?\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "Tool Calls:\n", + " tavily_search_results_json (call_uXGI87Qw09CHNiDgYBgOrhoJ)\n", + " Call ID: call_uXGI87Qw09CHNiDgYBgOrhoJ\n", + " Args:\n", + " query: current news in NYC\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", + "\n", + "[{\"url\": \"https://abc7ny.com/\", \"content\": \"New York's source for breaking news, weather and live video. Covering NYC, New Jersey, Long Island and all of the greater New York City area.\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "For the latest news in NYC, you can visit [ABC7 New York](https://abc7ny.com/). They provide updates on breaking news, weather, and live video coverage for New York City, New Jersey, Long Island, and the greater NYC area.\n" + ] + } + ], + "source": [ + "inputs = {\"messages\": [(\"user\", \"How about NYC?\")]}\n", + "print_stream(graph.stream(inputs, config={\"configurable\": {\"thread_id\": 2}}, stream_mode=\"values\"))" + ] + }, + { + "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": 24, + "id": "fe93def9-6ba4-4c89-9e84-1ff607dbfc8c", + "metadata": {}, + "outputs": [], + "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?\")]}" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "4d934d6a-6550-453b-8c23-fbb8b4656da6", + "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", + " tavily_search_results_json (call_Wg4AZqacqqUHHmQfjOjudAyP)\n", + " Call ID: call_Wg4AZqacqqUHHmQfjOjudAyP\n", + " Args:\n", + " query: current weather in San Francisco\n" + ] + } + ], + "source": [ + "print_stream(graph.stream(inputs, config, stream_mode=\"values\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "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": 27, + "id": "7ad01f3a-e838-4230-ab07-2f850bb7e7cb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", + "\n", + "[{\"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': 1718290938, 'localtime': '2024-06-13 8:02'}, 'current': {'last_updated_epoch': 1718290800, 'last_updated': '2024-06-13 08:00', 'temp_c': 14.4, 'temp_f': 57.9, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1013.0, 'pressure_in': 29.92, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 84, 'cloud': 75, 'feelslike_c': 13.4, 'feelslike_f': 56.2, 'windchill_c': 11.1, 'windchill_f': 52.0, 'heatindex_c': 12.5, 'heatindex_f': 54.6, 'dewpoint_c': 8.8, 'dewpoint_f': 47.9, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 4.0, 'gust_mph': 11.3, 'gust_kph': 18.1}}\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "The current weather in San Francisco is:\n", + "\n", + "- **Temperature**: 14.4°C (57.9°F)\n", + "- **Condition**: Partly cloudy\n", + "- **Wind**: 2.2 mph (3.6 kph) from the north\n", + "- **Humidity**: 84%\n", + "- **Visibility**: 16 km (9 miles)\n", + "- **UV Index**: 4\n", + "\n", + "![Weather Icon](//cdn.weatherapi.com/weather/64x64/day/116.png)\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 +} From 4ecb8fa08874c6687af3455ee61f9098e9e4833a Mon Sep 17 00:00:00 2001 From: vbarda Date: Thu, 13 Jun 2024 11:09:57 -0400 Subject: [PATCH 2/7] add docs mention --- docs/docs/how-tos/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/how-tos/index.md b/docs/docs/how-tos/index.md index e74b9cc17..41c2a9c01 100644 --- a/docs/docs/how-tos/index.md +++ b/docs/docs/how-tos/index.md @@ -6,6 +6,7 @@ Welcome to the LangGraph how-to guides! These guides provide practical, step-by- The core guides show how to address common needs when building out AI workflows, with special focus placed on [ReAct](https://arxiv.org/abs/2210.03629)-style agents with [tool calling](https://python.langchain.com/docs/modules/model_io/chat/function_calling/). +- [ReAct agent](create-react-agent.ipynb): How to create a simple ReAct agent using LangGraph - [Persistence](persistence.ipynb): How to give your graph "memory" and resilience by saving and loading state - [Time travel](time-travel.ipynb): How to navigate and manipulate graph state history once it's persisted - [Async execution](async.ipynb): How to run nodes asynchronously for improved performance From ca4ce87c00b25865eb4da5397b5ce740cca55133 Mon Sep 17 00:00:00 2001 From: vbarda Date: Thu, 13 Jun 2024 11:10:47 -0400 Subject: [PATCH 3/7] nit --- docs/docs/how-tos/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/how-tos/index.md b/docs/docs/how-tos/index.md index 41c2a9c01..15057d2db 100644 --- a/docs/docs/how-tos/index.md +++ b/docs/docs/how-tos/index.md @@ -6,7 +6,7 @@ Welcome to the LangGraph how-to guides! These guides provide practical, step-by- The core guides show how to address common needs when building out AI workflows, with special focus placed on [ReAct](https://arxiv.org/abs/2210.03629)-style agents with [tool calling](https://python.langchain.com/docs/modules/model_io/chat/function_calling/). -- [ReAct agent](create-react-agent.ipynb): How to create a simple ReAct agent using LangGraph +- [ReAct agent](create-react-agent.ipynb): How to create a simple ReAct agent - [Persistence](persistence.ipynb): How to give your graph "memory" and resilience by saving and loading state - [Time travel](time-travel.ipynb): How to navigate and manipulate graph state history once it's persisted - [Async execution](async.ipynb): How to run nodes asynchronously for improved performance From cfbb6ba7ee4f60d7eab72254d6499555f39c69fe Mon Sep 17 00:00:00 2001 From: vbarda Date: Thu, 13 Jun 2024 19:20:23 -0400 Subject: [PATCH 4/7] code review --- docs/docs/how-tos/index.md | 2 +- examples/create-react-agent.ipynb | 434 ++++++++++++------------------ 2 files changed, 173 insertions(+), 263 deletions(-) diff --git a/docs/docs/how-tos/index.md b/docs/docs/how-tos/index.md index 15057d2db..234f1fcd2 100644 --- a/docs/docs/how-tos/index.md +++ b/docs/docs/how-tos/index.md @@ -6,7 +6,7 @@ Welcome to the LangGraph how-to guides! These guides provide practical, step-by- The core guides show how to address common needs when building out AI workflows, with special focus placed on [ReAct](https://arxiv.org/abs/2210.03629)-style agents with [tool calling](https://python.langchain.com/docs/modules/model_io/chat/function_calling/). -- [ReAct agent](create-react-agent.ipynb): How to create a simple ReAct agent +- [ReAct agent](create-react-agent.ipynb): How to create a tool-calling agent that **Re**asons and **Act**s to accomplish tasks - [Persistence](persistence.ipynb): How to give your graph "memory" and resilience by saving and loading state - [Time travel](time-travel.ipynb): How to navigate and manipulate graph state history once it's persisted - [Async execution](async.ipynb): How to run nodes asynchronously for improved performance diff --git a/examples/create-react-agent.ipynb b/examples/create-react-agent.ipynb index 9cd2f13d7..d9ccff1c0 100644 --- a/examples/create-react-agent.ipynb +++ b/examples/create-react-agent.ipynb @@ -5,7 +5,7 @@ "id": "992c4695-ec4f-428d-bd05-fb3b5fbd70f4", "metadata": {}, "source": [ - "# How to: create a ReAct agent" + "# How to create a ReAct agent" ] }, { @@ -16,7 +16,7 @@ "outputs": [], "source": [ "%%capture --no-stderr\n", - "%pip install -U langgraph langchain-community langchain-openai tavily-python" + "%pip install -U langgraph langchain-openai" ] }, { @@ -37,8 +37,7 @@ "name": "stdin", "output_type": "stream", "text": [ - "OPENAI_API_KEY: ········\n", - "TAVILY_API_KEY: ········\n" + "OPENAI_API_KEY: ········\n" ] } ], @@ -48,12 +47,11 @@ "\n", "\n", "def _set_env(var: str):\n", - " # if not os.environ.get(var):\n", - " os.environ[var] = getpass.getpass(f\"{var}: \")\n", + " if not os.environ.get(var):\n", + " os.environ[var] = getpass.getpass(f\"{var}: \")\n", "\n", "\n", "_set_env(\"OPENAI_API_KEY\")\n", - "_set_env(\"TAVILY_API_KEY\")\n", "\n", "# Recommended\n", "_set_env(\"LANGCHAIN_API_KEY\")\n", @@ -66,7 +64,7 @@ "id": "03c0f089-070c-4cd4-87e0-6c51f2477b82", "metadata": {}, "source": [ - "## How to: create a simple ReAct agent" + "## How to create a simple ReAct agent" ] }, { @@ -74,12 +72,12 @@ "id": "f1c8e137-e6e6-4f9f-bd1b-77359a1c4ec5", "metadata": {}, "source": [ - "Let's create a simple ReAct agent app that can search the web. 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", + "Let's create a simple ReAct 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)\n", "\n", - "In our example we'll use `ChatOpenAI` as our agent and [Tavily Search API](https://tavily.com/) as our tool." + "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)" ] }, { @@ -93,51 +91,30 @@ { "cell_type": "code", "execution_count": 3, - "id": "47726059-e6ea-4c5e-babe-aa5e6bad739f", + "id": "029c838a-c6e7-4679-9a8b-953703fe3041", "metadata": {}, "outputs": [], "source": [ - "from langchain_openai import ChatOpenAI" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "ea3a8657-ecb3-42f9-8b94-cd2bbca68055", - "metadata": {}, - "outputs": [], - "source": [ - "model = ChatOpenAI(model=\"gpt-4o\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "98934efd-1b28-4475-af26-b4d55c8eae18", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_community.tools.tavily_search import TavilySearchResults" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "c69aac7b-0053-4c28-8524-1d5d58451a87", - "metadata": {}, - "outputs": [], - "source": [ - "tavily_search_tool = TavilySearchResults(max_results=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "e132bd2c-a98a-46e2-b0a8-02ec4dec4f58", - "metadata": {}, - "outputs": [], - "source": [ - "tools = [tavily_search_tool]" + "from typing import Literal\n", + "\n", + "from langchain_core.tools import tool\n", + "from langchain_openai import ChatOpenAI\n", + "\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", + "tools = [get_weather]" ] }, { @@ -150,38 +127,19 @@ }, { "cell_type": "code", - "execution_count": 8, - "id": "11fa1a0f-b99e-4b39-9827-b191b601e79c", - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph.prebuilt import create_react_agent" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "fe4bc2a0-075d-4042-8bfb-738cbf1f98de", + "execution_count": 4, + "id": "3d2df9e7-4c2c-494a-9249-5a2ee32eca3e", "metadata": {}, "outputs": [], "source": [ + "from langgraph.prebuilt import create_react_agent\n", "graph = create_react_agent(model, tools=tools)" ] }, { "cell_type": "code", - "execution_count": 10, - "id": "65256d47-2fab-416e-a9d3-4fac25951c0a", - "metadata": {}, - "outputs": [], - "source": [ - "from IPython.display import display, Image" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "7dc12855-2cb4-4f64-80cf-ef3297e6eb96", + "execution_count": 5, + "id": "fa16de4c-aac0-4ff4-ab69-60d399f75423", "metadata": {}, "outputs": [ { @@ -196,12 +154,14 @@ } ], "source": [ + "from IPython.display import display, Image\n", + "\n", "display(Image(graph.get_graph().draw_mermaid_png()))" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 6, "id": "16636975-5f2d-4dc7-ab8e-d0bea0830a28", "metadata": {}, "outputs": [], @@ -225,7 +185,17 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 7, + "id": "46aa3f8f-067d-4178-99f8-806071ea78dd", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_core.tools import Tool" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "id": "9ffff6c3-a4f5-47c9-b51d-97caaee85cd6", "metadata": {}, "outputs": [ @@ -238,27 +208,17 @@ "what is the weather in sf\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "Tool Calls:\n", - " tavily_search_results_json (call_3mZvRQf2INoE9kHCtMD7wYXf)\n", - " Call ID: call_3mZvRQf2INoE9kHCtMD7wYXf\n", + " get_weather (call_g6w9lHn3fxYo2ABE3Ihhprbr)\n", + " Call ID: call_g6w9lHn3fxYo2ABE3Ihhprbr\n", " Args:\n", - " query: current weather in San Francisco\n", + " city: sf\n", "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search_results_json\n", + "Name: get_weather\n", "\n", - "[{\"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': 1718290752, 'localtime': '2024-06-13 7:59'}, 'current': {'last_updated_epoch': 1718289900, 'last_updated': '2024-06-13 07:45', 'temp_c': 14.4, 'temp_f': 57.9, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1013.0, 'pressure_in': 29.92, 'precip_mm': 0.01, 'precip_in': 0.0, 'humidity': 84, 'cloud': 75, 'feelslike_c': 13.4, 'feelslike_f': 56.0, 'windchill_c': 10.1, 'windchill_f': 50.1, 'heatindex_c': 11.7, 'heatindex_f': 53.1, 'dewpoint_c': 8.8, 'dewpoint_f': 47.9, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 3.0, 'gust_mph': 12.7, 'gust_kph': 20.4}}\"}]\n", + "It's always sunny in sf\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "The current weather in San Francisco is as follows:\n", - "- **Condition:** Partly cloudy\n", - "- **Temperature:** 14.4°C (57.9°F)\n", - "- **Feels Like:** 13.4°C (56.0°F)\n", - "- **Wind:** 2.2 mph (3.6 kph) from the North\n", - "- **Humidity:** 84%\n", - "- **Pressure:** 1013.0 mb\n", - "- **Visibility:** 16.0 km (9.0 miles)\n", - "- **UV Index:** 3\n", - "\n", - "![Partly cloudy](//cdn.weatherapi.com/weather/64x64/day/116.png)\n" + "The weather in San Francisco is currently sunny.\n" ] } ], @@ -277,7 +237,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 9, "id": "187479f9-32fa-4611-9487-cf816ba2e147", "metadata": {}, "outputs": [ @@ -290,7 +250,7 @@ "who built you?\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "I was developed by OpenAI, a research organization focused on artificial intelligence. OpenAI creates and maintains AI models like me to assist with a wide range of tasks and provide information.\n" + "I was created by OpenAI, a research organization focused on developing and advancing artificial intelligence technology.\n" ] } ], @@ -304,7 +264,7 @@ "id": "82b06aa3-6414-48e6-ba11-07bf065a316a", "metadata": {}, "source": [ - "## How to: add system prompt to `create_react_agent`" + "## How to add system prompt to `create_react_agent`" ] }, { @@ -319,19 +279,8 @@ }, { "cell_type": "code", - "execution_count": 15, - "id": "2396d3ac-88f8-4a40-9e97-442173ba843c", - "metadata": {}, - "outputs": [], - "source": [ - "system_prompt = \"You are a helpful bot named Fred.\"\n", - "graph = create_react_agent(model, tools, messages_modifier=system_prompt)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "50d989d5-424e-447e-b70e-931ead21e663", + "execution_count": 10, + "id": "23ea0a31-3e6b-433b-a832-036655579ebe", "metadata": {}, "outputs": [ { @@ -342,24 +291,25 @@ "\n", "What's your name? And what's the weather in SF?\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "My name is Fred. Let me check the current weather in San Francisco for you.\n", "Tool Calls:\n", - " tavily_search_results_json (call_UuiAgBOpGLekVLNJxwjsTzGY)\n", - " Call ID: call_UuiAgBOpGLekVLNJxwjsTzGY\n", + " get_weather (call_PGwTiytTVAAvNKWp4nznPi4s)\n", + " Call ID: call_PGwTiytTVAAvNKWp4nznPi4s\n", " Args:\n", - " query: current weather in San Francisco\n", + " city: sf\n", "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search_results_json\n", + "Name: get_weather\n", "\n", - "[{\"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': 1718290752, 'localtime': '2024-06-13 7:59'}, 'current': {'last_updated_epoch': 1718289900, 'last_updated': '2024-06-13 07:45', 'temp_c': 14.4, 'temp_f': 57.9, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1013.0, 'pressure_in': 29.92, 'precip_mm': 0.01, 'precip_in': 0.0, 'humidity': 84, 'cloud': 75, 'feelslike_c': 13.4, 'feelslike_f': 56.0, 'windchill_c': 10.1, 'windchill_f': 50.1, 'heatindex_c': 11.7, 'heatindex_f': 53.1, 'dewpoint_c': 8.8, 'dewpoint_f': 47.9, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 3.0, 'gust_mph': 12.7, 'gust_kph': 20.4}}\"}]\n", + "It's always sunny in sf\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "My name is Fred. The current weather in San Francisco is partly cloudy with a temperature of approximately 14.4°C (57.9°F). The wind is blowing from the north at about 2.2 mph (3.6 kph), and the humidity is around 84%.\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\"))" ] @@ -374,29 +324,8 @@ }, { "cell_type": "code", - "execution_count": 17, - "id": "894b9d53-cd99-465c-b183-988f797d6b5b", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_core.prompts import ChatPromptTemplate\n", - "prompt = ChatPromptTemplate.from_messages([\n", - " (\"system\", \"You are a helpful bot named Fred.\"),\n", - " (\"placeholder\", \"{messages}\"),\n", - " (\"user\", \"Remember, always be polite!\"),\n", - "])\n", - "\n", - "def modify_messages(messages: list):\n", - " # You can do more complex modifications here\n", - " return prompt.invoke({\"messages\": messages})\n", - "\n", - "graph = create_react_agent(model, tools, messages_modifier=modify_messages)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "8602282f-72ec-405f-b014-e1e319f73d33", + "execution_count": 11, + "id": "23c40ab3-c574-47be-a80f-654e9035cd6d", "metadata": {}, "outputs": [ { @@ -405,43 +334,38 @@ "text": [ "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", - "What's your name? And what's the weather in SF?\n", + "What's my name? And what's the weather in SF?\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "Hello! My name is Fred. Let me check the current weather in San Francisco for you.\n", "Tool Calls:\n", - " tavily_search_results_json (call_QOco9uwxOZaoh9WaSwoMc3eA)\n", - " Call ID: call_QOco9uwxOZaoh9WaSwoMc3eA\n", + " get_weather (call_scpzIjdK3l411zcEn2T00Xm0)\n", + " Call ID: call_scpzIjdK3l411zcEn2T00Xm0\n", " Args:\n", - " query: current weather in San Francisco\n", + " city: sf\n", "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search_results_json\n", + "Name: get_weather\n", "\n", - "HTTPError('502 Server Error: Bad Gateway for url: https://api.tavily.com/search')\n", + "It's always sunny in sf\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "Of course! I always strive to be polite and helpful. Let's try to find out the current weather in San Francisco again.\n", - "Tool Calls:\n", - " tavily_search_results_json (call_G6x1cxoXQbRBPZ8i18X40j0d)\n", - " Call ID: call_G6x1cxoXQbRBPZ8i18X40j0d\n", - " Args:\n", - " query: current weather in San Francisco\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search_results_json\n", - "\n", - "[{\"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': 1718290752, 'localtime': '2024-06-13 7:59'}, 'current': {'last_updated_epoch': 1718289900, 'last_updated': '2024-06-13 07:45', 'temp_c': 14.4, 'temp_f': 57.9, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1013.0, 'pressure_in': 29.92, 'precip_mm': 0.01, 'precip_in': 0.0, 'humidity': 84, 'cloud': 75, 'feelslike_c': 13.4, 'feelslike_f': 56.0, 'windchill_c': 10.1, 'windchill_f': 50.1, 'heatindex_c': 11.7, 'heatindex_f': 53.1, 'dewpoint_c': 8.8, 'dewpoint_f': 47.9, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 3.0, 'gust_mph': 12.7, 'gust_kph': 20.4}}\"}]\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "Of course! I always strive to be polite and helpful.\n", - "\n", - "Currently, in San Francisco, it is partly cloudy with a temperature of approximately 14.4°C (57.9°F). The wind is blowing from the north at around 2.2 mph (3.6 kph). The humidity level is quite high at 84%, and visibility is good at 16 km (9 miles).\n", - "\n", - "Is there anything else you would like to know?\n" + "Your name is Joe. The weather in San Francisco is always sunny.\n" ] } ], "source": [ - "inputs = {\"messages\": [(\"user\", \"What's your name? And what's the weather in SF?\")]}\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "prompt = ChatPromptTemplate.from_messages([\n", + " (\"system\", \"You are a helpful bot named Fred.\"),\n", + " (\"user\", \"My name is Joe\"),\n", + " (\"placeholder\", \"{messages}\"),\n", + "])\n", + "\n", + "def modify_messages(messages: list):\n", + " # You can do more complex modifications here\n", + " return prompt.invoke({\"messages\": messages})\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\"))" ] }, @@ -450,7 +374,7 @@ "id": "0af418b8-bdd3-4e10-a552-9d8d2a409a57", "metadata": {}, "source": [ - "## How to: add memory to `create_react_agent`" + "## How to add memory to `create_react_agent`" ] }, { @@ -463,30 +387,8 @@ }, { "cell_type": "code", - "execution_count": 19, - "id": "dfd72a3c-3ff9-4bc3-ab51-f3c8424e7932", - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph.checkpoint import MemorySaver\n", - "graph = create_react_agent(model, tools, checkpointer=MemorySaver())" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "3db05867-1ced-402c-b739-72afda037e7f", - "metadata": {}, - "outputs": [], - "source": [ - "config = {\"configurable\": {\"thread_id\": \"1\"}}\n", - "inputs = {\"messages\": [(\"user\", \"What's the weather in SF?\")]}" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "fcf1f692-b437-4f8d-9a75-94a018e90a7c", + "execution_count": 12, + "id": "c43d071a-a91e-4646-a035-b3fed9cd9f0c", "metadata": {}, "outputs": [ { @@ -495,24 +397,30 @@ "text": [ "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", - "What's the weather in SF?\n", + "What's the weather in NYC?\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "Tool Calls:\n", - " tavily_search_results_json (call_SQua8Xc6fLjtJlS8CvaCxH2U)\n", - " Call ID: call_SQua8Xc6fLjtJlS8CvaCxH2U\n", + " get_weather (call_C5yEOD1GhlVPX9Gc5nnqgUXF)\n", + " Call ID: call_C5yEOD1GhlVPX9Gc5nnqgUXF\n", " Args:\n", - " query: current weather in San Francisco\n", + " city: nyc\n", "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search_results_json\n", + "Name: get_weather\n", "\n", - "[{\"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': 1718290938, 'localtime': '2024-06-13 8:02'}, 'current': {'last_updated_epoch': 1718290800, 'last_updated': '2024-06-13 08:00', 'temp_c': 14.4, 'temp_f': 57.9, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1013.0, 'pressure_in': 29.92, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 84, 'cloud': 75, 'feelslike_c': 13.4, 'feelslike_f': 56.2, 'windchill_c': 11.1, 'windchill_f': 52.0, 'heatindex_c': 12.5, 'heatindex_f': 54.6, 'dewpoint_c': 8.8, 'dewpoint_f': 47.9, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 4.0, 'gust_mph': 11.3, 'gust_kph': 18.1}}\"}]\n", + "It might be cloudy in nyc\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "The current weather in San Francisco is partly cloudy with a temperature of 14.4°C (57.9°F). The wind is blowing from the north at 2.2 mph (3.6 kph). Humidity is at 84%, and visibility is 16 km (9 miles). The UV index is 4.\n" + "The weather in NYC might be cloudy.\n" ] } ], "source": [ + "from langgraph.checkpoint import MemorySaver\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\"))" ] }, @@ -526,7 +434,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 13, "id": "b509417b-70f3-4736-b838-5d1729ed759e", "metadata": {}, "outputs": [ @@ -536,25 +444,54 @@ "text": [ "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", - "How about NYC?\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " tavily_search_results_json (call_s3cYMxsn11IfPxEMsxMp9Ycb)\n", - " Call ID: call_s3cYMxsn11IfPxEMsxMp9Ycb\n", - " Args:\n", - " query: current weather in New York City\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search_results_json\n", - "\n", - "[{\"url\": \"https://www.weatherapi.com/\", \"content\": \"{'location': {'name': 'New York', 'region': 'New York', 'country': 'United States of America', 'lat': 40.71, 'lon': -74.01, 'tz_id': 'America/New_York', 'localtime_epoch': 1718290946, 'localtime': '2024-06-13 11:02'}, 'current': {'last_updated_epoch': 1718290800, 'last_updated': '2024-06-13 11:00', 'temp_c': 23.9, 'temp_f': 75.0, 'is_day': 1, 'condition': {'text': 'Sunny', 'icon': '//cdn.weatherapi.com/weather/64x64/day/113.png', 'code': 1000}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1018.0, 'pressure_in': 30.05, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 55, 'cloud': 0, 'feelslike_c': 24.9, 'feelslike_f': 76.7, 'windchill_c': 26.1, 'windchill_f': 78.9, 'heatindex_c': 26.2, 'heatindex_f': 79.2, 'dewpoint_c': 12.5, 'dewpoint_f': 54.6, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 7.0, 'gust_mph': 7.2, 'gust_kph': 11.6}}\"}]\n", + "What's it known for?\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "The current weather in New York City is sunny with a temperature of 23.9°C (75.0°F). The wind is blowing from the north at 2.2 mph (3.6 kph). Humidity is at 55%, and visibility is 16 km (9 miles). The UV index is 7.\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\", \"How about NYC?\")]}\n", + "inputs = {\"messages\": [(\"user\", \"What's it known for?\")]}\n", "print_stream(graph.stream(inputs, config=config, stream_mode=\"values\"))" ] }, @@ -568,7 +505,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 14, "id": "1bb09dbe-bbba-4e8f-b44c-b18bd2ed96ff", "metadata": {}, "outputs": [ @@ -578,25 +515,15 @@ "text": [ "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", - "How about NYC?\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " tavily_search_results_json (call_uXGI87Qw09CHNiDgYBgOrhoJ)\n", - " Call ID: call_uXGI87Qw09CHNiDgYBgOrhoJ\n", - " Args:\n", - " query: current news in NYC\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search_results_json\n", - "\n", - "[{\"url\": \"https://abc7ny.com/\", \"content\": \"New York's source for breaking news, weather and live video. Covering NYC, New Jersey, Long Island and all of the greater New York City area.\"}]\n", + "What's it known for?\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "For the latest news in NYC, you can visit [ABC7 New York](https://abc7ny.com/). They provide updates on breaking news, weather, and live video coverage for New York City, New Jersey, Long Island, and the greater NYC area.\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\", \"How about NYC?\")]}\n", + "inputs = {\"messages\": [(\"user\", \"What's it known for?\")]}\n", "print_stream(graph.stream(inputs, config={\"configurable\": {\"thread_id\": 2}}, stream_mode=\"values\"))" ] }, @@ -605,7 +532,7 @@ "id": "42e730aa-8fac-48a5-9c67-b51393665469", "metadata": {}, "source": [ - "## How to: add human-in-the-loop to `create_react_agent`" + "## How to add human-in-the-loop to `create_react_agent`" ] }, { @@ -618,23 +545,8 @@ }, { "cell_type": "code", - "execution_count": 24, - "id": "fe93def9-6ba4-4c89-9e84-1ff607dbfc8c", - "metadata": {}, - "outputs": [], - "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?\")]}" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "4d934d6a-6550-453b-8c23-fbb8b4656da6", + "execution_count": 15, + "id": "8cd2cbcc-8a1f-443e-9cc9-dc18cd0ceac6", "metadata": {}, "outputs": [ { @@ -646,20 +558,27 @@ "What's the weather in SF?\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "Tool Calls:\n", - " tavily_search_results_json (call_Wg4AZqacqqUHHmQfjOjudAyP)\n", - " Call ID: call_Wg4AZqacqqUHHmQfjOjudAyP\n", + " get_weather (call_I7B9YW4ENth7QXYzDpiIoLCE)\n", + " Call ID: call_I7B9YW4ENth7QXYzDpiIoLCE\n", " Args:\n", - " query: current weather in San Francisco\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": 26, + "execution_count": 16, "id": "493d4963-b27b-46ef-8474-1527b08c1c03", "metadata": {}, "outputs": [ @@ -678,7 +597,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 17, "id": "7ad01f3a-e838-4230-ab07-2f850bb7e7cb", "metadata": {}, "outputs": [ @@ -687,21 +606,12 @@ "output_type": "stream", "text": [ "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search_results_json\n", + "Name: get_weather\n", "\n", - "[{\"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': 1718290938, 'localtime': '2024-06-13 8:02'}, 'current': {'last_updated_epoch': 1718290800, 'last_updated': '2024-06-13 08:00', 'temp_c': 14.4, 'temp_f': 57.9, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1013.0, 'pressure_in': 29.92, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 84, 'cloud': 75, 'feelslike_c': 13.4, 'feelslike_f': 56.2, 'windchill_c': 11.1, 'windchill_f': 52.0, 'heatindex_c': 12.5, 'heatindex_f': 54.6, 'dewpoint_c': 8.8, 'dewpoint_f': 47.9, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 4.0, 'gust_mph': 11.3, 'gust_kph': 18.1}}\"}]\n", + "It's always sunny in sf\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "The current weather in San Francisco is:\n", - "\n", - "- **Temperature**: 14.4°C (57.9°F)\n", - "- **Condition**: Partly cloudy\n", - "- **Wind**: 2.2 mph (3.6 kph) from the north\n", - "- **Humidity**: 84%\n", - "- **Visibility**: 16 km (9 miles)\n", - "- **UV Index**: 4\n", - "\n", - "![Weather Icon](//cdn.weatherapi.com/weather/64x64/day/116.png)\n" + "The weather in San Francisco is currently sunny.\n" ] } ], From fabade8ff5e263da4638dffa4dd8d3a8f1d80266 Mon Sep 17 00:00:00 2001 From: vbarda Date: Thu, 13 Jun 2024 19:24:37 -0400 Subject: [PATCH 5/7] lint --- examples/create-react-agent.ipynb | 39 ++++++++++++++++--------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/examples/create-react-agent.ipynb b/examples/create-react-agent.ipynb index d9ccff1c0..e591c7d40 100644 --- a/examples/create-react-agent.ipynb +++ b/examples/create-react-agent.ipynb @@ -34,7 +34,7 @@ "metadata": {}, "outputs": [ { - "name": "stdin", + "name": "stdout", "output_type": "stream", "text": [ "OPENAI_API_KEY: ········\n" @@ -100,7 +100,6 @@ "from langchain_core.tools import tool\n", "from langchain_openai import ChatOpenAI\n", "\n", - "\n", "model = ChatOpenAI(model=\"gpt-4o\", temperature=0)\n", "\n", "\n", @@ -114,6 +113,7 @@ " else:\n", " raise AssertionError(\"Unknown city\")\n", "\n", + "\n", "tools = [get_weather]" ] }, @@ -133,6 +133,7 @@ "outputs": [], "source": [ "from langgraph.prebuilt import create_react_agent\n", + "\n", "graph = create_react_agent(model, tools=tools)" ] }, @@ -154,7 +155,7 @@ } ], "source": [ - "from IPython.display import display, Image\n", + "from IPython.display import Image, display\n", "\n", "display(Image(graph.get_graph().draw_mermaid_png()))" ] @@ -183,16 +184,6 @@ "Let's run the app with an input that needs a tool call" ] }, - { - "cell_type": "code", - "execution_count": 7, - "id": "46aa3f8f-067d-4178-99f8-806071ea78dd", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_core.tools import Tool" - ] - }, { "cell_type": "code", "execution_count": 8, @@ -353,16 +344,21 @@ ], "source": [ "from langchain_core.prompts import ChatPromptTemplate\n", - "prompt = ChatPromptTemplate.from_messages([\n", - " (\"system\", \"You are a helpful bot named Fred.\"),\n", - " (\"user\", \"My name is Joe\"),\n", - " (\"placeholder\", \"{messages}\"),\n", - "])\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", @@ -416,6 +412,7 @@ ], "source": [ "from langgraph.checkpoint import MemorySaver\n", + "\n", "graph = create_react_agent(model, tools, checkpointer=MemorySaver())\n", "\n", "config = {\"configurable\": {\"thread_id\": \"1\"}}\n", @@ -524,7 +521,11 @@ ], "source": [ "inputs = {\"messages\": [(\"user\", \"What's it known for?\")]}\n", - "print_stream(graph.stream(inputs, config={\"configurable\": {\"thread_id\": 2}}, stream_mode=\"values\"))" + "print_stream(\n", + " graph.stream(\n", + " inputs, config={\"configurable\": {\"thread_id\": 2}}, stream_mode=\"values\"\n", + " )\n", + ")" ] }, { From 0b703444a160a89e05ae743e13b79c2e592926b7 Mon Sep 17 00:00:00 2001 From: vbarda Date: Thu, 13 Jun 2024 19:53:04 -0400 Subject: [PATCH 6/7] update script/yml --- docs/_scripts/copy_notebooks.py | 1 + docs/mkdocs.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/_scripts/copy_notebooks.py b/docs/_scripts/copy_notebooks.py index 9bf27cfd1..c955dd6b7 100644 --- a/docs/_scripts/copy_notebooks.py +++ b/docs/_scripts/copy_notebooks.py @@ -29,6 +29,7 @@ _MANUAL = { "configuration.ipynb", "map-reduce.ipynb", "extraction/retries.ipynb", + "create-react-agent.ipynb" ], "tutorials": [ "introduction.ipynb", diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 03b15f54b..4ae33de7b 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -137,6 +137,7 @@ nav: - "How-to Guides": - 'how-tos/index.md' - Core: + - "ReAct Agent": how-tos/create-react-agent.ipynb - "Persistence": how-tos/persistence.ipynb - "Time Travel": how-tos/time-travel.ipynb - "Async Execution": how-tos/async.ipynb From fe464591f7bfed9c537883be5b56591c4d9b2b61 Mon Sep 17 00:00:00 2001 From: vbarda Date: Mon, 17 Jun 2024 15:24:17 -0400 Subject: [PATCH 7/7] code review --- docs/_scripts/copy_notebooks.py | 2 +- examples/create-react-agent.ipynb | 32 ++++++++++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/docs/_scripts/copy_notebooks.py b/docs/_scripts/copy_notebooks.py index c955dd6b7..b573c1a22 100644 --- a/docs/_scripts/copy_notebooks.py +++ b/docs/_scripts/copy_notebooks.py @@ -29,7 +29,7 @@ _MANUAL = { "configuration.ipynb", "map-reduce.ipynb", "extraction/retries.ipynb", - "create-react-agent.ipynb" + "create-react-agent.ipynb", ], "tutorials": [ "introduction.ipynb", diff --git a/examples/create-react-agent.ipynb b/examples/create-react-agent.ipynb index e591c7d40..35a3bb6e3 100644 --- a/examples/create-react-agent.ipynb +++ b/examples/create-react-agent.ipynb @@ -9,14 +9,14 @@ ] }, { - "cell_type": "code", - "execution_count": 1, - "id": "a213e11a-5c62-4ddb-a707-490d91add383", + "cell_type": "markdown", + "id": "e0fcced0-9767-412f-90f9-7f3cd618ff90", "metadata": {}, - "outputs": [], "source": [ - "%%capture --no-stderr\n", - "%pip install -U langgraph langchain-openai" + "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)" ] }, { @@ -27,6 +27,17 @@ "## 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, @@ -64,19 +75,14 @@ "id": "03c0f089-070c-4cd4-87e0-6c51f2477b82", "metadata": {}, "source": [ - "## How to create a simple ReAct agent" + "## How to create a simple ReAct agent with `create_react_agent`" ] }, { "cell_type": "markdown", - "id": "f1c8e137-e6e6-4f9f-bd1b-77359a1c4ec5", + "id": "91efaf20-711b-4b94-837e-dcef10d8abdd", "metadata": {}, "source": [ - "Let's create a simple ReAct 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)\n", - "\n", "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)" ] },