From c88750d54b0faf7a3a1250bb9be093dbfa74b9fc Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 22 Jan 2024 21:54:55 -0500 Subject: [PATCH] Docs: Agent streaming notebooks (#15858) Update information about streaming in the agents section. Show how to use astream_events to get token by token streaming. --- .../modules/agents/how_to/streaming.ipynb | 1680 +++++++++-------- .../agents/how_to/streaming_events.ipynb | 350 ---- 2 files changed, 862 insertions(+), 1168 deletions(-) delete mode 100644 docs/docs/modules/agents/how_to/streaming_events.ipynb diff --git a/docs/docs/modules/agents/how_to/streaming.ipynb b/docs/docs/modules/agents/how_to/streaming.ipynb index deb3e35891..b6095de0a4 100644 --- a/docs/docs/modules/agents/how_to/streaming.ipynb +++ b/docs/docs/modules/agents/how_to/streaming.ipynb @@ -17,65 +17,163 @@ "source": [ "# Streaming\n", "\n", - "Streaming is an important UX consideration for LLM apps, and agents are no exception. Streaming with agents is made more complicated by the fact that it's not just tokens that you will want to stream, but you may also want to stream back the intermediate steps an agent takes.\n", + "Streaming is an important UX consideration for LLM apps, and agents are no exception. Streaming with agents is made more complicated by the fact that it's not just tokens of the final answer that you will want to stream, but you may also want to stream back the intermediate steps an agent takes.\n", "\n", - "Let's take a look at how to do this." + "In this notebook, we'll cover the `stream/astream` and `astream_events` for streaming.\n", + "\n", + "Our agent will use a tools API for tool invocation with the tools:\n", + "\n", + "1. `where_cat_is_hiding`: Returns a location where the cat is hiding\n", + "2. `get_items`: Lists items that can be found in a particular place\n", + "\n", + "These tools will allow us to explore streaming in a more interesting situation where the agent will have to use both tools to answer some questions (e.g., to answer the question `what items are located where the cat is hiding?`).\n", + "\n", + "Ready?🏎️" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d40aae3d-b872-4e0f-ad54-8df6150fa863", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain import hub\n", + "from langchain.agents import AgentExecutor, create_openai_tools_agent\n", + "from langchain.prompts import ChatPromptTemplate\n", + "from langchain.tools import tool\n", + "from langchain_core.callbacks import Callbacks\n", + "from langchain_openai import ChatOpenAI" ] }, { "cell_type": "markdown", - "id": "def159c3", + "id": "59502ed8-2f9f-4758-a0d5-90a0392ed33d", "metadata": {}, "source": [ - "## Set up the agent\n", - "\n", - "Let's set up a simple agent for demonstration purposes. For our tool, we will use [Tavily](/docs/integrations/tools/tavily_search). Make sure that you've exported an API key with \n", + "## Create the model\n", "\n", - "```bash\n", - "export TAVILY_API_KEY=\"...\"\n", - "```" + "**Attention** We're setting `streaming=True` on the LLM. This will allow us to stream tokens from the agent using the `astream_events` API. This is needed for older versions of LangChain." ] }, { "cell_type": "code", - "execution_count": 1, - "id": "670078c4", + "execution_count": 2, + "id": "66e36d43-2c12-4cda-b591-383eb61b4f69", "metadata": {}, "outputs": [], "source": [ - "from langchain_community.tools.tavily_search import TavilySearchResults\n", - "\n", - "search = TavilySearchResults()\n", - "tools = [search]" + "model = ChatOpenAI(temperature=0, streaming=True)" ] }, { "cell_type": "markdown", - "id": "5e04164b", + "id": "7ec9c5e5-34d4-4208-9f78-7f9a1ff3029b", "metadata": {}, "source": [ - "We will use a prompt from the hub - you can inspect the prompt more at [https://smith.langchain.com/hub/hwchase17/openai-functions-agent](https://smith.langchain.com/hub/hwchase17/openai-functions-agent)" + "## Tools\n", + "\n", + "We define two tools that rely on a chat model to generate output!" ] }, { "cell_type": "code", "execution_count": 3, - "id": "d8c5d907", + "id": "cd29a18c-e11c-4fbe-9fb8-b64dc9be95fd", "metadata": {}, "outputs": [], "source": [ - "from langchain import hub\n", - "from langchain.agents import AgentExecutor, create_openai_functions_agent\n", - "from langchain_openai import ChatOpenAI\n", + "import random\n", "\n", - "# Get the prompt to use - you can modify this!\n", - "# If you want to see the prompt in full, you can at: https://smith.langchain.com/hub/hwchase17/openai-functions-agent\n", - "prompt = hub.pull(\"hwchase17/openai-functions-agent\")\n", "\n", - "llm = ChatOpenAI(model=\"gpt-3.5-turbo\", temperature=0)\n", + "@tool\n", + "async def where_cat_is_hiding() -> str:\n", + " \"\"\"Where is the cat hiding right now?\"\"\"\n", + " return random.choice([\"under the bed\", \"on the shelf\"])\n", "\n", - "agent = create_openai_functions_agent(llm, tools, prompt)\n", - "agent_executor = AgentExecutor(agent=agent, tools=tools)" + "\n", + "@tool\n", + "async def get_items(place: str) -> str:\n", + " \"\"\"Use this tool to look up which items are in the given place.\"\"\"\n", + " if \"bed\" in place: # For under the bed\n", + " return \"socks, shoes and dust bunnies\"\n", + " if \"shelf\" in place: # For 'shelf'\n", + " return \"books, penciles and pictures\"\n", + " else: # if the agent decides to ask about a different place\n", + " return \"cat snacks\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "1257a508-c791-4d81-82d2-df021c560bec", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'on the shelf'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "await where_cat_is_hiding.ainvoke({})" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "eea408ee-5260-418c-b769-5ba20e2999e1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'books, penciles and pictures'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "await get_items.ainvoke({\"place\": \"shelf\"})" + ] + }, + { + "cell_type": "markdown", + "id": "07c08cd5-34eb-41a7-b524-7c3d1d274a67", + "metadata": {}, + "source": [ + "## Initialize the agent\n", + "\n", + "Here, we'll initialize an OpenAI tools agent.\n", + "\n", + "**ATTENTION** Please note that we associated the name `Agent` with our agent using `\"run_name\"=\"Agent\"`. We'll use that fact later on with the `astream_events` API." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "adecca7a-9864-496d-a3a9-906b56ecd03b", + "metadata": {}, + "outputs": [], + "source": [ + "# Get the prompt to use - you can modify this!\n", + "prompt = hub.pull(\"hwchase17/openai-tools-agent\")\n", + "# print(prompt.messages) -- to see the prompt\n", + "tools = [get_items, where_cat_is_hiding]\n", + "agent = create_openai_tools_agent(\n", + " model.with_config({\"tags\": [\"agent_llm\"]}), tools, prompt\n", + ")\n", + "agent_executor = AgentExecutor(agent=agent, tools=tools).with_config(\n", + " {\"run_name\": \"Agent\"}\n", + ")" ] }, { @@ -83,51 +181,132 @@ "id": "cba9a9eb", "metadata": {}, "source": [ - "## Stream intermediate steps\n", + "## Stream Intermediate Steps\n", + "\n", + "We'll use `.stream` method of the AgentExecutor to stream the agent's intermediate steps.\n", + "\n", + "The output from `.stream` alternates between (action, observation) pairs, finally concluding with the answer if the agent achieved its objective. \n", + "\n", + "It'll look like this:\n", + "\n", + "1. actions output\n", + "2. observations output\n", + "3. actions output\n", + "4. observations output\n", + "\n", + "**... (continue until goal is reached) ...**\n", + "\n", + "Then, if the final goal is reached, the agent will output the **final answer**.\n", "\n", - "Let's look at how to stream intermediate steps. We can do this easily by just using the `.stream` method on the AgentExecutor" + "\n", + "The contents of these outputs are summarized here:\n", + "\n", + "| Output | Contents |\n", + "|----------------------|------------------------------------------------------------------------------------------------------|\n", + "| **Actions** | `actions` `AgentAction` or a subclass, `messages` chat messages corresponding to action invocation |\n", + "| **Observations** | `steps` History of what the agent did so far, including the current action and its observation, `messages` chat message with function invocation results (aka observations)|\n", + "| **Final answer** | `output` `AgentFinish`, `messages` chat messages with the final output|" ] }, { "cell_type": "code", - "execution_count": 4, - "id": "b6bd9bf2", + "execution_count": 7, + "id": "eab4d4a0-55ed-407a-baf0-9f0eaf8c3518", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{'actions': [AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}})])], 'messages': [AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}})]}\n", "------\n", - "{'steps': [AgentStep(action=AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}})]), observation=[{'url': 'https://weather.com/weather/tenday/l/San Francisco CA USCA0987:1:US', 'content': 'recents Specialty Forecasts 10 Day Weather-San Francisco, CA Today Mon 18 | Day Fri 22 Fri 22 | Day Foggy early, then partly cloudy later in the day. High around 60F. Winds W at 10 to 15 mph. Considerable cloudiness with occasional rain showers. High 59F. Winds SSE at 5 to 10 mph. Chance of rain 50%. Thu 28 | Night Cloudy with showers. Low 46F. Winds S at 5 to 10 mph. Chance of rain 40%. Fri 29 Fri 29 | Day10 Day Weather-San Francisco, CA As of 5:52 pm PST alertLevel3 Coastal Flood Advisory+1 More Tonight Mostly Cloudy Night --/44° Rain 7% Arrow Up Sun 24| Night 44° Mostly Cloudy Night Rain 7%...'}])], 'messages': [FunctionMessage(content='[{\"url\": \"https://weather.com/weather/tenday/l/San Francisco CA USCA0987:1:US\", \"content\": \"recents Specialty Forecasts 10 Day Weather-San Francisco, CA Today Mon 18 | Day Fri 22 Fri 22 | Day Foggy early, then partly cloudy later in the day. High around 60F. Winds W at 10 to 15 mph. Considerable cloudiness with occasional rain showers. High 59F. Winds SSE at 5 to 10 mph. Chance of rain 50%. Thu 28 | Night Cloudy with showers. Low 46F. Winds S at 5 to 10 mph. Chance of rain 40%. Fri 29 Fri 29 | Day10 Day Weather-San Francisco, CA As of 5:52 pm PST alertLevel3 Coastal Flood Advisory+1 More Tonight Mostly Cloudy Night --/44° Rain 7% Arrow Up Sun 24| Night 44° Mostly Cloudy Night Rain 7%...\"}]', name='tavily_search_results_json')]}\n", + "{'actions': [...], 'messages': [...]}\n", "------\n", - "{'actions': [AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in Los Angeles'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in Los Angeles'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in Los Angeles\"\\n}', 'name': 'tavily_search_results_json'}})])], 'messages': [AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in Los Angeles\"\\n}', 'name': 'tavily_search_results_json'}})]}\n", + "{'messages': [...], 'steps': [...]}\n", "------\n", - "{'steps': [AgentStep(action=AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in Los Angeles'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in Los Angeles'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in Los Angeles\"\\n}', 'name': 'tavily_search_results_json'}})]), observation=[{'url': 'https://weather.com/weather/tenday/l/Los+Angeles+CA?canonicalCityId=84c64154109916077c8d3c2352410aaae5f6eeff682000e3a7470e38976128c2', 'content': 'recents Specialty Forecasts 10 Day Weather-Los Angeles, CA Air Quality Alert Today Tue 26 | Day Considerable cloudiness with occasional rain showers. High 64F. Winds light and variable. Chance of rain 50%. Considerable cloudiness with occasional rain showers. High 62F. Winds light and variable. Chance of rain 60%. Wed 03 Wed 03 | Day Overcast with showers at times. High 66F. Winds light and variable. Chance of rain 40%.Today 66°/ 50° 6% Sun 24 | Day 66° 6% WSW 4 mph Partly cloudy skies. High 66F. Winds light and variable. Humidity 65% UV Index 3 of 11 Sunrise 6:56 am Sunset 4:49 pm Sun 24 | Night 50° 10% N 1 mph...'}, {'url': 'https://weather.com/weather/tenday/l/Los+Angeles+CA?canonicalCityId=d4a04df2f5cd7d6ef329c49238253e994619763fd5f77a424ca3f1af9957e717', 'content': 'recents Specialty Forecasts 10 Day Weather-Los Angeles, CA Air Quality Alert Today Tue 26 | Day Rain showers early with some sunshine later in the day. High 61F. Winds SSE at 5 to 10 mph. Chance of rain 60%. Thu 04 Thu 04 | Day Overcast with rain showers at times. High 63F. Winds S at 5 to 10 mph. Chance of rain 50%. Wed 03 Wed 03 | Day Cloudy with occasional showers. High 63F. Winds SE at 5 to 10 mph. Chance of rain 50%.10 Day Weather - Los Angeles, CA As of 12:06 am PST Tonight --/ 49° 5% Sat 23 | Night 49° 5% NNW 2 mph Partly cloudy this evening, then becoming foggy and damp after midnight. Low 49F. Winds...'}, {'url': 'https://weather.com/weather/hourbyhour/l/Los+Angeles+CA?canonicalCityId=84c64154109916077c8d3c2352410aaae5f6eeff682000e3a7470e38976128c2', 'content': 'recents Specialty Forecasts Hourly Weather-Los Angeles, CA Air Quality Alert Tuesday, December 26 10 am Partly Cloudy Cold & Flu Forecast Flu risk is low in your area 3 pm Partly Cloudy 4 pm Mostly Cloudy 5 pm Mostly Cloudy 6 pm Mostly Cloudy 7 pm Cloudy 8 pm Cloudy 9 pm Mostly Cloudy 10 am Cloudy 11 am Mostly Cloudy 12 pm Cloudy 1 pm Mostly Cloudy 2 pm Cloudy 3 pm Cloudy 4 pm Cloudy 5 pm Cloudy 6 pmHourly Weather Forecast for Los Angeles, CA - The Weather Channel | Weather.com - Los Angeles, CA As of 11:12 am PST Saturday, December 23 12 pm 64° 4% Mostly Cloudy Feels Like 64°...'}])], 'messages': [FunctionMessage(content='[{\"url\": \"https://weather.com/weather/tenday/l/Los+Angeles+CA?canonicalCityId=84c64154109916077c8d3c2352410aaae5f6eeff682000e3a7470e38976128c2\", \"content\": \"recents Specialty Forecasts 10 Day Weather-Los Angeles, CA Air Quality Alert Today Tue 26 | Day Considerable cloudiness with occasional rain showers. High 64F. Winds light and variable. Chance of rain 50%. Considerable cloudiness with occasional rain showers. High 62F. Winds light and variable. Chance of rain 60%. Wed 03 Wed 03 | Day Overcast with showers at times. High 66F. Winds light and variable. Chance of rain 40%.Today 66°/ 50° 6% Sun 24 | Day 66° 6% WSW 4 mph Partly cloudy skies. High 66F. Winds light and variable. Humidity 65% UV Index 3 of 11 Sunrise 6:56 am Sunset 4:49 pm Sun 24 | Night 50° 10% N 1 mph...\"}, {\"url\": \"https://weather.com/weather/tenday/l/Los+Angeles+CA?canonicalCityId=d4a04df2f5cd7d6ef329c49238253e994619763fd5f77a424ca3f1af9957e717\", \"content\": \"recents Specialty Forecasts 10 Day Weather-Los Angeles, CA Air Quality Alert Today Tue 26 | Day Rain showers early with some sunshine later in the day. High 61F. Winds SSE at 5 to 10 mph. Chance of rain 60%. Thu 04 Thu 04 | Day Overcast with rain showers at times. High 63F. Winds S at 5 to 10 mph. Chance of rain 50%. Wed 03 Wed 03 | Day Cloudy with occasional showers. High 63F. Winds SE at 5 to 10 mph. Chance of rain 50%.10 Day Weather - Los Angeles, CA As of 12:06 am PST Tonight --/ 49° 5% Sat 23 | Night 49° 5% NNW 2 mph Partly cloudy this evening, then becoming foggy and damp after midnight. Low 49F. Winds...\"}, {\"url\": \"https://weather.com/weather/hourbyhour/l/Los+Angeles+CA?canonicalCityId=84c64154109916077c8d3c2352410aaae5f6eeff682000e3a7470e38976128c2\", \"content\": \"recents Specialty Forecasts Hourly Weather-Los Angeles, CA Air Quality Alert Tuesday, December 26 10 am Partly Cloudy Cold & Flu Forecast Flu risk is low in your area 3 pm Partly Cloudy 4 pm Mostly Cloudy 5 pm Mostly Cloudy 6 pm Mostly Cloudy 7 pm Cloudy 8 pm Cloudy 9 pm Mostly Cloudy 10 am Cloudy 11 am Mostly Cloudy 12 pm Cloudy 1 pm Mostly Cloudy 2 pm Cloudy 3 pm Cloudy 4 pm Cloudy 5 pm Cloudy 6 pmHourly Weather Forecast for Los Angeles, CA - The Weather Channel | Weather.com - Los Angeles, CA As of 11:12 am PST Saturday, December 23 12 pm 64° 4% Mostly Cloudy Feels Like 64°...\"}]', name='tavily_search_results_json')]}\n", + "{'actions': [...], 'messages': [...]}\n", "------\n", - "{'output': \"The weather in San Francisco is currently foggy early, then partly cloudy later in the day with a high around 60°F. There is a chance of rain showers with a high of 59°F tomorrow. The temperature will drop to a low of 46°F on Thursday night with cloudy conditions and showers.\\n\\nIn Los Angeles, there is considerable cloudiness with occasional rain showers today. The high temperature is expected to be 64°F with light and variable winds. Tomorrow, there will be considerable cloudiness with occasional rain showers and a high of 62°F. The weather will be overcast with showers at times on Wednesday with a high of 66°F.\\n\\nPlease note that weather conditions can change rapidly, so it's always a good idea to check a reliable weather source for the most up-to-date information.\", 'messages': [AIMessage(content=\"The weather in San Francisco is currently foggy early, then partly cloudy later in the day with a high around 60°F. There is a chance of rain showers with a high of 59°F tomorrow. The temperature will drop to a low of 46°F on Thursday night with cloudy conditions and showers.\\n\\nIn Los Angeles, there is considerable cloudiness with occasional rain showers today. The high temperature is expected to be 64°F with light and variable winds. Tomorrow, there will be considerable cloudiness with occasional rain showers and a high of 62°F. The weather will be overcast with showers at times on Wednesday with a high of 66°F.\\n\\nPlease note that weather conditions can change rapidly, so it's always a good idea to check a reliable weather source for the most up-to-date information.\")]}\n", - "------\n" + "{'messages': [...], 'steps': [...]}\n", + "------\n", + "{'messages': [...],\n", + " 'output': 'The items located where the cat is hiding on the shelf are books, '\n", + " 'pencils, and pictures.'}\n" ] } ], "source": [ - "for chunk in agent_executor.stream({\"input\": \"what is the weather in SF and then LA\"}):\n", - " print(chunk)\n", - " print(\"------\")" + "# Note: We use `pprint` to print only to depth 1, it makes it easier to see the output from a high level, before digging in.\n", + "import pprint\n", + "\n", + "chunks = []\n", + "\n", + "async for chunk in agent_executor.astream(\n", + " {\"input\": \"what's items are located where the cat is hiding?\"}\n", + "):\n", + " chunks.append(chunk)\n", + " print(\"------\")\n", + " pprint.pprint(chunk, depth=1)" ] }, { "cell_type": "markdown", - "id": "433c78f0", + "id": "76a930c7-7c6f-4602-b265-d38018f067be", "metadata": {}, "source": [ - "You can see that we get back a bunch of different information. There are two ways to work with this information:\n", + "### Using Messages\n", "\n", - "1. By using the AgentAction/observation/AgentFinish object\n", - "2. By using the `messages` object\n", - "\n", - "You may prefer to use the `messages` object if you are working with a chatbot - because these are chat messages and can be rendered directly. If you don't care about that, the AgentAction/observation/AgentFinish is probably the easier one to inspect." + "You can access the underlying `messages` from the outputs. Using messages can be nice when working with chat applications - because everything is a message!" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "4d5a3112-b2d4-488a-ac76-aa40dcec9cfe", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[OpenAIToolAgentAction(tool='where_cat_is_hiding', tool_input={}, log='\\nInvoking: `where_cat_is_hiding` with `{}`\\n\\n\\n', message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pKy4OLcBx6pR6k3GHBOlH68r', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]})], tool_call_id='call_pKy4OLcBx6pR6k3GHBOlH68r')]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "chunks[0][\"actions\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "2f5eead3-f6f0-40b7-82c7-3b485c634e94", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pKy4OLcBx6pR6k3GHBOlH68r', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]})]\n", + "[FunctionMessage(content='on the shelf', name='where_cat_is_hiding')]\n", + "[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_qZTz1mRfCCXT18SUy0E07eS4', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]})]\n", + "[FunctionMessage(content='books, penciles and pictures', name='get_items')]\n", + "[AIMessage(content='The items located where the cat is hiding on the shelf are books, pencils, and pictures.')]\n" + ] + } + ], + "source": [ + "for chunk in chunks:\n", + " print(chunk[\"messages\"])" + ] + }, + { + "cell_type": "markdown", + "id": "1397f859-8595-488e-9857-c4e090a136d3", + "metadata": {}, + "source": [ + "In addition, they contain full logging information (`actions` and `steps`) which may be easier to process for rendering purposes." ] }, { @@ -135,14 +314,16 @@ "id": "edd291a7", "metadata": {}, "source": [ - "### Using AgentAction/observation/AgentFinish\n", + "### Using AgentAction/Observation\n", "\n", - "You can access these raw objects as part of the streamed payload. This gives you more low level information, but can be harder to parse." + "The outputs also contain richer structured information inside of `actions` and `steps`, which could be useful in some situations, but can also be harder to parse.\n", + "\n", + "**Attention** `AgentFinish` is not available as part of the `streaming` method. If this is something you'd like to be added, please start a discussion on github and explain why its needed." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 10, "id": "603bff1d", "metadata": {}, "outputs": [ @@ -150,109 +331,287 @@ "name": "stdout", "output_type": "stream", "text": [ - "Calling Tool ```tavily_search_results_json``` with input ```{'query': 'weather in San Francisco'}```\n", - "------\n", - "Got result: ```[{'url': 'https://weather.com/weather/tenday/l/San Francisco CA USCA0987:1:US', 'content': 'recents Specialty Forecasts 10 Day Weather-San Francisco, CA Today Mon 18 | Day Fri 22 Fri 22 | Day Foggy early, then partly cloudy later in the day. High around 60F. Winds W at 10 to 15 mph. Considerable cloudiness with occasional rain showers. High 59F. Winds SSE at 5 to 10 mph. Chance of rain 50%. Thu 28 | Night Cloudy with showers. Low 46F. Winds S at 5 to 10 mph. Chance of rain 40%. Fri 29 Fri 29 | Day10 Day Weather-San Francisco, CA As of 5:52 pm PST alertLevel3 Coastal Flood Advisory+1 More Tonight Mostly Cloudy Night --/44° Rain 7% Arrow Up Sun 24| Night 44° Mostly Cloudy Night Rain 7%...'}]```\n", - "------\n", - "Calling Tool ```tavily_search_results_json``` with input ```{'query': 'weather in Los Angeles'}```\n", - "------\n", - "Got result: ```[{'url': 'https://hoodline.com/2023/12/los-angeles-hit-with-no-burn-order-during-cloudy-holiday-forecast-aqmd-urges-compliance-for-public-health/', 'content': 'skies and a chance of rain. According to the National Weather Service, today’s weather in Los Angeles is mostly sunny visiting the AQMD site or using its mobile app. While Los Angeles navigates through a cloudy and cooler weather Weather & Environment in ... Los Angeles Hit with No-Burn Order During Cloudy Holiday Forecast and cooler weather pattern, with temperatures fluctuating around the high 60 degrees and chances of rain by FridayPublished on December 26, 2023. Los Angeles residents face a restricted holiday season as the South Coast Air Quality Management District (AQMD) extends a mandatory no-burn order amid multiple ...'}, {'url': 'https://weather.com/weather/tenday/l/Los+Angeles+CA?canonicalCityId=84c64154109916077c8d3c2352410aaae5f6eeff682000e3a7470e38976128c2', 'content': 'recents Specialty Forecasts 10 Day Weather-Los Angeles, CA Tonight Sat 23 | Night Considerable cloudiness with occasional rain showers. Low 48F. Winds light and variable. Chance of rain 60%. Thu 04 Mon 01 | Day Considerable clouds early. Some decrease in clouds later in the day. High 66F. Winds light and variable. Thu 04 | Night Showers early becoming less numerous late. Low 48F. Winds light and variable. Chance of rain 40%. Fri 05Today 66°/ 50° 6% Sun 24 | Day 66° 6% WSW 4 mph Partly cloudy skies. High 66F. Winds light and variable. Humidity 65% UV Index 3 of 11 Sunrise 6:56 am Sunset 4:49 pm Sun 24 | Night 50° 10% N 1 mph...'}, {'url': 'https://weather.com/weather/tenday/l/Los+Angeles+CA?canonicalCityId=d4a04df2f5cd7d6ef329c49238253e994619763fd5f77a424ca3f1af9957e717', 'content': 'recents Specialty Forecasts 10 Day Weather-Los Angeles, CA Tonight Sat 23 | Night Considerable cloudiness with occasional rain showers. Low 48F. Winds light and variable. Chance of rain 60%. Thu 04 Mon 01 | Day Considerable clouds early. Some decrease in clouds later in the day. High 66F. Winds light and variable. Thu 04 | Night Showers early becoming less numerous late. Low 48F. Winds light and variable. Chance of rain 40%. Fri 0510 Day Weather - Los Angeles, CA As of 12:06 am PST Tonight --/ 49° 5% Sat 23 | Night 49° 5% NNW 2 mph Partly cloudy this evening, then becoming foggy and damp after midnight. Low 49F. Winds...'}]```\n", - "------\n", - "The weather in San Francisco is currently foggy early, then partly cloudy later in the day with a high around 60°F. There is a chance of rain showers with a high of 59°F tomorrow. The temperature will drop to a low of 46°F on Thursday night with cloudy skies and showers.\n", - "\n", - "In Los Angeles, there is considerable cloudiness with occasional rain showers. The temperature will drop to a low of 48°F tonight with light and variable winds. Tomorrow, there will be considerable clouds early with some decrease in clouds later in the day and a high of 66°F. Showers are expected in the evening with a low of 48°F.\n", - "------\n" + "Calling Tool: `where_cat_is_hiding` with input `{}`\n", + "---\n", + "Tool Result: `on the shelf`\n", + "---\n", + "Calling Tool: `get_items` with input `{'place': 'shelf'}`\n", + "---\n", + "Tool Result: `books, penciles and pictures`\n", + "---\n", + "Final Output: The items located where the cat is hiding on the shelf are books, pencils, and pictures.\n", + "---\n" ] } ], "source": [ - "for chunk in agent_executor.stream({\"input\": \"what is the weather in SF and then LA\"}):\n", + "async for chunk in agent_executor.astream(\n", + " {\"input\": \"what's items are located where the cat is hiding?\"}\n", + "):\n", " # Agent Action\n", " if \"actions\" in chunk:\n", " for action in chunk[\"actions\"]:\n", - " print(\n", - " f\"Calling Tool ```{action.tool}``` with input ```{action.tool_input}```\"\n", - " )\n", + " print(f\"Calling Tool: `{action.tool}` with input `{action.tool_input}`\")\n", " # Observation\n", " elif \"steps\" in chunk:\n", " for step in chunk[\"steps\"]:\n", - " print(f\"Got result: ```{step.observation}```\")\n", + " print(f\"Tool Result: `{step.observation}`\")\n", " # Final result\n", " elif \"output\" in chunk:\n", - " print(chunk[\"output\"])\n", + " print(f'Final Output: {chunk[\"output\"]}')\n", " else:\n", - " raise ValueError\n", - " print(\"------\")" + " raise ValueError()\n", + " print(\"---\")" ] }, { + "attachments": {}, "cell_type": "markdown", - "id": "72df7b43", + "id": "5058f098-d8b5-4500-bd99-b972af3ecc09", "metadata": {}, "source": [ - "### Using messages\n", + "## Custom Streaming With Events\n", "\n", - "Using messages can be nice when working with chat applications - because everything is a message!" + "Use the `astream_events` API in case the default behavior of *stream* does not work for your application (e.g., if you need to stream individual tokens from the agent or surface steps occuring **within** tools).\n", + "\n", + "⚠️ This is a **beta** API, meaning that some details might change slightly in the future based on usage.\n", + "⚠️ To make sure all callbacks work properly, use `async` code throughout. Try avoiding mixing in sync versions of code (e.g., sync versions of tools).\n", + "\n", + "Let's use this API to stream the following events:\n", + "\n", + "1. Agent Start with inputs\n", + "1. Tool Start with inputs\n", + "1. Tool End with outputs\n", + "1. Stream the agent final anwer token by token\n", + "1. Agent End with outputs" ] }, { "cell_type": "code", - "execution_count": 7, - "id": "ca79c8d9", + "execution_count": 11, + "id": "46c59cac-25fa-4f42-8cf2-9bcaed6d92c4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}})]\n", - "------\n", - "[FunctionMessage(content='[{\"url\": \"https://www.cbsnews.com/sanfrancisco/news/next-round-of-rain-set-to-arrive-in-bay-area-wednesday-morning/\", \"content\": \"weather persists through Thursday morning. The second system is projected to get to the Bay Area early Friday, Watch CBS News Next round of rain set to arrive in Bay Area Wednesday morning December 26, 2023 / 8:17 AM PST to the Bay Area on Wednesday with the arrival of the first of two storm systems. Overnight lows should be mostly in the 40s in the region, with some areas around the bay dropping into the 50s.Watch CBS News Weather Next round of rain set to arrive in Bay Area Wednesday morning December 26, 2023 / 8:17 AM PST / CBS/Bay City News Service While the outlook on Tuesday is cloudy and...\"}, {\"url\": \"https://weather.com/weather/tenday/l/San Francisco CA USCA0987:1:US\", \"content\": \"recents Specialty Forecasts 10 Day Weather-San Francisco, CA Today Mon 18 | Day Fri 22 Fri 22 | Day Foggy early, then partly cloudy later in the day. High around 60F. Winds W at 10 to 15 mph. Considerable cloudiness with occasional rain showers. High 59F. Winds SSE at 5 to 10 mph. Chance of rain 50%. Thu 28 | Night Cloudy with showers. Low 46F. Winds S at 5 to 10 mph. Chance of rain 40%. Fri 29 Fri 29 | Day10 Day Weather-San Francisco, CA As of 5:52 pm PST alertLevel3 Coastal Flood Advisory+1 More Tonight Mostly Cloudy Night --/44° Rain 7% Arrow Up Sun 24| Night 44° Mostly Cloudy Night Rain 7%...\"}]', name='tavily_search_results_json')]\n", - "------\n", - "[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in Los Angeles\"\\n}', 'name': 'tavily_search_results_json'}})]\n", - "------\n", - "[FunctionMessage(content='[{\"url\": \"https://weather.com/weather/tenday/l/Los+Angeles+CA?canonicalCityId=d4a04df2f5cd7d6ef329c49238253e994619763fd5f77a424ca3f1af9957e717\", \"content\": \"recents Specialty Forecasts 10 Day Weather-Los Angeles, CA Tonight Sat 23 | Night Considerable cloudiness with occasional rain showers. Low 48F. Winds light and variable. Chance of rain 60%. Thu 04 Mon 01 | Day Considerable clouds early. Some decrease in clouds later in the day. High 66F. Winds light and variable. Thu 04 | Night Showers early becoming less numerous late. Low 48F. Winds light and variable. Chance of rain 40%. Fri 0510 Day Weather - Los Angeles, CA As of 12:06 am PST Tonight --/ 49° 5% Sat 23 | Night 49° 5% NNW 2 mph Partly cloudy this evening, then becoming foggy and damp after midnight. Low 49F. Winds...\"}, {\"url\": \"https://weather.com/weather/tenday/l/Los+Angeles+CA?canonicalCityId=84c64154109916077c8d3c2352410aaae5f6eeff682000e3a7470e38976128c2\", \"content\": \"recents Specialty Forecasts 10 Day Weather-Los Angeles, CA Tonight Sat 23 | Night Considerable cloudiness with occasional rain showers. Low 48F. Winds light and variable. Chance of rain 60%. Thu 04 Mon 01 | Day Considerable clouds early. Some decrease in clouds later in the day. High 66F. Winds light and variable. Thu 04 | Night Showers early becoming less numerous late. Low 48F. Winds light and variable. Chance of rain 40%. Fri 05Today 66°/ 50° 6% Sun 24 | Day 66° 6% WSW 4 mph Partly cloudy skies. High 66F. Winds light and variable. Humidity 65% UV Index 3 of 11 Sunrise 6:56 am Sunset 4:49 pm Sun 24 | Night 50° 10% N 1 mph...\"}, {\"url\": \"https://abc7.com/weather/\", \"content\": \"WATCH LIVE AccuWeather in the region are forecast to be high.More in the region are forecast to be high.More NOW IN EFFECT FROM 4 AM THURSDAY TO 10 PM PST SATURDAY...MoreToday\\'s Weather Los Angeles, CA Current Today Tonight MOSTLY CLOUDY 65 ° Feels Like 65° Sunrise 6:55 AM Humidity 65% Sunset 4:48 PM Windspeed ESE 3 mph Moonrise 2:08 PM Pressure 30.0 in...\"}]', name='tavily_search_results_json')]\n", - "------\n", - "[AIMessage(content='The weather in San Francisco is expected to have rain on Wednesday and Thursday. The temperature will range from the 40s to the 50s. You can find more information [here](https://www.cbsnews.com/sanfrancisco/news/next-round-of-rain-set-to-arrive-in-bay-area-wednesday-morning/) and [here](https://weather.com/weather/tenday/l/San Francisco CA USCA0987:1:US).\\n\\nThe weather in Los Angeles is expected to have occasional rain showers with temperatures ranging from the 40s to the 60s. You can find more information [here](https://weather.com/weather/tenday/l/Los+Angeles+CA?canonicalCityId=d4a04df2f5cd7d6ef329c49238253e994619763fd5f77a424ca3f1af9957e717) and [here](https://weather.com/weather/tenday/l/Los+Angeles+CA?canonicalCityId=84c64154109916077c8d3c2352410aaae5f6eeff682000e3a7470e38976128c2).')]\n", - "------\n" + "Starting agent: Agent with input: {'input': 'where is the cat hiding? what items are in that location?'}\n", + "--\n", + "Starting tool: where_cat_is_hiding with inputs: {}\n", + "Done tool: where_cat_is_hiding\n", + "Tool output was: on the shelf\n", + "--\n", + "--\n", + "Starting tool: get_items with inputs: {'place': 'shelf'}\n", + "Done tool: get_items\n", + "Tool output was: books, penciles and pictures\n", + "--\n", + "The| cat| is| currently| hiding| on| the| shelf|.| In| that| location|,| you| can| find| books|,| pencils|,| and| pictures|.|\n", + "--\n", + "Done agent: Agent with output: The cat is currently hiding on the shelf. In that location, you can find books, pencils, and pictures.\n" ] } ], "source": [ - "for chunk in agent_executor.stream({\"input\": \"what is the weather in SF and then LA\"}):\n", - " print(chunk[\"messages\"])\n", - " print(\"------\")" + "async for event in agent_executor.astream_events(\n", + " {\"input\": \"where is the cat hiding? what items are in that location?\"},\n", + " version=\"v1\",\n", + "):\n", + " kind = event[\"event\"]\n", + " if kind == \"on_chain_start\":\n", + " if (\n", + " event[\"name\"] == \"Agent\"\n", + " ): # Was assigned when creating the agent with `.with_config({\"run_name\": \"Agent\"})`\n", + " print(\n", + " f\"Starting agent: {event['name']} with input: {event['data'].get('input')}\"\n", + " )\n", + " elif kind == \"on_chain_end\":\n", + " if (\n", + " event[\"name\"] == \"Agent\"\n", + " ): # Was assigned when creating the agent with `.with_config({\"run_name\": \"Agent\"})`\n", + " print()\n", + " print(\"--\")\n", + " print(\n", + " f\"Done agent: {event['name']} with output: {event['data'].get('output')['output']}\"\n", + " )\n", + " if kind == \"on_chat_model_stream\":\n", + " content = event[\"data\"][\"chunk\"].content\n", + " if content:\n", + " # Empty content in the context of OpenAI means\n", + " # that the model is asking for a tool to be invoked.\n", + " # So we only print non-empty content\n", + " print(content, end=\"|\")\n", + " elif kind == \"on_tool_start\":\n", + " print(\"--\")\n", + " print(\n", + " f\"Starting tool: {event['name']} with inputs: {event['data'].get('input')}\"\n", + " )\n", + " elif kind == \"on_tool_end\":\n", + " print(f\"Done tool: {event['name']}\")\n", + " print(f\"Tool output was: {event['data'].get('output')}\")\n", + " print(\"--\")" ] }, { "cell_type": "markdown", - "id": "0dc01b0f", + "id": "09711ba8-f60e-4a5d-9ace-1bdc613a7c44", "metadata": {}, "source": [ - "## Stream tokens\n", + "### Stream Events from within Tools\n", "\n", - "In addition to streaming the final result, you can also stream tokens. This will require slightly more complicated parsing of the logs\n", + "If your tool leverages LangChain runnable objects (e.g., LCEL chains, LLMs, retrievers etc.) and you want to stream events from those objects as well, you'll need to make sure that callbacks are propagated correctly.\n", "\n", - "You will also need to make sure you set the LLM to be streaming" + "To see how to pass callbacks, let's re-implement the `get_items` tool to make it use an LLM and pass callbacks to that LLM. Feel free to adapt this to your use case." ] }, { "cell_type": "code", - "execution_count": 8, - "id": "3e92d09d", + "execution_count": 12, + "id": "fdd005f4-31d3-450f-b16b-b614c26a72f3", "metadata": {}, "outputs": [], "source": [ - "llm = ChatOpenAI(model=\"gpt-3.5-turbo\", temperature=0, streaming=True)\n", + "@tool\n", + "async def get_items(place: str, callbacks: Callbacks) -> str: # <--- Accept callbacks\n", + " \"\"\"Use this tool to look up which items are in the given place.\"\"\"\n", + " template = ChatPromptTemplate.from_messages(\n", + " [\n", + " (\n", + " \"human\",\n", + " \"Can you tell me what kind of items i might find in the following place: '{place}'. \"\n", + " \"List at least 3 such items separating them by a comma. And include a brief description of each item..\",\n", + " )\n", + " ]\n", + " )\n", + " chain = template | model.with_config(\n", + " {\n", + " \"run_name\": \"Get Items LLM\",\n", + " \"tags\": [\"tool_llm\"],\n", + " \"callbacks\": callbacks, # <-- Propagate callbacks\n", + " }\n", + " )\n", + " chunks = [chunk async for chunk in chain.astream({\"place\": place})]\n", + " return \"\".join(chunk.content for chunk in chunks)" + ] + }, + { + "cell_type": "markdown", + "id": "66828308-538f-4a06-8ed6-bf398d7a3d56", + "metadata": {}, + "source": [ + "^ Take a look at how the tool propagates callbacks. \n", "\n", - "agent = create_openai_functions_agent(llm, tools, prompt)\n", - "agent_executor = AgentExecutor(agent=agent, tools=tools)" + "Next, let's initialize our agent, and take a look at the new output." ] }, { "cell_type": "code", - "execution_count": 9, - "id": "753ff598", + "execution_count": 13, + "id": "095df835-ab27-4791-80e9-07cdba180822", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting agent: Agent with input: {'input': 'where is the cat hiding? what items are in that location?'}\n", + "--\n", + "Starting tool: where_cat_is_hiding with inputs: {}\n", + "Done tool: where_cat_is_hiding\n", + "Tool output was: on the shelf\n", + "--\n", + "--\n", + "Starting tool: get_items with inputs: {'place': 'shelf'}\n", + "In| a| shelf|,| you| might| find|:\n", + "\n", + "|1|.| Books|:| A| shelf| is| commonly| used| to| store| books|.| It| may| contain| various| genres| such| as| novels|,| textbooks|,| or| reference| books|.| Books| provide| knowledge|,| entertainment|,| and| can| transport| you| to| different| worlds| through| storytelling|.\n", + "\n", + "|2|.| Decor|ative| items|:| Sh|elves| often| display| decorative| items| like| figur|ines|,| v|ases|,| or| photo| frames|.| These| items| add| a| personal| touch| to| the| space| and| can| reflect| the| owner|'s| interests| or| memories|.\n", + "\n", + "|3|.| Storage| boxes|:| Sh|elves| can| also| hold| storage| boxes| or| baskets|.| These| containers| help| organize| and| decl|utter| the| space| by| storing| miscellaneous| items| like| documents|,| accessories|,| or| small| household| items|.| They| provide| a| neat| and| tidy| appearance| to| the| shelf|.|Done tool: get_items\n", + "Tool output was: In a shelf, you might find:\n", + "\n", + "1. Books: A shelf is commonly used to store books. It may contain various genres such as novels, textbooks, or reference books. Books provide knowledge, entertainment, and can transport you to different worlds through storytelling.\n", + "\n", + "2. Decorative items: Shelves often display decorative items like figurines, vases, or photo frames. These items add a personal touch to the space and can reflect the owner's interests or memories.\n", + "\n", + "3. Storage boxes: Shelves can also hold storage boxes or baskets. These containers help organize and declutter the space by storing miscellaneous items like documents, accessories, or small household items. They provide a neat and tidy appearance to the shelf.\n", + "--\n", + "The| cat| is| hiding| on| the| shelf|.| In| that| location|,| you| might| find| books|,| decorative| items|,| and| storage| boxes|.|\n", + "--\n", + "Done agent: Agent with output: The cat is hiding on the shelf. In that location, you might find books, decorative items, and storage boxes.\n" + ] + } + ], + "source": [ + "# Get the prompt to use - you can modify this!\n", + "prompt = hub.pull(\"hwchase17/openai-tools-agent\")\n", + "# print(prompt.messages) -- to see the prompt\n", + "tools = [get_items, where_cat_is_hiding]\n", + "agent = create_openai_tools_agent(\n", + " model.with_config({\"tags\": [\"agent_llm\"]}), tools, prompt\n", + ")\n", + "agent_executor = AgentExecutor(agent=agent, tools=tools).with_config(\n", + " {\"run_name\": \"Agent\"}\n", + ")\n", + "\n", + "async for event in agent_executor.astream_events(\n", + " {\"input\": \"where is the cat hiding? what items are in that location?\"},\n", + " version=\"v1\",\n", + "):\n", + " kind = event[\"event\"]\n", + " if kind == \"on_chain_start\":\n", + " if (\n", + " event[\"name\"] == \"Agent\"\n", + " ): # Was assigned when creating the agent with `.with_config({\"run_name\": \"Agent\"})`\n", + " print(\n", + " f\"Starting agent: {event['name']} with input: {event['data'].get('input')}\"\n", + " )\n", + " elif kind == \"on_chain_end\":\n", + " if (\n", + " event[\"name\"] == \"Agent\"\n", + " ): # Was assigned when creating the agent with `.with_config({\"run_name\": \"Agent\"})`\n", + " print()\n", + " print(\"--\")\n", + " print(\n", + " f\"Done agent: {event['name']} with output: {event['data'].get('output')['output']}\"\n", + " )\n", + " if kind == \"on_chat_model_stream\":\n", + " content = event[\"data\"][\"chunk\"].content\n", + " if content:\n", + " # Empty content in the context of OpenAI means\n", + " # that the model is asking for a tool to be invoked.\n", + " # So we only print non-empty content\n", + " print(content, end=\"|\")\n", + " elif kind == \"on_tool_start\":\n", + " print(\"--\")\n", + " print(\n", + " f\"Starting tool: {event['name']} with inputs: {event['data'].get('input')}\"\n", + " )\n", + " elif kind == \"on_tool_end\":\n", + " print(f\"Done tool: {event['name']}\")\n", + " print(f\"Tool output was: {event['data'].get('output')}\")\n", + " print(\"--\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "24386754-5cd6-4322-82f7-affb93322bad", + "metadata": {}, + "source": [ + "### Other aproaches\n", + "\n", + "#### Using astream_log\n", + "\n", + "**Note** You can also use the [astream_log](https://python.langchain.com/docs/expression_language/interface#async-stream-intermediate-steps) API. This API produces a granular log of all events that occur during execution. The log format is based on the [JSONPatch](https://jsonpatch.com/) standard. It's granular, but requires effort to parse. For this reason, we created the `astream_events` API instead." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "01ad657f-7759-4fb3-a7ca-e2d7e7f8b28f", "metadata": {}, "outputs": [ { @@ -262,522 +621,100 @@ "RunLogPatch({'op': 'replace',\n", " 'path': '',\n", " 'value': {'final_output': None,\n", - " 'id': '32650ba8-8a53-4b76-8846-dbb6c3a65727',\n", + " 'id': 'c261bc30-60d1-4420-9c66-c6c0797f2c2d',\n", " 'logs': {},\n", - " 'streamed_output': []}})\n", + " 'name': 'Agent',\n", + " 'streamed_output': [],\n", + " 'type': 'chain'}})\n", "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI',\n", + " 'path': '/logs/RunnableSequence',\n", " 'value': {'end_time': None,\n", " 'final_output': None,\n", - " 'id': 'ce3a507d-210d-40aa-8576-dd0aa97e6498',\n", + " 'id': '183cb6f8-ed29-4967-b1ea-024050ce66c7',\n", " 'metadata': {},\n", - " 'name': 'ChatOpenAI',\n", - " 'start_time': '2023-12-26T17:55:56.653',\n", + " 'name': 'RunnableSequence',\n", + " 'start_time': '2024-01-22T20:38:43.650+00:00',\n", " 'streamed_output': [],\n", " 'streamed_output_str': [],\n", - " 'tags': ['seq:step:3'],\n", - " 'type': 'llm'}})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': '', 'name': 'tavily_search_results_json'}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': '{\\n', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': ' ', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': ' \"', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': 'query', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': '\":', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': ' \"', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': 'weather', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': ' in', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': ' San', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': ' Francisco', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': '\"\\n', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': '}', 'name': ''}})})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/streamed_output/-',\n", - " 'value': AIMessageChunk(content='')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/final_output',\n", - " 'value': {'generations': [[{'generation_info': {'finish_reason': 'function_call'},\n", - " 'message': AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}}),\n", - " 'text': '',\n", - " 'type': 'ChatGeneration'}]],\n", - " 'llm_output': None,\n", - " 'run': None}},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI/end_time',\n", - " 'value': '2023-12-26T17:55:57.337'})\n", + " 'tags': [],\n", + " 'type': 'chain'}})\n", "RunLogPatch({'op': 'add',\n", - " 'path': '/streamed_output/-',\n", - " 'value': {'actions': [AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}})])],\n", - " 'messages': [AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}})]}},\n", - " {'op': 'replace',\n", - " 'path': '/final_output',\n", - " 'value': {'actions': [AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}})])],\n", - " 'messages': [AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}})]}})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/streamed_output/-',\n", - " 'value': {'messages': [FunctionMessage(content='[{\"url\": \"https://www.cbsnews.com/sanfrancisco/news/next-round-of-rain-set-to-arrive-in-bay-area-wednesday-morning/\", \"content\": \"weather persists through Thursday morning. The second system is projected to get to the Bay Area early Friday, Watch CBS News Next round of rain set to arrive in Bay Area Wednesday morning December 26, 2023 / 8:17 AM PST to the Bay Area on Wednesday with the arrival of the first of two storm systems. Overnight lows should be mostly in the 40s in the region, with some areas around the bay dropping into the 50s.Watch CBS News Weather Next round of rain set to arrive in Bay Area Wednesday morning December 26, 2023 / 8:17 AM PST / CBS/Bay City News Service While the outlook on Tuesday is cloudy and...\"}, {\"url\": \"https://weather.com/weather/tenday/l/San Francisco CA USCA0987:1:US\", \"content\": \"recents Specialty Forecasts 10 Day Weather-San Francisco, CA Today Mon 18 | Day Fri 22 Fri 22 | Day Foggy early, then partly cloudy later in the day. High around 60F. Winds W at 10 to 15 mph. Considerable cloudiness with occasional rain showers. High 59F. Winds SSE at 5 to 10 mph. Chance of rain 50%. Thu 28 | Night Cloudy with showers. Low 46F. Winds S at 5 to 10 mph. Chance of rain 40%. Fri 29 Fri 29 | Day10 Day Weather-San Francisco, CA As of 5:52 pm PST alertLevel3 Coastal Flood Advisory+1 More Tonight Mostly Cloudy Night --/44° Rain 7% Arrow Up Sun 24| Night 44° Mostly Cloudy Night Rain 7%...\"}]', name='tavily_search_results_json')],\n", - " 'steps': [AgentStep(action=AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}})]), observation=[{'url': 'https://www.cbsnews.com/sanfrancisco/news/next-round-of-rain-set-to-arrive-in-bay-area-wednesday-morning/', 'content': 'weather persists through Thursday morning. The second system is projected to get to the Bay Area early Friday, Watch CBS News Next round of rain set to arrive in Bay Area Wednesday morning December 26, 2023 / 8:17 AM PST to the Bay Area on Wednesday with the arrival of the first of two storm systems. Overnight lows should be mostly in the 40s in the region, with some areas around the bay dropping into the 50s.Watch CBS News Weather Next round of rain set to arrive in Bay Area Wednesday morning December 26, 2023 / 8:17 AM PST / CBS/Bay City News Service While the outlook on Tuesday is cloudy and...'}, {'url': 'https://weather.com/weather/tenday/l/San Francisco CA USCA0987:1:US', 'content': 'recents Specialty Forecasts 10 Day Weather-San Francisco, CA Today Mon 18 | Day Fri 22 Fri 22 | Day Foggy early, then partly cloudy later in the day. High around 60F. Winds W at 10 to 15 mph. Considerable cloudiness with occasional rain showers. High 59F. Winds SSE at 5 to 10 mph. Chance of rain 50%. Thu 28 | Night Cloudy with showers. Low 46F. Winds S at 5 to 10 mph. Chance of rain 40%. Fri 29 Fri 29 | Day10 Day Weather-San Francisco, CA As of 5:52 pm PST alertLevel3 Coastal Flood Advisory+1 More Tonight Mostly Cloudy Night --/44° Rain 7% Arrow Up Sun 24| Night 44° Mostly Cloudy Night Rain 7%...'}])]}},\n", - " {'op': 'add',\n", - " 'path': '/final_output/steps',\n", - " 'value': [AgentStep(action=AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}})]), observation=[{'url': 'https://www.cbsnews.com/sanfrancisco/news/next-round-of-rain-set-to-arrive-in-bay-area-wednesday-morning/', 'content': 'weather persists through Thursday morning. The second system is projected to get to the Bay Area early Friday, Watch CBS News Next round of rain set to arrive in Bay Area Wednesday morning December 26, 2023 / 8:17 AM PST to the Bay Area on Wednesday with the arrival of the first of two storm systems. Overnight lows should be mostly in the 40s in the region, with some areas around the bay dropping into the 50s.Watch CBS News Weather Next round of rain set to arrive in Bay Area Wednesday morning December 26, 2023 / 8:17 AM PST / CBS/Bay City News Service While the outlook on Tuesday is cloudy and...'}, {'url': 'https://weather.com/weather/tenday/l/San Francisco CA USCA0987:1:US', 'content': 'recents Specialty Forecasts 10 Day Weather-San Francisco, CA Today Mon 18 | Day Fri 22 Fri 22 | Day Foggy early, then partly cloudy later in the day. High around 60F. Winds W at 10 to 15 mph. Considerable cloudiness with occasional rain showers. High 59F. Winds SSE at 5 to 10 mph. Chance of rain 50%. Thu 28 | Night Cloudy with showers. Low 46F. Winds S at 5 to 10 mph. Chance of rain 40%. Fri 29 Fri 29 | Day10 Day Weather-San Francisco, CA As of 5:52 pm PST alertLevel3 Coastal Flood Advisory+1 More Tonight Mostly Cloudy Night --/44° Rain 7% Arrow Up Sun 24| Night 44° Mostly Cloudy Night Rain 7%...'}])]},\n", - " {'op': 'add',\n", - " 'path': '/final_output/messages/1',\n", - " 'value': FunctionMessage(content='[{\"url\": \"https://www.cbsnews.com/sanfrancisco/news/next-round-of-rain-set-to-arrive-in-bay-area-wednesday-morning/\", \"content\": \"weather persists through Thursday morning. The second system is projected to get to the Bay Area early Friday, Watch CBS News Next round of rain set to arrive in Bay Area Wednesday morning December 26, 2023 / 8:17 AM PST to the Bay Area on Wednesday with the arrival of the first of two storm systems. Overnight lows should be mostly in the 40s in the region, with some areas around the bay dropping into the 50s.Watch CBS News Weather Next round of rain set to arrive in Bay Area Wednesday morning December 26, 2023 / 8:17 AM PST / CBS/Bay City News Service While the outlook on Tuesday is cloudy and...\"}, {\"url\": \"https://weather.com/weather/tenday/l/San Francisco CA USCA0987:1:US\", \"content\": \"recents Specialty Forecasts 10 Day Weather-San Francisco, CA Today Mon 18 | Day Fri 22 Fri 22 | Day Foggy early, then partly cloudy later in the day. High around 60F. Winds W at 10 to 15 mph. Considerable cloudiness with occasional rain showers. High 59F. Winds SSE at 5 to 10 mph. Chance of rain 50%. Thu 28 | Night Cloudy with showers. Low 46F. Winds S at 5 to 10 mph. Chance of rain 40%. Fri 29 Fri 29 | Day10 Day Weather-San Francisco, CA As of 5:52 pm PST alertLevel3 Coastal Flood Advisory+1 More Tonight Mostly Cloudy Night --/44° Rain 7% Arrow Up Sun 24| Night 44° Mostly Cloudy Night Rain 7%...\"}]', name='tavily_search_results_json')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2',\n", + " 'path': '/logs/RunnableAssign',\n", " 'value': {'end_time': None,\n", " 'final_output': None,\n", - " 'id': '503b959e-b6c2-427b-b2e8-7d40497a2458',\n", + " 'id': '7fe1bb27-3daf-492e-bc7e-28602398f008',\n", " 'metadata': {},\n", - " 'name': 'ChatOpenAI',\n", - " 'start_time': '2023-12-26T17:56:00.983',\n", + " 'name': 'RunnableAssign',\n", + " 'start_time': '2024-01-22T20:38:43.652+00:00',\n", " 'streamed_output': [],\n", " 'streamed_output_str': [],\n", - " 'tags': ['seq:step:3'],\n", - " 'type': 'llm'}})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI:2/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': 'The'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='The')})\n", + " 'tags': ['seq:step:1'],\n", + " 'type': 'chain'}})\n", "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' weather'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' weather')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' in'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' in')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' San'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' San')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' Francisco'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' Francisco')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' is'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' is')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' currently'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' currently')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' cloudy'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' cloudy')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' with'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' with')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' occasional'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' occasional')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' rain'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' rain')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' showers'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' showers')})\n", + " 'path': '/logs/RunnableAssign/streamed_output/-',\n", + " 'value': {'input': 'where is the cat hiding? what items are in that '\n", + " 'location?',\n", + " 'intermediate_steps': []}})\n", "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '.'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='.')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' The'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' The')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' temperature'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' temperature')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' is'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' is')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' around'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' around')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' '},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' ')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '59'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='59')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '°F'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='°F')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' ('},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' (')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '15'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='15')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '°C'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='°C')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ')'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=')')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' with'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' with')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' winds'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' winds')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' from'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' from')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' the'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' the')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' southeast'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' southeast')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' at'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' at')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' '},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' ')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '5'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='5')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' to'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' to')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' '},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' ')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '10'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='10')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' mph'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' mph')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '.'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='.')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' The'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' The')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' overnight'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' overnight')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' low'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' low')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' is'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' is')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' expected'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' expected')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' to'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' to')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' be'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' be')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' around'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' around')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' '},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' ')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '46'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='46')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '°F'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='°F')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' ('},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' (')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '8'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='8')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '°C'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='°C')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ')'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=')')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' with'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' with')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' a'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' a')})\n", - "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' chance'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' chance')})\n", + " 'path': '/logs/RunnableParallel',\n", + " 'value': {'end_time': None,\n", + " 'final_output': None,\n", + " 'id': 'b034e867-e6bb-4296-bfe6-752c44fba6ce',\n", + " 'metadata': {},\n", + " 'name': 'RunnableParallel',\n", + " 'start_time': '2024-01-22T20:38:43.652+00:00',\n", + " 'streamed_output': [],\n", + " 'streamed_output_str': [],\n", + " 'tags': [],\n", + " 'type': 'chain'}})\n", "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' of'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' of')})\n", + " 'path': '/logs/RunnableLambda',\n", + " 'value': {'end_time': None,\n", + " 'final_output': None,\n", + " 'id': '65ceef3e-7a80-4015-8b5b-d949326872e9',\n", + " 'metadata': {},\n", + " 'name': 'RunnableLambda',\n", + " 'start_time': '2024-01-22T20:38:43.653+00:00',\n", + " 'streamed_output': [],\n", + " 'streamed_output_str': [],\n", + " 'tags': ['map:key:agent_scratchpad'],\n", + " 'type': 'chain'}})\n", + "RunLogPatch({'op': 'add', 'path': '/logs/RunnableLambda/streamed_output/-', 'value': []})\n", "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': ' showers'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content=' showers')})\n", + " 'path': '/logs/RunnableParallel/streamed_output/-',\n", + " 'value': {'agent_scratchpad': []}})\n", "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output_str/-',\n", - " 'value': '.'},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='.')})\n", - "RunLogPatch({'op': 'add', 'path': '/logs/ChatOpenAI:2/streamed_output_str/-', 'value': ''},\n", - " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/streamed_output/-',\n", - " 'value': AIMessageChunk(content='')})\n", + " 'path': '/logs/RunnableAssign/streamed_output/-',\n", + " 'value': {'agent_scratchpad': []}})\n", "RunLogPatch({'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/final_output',\n", - " 'value': {'generations': [[{'generation_info': {'finish_reason': 'stop'},\n", - " 'message': AIMessage(content='The weather in San Francisco is currently cloudy with occasional rain showers. The temperature is around 59°F (15°C) with winds from the southeast at 5 to 10 mph. The overnight low is expected to be around 46°F (8°C) with a chance of showers.'),\n", - " 'text': 'The weather in San Francisco is '\n", - " 'currently cloudy with occasional rain '\n", - " 'showers. The temperature is around 59°F '\n", - " '(15°C) with winds from the southeast at '\n", - " '5 to 10 mph. The overnight low is '\n", - " 'expected to be around 46°F (8°C) with a '\n", - " 'chance of showers.',\n", - " 'type': 'ChatGeneration'}]],\n", - " 'llm_output': None,\n", - " 'run': None}},\n", + " 'path': '/logs/RunnableLambda/final_output',\n", + " 'value': {'output': []}},\n", " {'op': 'add',\n", - " 'path': '/logs/ChatOpenAI:2/end_time',\n", - " 'value': '2023-12-26T17:56:02.356'})\n", + " 'path': '/logs/RunnableLambda/end_time',\n", + " 'value': '2024-01-22T20:38:43.654+00:00'})\n", "RunLogPatch({'op': 'add',\n", - " 'path': '/streamed_output/-',\n", - " 'value': {'messages': [AIMessage(content='The weather in San Francisco is currently cloudy with occasional rain showers. The temperature is around 59°F (15°C) with winds from the southeast at 5 to 10 mph. The overnight low is expected to be around 46°F (8°C) with a chance of showers.')],\n", - " 'output': 'The weather in San Francisco is currently cloudy with '\n", - " 'occasional rain showers. The temperature is around 59°F '\n", - " '(15°C) with winds from the southeast at 5 to 10 mph. '\n", - " 'The overnight low is expected to be around 46°F (8°C) '\n", - " 'with a chance of showers.'}},\n", + " 'path': '/logs/RunnableParallel/final_output',\n", + " 'value': {'agent_scratchpad': []}},\n", " {'op': 'add',\n", - " 'path': '/final_output/output',\n", - " 'value': 'The weather in San Francisco is currently cloudy with occasional '\n", - " 'rain showers. The temperature is around 59°F (15°C) with winds '\n", - " 'from the southeast at 5 to 10 mph. The overnight low is expected '\n", - " 'to be around 46°F (8°C) with a chance of showers.'},\n", - " {'op': 'add',\n", - " 'path': '/final_output/messages/2',\n", - " 'value': AIMessage(content='The weather in San Francisco is currently cloudy with occasional rain showers. The temperature is around 59°F (15°C) with winds from the southeast at 5 to 10 mph. The overnight low is expected to be around 46°F (8°C) with a chance of showers.')})\n" + " 'path': '/logs/RunnableParallel/end_time',\n", + " 'value': '2024-01-22T20:38:43.655+00:00'})\n" ] } ], "source": [ + "i = 0\n", "async for chunk in agent_executor.astream_log(\n", - " {\"input\": \"what is the weather in sf\", \"chat_history\": []},\n", - " include_names=[\"ChatOpenAI\"],\n", + " {\"input\": \"where is the cat hiding? what items are in that location?\"},\n", "):\n", - " print(chunk)" + " print(chunk)\n", + " i += 1\n", + " if i > 10:\n", + " break" ] }, { "cell_type": "markdown", - "id": "51a51076", + "id": "5763c64b-7fff-4167-9eb3-172209cef958", "metadata": {}, "source": [ "This may require some logic to get in a workable format" @@ -785,8 +722,8 @@ }, { "cell_type": "code", - "execution_count": 10, - "id": "7cdae318", + "execution_count": 15, + "id": "f7120cbd-6bea-4706-821a-ff3b6722bf1d", "metadata": {}, "outputs": [ { @@ -796,272 +733,104 @@ "\n", "None\n", "----\n", - "/logs/ChatOpenAI\n", - "{'id': '3f6d3587-600f-419b-8225-8908a347b7d2', 'name': 'ChatOpenAI', 'type': 'llm', 'tags': ['seq:step:3'], 'metadata': {}, 'start_time': '2023-12-26T17:56:19.884', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", + "/logs/RunnableSequence\n", + "{'id': '22bbd5db-9578-4e3f-a6ec-9b61f08cb8a9', 'name': 'RunnableSequence', 'type': 'chain', 'tags': [], 'metadata': {}, 'start_time': '2024-01-22T20:38:43.668+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '', 'name': 'tavily_search_results_json'}}\n", + "/logs/RunnableAssign\n", + "{'id': 'e0c00ae2-aaa2-4a09-bc93-cb34bf3f6554', 'name': 'RunnableAssign', 'type': 'chain', 'tags': ['seq:step:1'], 'metadata': {}, 'start_time': '2024-01-22T20:38:43.672+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n', 'name': 'tavily_search_results_json'}}\n", + "/logs/RunnableAssign/streamed_output/-\n", + "{'input': 'where is the cat hiding? what items are in that location?', 'intermediate_steps': []}\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n ', 'name': 'tavily_search_results_json'}}\n", + "/logs/RunnableParallel\n", + "{'id': '26ff576d-ff9d-4dea-98b2-943312a37f4d', 'name': 'RunnableParallel', 'type': 'chain', 'tags': [], 'metadata': {}, 'start_time': '2024-01-22T20:38:43.674+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"', 'name': 'tavily_search_results_json'}}\n", + "/logs/RunnableLambda\n", + "{'id': '9f343c6a-23f7-4a28-832f-d4fe3e95d1dc', 'name': 'RunnableLambda', 'type': 'chain', 'tags': ['map:key:agent_scratchpad'], 'metadata': {}, 'start_time': '2024-01-22T20:38:43.685+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"query', 'name': 'tavily_search_results_json'}}\n", + "/logs/RunnableLambda/streamed_output/-\n", + "[]\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"query\":', 'name': 'tavily_search_results_json'}}\n", + "/logs/RunnableParallel/streamed_output/-\n", + "{'agent_scratchpad': []}\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"', 'name': 'tavily_search_results_json'}}\n", + "/logs/RunnableAssign/streamed_output/-\n", + "{'input': 'where is the cat hiding? what items are in that location?', 'intermediate_steps': [], 'agent_scratchpad': []}\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather', 'name': 'tavily_search_results_json'}}\n", + "/logs/RunnableLambda/end_time\n", + "2024-01-22T20:38:43.687+00:00\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in', 'name': 'tavily_search_results_json'}}\n", + "/logs/RunnableParallel/end_time\n", + "2024-01-22T20:38:43.688+00:00\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San', 'name': 'tavily_search_results_json'}}\n", + "/logs/RunnableAssign/end_time\n", + "2024-01-22T20:38:43.688+00:00\n", "----\n", - "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco', 'name': 'tavily_search_results_json'}}\n", + "/logs/ChatPromptTemplate\n", + "{'id': '7e3a84d5-46b8-4782-8eed-d1fe92be6a30', 'name': 'ChatPromptTemplate', 'type': 'prompt', 'tags': ['seq:step:2'], 'metadata': {}, 'start_time': '2024-01-22T20:38:43.689+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", + "----\n", + "/logs/ChatPromptTemplate/end_time\n", + "2024-01-22T20:38:43.689+00:00\n", + "----\n", + "/logs/ChatOpenAI\n", + "{'id': '6446f7ec-b3e4-4637-89d8-b4b34b46ea14', 'name': 'ChatOpenAI', 'type': 'llm', 'tags': ['seq:step:3', 'agent_llm'], 'metadata': {}, 'start_time': '2024-01-22T20:38:43.690+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", "----\n", "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n', 'name': 'tavily_search_results_json'}}\n", + "content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_gKFg6FX8ZQ88wFUs94yx86PF', 'function': {'arguments': '', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}\n", "----\n", "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}}\n", + "content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_gKFg6FX8ZQ88wFUs94yx86PF', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}\n", "----\n", "/logs/ChatOpenAI/streamed_output/-\n", - "content='' additional_kwargs={'function_call': {'arguments': '{\\n \"query\": \"weather in San Francisco\"\\n}', 'name': 'tavily_search_results_json'}}\n", + "content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_gKFg6FX8ZQ88wFUs94yx86PF', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}\n", "----\n", "/logs/ChatOpenAI/end_time\n", - "2023-12-26T17:56:20.849\n", + "2024-01-22T20:38:44.203+00:00\n", "----\n", - "/final_output\n", - "None\n", + "/logs/OpenAIToolsAgentOutputParser\n", + "{'id': '65912835-8dcd-4be2-ad05-9f239a7ef704', 'name': 'OpenAIToolsAgentOutputParser', 'type': 'parser', 'tags': ['seq:step:4'], 'metadata': {}, 'start_time': '2024-01-22T20:38:44.204+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", "----\n", - "/final_output/messages/1\n", - "content='[{\"url\": \"https://weather.com/weather/tenday/l/San Francisco CA USCA0987:1:US\", \"content\": \"recents Specialty Forecasts 10 Day Weather-San Francisco, CA Today Mon 18 | Day Fri 22 Fri 22 | Day Foggy early, then partly cloudy later in the day. High around 60F. Winds W at 10 to 15 mph. Considerable cloudiness with occasional rain showers. High 59F. Winds SSE at 5 to 10 mph. Chance of rain 50%. Thu 28 | Night Cloudy with showers. Low 46F. Winds S at 5 to 10 mph. Chance of rain 40%. Fri 29 Fri 29 | Day10 Day Weather-San Francisco, CA As of 5:52 pm PST alertLevel3 Coastal Flood Advisory+1 More Tonight Mostly Cloudy Night --/44° Rain 7% Arrow Up Sun 24| Night 44° Mostly Cloudy Night Rain 7%...\"}]' name='tavily_search_results_json'\n", + "/logs/OpenAIToolsAgentOutputParser/end_time\n", + "2024-01-22T20:38:44.205+00:00\n", "----\n", - "/logs/ChatOpenAI:2\n", - "{'id': 'fc7ab413-6f59-4a9e-bae1-3140abdaff55', 'name': 'ChatOpenAI', 'type': 'llm', 'tags': ['seq:step:3'], 'metadata': {}, 'start_time': '2023-12-26T17:56:24.546', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", + "/logs/RunnableSequence/streamed_output/-\n", + "[OpenAIToolAgentAction(tool='where_cat_is_hiding', tool_input={}, log='\\nInvoking: `where_cat_is_hiding` with `{}`\\n\\n\\n', message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_gKFg6FX8ZQ88wFUs94yx86PF', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]})], tool_call_id='call_gKFg6FX8ZQ88wFUs94yx86PF')]\n", "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content=''\n", + "/logs/RunnableSequence/end_time\n", + "2024-01-22T20:38:44.206+00:00\n", "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently fog'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around '\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F.'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day,'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy.'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at '\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to '\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph.'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow,'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloud'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers and'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers and a'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers and a high'\n", - "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers and a high of'\n", + "/final_output\n", + "None\n", "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers and a high of '\n", + "/logs/where_cat_is_hiding\n", + "{'id': '21fde139-0dfa-42bb-ad90-b5b1e984aaba', 'name': 'where_cat_is_hiding', 'type': 'tool', 'tags': [], 'metadata': {}, 'start_time': '2024-01-22T20:38:44.208+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers and a high of 59'\n", + "/logs/where_cat_is_hiding/end_time\n", + "2024-01-22T20:38:44.208+00:00\n", "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers and a high of 59°F'\n", + "/final_output/messages/1\n", + "content='under the bed' name='where_cat_is_hiding'\n", "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers and a high of 59°F.'\n", + "/logs/RunnableSequence:2\n", + "{'id': '37d52845-b689-4c18-9c10-ffdd0c4054b0', 'name': 'RunnableSequence', 'type': 'chain', 'tags': [], 'metadata': {}, 'start_time': '2024-01-22T20:38:44.210+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", "----\n", - "/logs/ChatOpenAI:2/streamed_output/-\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers and a high of 59°F.'\n", + "/logs/RunnableAssign:2\n", + "{'id': '30024dea-064f-4b04-b130-671f47ac59bc', 'name': 'RunnableAssign', 'type': 'chain', 'tags': ['seq:step:1'], 'metadata': {}, 'start_time': '2024-01-22T20:38:44.213+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", "----\n", - "/logs/ChatOpenAI:2/end_time\n", - "2023-12-26T17:56:25.673\n", + "/logs/RunnableAssign:2/streamed_output/-\n", + "{'input': 'where is the cat hiding? what items are in that location?', 'intermediate_steps': [(OpenAIToolAgentAction(tool='where_cat_is_hiding', tool_input={}, log='\\nInvoking: `where_cat_is_hiding` with `{}`\\n\\n\\n', message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_gKFg6FX8ZQ88wFUs94yx86PF', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]})], tool_call_id='call_gKFg6FX8ZQ88wFUs94yx86PF'), 'under the bed')]}\n", "----\n", - "/final_output/messages/2\n", - "content='The weather in San Francisco is currently foggy with a high around 60°F. Later in the day, it will become partly cloudy. The wind is coming from the west at 10 to 15 mph. Tomorrow, there will be considerable cloudiness with occasional rain showers and a high of 59°F.'\n", + "/logs/RunnableParallel:2\n", + "{'id': '98906cd7-93c2-47e8-a7d7-2e8d4ab09ed0', 'name': 'RunnableParallel', 'type': 'chain', 'tags': [], 'metadata': {}, 'start_time': '2024-01-22T20:38:44.215+00:00', 'streamed_output': [], 'streamed_output_str': [], 'final_output': None, 'end_time': None}\n", "----\n" ] } ], "source": [ + "i = 0\n", "path_status = {}\n", "async for chunk in agent_executor.astream_log(\n", - " {\"input\": \"what is the weather in sf\", \"chat_history\": []},\n", - " include_names=[\"ChatOpenAI\"],\n", + " {\"input\": \"where is the cat hiding? what items are in that location?\"},\n", "):\n", " for op in chunk.ops:\n", " if op[\"op\"] == \"add\":\n", @@ -1071,16 +840,291 @@ " path_status[op[\"path\"]] += op[\"value\"]\n", " print(op[\"path\"])\n", " print(path_status.get(op[\"path\"]))\n", - " print(\"----\")" + " print(\"----\")\n", + " i += 1\n", + " if i > 30:\n", + " break" + ] + }, + { + "cell_type": "markdown", + "id": "d85bf6ed-8d89-46fb-bbd8-6c84de7ae18f", + "metadata": {}, + "source": [ + "#### Using callbacks (Legacy)\n", + "\n", + "Another approach to streaming is using callbacks. This may be useful if you're still on an older version of LangChain and cannot upgrade.\n", + "\n", + "Generall, this is **NOT** a recommended approach because:\n", + "\n", + "1. for most applications, you'll need to create two workers, write the callbacks to a queue and have another worker reading from the queue (i.e., there's hidden complexity to make this work).\n", + "2. **end** events may be missing some metadata (e.g., like run name). So if you need the additional metadata, you should inherit from `BaseTracer` instead of `AsyncCallbackHandler` to pick up the relevant information from the runs (aka traces), or else implement the aggregation logic yourself based on the `run_id`.\n", + "3. There is inconsistent behavior with the callbacks (e.g., how inputs and outputs are encoded) depending on the callback type that you'll need to workaround.\n", + "\n", + "For illustration purposes, we implement a callback below that shows how to get *token by token* streaming. Feel free to implement other callbacks based on your application needs.\n", + "\n", + "But `astream_events` does all of this you under the hood, so you don't have to!" ] }, { "cell_type": "code", - "execution_count": null, - "id": "4fdfc76d", + "execution_count": 16, + "id": "2c577a4a-b754-4c32-a951-8003b876ea9a", "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "on chain start: \n", + "{'input': 'where is the cat hiding and what items can be found there?'}\n", + "on chain start: \n", + "{'input': ''}\n", + "on chain start: \n", + "{'input': ''}\n", + "on chain start: \n", + "{'input': ''}\n", + "on chain start: \n", + "{'input': ''}\n", + "On chain end\n", + "[]\n", + "On chain end\n", + "{'agent_scratchpad': []}\n", + "On chain end\n", + "{'input': 'where is the cat hiding and what items can be found there?', 'intermediate_steps': [], 'agent_scratchpad': []}\n", + "on chain start: \n", + "{'input': 'where is the cat hiding and what items can be found there?', 'intermediate_steps': [], 'agent_scratchpad': []}\n", + "On chain end\n", + "{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'ChatPromptValue'], 'kwargs': {'messages': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'SystemMessage'], 'kwargs': {'content': 'You are a helpful assistant', 'additional_kwargs': {}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'HumanMessage'], 'kwargs': {'content': 'where is the cat hiding and what items can be found there?', 'additional_kwargs': {}}}]}}\n", + "agent_llm: \n", + "\n", + "on chain start: \n", + "content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}\n", + "On chain end\n", + "[{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'agent', 'OpenAIToolAgentAction'], 'kwargs': {'tool': 'where_cat_is_hiding', 'tool_input': {}, 'log': '\\nInvoking: `where_cat_is_hiding` with `{}`\\n\\n\\n', 'message_log': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessageChunk'], 'kwargs': {'example': False, 'content': '', 'additional_kwargs': {'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}}}], 'tool_call_id': 'call_pboyZTT0587rJtujUluO2OOc'}}]\n", + "On chain end\n", + "[OpenAIToolAgentAction(tool='where_cat_is_hiding', tool_input={}, log='\\nInvoking: `where_cat_is_hiding` with `{}`\\n\\n\\n', message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]})], tool_call_id='call_pboyZTT0587rJtujUluO2OOc')]\n", + "Tool start\n", + "{'name': 'where_cat_is_hiding', 'description': 'where_cat_is_hiding() -> str - Where is the cat hiding right now?'}\n", + "Tool end\n", + "on the shelf\n", + "on chain start: \n", + "{'input': ''}\n", + "on chain start: \n", + "{'input': ''}\n", + "on chain start: \n", + "{'input': ''}\n", + "on chain start: \n", + "{'input': ''}\n", + "On chain end\n", + "[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}), ToolMessage(content='on the shelf', additional_kwargs={'name': 'where_cat_is_hiding'}, tool_call_id='call_pboyZTT0587rJtujUluO2OOc')]\n", + "On chain end\n", + "{'agent_scratchpad': [AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}), ToolMessage(content='on the shelf', additional_kwargs={'name': 'where_cat_is_hiding'}, tool_call_id='call_pboyZTT0587rJtujUluO2OOc')]}\n", + "On chain end\n", + "{'input': 'where is the cat hiding and what items can be found there?', 'intermediate_steps': [(OpenAIToolAgentAction(tool='where_cat_is_hiding', tool_input={}, log='\\nInvoking: `where_cat_is_hiding` with `{}`\\n\\n\\n', message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]})], tool_call_id='call_pboyZTT0587rJtujUluO2OOc'), 'on the shelf')], 'agent_scratchpad': [AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}), ToolMessage(content='on the shelf', additional_kwargs={'name': 'where_cat_is_hiding'}, tool_call_id='call_pboyZTT0587rJtujUluO2OOc')]}\n", + "on chain start: \n", + "{'input': 'where is the cat hiding and what items can be found there?', 'intermediate_steps': [(OpenAIToolAgentAction(tool='where_cat_is_hiding', tool_input={}, log='\\nInvoking: `where_cat_is_hiding` with `{}`\\n\\n\\n', message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]})], tool_call_id='call_pboyZTT0587rJtujUluO2OOc'), 'on the shelf')], 'agent_scratchpad': [AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}), ToolMessage(content='on the shelf', additional_kwargs={'name': 'where_cat_is_hiding'}, tool_call_id='call_pboyZTT0587rJtujUluO2OOc')]}\n", + "On chain end\n", + "{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'ChatPromptValue'], 'kwargs': {'messages': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'SystemMessage'], 'kwargs': {'content': 'You are a helpful assistant', 'additional_kwargs': {}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'HumanMessage'], 'kwargs': {'content': 'where is the cat hiding and what items can be found there?', 'additional_kwargs': {}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessageChunk'], 'kwargs': {'example': False, 'content': '', 'additional_kwargs': {'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'ToolMessage'], 'kwargs': {'tool_call_id': 'call_pboyZTT0587rJtujUluO2OOc', 'content': 'on the shelf', 'additional_kwargs': {'name': 'where_cat_is_hiding'}}}]}}\n", + "agent_llm: \n", + "\n", + "on chain start: \n", + "content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]}\n", + "On chain end\n", + "[{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'agent', 'OpenAIToolAgentAction'], 'kwargs': {'tool': 'get_items', 'tool_input': {'place': 'shelf'}, 'log': \"\\nInvoking: `get_items` with `{'place': 'shelf'}`\\n\\n\\n\", 'message_log': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessageChunk'], 'kwargs': {'example': False, 'content': '', 'additional_kwargs': {'tool_calls': [{'index': 0, 'id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]}}}], 'tool_call_id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh'}}]\n", + "On chain end\n", + "[OpenAIToolAgentAction(tool='get_items', tool_input={'place': 'shelf'}, log=\"\\nInvoking: `get_items` with `{'place': 'shelf'}`\\n\\n\\n\", message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]})], tool_call_id='call_vIVtgUb9Gvmc3zAGIrshnmbh')]\n", + "Tool start\n", + "{'name': 'get_items', 'description': 'get_items(place: str, callbacks: Union[List[langchain_core.callbacks.base.BaseCallbackHandler], langchain_core.callbacks.base.BaseCallbackManager, NoneType]) -> str - Use this tool to look up which items are in the given place.'}\n", + "tool_llm: In| a| shelf|,| you| might| find|:\n", + "\n", + "|1|.| Books|:| A| shelf| is| commonly| used| to| store| books|.| Books| can| be| of| various| genres|,| such| as| novels|,| textbooks|,| or| reference| books|.| They| provide| knowledge|,| entertainment|,| and| can| transport| you| to| different| worlds| through| storytelling|.\n", + "\n", + "|2|.| Decor|ative| items|:| Sh|elves| often| serve| as| a| display| area| for| decorative| items| like| figur|ines|,| v|ases|,| or| sculptures|.| These| items| add| aesthetic| value| to| the| space| and| reflect| the| owner|'s| personal| taste| and| style|.\n", + "\n", + "|3|.| Storage| boxes|:| Sh|elves| can| also| be| used| to| store| various| items| in| organized| boxes|.| These| boxes| can| hold| anything| from| office| supplies|,| craft| materials|,| or| sentimental| items|.| They| help| keep| the| space| tidy| and| provide| easy| access| to| stored| belongings|.|\n", + "\n", + "Tool end\n", + "In a shelf, you might find:\n", + "\n", + "1. Books: A shelf is commonly used to store books. Books can be of various genres, such as novels, textbooks, or reference books. They provide knowledge, entertainment, and can transport you to different worlds through storytelling.\n", + "\n", + "2. Decorative items: Shelves often serve as a display area for decorative items like figurines, vases, or sculptures. These items add aesthetic value to the space and reflect the owner's personal taste and style.\n", + "\n", + "3. Storage boxes: Shelves can also be used to store various items in organized boxes. These boxes can hold anything from office supplies, craft materials, or sentimental items. They help keep the space tidy and provide easy access to stored belongings.\n", + "on chain start: \n", + "{'input': ''}\n", + "on chain start: \n", + "{'input': ''}\n", + "on chain start: \n", + "{'input': ''}\n", + "on chain start: \n", + "{'input': ''}\n", + "On chain end\n", + "[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}), ToolMessage(content='on the shelf', additional_kwargs={'name': 'where_cat_is_hiding'}, tool_call_id='call_pboyZTT0587rJtujUluO2OOc'), AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]}), ToolMessage(content=\"In a shelf, you might find:\\n\\n1. Books: A shelf is commonly used to store books. Books can be of various genres, such as novels, textbooks, or reference books. They provide knowledge, entertainment, and can transport you to different worlds through storytelling.\\n\\n2. Decorative items: Shelves often serve as a display area for decorative items like figurines, vases, or sculptures. These items add aesthetic value to the space and reflect the owner's personal taste and style.\\n\\n3. Storage boxes: Shelves can also be used to store various items in organized boxes. These boxes can hold anything from office supplies, craft materials, or sentimental items. They help keep the space tidy and provide easy access to stored belongings.\", additional_kwargs={'name': 'get_items'}, tool_call_id='call_vIVtgUb9Gvmc3zAGIrshnmbh')]\n", + "On chain end\n", + "{'agent_scratchpad': [AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}), ToolMessage(content='on the shelf', additional_kwargs={'name': 'where_cat_is_hiding'}, tool_call_id='call_pboyZTT0587rJtujUluO2OOc'), AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]}), ToolMessage(content=\"In a shelf, you might find:\\n\\n1. Books: A shelf is commonly used to store books. Books can be of various genres, such as novels, textbooks, or reference books. They provide knowledge, entertainment, and can transport you to different worlds through storytelling.\\n\\n2. Decorative items: Shelves often serve as a display area for decorative items like figurines, vases, or sculptures. These items add aesthetic value to the space and reflect the owner's personal taste and style.\\n\\n3. Storage boxes: Shelves can also be used to store various items in organized boxes. These boxes can hold anything from office supplies, craft materials, or sentimental items. They help keep the space tidy and provide easy access to stored belongings.\", additional_kwargs={'name': 'get_items'}, tool_call_id='call_vIVtgUb9Gvmc3zAGIrshnmbh')]}\n", + "On chain end\n", + "{'input': 'where is the cat hiding and what items can be found there?', 'intermediate_steps': [(OpenAIToolAgentAction(tool='where_cat_is_hiding', tool_input={}, log='\\nInvoking: `where_cat_is_hiding` with `{}`\\n\\n\\n', message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]})], tool_call_id='call_pboyZTT0587rJtujUluO2OOc'), 'on the shelf'), (OpenAIToolAgentAction(tool='get_items', tool_input={'place': 'shelf'}, log=\"\\nInvoking: `get_items` with `{'place': 'shelf'}`\\n\\n\\n\", message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]})], tool_call_id='call_vIVtgUb9Gvmc3zAGIrshnmbh'), \"In a shelf, you might find:\\n\\n1. Books: A shelf is commonly used to store books. Books can be of various genres, such as novels, textbooks, or reference books. They provide knowledge, entertainment, and can transport you to different worlds through storytelling.\\n\\n2. Decorative items: Shelves often serve as a display area for decorative items like figurines, vases, or sculptures. These items add aesthetic value to the space and reflect the owner's personal taste and style.\\n\\n3. Storage boxes: Shelves can also be used to store various items in organized boxes. These boxes can hold anything from office supplies, craft materials, or sentimental items. They help keep the space tidy and provide easy access to stored belongings.\")], 'agent_scratchpad': [AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}), ToolMessage(content='on the shelf', additional_kwargs={'name': 'where_cat_is_hiding'}, tool_call_id='call_pboyZTT0587rJtujUluO2OOc'), AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]}), ToolMessage(content=\"In a shelf, you might find:\\n\\n1. Books: A shelf is commonly used to store books. Books can be of various genres, such as novels, textbooks, or reference books. They provide knowledge, entertainment, and can transport you to different worlds through storytelling.\\n\\n2. Decorative items: Shelves often serve as a display area for decorative items like figurines, vases, or sculptures. These items add aesthetic value to the space and reflect the owner's personal taste and style.\\n\\n3. Storage boxes: Shelves can also be used to store various items in organized boxes. These boxes can hold anything from office supplies, craft materials, or sentimental items. They help keep the space tidy and provide easy access to stored belongings.\", additional_kwargs={'name': 'get_items'}, tool_call_id='call_vIVtgUb9Gvmc3zAGIrshnmbh')]}\n", + "on chain start: \n", + "{'input': 'where is the cat hiding and what items can be found there?', 'intermediate_steps': [(OpenAIToolAgentAction(tool='where_cat_is_hiding', tool_input={}, log='\\nInvoking: `where_cat_is_hiding` with `{}`\\n\\n\\n', message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]})], tool_call_id='call_pboyZTT0587rJtujUluO2OOc'), 'on the shelf'), (OpenAIToolAgentAction(tool='get_items', tool_input={'place': 'shelf'}, log=\"\\nInvoking: `get_items` with `{'place': 'shelf'}`\\n\\n\\n\", message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]})], tool_call_id='call_vIVtgUb9Gvmc3zAGIrshnmbh'), \"In a shelf, you might find:\\n\\n1. Books: A shelf is commonly used to store books. Books can be of various genres, such as novels, textbooks, or reference books. They provide knowledge, entertainment, and can transport you to different worlds through storytelling.\\n\\n2. Decorative items: Shelves often serve as a display area for decorative items like figurines, vases, or sculptures. These items add aesthetic value to the space and reflect the owner's personal taste and style.\\n\\n3. Storage boxes: Shelves can also be used to store various items in organized boxes. These boxes can hold anything from office supplies, craft materials, or sentimental items. They help keep the space tidy and provide easy access to stored belongings.\")], 'agent_scratchpad': [AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}), ToolMessage(content='on the shelf', additional_kwargs={'name': 'where_cat_is_hiding'}, tool_call_id='call_pboyZTT0587rJtujUluO2OOc'), AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]}), ToolMessage(content=\"In a shelf, you might find:\\n\\n1. Books: A shelf is commonly used to store books. Books can be of various genres, such as novels, textbooks, or reference books. They provide knowledge, entertainment, and can transport you to different worlds through storytelling.\\n\\n2. Decorative items: Shelves often serve as a display area for decorative items like figurines, vases, or sculptures. These items add aesthetic value to the space and reflect the owner's personal taste and style.\\n\\n3. Storage boxes: Shelves can also be used to store various items in organized boxes. These boxes can hold anything from office supplies, craft materials, or sentimental items. They help keep the space tidy and provide easy access to stored belongings.\", additional_kwargs={'name': 'get_items'}, tool_call_id='call_vIVtgUb9Gvmc3zAGIrshnmbh')]}\n", + "On chain end\n", + "{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'ChatPromptValue'], 'kwargs': {'messages': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'SystemMessage'], 'kwargs': {'content': 'You are a helpful assistant', 'additional_kwargs': {}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'HumanMessage'], 'kwargs': {'content': 'where is the cat hiding and what items can be found there?', 'additional_kwargs': {}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessageChunk'], 'kwargs': {'example': False, 'content': '', 'additional_kwargs': {'tool_calls': [{'index': 0, 'id': 'call_pboyZTT0587rJtujUluO2OOc', 'function': {'arguments': '{}', 'name': 'where_cat_is_hiding'}, 'type': 'function'}]}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'ToolMessage'], 'kwargs': {'tool_call_id': 'call_pboyZTT0587rJtujUluO2OOc', 'content': 'on the shelf', 'additional_kwargs': {'name': 'where_cat_is_hiding'}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessageChunk'], 'kwargs': {'example': False, 'content': '', 'additional_kwargs': {'tool_calls': [{'index': 0, 'id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'function': {'arguments': '{\\n \"place\": \"shelf\"\\n}', 'name': 'get_items'}, 'type': 'function'}]}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'ToolMessage'], 'kwargs': {'tool_call_id': 'call_vIVtgUb9Gvmc3zAGIrshnmbh', 'content': \"In a shelf, you might find:\\n\\n1. Books: A shelf is commonly used to store books. Books can be of various genres, such as novels, textbooks, or reference books. They provide knowledge, entertainment, and can transport you to different worlds through storytelling.\\n\\n2. Decorative items: Shelves often serve as a display area for decorative items like figurines, vases, or sculptures. These items add aesthetic value to the space and reflect the owner's personal taste and style.\\n\\n3. Storage boxes: Shelves can also be used to store various items in organized boxes. These boxes can hold anything from office supplies, craft materials, or sentimental items. They help keep the space tidy and provide easy access to stored belongings.\", 'additional_kwargs': {'name': 'get_items'}}}]}}\n", + "agent_llm: The| cat| is| hiding| on| the| shelf|.| In| the| shelf|,| you| might| find| books|,| decorative| items|,| and| storage| boxes|.|\n", + "\n", + "on chain start: \n", + "content='The cat is hiding on the shelf. In the shelf, you might find books, decorative items, and storage boxes.'\n", + "On chain end\n", + "{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'agent', 'AgentFinish'], 'kwargs': {'return_values': {'output': 'The cat is hiding on the shelf. In the shelf, you might find books, decorative items, and storage boxes.'}, 'log': 'The cat is hiding on the shelf. In the shelf, you might find books, decorative items, and storage boxes.'}}\n", + "On chain end\n", + "return_values={'output': 'The cat is hiding on the shelf. In the shelf, you might find books, decorative items, and storage boxes.'} log='The cat is hiding on the shelf. In the shelf, you might find books, decorative items, and storage boxes.'\n", + "On chain end\n", + "{'output': 'The cat is hiding on the shelf. In the shelf, you might find books, decorative items, and storage boxes.'}\n" + ] + } + ], + "source": [ + "from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, TypeVar, Union\n", + "from uuid import UUID\n", + "\n", + "from langchain_core.callbacks.base import AsyncCallbackHandler\n", + "from langchain_core.messages import BaseMessage\n", + "from langchain_core.outputs import ChatGenerationChunk, GenerationChunk, LLMResult\n", + "\n", + "# Here is a custom handler that will print the tokens to stdout.\n", + "# Instead of printing to stdout you can send the data elsewhere; e.g., to a streaming API response\n", + "\n", + "\n", + "class TokenByTokenHandler(AsyncCallbackHandler):\n", + " def __init__(self, tags_of_interest: List[str]) -> None:\n", + " \"\"\"A custom call back handler.\n", + "\n", + " Args:\n", + " tags_of_interest: Only LLM tokens from models with these tags will be\n", + " printed.\n", + " \"\"\"\n", + " self.tags_of_interest = tags_of_interest\n", + "\n", + " async def on_chain_start(\n", + " self,\n", + " serialized: Dict[str, Any],\n", + " inputs: Dict[str, Any],\n", + " *,\n", + " run_id: UUID,\n", + " parent_run_id: Optional[UUID] = None,\n", + " tags: Optional[List[str]] = None,\n", + " metadata: Optional[Dict[str, Any]] = None,\n", + " **kwargs: Any,\n", + " ) -> None:\n", + " \"\"\"Run when chain starts running.\"\"\"\n", + " print(\"on chain start: \")\n", + " print(inputs)\n", + "\n", + " async def on_chain_end(\n", + " self,\n", + " outputs: Dict[str, Any],\n", + " *,\n", + " run_id: UUID,\n", + " parent_run_id: Optional[UUID] = None,\n", + " tags: Optional[List[str]] = None,\n", + " **kwargs: Any,\n", + " ) -> None:\n", + " \"\"\"Run when chain ends running.\"\"\"\n", + " print(\"On chain end\")\n", + " print(outputs)\n", + "\n", + " async def on_chat_model_start(\n", + " self,\n", + " serialized: Dict[str, Any],\n", + " messages: List[List[BaseMessage]],\n", + " *,\n", + " run_id: UUID,\n", + " parent_run_id: Optional[UUID] = None,\n", + " tags: Optional[List[str]] = None,\n", + " metadata: Optional[Dict[str, Any]] = None,\n", + " **kwargs: Any,\n", + " ) -> Any:\n", + " \"\"\"Run when a chat model starts running.\"\"\"\n", + " overlap_tags = self.get_overlap_tags(tags)\n", + "\n", + " if overlap_tags:\n", + " print(\",\".join(overlap_tags), end=\": \", flush=True)\n", + "\n", + " def on_tool_start(\n", + " self,\n", + " serialized: Dict[str, Any],\n", + " input_str: str,\n", + " *,\n", + " run_id: UUID,\n", + " parent_run_id: Optional[UUID] = None,\n", + " tags: Optional[List[str]] = None,\n", + " metadata: Optional[Dict[str, Any]] = None,\n", + " inputs: Optional[Dict[str, Any]] = None,\n", + " **kwargs: Any,\n", + " ) -> Any:\n", + " \"\"\"Run when tool starts running.\"\"\"\n", + " print(\"Tool start\")\n", + " print(serialized)\n", + "\n", + " def on_tool_end(\n", + " self,\n", + " output: str,\n", + " *,\n", + " run_id: UUID,\n", + " parent_run_id: Optional[UUID] = None,\n", + " **kwargs: Any,\n", + " ) -> Any:\n", + " \"\"\"Run when tool ends running.\"\"\"\n", + " print(\"Tool end\")\n", + " print(output)\n", + "\n", + " async def on_llm_end(\n", + " self,\n", + " response: LLMResult,\n", + " *,\n", + " run_id: UUID,\n", + " parent_run_id: Optional[UUID] = None,\n", + " tags: Optional[List[str]] = None,\n", + " **kwargs: Any,\n", + " ) -> None:\n", + " \"\"\"Run when LLM ends running.\"\"\"\n", + " overlap_tags = self.get_overlap_tags(tags)\n", + "\n", + " if overlap_tags:\n", + " # Who can argue with beauty?\n", + " print()\n", + " print()\n", + "\n", + " def get_overlap_tags(self, tags: Optional[List[str]]) -> List[str]:\n", + " \"\"\"Check for overlap with filtered tags.\"\"\"\n", + " if not tags:\n", + " return []\n", + " return sorted(set(tags or []) & set(self.tags_of_interest or []))\n", + "\n", + " async def on_llm_new_token(\n", + " self,\n", + " token: str,\n", + " *,\n", + " chunk: Optional[Union[GenerationChunk, ChatGenerationChunk]] = None,\n", + " run_id: UUID,\n", + " parent_run_id: Optional[UUID] = None,\n", + " tags: Optional[List[str]] = None,\n", + " **kwargs: Any,\n", + " ) -> None:\n", + " \"\"\"Run on new LLM token. Only available when streaming is enabled.\"\"\"\n", + " overlap_tags = self.get_overlap_tags(tags)\n", + "\n", + " if token and overlap_tags:\n", + " print(token, end=\"|\", flush=True)\n", + "\n", + "\n", + "handler = TokenByTokenHandler(tags_of_interest=[\"tool_llm\", \"agent_llm\"])\n", + "\n", + "result = await agent_executor.ainvoke(\n", + " {\"input\": \"where is the cat hiding and what items can be found there?\"},\n", + " {\"callbacks\": [handler]},\n", + ")" + ] } ], "metadata": { @@ -1099,7 +1143,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.1" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/docs/docs/modules/agents/how_to/streaming_events.ipynb b/docs/docs/modules/agents/how_to/streaming_events.ipynb deleted file mode 100644 index 4f1ad14a37..0000000000 --- a/docs/docs/modules/agents/how_to/streaming_events.ipynb +++ /dev/null @@ -1,350 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "b69e747b-4e79-4caf-8f8b-c6e70275a31d", - "metadata": {}, - "source": [ - "# Event Streaming\n", - "\n", - "**NEW** This is a new API only works with recent versions of langchain-core!\n", - "\n", - "In this notebook, we'll see how to use `astream_events` to stream **token by token** from LLM calls used within the tools invoked by the agent. \n", - "\n", - "We will **only** stream tokens from LLMs used within tools and from no other LLMs (just to show that we can)! \n", - "\n", - "Feel free to adapt this example to the needs of your application.\n", - "\n", - "Our agent will use the OpenAI tools API for tool invocation, and we'll provide the agent with two tools:\n", - "\n", - "1. `where_cat_is_hiding`: A tool that uses an LLM to tell us where the cat is hiding\n", - "2. `tell_me_a_joke_about`: A tool that can use an LLM to tell a joke about the given topic\n", - "\n", - "\n", - "## ⚠️ Beta API ⚠️ ##\n", - "\n", - "Event Streaming is a **beta** API, and may change a bit based on feedback.\n", - "\n", - "Keep in mind the following constraints (repeated in tools section):\n", - "\n", - "* streaming only works properly if using `async`\n", - "* propagate callbacks if definning custom functions / runnables\n", - "* If creating a tool that uses an LLM, make sure to use `.astream()` on the LLM rather than `.ainvoke` to ask the LLM to stream tokens.\n", - "\n", - "## Event Hooks Reference\n", - "\n", - "\n", - "Here is a reference table that shows some events that might be emitted by the various Runnable objects.\n", - "Definitions for some of the Runnable are included after the table.\n", - "\n", - "⚠️ When streaming the inputs for the runnable will not be available until the input stream has been entirely consumed This means that the inputs will be available at for the corresponding `end` hook rather than `start` event.\n", - "\n", - "\n", - "| event | name | chunk | input | output |\n", - "|----------------------|------------------|---------------------------------|-----------------------------------------------|-------------------------------------------------|\n", - "| on_chat_model_start | [model name] | | {\"messages\": [[SystemMessage, HumanMessage]]} | |\n", - "| on_chat_model_stream | [model name] | AIMessageChunk(content=\"hello\") | | |\n", - "| on_chat_model_end | [model name] | | {\"messages\": [[SystemMessage, HumanMessage]]} | {\"generations\": [...], \"llm_output\": None, ...} |\n", - "| on_llm_start | [model name] | | {'input': 'hello'} | |\n", - "| on_llm_stream | [model name] | 'Hello' | | |\n", - "| on_llm_end | [model name] | | 'Hello human!' |\n", - "| on_chain_start | format_docs | | | |\n", - "| on_chain_stream | format_docs | \"hello world!, goodbye world!\" | | |\n", - "| on_chain_end | format_docs | | [Document(...)] | \"hello world!, goodbye world!\" |\n", - "| on_tool_start | some_tool | | {\"x\": 1, \"y\": \"2\"} | |\n", - "| on_tool_stream | some_tool | {\"x\": 1, \"y\": \"2\"} | | |\n", - "| on_tool_end | some_tool | | | {\"x\": 1, \"y\": \"2\"} |\n", - "| on_retriever_start | [retriever name] | | {\"query\": \"hello\"} | |\n", - "| on_retriever_chunk | [retriever name] | {documents: [...]} | | |\n", - "| on_retriever_end | [retriever name] | | {\"query\": \"hello\"} | {documents: [...]} |\n", - "| on_prompt_start | [template_name] | | {\"question\": \"hello\"} | |\n", - "| on_prompt_end | [template_name] | | {\"question\": \"hello\"} | ChatPromptValue(messages: [SystemMessage, ...]) |\n", - "\n", - "\n", - "Here are declarations associated with the events shown above:\n", - "\n", - "`format_docs`:\n", - "\n", - "```python\n", - "def format_docs(docs: List[Document]) -> str:\n", - " '''Format the docs.'''\n", - " return \", \".join([doc.page_content for doc in docs])\n", - "\n", - "format_docs = RunnableLambda(format_docs)\n", - "```\n", - "\n", - "`some_tool`:\n", - "\n", - "```python\n", - "@tool\n", - "def some_tool(x: int, y: str) -> dict:\n", - " '''Some_tool.'''\n", - " return {\"x\": x, \"y\": y}\n", - "```\n", - "\n", - "`prompt`:\n", - "\n", - "```python\n", - "template = ChatPromptTemplate.from_messages(\n", - " [(\"system\", \"You are Cat Agent 007\"), (\"human\", \"{question}\")]\n", - ").with_config({\"run_name\": \"my_template\", \"tags\": [\"my_template\"]})\n", - "```\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "29205bef-2288-48e9-9067-f19072277a97", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from langchain import hub\n", - "from langchain.agents import AgentExecutor, create_openai_tools_agent\n", - "from langchain.tools import tool\n", - "from langchain_core.callbacks import Callbacks\n", - "from langchain_core.prompts import ChatPromptTemplate\n", - "from langchain_openai import ChatOpenAI" - ] - }, - { - "cell_type": "markdown", - "id": "d6b0fafa-ce3b-489b-bf1d-d37b87f4819e", - "metadata": {}, - "source": [ - "## Create the model\n", - "\n", - "**Attention** For older versions of langchain, we must set `streaming=True`" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "fa3c3761-a1cd-4118-8559-ea4d8857d394", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "model = ChatOpenAI(temperature=0, streaming=True)" - ] - }, - { - "cell_type": "markdown", - "id": "b76e1a3b-2983-42d9-ac12-4a0f32cd4a24", - "metadata": {}, - "source": [ - "## Tools\n", - "\n", - "We define two tools that rely on a chat model to generate output!\n", - "\n", - "Please note a few different things:\n", - "\n", - "1. The tools are **async**\n", - "1. The model is invoked using **.astream()** to force the output to stream\n", - "1. For older langchain versions you should set `streaming=True` on the model!\n", - "1. We attach tags to the model so that we can filter on said tags in our callback handler\n", - "1. The tools accept callbacks and propagate them to the model as a runtime argument" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "c767f760-fe52-47e5-9c2a-622f03507aaf", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "@tool\n", - "async def where_cat_is_hiding(callbacks: Callbacks) -> str: # <--- Accept callbacks\n", - " \"\"\"Where is the cat hiding right now?\"\"\"\n", - " chunks = [\n", - " chunk\n", - " async for chunk in model.astream(\n", - " \"Give one up to three word answer about where the cat might be hiding in the house right now.\",\n", - " {\n", - " \"tags\": [\"tool_llm\"],\n", - " \"callbacks\": callbacks,\n", - " }, # <--- Propagate callbacks and assign a tag to this model\n", - " )\n", - " ]\n", - " return \"\".join(chunk.content for chunk in chunks)\n", - "\n", - "\n", - "@tool\n", - "async def tell_me_a_joke_about(\n", - " topic: str, callbacks: Callbacks\n", - ") -> str: # <--- Accept callbacks\n", - " \"\"\"Tell a joke about a given topic.\"\"\"\n", - " template = ChatPromptTemplate.from_messages(\n", - " [\n", - " (\"system\", \"You are Cat Agent 007. You are funny and know many jokes.\"),\n", - " (\"human\", \"Tell me a long joke about {topic}\"),\n", - " ]\n", - " )\n", - " chain = template | model.with_config({\"tags\": [\"tool_llm\"]})\n", - " chunks = [\n", - " chunk\n", - " async for chunk in chain.astream({\"topic\": topic}, {\"callbacks\": callbacks})\n", - " ]\n", - " return \"\".join(chunk.content for chunk in chunks)" - ] - }, - { - "cell_type": "markdown", - "id": "cba476f8-29da-4c2c-9134-186871caf7ae", - "metadata": {}, - "source": [ - "## Initialize the Agent" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "0bab4488-bf4c-461f-b41e-5e60310fe0f2", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "input_variables=['agent_scratchpad', 'input'] input_types={'chat_history': typing.List[typing.Union[langchain_core.messages.ai.AIMessage, langchain_core.messages.human.HumanMessage, langchain_core.messages.chat.ChatMessage, langchain_core.messages.system.SystemMessage, langchain_core.messages.function.FunctionMessage, langchain_core.messages.tool.ToolMessage]], 'agent_scratchpad': typing.List[typing.Union[langchain_core.messages.ai.AIMessage, langchain_core.messages.human.HumanMessage, langchain_core.messages.chat.ChatMessage, langchain_core.messages.system.SystemMessage, langchain_core.messages.function.FunctionMessage, langchain_core.messages.tool.ToolMessage]]} messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='You are a helpful assistant')), MessagesPlaceholder(variable_name='chat_history', optional=True), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')), MessagesPlaceholder(variable_name='agent_scratchpad')]\n", - "[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='You are a helpful assistant')), MessagesPlaceholder(variable_name='chat_history', optional=True), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')), MessagesPlaceholder(variable_name='agent_scratchpad')]\n" - ] - } - ], - "source": [ - "# Get the prompt to use - you can modify this!\n", - "prompt = hub.pull(\"hwchase17/openai-tools-agent\")\n", - "print(prompt)\n", - "print(prompt.messages)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "1762f4e1-402a-4bfb-af26-eb5b7b8f56bd", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "tools = [tell_me_a_joke_about, where_cat_is_hiding]\n", - "agent = create_openai_tools_agent(model.with_config({\"tags\": [\"agent\"]}), tools, prompt)\n", - "executor = AgentExecutor(agent=agent, tools=tools)" - ] - }, - { - "cell_type": "markdown", - "id": "841271d7-1de1-41a9-9387-bb04368537f1", - "metadata": {}, - "source": [ - "## Stream the output\n", - "\n", - "The streamed output is shown with a `|` as the delimiter between tokens. " - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "a5d94bd8-4a55-4527-b21a-4245a38c7c26", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/eugene/src/langchain/libs/core/langchain_core/_api/beta_decorator.py:86: LangChainBetaWarning: This API is in beta and may change in the future.\n", - " warn_beta(\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--\n", - "Starting tool: where_cat_is_hiding with inputs: {}\n", - "\n", - "\n", - "|Under| the| bed|.||\n", - "\n", - "Ended tool: where_cat_is_hiding\n", - "--\n", - "Starting tool: tell_me_a_joke_about with inputs: {'topic': 'under the bed'}\n", - "\n", - "\n", - "|Sure|,| here|'s| a| long| joke| about| what|'s| hiding| under| the| bed|:\n", - "\n", - "|Once| upon| a| time|,| there| was| a| mis|chie|vous| little| boy| named| Tim|my|.| Tim|my| had| always| been| afraid| of| what| might| be| lurking| under| his| bed| at| night|.| Every| evening|,| he| would| ti|pt|oe| into| his| room|,| turn| off| the| lights|,| and| then| make| a| daring| leap| onto| his| bed|,| ensuring| that| nothing| could| grab| his| ankles|.\n", - "\n", - "|One| night|,| Tim|my|'s| parents| decided| to| play| a| prank| on| him|.| They| hid| a| remote|-controlled| toy| monster| under| his| bed|,| complete| with| glowing| eyes| and| a| grow|ling| sound| effect|.| As| Tim|my| settled| into| bed|,| his| parents| quietly| sn|uck| into| his| room|,| ready| to| give| him| the| scare| of| a| lifetime|.\n", - "\n", - "|Just| as| Tim|my| was| about| to| drift| off| to| sleep|,| he| heard| a| faint| grow|l| coming| from| under| his| bed|.| His| eyes| widened| with| fear|,| and| his| heart| started| racing|.| He| must|ered| up| the| courage| to| peek| under| the| bed|,| and| to| his| surprise|,| he| saw| a| pair| of| glowing| eyes| staring| back| at| him|.\n", - "\n", - "|Terr|ified|,| Tim|my| jumped| out| of| bed| and| ran| to| his| parents|,| screaming|,| \"|There|'s| a| monster| under| my| bed|!| Help|!\"\n", - "\n", - "|His| parents|,| trying| to| st|ifle| their| laughter|,| rushed| into| his| room|.| They| pretended| to| be| just| as| scared| as| Tim|my|,| and| together|,| they| brav|ely| approached| the| bed|.| Tim|my|'s| dad| grabbed| a| bro|om|stick|,| ready| to| defend| his| family| against| the| imaginary| monster|.\n", - "\n", - "|As| they| got| closer|,| the| \"|monster|\"| under| the| bed| started| to| move|.| Tim|my|'s| mom|,| unable| to| contain| her| laughter| any| longer|,| pressed| a| button| on| the| remote| control|,| causing| the| toy| monster| to| sc|urry| out| from| under| the| bed|.| Tim|my|'s| fear| quickly| turned| into| confusion|,| and| then| into| laughter| as| he| realized| it| was| all| just| a| prank|.\n", - "\n", - "|From| that| day| forward|,| Tim|my| learned| that| sometimes| the| things| we| fear| the| most| are| just| fig|ments| of| our| imagination|.| And| as| for| what|'s| hiding| under| his| bed|?| Well|,| it|'s| just| dust| b|unn|ies| and| the| occasional| missing| sock|.| Nothing| to| be| afraid| of|!\n", - "\n", - "|Remember|,| laughter| is| the| best| monster| repell|ent|!||\n", - "\n", - "Ended tool: tell_me_a_joke_about\n" - ] - } - ], - "source": [ - "async for event in executor.astream_events(\n", - " {\"input\": \"where is the cat hiding? Tell me a joke about that location?\"},\n", - " include_tags=[\"tool_llm\"],\n", - " include_types=[\"tool\"],\n", - "):\n", - " hook = event[\"event\"]\n", - " if hook == \"on_chat_model_stream\":\n", - " print(event[\"data\"][\"chunk\"].content, end=\"|\")\n", - " elif hook in {\"on_chat_model_start\", \"on_chat_model_end\"}:\n", - " print()\n", - " print()\n", - " elif hook == \"on_tool_start\":\n", - " print(\"--\")\n", - " print(\n", - " f\"Starting tool: {event['name']} with inputs: {event['data'].get('input')}\"\n", - " )\n", - " elif hook == \"on_tool_end\":\n", - " print(f\"Ended tool: {event['name']}\")\n", - " else:\n", - " pass" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -}