From 49ccfdb7802cbf9b6836a207ddab7ea3e7b728b7 Mon Sep 17 00:00:00 2001 From: William FH <13333726+hinthornw@users.noreply.github.com> Date: Mon, 6 May 2024 17:41:12 -0700 Subject: [PATCH] Improve Intro Tutorial (#402) --- examples/introduction.ipynb | 779 ++++++++++++++++++++++++------------ 1 file changed, 525 insertions(+), 254 deletions(-) diff --git a/examples/introduction.ipynb b/examples/introduction.ipynb index 74ebbbf1d..db017db7a 100644 --- a/examples/introduction.ipynb +++ b/examples/introduction.ipynb @@ -33,7 +33,7 @@ "%pip install -U langgraph langsmith\n", "\n", "# Used for this tutorial; not a requirement for LangGraph\n", - "%pip install -U langchain langchain_anthropic" + "%pip install -U langchain_anthropic" ] }, { @@ -125,12 +125,12 @@ "id": "4137feed-746e-4c72-a34a-f7a699ad5dcf", "metadata": {}, "source": [ - "**Notice** that we've defined our `State` as a TypedDict with a single key: `messages`. The `messages` key is annotated with the `add_messages` function, which tells LangGraph to append new messages to the existing list, rather than overwriting it.\n", + "**Notice** that we've defined our `State` as a TypedDict with a single key: `messages`. The `messages` key is annotated with the [`add_messages`](https://langchain-ai.github.io/langgraph/reference/graphs/?h=add+messages#add_messages) function, which tells LangGraph to append new messages to the existing list, rather than overwriting it.\n", "\n", "So now our graph knows two things:\n", "\n", "1. Every `node` we define will receive the current `State` as input and return a value that updates that state.\n", - "2. `messages` will be _appended_ to the current list, rather than directly overwritten. This is communicated via the prebuilt `add_messages` function in the `Annotated` syntax.\n", + "2. `messages` will be _appended_ to the current list, rather than directly overwritten. This is communicated via the prebuilt [`add_messages`](https://langchain-ai.github.io/langgraph/reference/graphs/?h=add+messages#add_messages) function in the `Annotated` syntax.\n", "\n", "Next, add a \"`chatbot`\" node. Nodes represent units of work. They are typically regular python functions." ] @@ -267,35 +267,49 @@ "metadata": {}, "outputs": [ { - "name": "stdout", + "name": "stdin", "output_type": "stream", "text": [ - "User: Hi there, I'm Will!\n" + "User: what's langgraph all about?\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Assistant: It's nice to meet you, Will! I'm Claude, an AI assistant created by Anthropic. I'm here to help with any questions or tasks you might have. Please let me know if there's anything I can assist you with.\n" + "Assistant: Langgraph is a new open-source deep learning framework that focuses on enabling efficient training and deployment of large language models. Some key things to know about Langgraph:\n", + "\n", + "1. Efficient Training: Langgraph is designed to accelerate the training of large language models by leveraging advanced optimization techniques and parallelization strategies.\n", + "\n", + "2. Modular Architecture: Langgraph has a modular architecture that allows for easy customization and extension of language models, making it flexible for a variety of NLP tasks.\n", + "\n", + "3. Hardware Acceleration: The framework is optimized for both CPU and GPU hardware, allowing for efficient model deployment on a wide range of devices.\n", + "\n", + "4. Scalability: Langgraph is designed to handle large-scale language models with billions of parameters, enabling the development of state-of-the-art NLP applications.\n", + "\n", + "5. Open-Source: Langgraph is an open-source project, allowing developers and researchers to collaborate, contribute, and build upon the framework.\n", + "\n", + "6. Performance: The goal of Langgraph is to provide superior performance and efficiency compared to existing deep learning frameworks, particularly for training and deploying large language models.\n", + "\n", + "Overall, Langgraph is a promising new deep learning framework that aims to address the challenges of building and deploying advanced natural language processing models at scale. It is an active area of research and development, with the potential to drive further advancements in the field of language AI.\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "User: hm that doesn't seem right...\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "User: What's my name?\n" + "Assistant: I'm sorry, I don't have enough context to determine what doesn't seem right. Could you please provide more details about what you're referring to? That would help me better understand and respond appropriately.\n" ] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "Assistant: I'm afraid I don't actually know your name. As an AI assistant, I don't have specific information about you or other individual users. I can only respond based on the context provided to me during our conversation.\n" - ] - }, - { - "name": "stdout", + "name": "stdin", "output_type": "stream", "text": [ "User: q\n" @@ -400,7 +414,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 3, "id": "0c52923c-5665-4f8c-a1ba-9799e369c49e", "metadata": {}, "outputs": [], @@ -418,7 +432,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 4, "id": "35c8978e-c07d-4dd0-a97b-0ce3a723eea5", "metadata": {}, "outputs": [ @@ -427,11 +441,11 @@ "text/plain": [ "[{'url': 'https://medium.com/@cplog/introduction-to-langgraph-a-beginners-guide-14f9be027141',\n", " 'content': 'Nodes: Nodes are the building blocks of your LangGraph. Each node represents a function or a computation step. You define nodes to perform specific tasks, such as processing input, making ...'},\n", - " {'url': 'https://www.analyticsvidhya.com/blog/2024/03/build-an-ai-coding-agent-with-langgraph-by-langchain/',\n", - " 'content': 'LangGraph is an extension of LangChain, which allows us to build cyclic, stateful, multi-actor agent systems. It implements a graph structure with nodes and edges. The nodes are functions or tools, and the edges are the connections between nodes. Edges are of two types: conditional and normal.'}]" + " {'url': 'https://js.langchain.com/docs/langgraph',\n", + " 'content': \"Assuming you have done the above Quick Start, you can build off it like:\\nHere, we manually define the first tool call that we will make.\\nNotice that it does that same thing as agent would have done (adds the agentOutcome key).\\n LangGraph\\n🦜🕸️LangGraph.js\\n⚡ Building language agents as graphs ⚡\\nOverview\\u200b\\nLangGraph is a library for building stateful, multi-actor applications with LLMs, built on top of (and intended to be used with) LangChain.js.\\n Therefore, we will use an object with one key (messages) with the value as an object: { value: Function, default?: () => any }\\nThe default key must be a factory that returns the default value for that attribute.\\n Streaming Node Output\\u200b\\nOne of the benefits of using LangGraph is that it is easy to stream output as it's produced by each node.\\n What this means is that only one of the downstream edges will be taken, and which one that is depends on the results of the start node.\\n\"}]" ] }, - "execution_count": 12, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -457,19 +471,10 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "id": "dc5af88b-47d2-43bf-9a2c-6c07506b1732", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/wfh/.pyenv/versions/3.11.2/lib/python3.11/site-packages/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: The function `bind_tools` is in beta. It is actively being worked on, so the API may change.\n", - " warn_beta(\n" - ] - } - ], + "outputs": [], "source": [ "from typing import Annotated\n", "\n", @@ -504,19 +509,52 @@ "id": "d1e84cfc-b1b2-48e3-8550-152a408c3926", "metadata": {}, "source": [ - "Now we'll add the tools to a new node. The `ToolNode` is a helper class in LangGraph that `invoke`'s the selected tools whenever the LLM responds with 1 or more tool calls. It relies on `tool_calling` support, which is available in Anthropic, OpenAI, Google Gemini, and a number of other LLM providers." + "Next we need to create a function to actually run the tools if they are called. We'll do this by adding the tools to a new node.\n", + "\n", + "Below, implement a `BasicToolNode` that checks the most recent message in the state and calls tools if the message contains `tool_calls. It relies on the LLM's `tool_calling` support, which is available in Anthropic, OpenAI, Google Gemini, and a number of other LLM providers.\n", + "\n", + "We will later replace this with LangGraph's prebuilt [ToolNode](https://langchain-ai.github.io/langgraph/reference/prebuilt/#toolnode) to speed things up, but building it ourselves first is instructive." ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "id": "12f1fc14-cd91-4cd4-9f2e-1d007f8beafc", "metadata": {}, "outputs": [], "source": [ - "from langgraph.prebuilt import ToolNode\n", + "import json\n", "\n", - "tool_node = ToolNode(tools=[tool])\n", + "from langchain_core.messages import ToolMessage\n", + "\n", + "\n", + "class BasicToolNode:\n", + " \"\"\"A node that runs the tools requested in the last AIMessage.\"\"\"\n", + "\n", + " def __init__(self, tools: list) -> None:\n", + " self.tools_by_name = {tool.name: tool for tool in tools}\n", + "\n", + " def __call__(self, inputs: dict):\n", + " if messages := inputs.get(\"messages\", []):\n", + " message = messages[-1]\n", + " else:\n", + " raise ValueError(\"No message found in input\")\n", + " outputs = []\n", + " for tool_call in message.tool_calls:\n", + " tool_result = self.tools_by_name[tool_call[\"name\"]].invoke(\n", + " tool_call[\"args\"]\n", + " )\n", + " outputs.append(\n", + " ToolMessage(\n", + " content=json.dumps(tool_result),\n", + " name=tool_call[\"name\"],\n", + " tool_call_id=tool_call[\"id\"],\n", + " )\n", + " )\n", + " return {\"messages\": outputs}\n", + "\n", + "\n", + "tool_node = BasicToolNode(tools=[tool])\n", "graph_builder.add_node(\"action\", tool_node)" ] }, @@ -529,23 +567,45 @@ "\n", "Recall that **edges** route the control flow from one node to the next. **Conditional edges** usually contain \"if\" statements to route to different nodes depending on the current graph state. These functions receive the current graph `state` and return a string or list of strings indicating which node(s) to call next.\n", "\n", - "Below, call `add_conditional_edges` to route from the `chatbot` node to either the `action` or \"`__end__`\" using the prebuilt `tools_condition` function. Then, create an edge from the action/tools node _back to_ the chat bot to let it observe the response from our search engine and decide whether it has enough information to answer the user's question." + "Below, call define a router function called `route_tools`, that checks for tool_calls in the chatbot's output. Provide this function to the graph by calling `add_conditional_edges`, which tells the graph that whenever the `chatbot` node completes to check this function to see where to go next. \n", + "\n", + "The condition will route to `action` if tool calls are present and \"`__end__`\" if not.\n", + "\n", + "Later, we will replace this with the prebuilt [tools_condition](https://langchain-ai.github.io/langgraph/reference/prebuilt/#tools_condition) to be more concise, but implementing it ourselves first makes things more clear. " ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "id": "d662df94-66ac-4c6c-92f0-4c93620f1c74", "metadata": {}, "outputs": [], "source": [ - "from langgraph.prebuilt import tools_condition\n", + "from typing import Literal\n", + "\n", + "\n", + "def route_tools(\n", + " state: State,\n", + ") -> Literal[\"action\", \"__end__\"]:\n", + " \"\"\"Use in the conditional_edge to route to the ToolNode if the last message\n", + "\n", + " has tool calls. Otherwise, route to the end.\"\"\"\n", + " if isinstance(state, list):\n", + " ai_message = state[-1]\n", + " elif messages := state.get(\"messages\", []):\n", + " ai_message = messages[-1]\n", + " else:\n", + " raise ValueError(f\"No messages found in input state to tool_edge: {state}\")\n", + " if hasattr(ai_message, \"tool_calls\") and len(ai_message.tool_calls) > 0:\n", + " return \"action\"\n", + " return \"__end__\"\n", + "\n", "\n", "# The `tools_condition` function returns \"action\" if the chatbot asks to use a tool, and \"__end__\" if\n", "# it is fine directly responding. This conditional routing defines the main agent loop.\n", "graph_builder.add_conditional_edges(\n", " \"chatbot\",\n", - " tools_condition,\n", + " route_tools,\n", " # The following dictionary lets you tell the graph to interpret the condition's outputs as a specific node\n", " # It defaults to the identity function, but if you\n", " # want to use a node named something else apart from \"action\",\n", @@ -573,13 +633,13 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "id": "8b49509c-9d97-457c-a76a-c495fb30ccbc", "metadata": {}, "outputs": [ { "data": { - "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAFBATQDASIAAhEBAxEB/8QAHQABAAIDAQEBAQAAAAAAAAAAAAYHBAUIAwIBCf/EAFgQAAEDAwICAwoJBQsKBQUAAAEAAgMEBQYHERIhEzFVCBQWFyJBUZOU0RUjMjZhdbPS4ThTcZGSCTVCUlRicnaBwcMzN0NFVnN0g7G0JCWCoaI0hbLC1P/EABsBAQACAwEBAAAAAAAAAAAAAAADBAECBQYH/8QAOhEBAAECAQcJBQgCAwAAAAAAAAECAxEEEhMhMVFSFBVBU5GhscHhBWFx0dIiMjNCYoGS8HKCNENj/9oADAMBAAIRAxEAPwD+qaIiAiIgIiICIiAiIgxa660Vs4O/KynpOPfh6eVrOLbr23PPrH61i+FVl7YoPaWe9QnUijp67OsajqYI6hgttwcGysDgD0tHz2KwfB619m0fqGe5VMpyyzks0010zMzGOrDfMeTpWMj01EV52CxPCqy9sUHtLPenhVZe2KD2lnvVd+D1r7No/UM9yeD1r7No/UM9yqc65PwVdsJ+bv1dyxPCqy9sUHtLPenhVZe2KD2lnvVd+D1r7No/UM9yeD1r7No/UM9yc65PwVdsHN36u5YnhVZe2KD2lnvTwqsvbFB7Sz3qu/B619m0fqGe5PB619m0fqGe5Odcn4Ku2Dm79XcsTwqsvbFB7Sz3p4VWXtig9pZ71Xfg9a+zaP1DPcng9a+zaP1DPcnOuT8FXbBzd+ruWKzJrPK9rGXahe9x2a1tSwkn0DmtmqRyiy2+mtIkioKaKRtTTFr2QtBHx7OogK7l0rN6jKLUXaImNcxr90RPmo5RY0ExGOOIiIpFQREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQV3n3z9xv6suH2tGvNemffP3G/qy4fa0a815v2t+LR/j51PSZF+BH7i0mYZpZcCsj7vfq5tBQNeyLpCxz3Pe48LWMYwFz3EnYNaCSt2oBrdbLVdcI6O7Wu+3KGKrgnhfjcTpK+kmY7ijqIg3yt2Eb8gf0HqXGoiKqoidi5VMxTMw0WYd0hj2N0+GVlJFW3O3ZFcJKPp4rfVl8DI2PMjuiEJeXh7A3oyA7m4gEMct/k+umEYXWUtNe7xJbpainjqh0tDUcMUTyQx8rhGWwgkEfGFu2x36lUs9TnNdhmAZJkNmvF3kx/LZKh7WW7huc9t6KohiqJKVnMSfGMLmNG+3PbrWLq+7Jc8rMtoqm1ZvJbLjYY2Y1bbRBLTU8kssD+l7+c0tDXteWgxzODeEHZriVdizRMxE+/HX7/gqzdriJmPD3LtynWPEcNvcVnul0kbdZqQV0VHS0U9VLLCXObxsbExxdza7cDcgDc7DmtPg2uVszXUPKsTZR1tNU2es70hldQ1PRzgRNe9znmIMj2c4tDXO8oAObuHBRbTCyXE6q43d6q0V9LAzTyjon1FXSPi6KcVG74XFwG0g2BLevkD1LaYPPXYlrbn1urrHdzT5FX09fQXWCifJRGNtFHG8STDyY3B8Ths7Yndu3Wopt0RExtnDf70kV1TMT0YrhREVRZabLv3lP/E0328auFU9l37yn/iab7eNXCvX+zP8Ahx/lV4UuF7Q+/T8BERdFyRERAREQEREBERAREQEREBERAREQEREBERAREQEREBERBXeffP3G/qy4fa0ajeV6f4znXevhHj9tvvevH0HwhSsn6Li24uHiB234W77dew9CsfJ8JosqrKKqqKispaikjlijko5ujPDIWFwPI7842fqWq8VVD2xe/bfwVHKsi5TVTcpuZsxGGyd8/N1rGVW7dqKKoxVeNAtNAwsGBY4GEglvwZDsSN9j8n6T+tbfF9MMQwmukrcfxi02SskjML56Cjjhe5hIJaS0AkbtB2+gKc+Kqh7Yvftv4J4qqHti9+2/gqU+y65jCb3injLbEa4p7oa1FsvFVQ9sXv238FUWutLW4BlelNBab3dGU+RZNFa68S1HGXQOjc4hp28k7gc1pzP/AOsdkt+cLW6VlrCvFmoMhtlRbrpRwXCgqG8E1LUxiSORvXs5p5ELf+Kqh7Yvftv4J4qqHti9+2/gnNEx/wBsdkscvtT0Sq4dz/pmOrAMbH/2uH7qyLfodp5abhTV1FhGP0lbTStmgqIbbEx8UjSC1zXBu4IIBBHoVk+Kqh7Yvftv4J4qqHti9+2/gpObK+u8WvLLHD3QimXfvKf+Jpvt41cKhDtJbZKY+muV3qI2SMk6OWs3a4tcHDcbdW4Cm66mT2IyaxFrOxnGZ7YiPJQyq/TfqiaRERTKIiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAud+6q+f2gf9d4Psnrohc791V8/tA/67wfZPQdEIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiIC537qr5/aB/13g+yeuiFzv3VXz+0D/rvB9k9B0QiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICItTkOT0GM0zJa2R5fKS2GngjMkszvQ1g5n6T1DrJA5rammapwphmImZwhtkVdz5/kVVITR2Sio4N+RrqwulI+lkbS0f2PK8fDPLv5NZP2plLot9UdvyWoyW9P5VlL+G/dR6KTaCa0XzGOB3wW5/flrkdz6SkkJMfM8yW7OYT53Mcv6/eGeXfyayftTKo9bNGDrxkWHXjIaS0ifHKvvhrIjJw1kW4cYJdxzYXNafSBxAbcRKaKOKO05Je3Nv3BuhXiW0OoZq+mMGSZFw3O4B7dnxtI+IhPnHCw7kHmHPeF0eq18M8u/k1k/amTwzy7+TWT9qZNFHFHackvbllIq2ZmuWMcC+is0rfO1s0rD+vhd/0W6smokNZVQ0d1opLNWTODIy94lp5XE7BrZQB5ROwAcGk7jYFY0U/lmJ+E+W1pXk92iMZhL0RFCriIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgxLvdKeyWuruFU7gpqWJ00hHXwtG52+nkqwoxVV0z7pch/5nVNBezi4m07esQs9DW/R8o7k9alOrL3Nw0s/gS19DFIf5jqqIEf277f2rRKWr7NqJjpme7D5+Dr5DRGE19IsUXehddXWsVtObm2AVLqISt6YRFxaJCzffhLgRxbbbgjzKrsivmVZrq1csOx7IfBK32S2U9dV1sNHFU1NTLO+QMY0ShzGxtbESTtuSduSi12xvKrn3Q7qG3ZibPc4cHpO+rrFbYZX1DxWVA3Eb92MaXbkgAnbkCOtVXRm5uh0Ivx0jWFoc4NLjwtBO25232H6iucBq7keaaf4BLb77crdlt1o6ieotuOWenrZajoniJ0xNQ4RwxB4PyiCTIADyWhdfMj1ci0Cvc9+qceu9ZX3KnnfQ0tO7gnip6pjpQ2VjwHOEThwndoDzsNwCGDXTR0R/dXzdRwXehqblVW+Gtp5a+lYySopWStdLC1+/A57Ad2h3C7Ykc+E7dSy1z0/GspvWvWo0WN5g/HK2ns1m4p3W+GpFS/aq4ekDx5Ldw7cMAJ4uRG2xxcD1WzLXassdutl4ZhJZjzLtcaqko4ql89S6olpwyMTBzWxAwPdvsXHiaNxtumBF3XhMOjnSNYWhzg0uPC0E7bnbfYfqK+KmmhraeSCoiZPBI0sfFK0Oa9p6wQeRC5Wq73kWqlx0YrJ8hmsd5jvd3tdRUWymgcwz08FTG6oY2Vjx5bYyOE7tAkOw3AI6qgjdFBGx8jpntaA6RwALztzJA2HP6FnXE4w3orz8dTe6f3yd0tVYq2Z9RPRsbLTTzP4pJqc8hxE8y5jgWknmRwkkkkqaKrrK90WoljLOuSlq43+ng+Ld/8Ak1v61aKtXNebXvjHvmPLFwMpoii7MQIiKFVEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREGpyyx+EmOV9tEnQyzx/FS/m5AeJjv7HBp/sVe2ytdX0jXyRGnqWngnp3Hd0Mg+Uw/SD+vkfOrYUVyjCjdKl1xtc8dBdS0NkdJHxxVIHUJACDuByDwdx6HAbKWMK6cyqcNy9kt+LMzFWyVQZnpDb8uyOnyGnvF5xm+xU3eb7hY6lsT54OIuEUgex7XAOJIPDuCTsVnWLTW32HKYcgZXXGsuMdmhshfWziXpIY5HyB73FvE6Qued3E8/RvzWXmuXO0yslVd8ut7rRaqbbpbi2phkp+Z2ABLmvJJ5AcAJ8wK9rLlL8itFHdLdYr1U0FZE2eCYUZaJGOG7XAEg7Ec1jk93ojH94daLlmdcTCDUnc62S00FghtN8v8AZqqz009DHcKGqjZUT08svSvilJjLS3j2ILWtcNuRXozueMfpsPs+P0N0vdujstxluVrr6erb33RPkLy9jJHMdxMPSyDZ4cSHcydgrC+EK/8A2cvXsn4p8IV/+zl69k/FOT3dxnWN8K+vGgVFdrvVXSPLcqtlfW0VPQVs9vro4nVcULS1vSfFHyjxOJc3hO7jsQDsve5aCWCRllNjrrth9RaaD4KgqrDUtikdSbgiF/Gx4cA7ygSOIEkg7kqdfCFf/s5evZPxT4Qr/wDZy9eyfinJ7u4zrO+EIrtBsclw/Hcft09ysTMfqO+rdcLbUBtXDKQ8SPL3tcHF/SP4uIEHiKn1uozb7fS0rqiasdBE2I1FS4OllLQBxvIABcdtzsBzPUq3yvuj8KwbJ3Y7kFZLZby1rHmluLW02zXDdruORzW7H07+Y+hT/CWwan0zaqmvdtdZiN3ss1xjqp5Rv1GaJxbGPMeAl3Pk5pG6aCqPv6o+Plta1XrNuMYnsb3AKB10yCrvZB7zponUNK7fdsji4GZ4+gFjWb+lrx+mwl5UlJBQUsNNTQx09NCxscUMTQ1jGgbBrQOQAA2AC9UrqiqdWyNn973CuXJu1zVIiIo0QiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgKvNZ9csb0QsMNZeXzVlzrX9Ba7JQM6WtuMx2AjijHM8yAXdQ3HnIBjOtfdFNwe8U+E4Xazmmp9wb/wCEsdO74ukaf9PVvHKKMbg7Egnl1A8Q89GO52diV+lzvPLp4Z6oVrNprtM34i3sO/8A4ejjI2jYNyOLYF256g4hBG8G0OyTV7KKPUHW1kMk1M7prFgkT+koLQPNJP5p6jbrJ3A/UGdIoiAiIgIiIOEf3UrRj4bw6y6k0EG9XZnC3XJzW8zSyO3ieT6GSkt/530LkXuOcLsV81mxutzDIrhiFg74eyjuFJLLSCurY+jcKNtWwt6EkSNLnBwdsQ1pa57XD+yeVYtas3xu5WC+UTLhaLlA+mqqaQkCSNw2I3BBafOHAgggEEEAqK3PQXAbrpZDpzPjNH4HwQiGC3MaR0O25EjH78Qk3LnGTfiLnOJJLjuE/Rcn2zMMw7jSup7JnNRWZjo9JI2C25bwGWtsgJ2ZDWNA3fGOQEgHLkB1hjeprXdaK+W2muFuq4a+gqo2zQVNNIJI5WEbhzXDkQR5wgykREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBc9ap6x5dmed3DSrSOlEeRUbY/h7K66I952KORvE0NBHxs7mndrRy/Ts7g6FXO3c/flJ90Z9ZWj/s3ILB0U0Ix3RCy1EFs6e53u4P6e7ZBcXdJW3GY8y+R557bk7NHIbnrJJNkIiAiIgIiICIiAiIgx7hbqW70FRQ11NDWUVRG6KanqGB8crHDZzXNPIgjkQVy5dsEy3uP6+qyLTymqsq0oke6ou2FGQvqbUCd31FA5x3LRzJiJ9PXvxM6rWhz75iZH9W1P2TkH7g+aWnUXEbVktiqDVWi5wNqKaVzCwlp9LTzBB3BHpC3qpTuLfyWtOvq3/EerrQEREBERAREQEREBERAREQEREBERAREQEXnPURUsZkmlZEwdbpHBo/WVr/Cmyj/AFvQe0s962imqrZA2iLV+FVl7YoPaWe9PCqy9sUHtLPettHXwyzhLaItX4VWXtig9pZ708KrL2xQe0s96aOvhkwlXndM63V3c96YyZlSYu7K4Kerigq6dtb3r3vE/iaJi7o37jj6Nm23+k335LgfTL90JnxXVXUDIqbTl91qc2rKKSO3R3gtdTuii6IMDhTuMhcTv8lu3VsV/STLvBPOcXuuPXi4W+qtdzppKSoiNUzmx7SDsd+RG+4PmIBX86O477l8Y/3Tt8ny2opfgjBqkvpamV7WRV9STvTSR7nm0N+N5HdpDAetNHXwyYS/ptZqisrLPQz3GjZb7hLBG+ppI5umbBKWgvYH7N4w07ji2G+2+w6lmLV+FVl7YoPaWe9PCqy9sUHtLPemjr4ZMJbRFq/Cqy9sUHtLPenhVZe2KD2lnvTR18MmEtoi1fhVZe2KD2lnvX3FklpncGx3SikcfM2oYT/1TR17pMJbFERRsCIiAtDn3zEyP6tqfsnLfLQ598xMj+ran7JyCsu4t/Ja06+rf8R6utUp3Fv5LWnX1b/iPV1oCIiAiIgIiICIiAiIgIiICIiAiIgKIZdl09JVi02kMNwLQ+epkHFHSMPVy/hSO/gt6gAXO5cLXyuonZS08s0h2jjaXuP0AblVDjT5Ku1R3GfY1dyPfs7hvzc8Agc/M1vC0fQ0KWnCmmbk9Gz4ruS2Yu1/a2Q/H41Q1c3T3GM3irI2NTcdpnnnvyBHC0fQ0AfQvbwftY/1bR+oZ7lDtYNXaTSOkx+eqo6isF1usFvPQQTSmJjneXJtGx5c4DqZyLj1b7ELIyLWzDcUprZLdLpLTOuVN35T0woKl9T0PLeR8LYzJG0b8y9rdjuDsQVHN65Vtql3IminVqjBKfB+19m0fqG+5PB+19m0fqG+5R2/6wYfjdntFzrL3E+kvDeO3GiikqpKtvDxF0ccTXPcACCSBsNxvstNVavQXLKNNoccqKK6WDKZa5klYA4uAgp3yDg5jhdxs4XBwJGxGwK10lfFLM1Uwnfg/a+zaP1Dfcng/a+zaP1Dfco9YNXMTyjJ6rH7VdTW3OmfLHI1lNMIuKM7SNbMWdG4tPIhriQpgmkr4pbRhOxgeD9r7No/UN9yeD9r7No/UN9yi+Pa14XleQiyWi89/wBc50jGPhpZjTyOjBLwyfg6J5Aad+Fx6l845rfhGW5BHZbTfo6uvmMggHQSsiqTHv0ghlcwRy8OxJ4HO2AJ8yaS5xS1zqJ6YSrwftfZtH6hvuTwftfZtH6hvuUPsevWCZJc7fQW6+ieavldBTPNJOyGWYAkxCVzAzpPJPxZdxcupRnWvukrDpxZL/TWq401ZllubGBRy0s81OyR72gMlkjAYxxaSQ0vaerkmkucUsTXREZ2K1vB+19m0fqG+5PB+19m0fqG+5VtlOuVPi9y1BdxwV1LilojrX26Ojq2VZncZNt3mMxuidwsAezi4dnl2wC86zXqhq9PbBfqCdttqrrXUdCBeLVXthEkjozIwbRB3NryGSHaMu28o800lziljPoWb4P2vs2j9Q33L8fjlpkaWvtdE5p8zqdhH/RRW/64YPi+RSWO536OmuET445x0Er4aZ0m3A2aZrTHEXbjYPc3rHpXxkeu2D4nd7la7pezBXWxzG10bKOeUUoexsjXyuZGQxha9vluIbvuN9wQGkucUts6jfCW2+3z4y4S4/UG3BvM0BJdRyD+KY+qP+lHwnq34gNjZGN5FBklvNRHG+nmjeYp6aXbjheOsHbrGxBBHIgg+dQWKVk0bJI3tkjeA5r2ncOB6iCv3H6s2nPbfw7Niu0MlJK3+NJG0yxu/sa2Yf8AqHoU9Nc3saa9c7cfhr1/soZXYpmia6Y1ws9ERQuILQ598xMj+ran7Jy3y0OffMTI/q2p+ycgrLuLfyWtOvq3/EerrVKdxb+S1p19W/4j1daAiIgIiICIiAiIgIiICIiAiIgIiIMa5UguFuqqUnYTxOj39G4I/vVS4rI5+N20Pa5kscDYZGOGxa9g4Xg/oc0hXGq6yqwy45cam60kDprVVvMtZHEN300pABlDfPG7bytubXeVsQ5xZNTGfRNuNu2Pl/d2DoZHdi3XMVdKpu6Cttxqccxy5W+21d3+BMjt91qaSgjMtQ+CKT4wxsHN7gHb8I5nYqLOyOrxXVe5ZzNieTXSz5DY6Wmpe87TJLV0ksEs3FBLBtxxB/SNcC4Bu4O5CvWmqYayBk9PKyeGQcTJI3BzXD0gjkV6KrOrVLsTRjOdEuWtOsSyHRmrwTIr7jlzuNK2x3C31FFZqY1s1qlnru+429GzdxbwHoi5gOxYN9gvvGcUyTH73heX1mNXOOiqMwvFzltlPB0lTb6euhfHC6WNp5eVs9+2/DxnfqK6iRYxaRZiMMJ2enyUDgHwrYtYvg3FbPk1tw6rqK+e9UN9oDHRUs25cyeimPMiWQkmNrnN2cTs0jZXVlVrnvmL3i3Us/e1TWUc1PFP+be9ha13L0EgrIvFmoMhtlRbrnRwXCgqG8E1NUxiSORvXs5p5EKLW7RHT60XCmrqHCbBR1tNI2aCogt0THxPad2ua4N3BBAIIRvFM0xhCvdNLzXz6YWzTSfEMixy+QWV9onrJLeW0EErKcs6YVIPA9r3DcFhc7dw3HWVHMfpL3ktl0ewyPDrzY7hiNdR1N2rq2jMVHA2lgfG8RTfJmMrjsOAnk4l2y6aRGNFqiJlzPYsRvkGhWllC+y3CO4UWZUtVUUzqV4lgiFxlc6R7dt2tDHblx2HCd+oqPZVSX6waR6jafyYZkdwv1feKquguNvtr6imr4pqtszZTM3ccQZs0tPlDgGwK65RMWuh1YRPRgo3MsNvOQZ9q1FSW+cx3bCIbdR1L4y2GaoPfg6MSHySRxs3G/LiG/WtXfqu45toNjlBS4zf6O5Wy5WKGpoq62SxSgxVNOZXtBHlMaGuJePJ2BO+y6GRG829uva5fyO3XywYrq5gYw683m7Zbc6+otdfS0ZkopWVjGhj5aj5MRh6iH7HaNu2+63dJhV5obdrzRT2+sq5K2001LSTd7vIuD2WhsTui5fGeWC3Zu/Pl1roVFnFroo3/wB1/NHdOKaoo9PMXgq4pIKqK10rJYpmlr2PELQ4OB5gg7ggreW+ndX55jcTAT3o6or3kDkGiF0PM/SagbfoPoXnXXOCgdFG8ukqZzwwU0Q4pZnehjes/T5gOZIAJUxwvGJbM2pr68R/CtYGiQRuLmwxt34Imnz7cRJPnc4+bZWbUTRE3J3TEe/HV3IMquRbt5nTKToiKJwBaHPvmJkf1bU/ZOW+Whz75iZH9W1P2TkFZdxb+S1p19W/4j1dapTuLfyWtOvq3/EerrQEREBERAREQEREBERAREQEREBERAREQRe56b2G51MlSKaWhqZDu+W31ElOXnfclwYQHHfzkErA8VFB2vevbfwU3RTxfuR+ZJF2unVFUoR4qKDte9e2/gniooO1717b+Cm6LOnub/BtprnFKEeKig7XvXtv4J4qKDte9e2/gpuiae5v8DTXOKUI8VFB2vevbfwVQ6TUlZmGsusON3G93R1sxist8FubHUcL2tmpzI/idt5XlDl6F0qudu5+/KT7oz6ytH/ZuTT3N/gaa5xStLxUUHa969t/BPFRQdr3r238FN0TT3N/gaa5xShHiooO1717b+CeKig7XvXtv4Kbomnub/A01zilCPFRQdr3r238F9N0otv8O53mRvXwmvc3/wB27H/3U1RY09zeaa5xS01gw+z4wZHW6hZDNINpKl7nSzyD0OkeS9w/SSqTvWjWtOM3ivueC6xfCNPUVElQLFmVvbUQNLnF3A2ojHSMYN9g1rQANvQuhUUVVVVc41TjKKZmdcubhrzrLp/5OfaLVN6pGfLu2BVja0O9JbSvPSAfpcFIcP7tHSPLazvCXKGY1dmnhkt2Swvt0sbv4pMoDN/oDirwUey/TzF9QKPvXJsdtd/pwNgy40kc/D/R4geE/SFqw3VFXU1zpY6qjqIqumlHFHNA8PY8ekEcitRn3zEyP6tqfsnKlK3uIMLtVVJXYDfMn0xuDzxl2N3aRsD3fz4pC4OH80bBaPLsX7o3T/FL0yny/GNTbGKKZszbzQut1wbF0bt+B0R6NzgPO880E67i38lrTr6t/wAR6utcRdzJ3U9PpfoLhltzDAsttdkpqLhhyejt5rLdLHxuPG58flMPP5PCTyK6awDuhdNtURG3GM0tF0qJPk0gqBFUn/kv4ZP/AIoLDREQEREBERAREQEREBERAREQEREBERAREQEREBFr7zcJLdAx8bWuLnbHiB9C1HhPVfm4f2T70EnXO3c/flJ90Z9ZWj/s3K1bzqDFjtrqLldKmit9BTt45ampdwRsG+3Mk7dZA/SVBLXT2DSTO8hyZ9bUMuef3Okp3xVDTJF3zHC9sbIgxm7AWNcSXkjcdY6kF3oox4T1X5uH9k+9PCeq/Nw/sn3oJOi8aOZ1RSxSuADntBIHUvZAREQEREBERAWhz75iZH9W1P2Tlvloc++YmR/VtT9k5BWXcW/ktadfVv8AiPUgz/ua9L9UOkfkmEWiuqZPlVkUHe9Sf0zRcL//AJKP9xb+S1p19W/4j1daDnIdydf8J8vTHWDK8UY3nHbLu9l3t7R/FbFLsWg9W+5K/fDDuj9O+V7wnGtTbezrqsZr3W+s4f4zopwWud/NYujEQc+W7u3MCpKyO35tQZFpndHnhFPlVplgY9382Vocwt/nEgbK6cWzXHs4oBW47fLdfaPl8fbapk7B+ksJ2WxuNto7xRy0lfSwVtJKNpIKmMSRvHoLSCCqXyjuLtJ8hrzcqHH34heBuWXLFal9uljPpa2Mhm/6WlBeKLnXxMa2af8AlYRrC3JaNnyLVn9AKni/pVcW0p/UrdocmuooqcV8NIyu6NvfDYOIxiTbyg0k7kb77boJaijHhPVfm4f2T708J6r83D+yfegk6KMeE9V+bh/ZPvTwnqvzcP7J96CTooFjWqVJmFHU1Vomhq6emq56GV/QyM4ZoZDHI3Z2xOzmkbjkduRIW28J6r83D+yfegk6LV2W6S3EzdK1jeDbbgB8+/0/QtogIiICIiAiIgIiIKh7p6/RWfT2lpeO8iuu1zp7bQRWGrFJVTVD3EtjEx5RNIa7if1hodtz2XMsWf5xhGK6g43V3WpoKuiv9nttPca24m6S2qCuEQkeamSNhk4Q4lpe3yS8Dc7AnsrU7T616l462z3i3i40fTsnDOldE+N7Du17JGua5jgepzSCoJa+5vxSz0N6o6bF4TS3qBlPcoqiofM2sa0uLXS8bzxPBe74w+X1c+Q2Cmu6H0tpsU7nvNdslyi6sdHTTEXW8zT8LmzNBIJO4DuLct34d2tIA2Ui1LscuC3HSKK1X3IBH4Ust8zam81M/fUEsNRK5s/G89Ls6JnDx78I3A2BVhWPub8Wx20Xi10mPGShu9OKStira6Wq6aEB3DHvLI4ho4nbAEbb8llW3QKxWq12a3QWeZ1JZ7g26ULZ7jNM6GpDHRh/E+UucA17hwuJbz6upBzbLkWRDSCfWB+WXluSsvpY2xisPwcIhce9e8jS/JJMY+Vtx8R34l+5PcL/AE2C6t5vFluQR3TF8oqY7ZTMuLxSRwxyQuMTofkyNcHuGz99htw8KtbLMK0mwzVuwjILdFbMsvtaay3CpNS2hqawf6Qc+9RUb7cztIS5vncN7Aq9C7JX49kVjnsnHa8hqpK25wd9vHfEz+HjdxB/E3fgbyaQOXIILRtf73U39ALKWPQROho4Y3jZ7WAELIQEREBERAREQFVPdIau2XSrTusZXiavvN7jkttns1E3pKqvqZG8DWRsHPYFw3d5tx1ktB2OuGt9k0OxVlyuMctyu1bIKW02OjHFVXKpOwbFG0bnrI3dsdgfOSAYPodohe5Mnl1U1TkiuWo9fGWUlCw8VLj9Md9qanHMcexIe8b77kAndznhMO5nwm7ac6DYVjd9hbTXegt7Y6mBjw8RvLi7h3HIkcWx23G4OxPWrNREBERAREQFBqn/AOpl/pn/AKqcql67ENXZK2ofBfsRbA6RxjD7DUOcG78tz3+Nzt59h+hBKly9fptQdU9StQaSzVNRSxY7Vx2+ihpsoltPe29OyQTyQsppRPxueSDI7h2bwho2JN5Pw7WAvcWX7EGs35B1gqCQP09/rxv3c22LOqmnumWWKmuGQGlZTVlZb55qKOqAHNr42TeWzffZshfsOW5QVTb7DlGZ6nXLHsoyu8W+rosPtdRUxY9cpKWA17n1LZJ2cPCdt278PJruXE13C3bS6f5bkGt0+mtgu+SXSzUs2Hi/109nqjSVNyqRMINjKzZzWtAL3Bm25eN+Q2V85ZRYtpXdY8qvcYtVZeXUmPMqwZZelJe/veHgZxBvlPf5Ww6+Z6l5V3cyYjcbBj9mmxvaix9hjtboa+aKelaeTmtmbIJNjy3BcQdhvvsghvcr0Rtunl5pDUT1Zp8mvEXfFS7ill4a2QcTzsN3HbcnbrKuNQyk0cyLBLbDadOTYsdswklqJaW6Uc9c4zSPL3Oa4VcfCCSfJ5/RsOS+/A3WLb9/8P3+oKn/APvQWdi3XU/+n+9SBQbTWy5naZLgcsuFmrmyCPvYWm3S0paRxcXHx1EvF1t224dufXvynKAiIgIiICIiAiIgIiICIiCI6qaV47rLhdbjGT0Qq7fUjia9p4ZaeUfJlid/Be3fkf0gggkGl9KNVci0dzWj0i1arTVzz7sxbMpfJivMQOzYJnH5NS3cDmfK5cyS10nSyh2rOk+Oa04VWYxk1H3zQz+XHMw8M1LKN+CaJ38F7d+R8+5BBBIITFFwrmXdfZh3IdlvGnud0XhjmFHTMkxe/h4ENxpXucxkta3i42ujLHAgbmQt4eIf5U9DdyNrJU656D49klynjnvjA+hubo2tbvURHYuLWgAF7eCQgAAcfIAckFyIiICIiAq71u1usehuJtut0bLX3KrkFLarLRjiqrlUnk2KJo3PWRu7blv5yQD9a262WHQ3Efhe79JWV1TIKa2WekHFVXGpPJsUTRuTuSNztyB85IBr7RDRS/XXLHatasdHWZ/VxltttLTxU2O0x32hiHMdKQfKf18yAebi4PvQ/RK+VuUv1X1WdFX6iVsfDQ21h4qXHqY77U8I5jpNieN/PrIBO7nO6AREBERAREQEREBERAREQc7d258xcD/rzZ/tXLolfym7q/uttVGZpU6f5ZZsagkxe/wXKCeio6iM1DoXccDzxTu+Le1zXbDY7Ecwuyu4n17z/uiMQv2SZjaLNa7ZFVR0trktUM0Rnc0OM5cJJH7tHFEARtz4xz25B0eiIgIiICIiAiIgIiICIiAiIgIiICItZkd+gxu1SVszTK4ERxQMID5pHHZrG78tyfOeQG5OwBKzETVOEMxEzOEP5+90d+5yZhk2S33NLVqFBklXWyuqagZQRTTgdTWiZg6M7ANa0cMTGgAANAAWy/c862/6I3TNMPzWkfbrVUCK40lZFIyppenHkPa2WEva4vaYzyPVEV1RV0Ul+q21t7c2uqA7iip3eVT0v0RtI2JH8cjiO56hs0ZoGwUmNqnVOM/DV5Tj3OrRkMzGNcpD418T7Yj9VJ91PGvifbEfqpPuqPImfZ4Z7Y+lJyCniSHxr4n2xH6qT7q0maa8Y5imK3O7UnfOQVVLCXxWy3wPM9Q/qDG7jYczzJ6hufMvFEz7PDPbH0nIKeJWXc84BLn+Yv1Y1GuluvOfSRlttsVLUNlgxumPVGxoJ+NIPlP+k7HmSem1UtfaKS5ljqiEGWPnHPG4sliPpZI0hzT9LSCpJiGU1MddHZbrL08sgJoq1xAdOACXRvA/htA33HygCeRBTCiuMbfZPz6eyFS9klVqM6JxhNkRFEoCIiAiIgIiIIl418TO+15icAdt2xvI/Xwp418U7Yj9VJ91QfBvmlbP91/eVvVXvZXatXKreZM4TMfejo/1eaue2Jt11UaPZOG30bvxr4p2xH6qT7qeNfFO2I/VSfdWkRRcvtdXP8o+lHz3PV9/o5H/AHQLSK3a03LFcowueKsv7ZWWq4RBjmA07nExzuJA5RuLg48zs8eZq6p0suWA6Tae2HEbRdY20NqpmwB/QPBlf1ySOAb8p7y5x+lxWeicvtdXP8o+k57nq+/0bvxr4p2xH6qT7qeNfFO2I/VSfdWkROX2urn+UfSc9z1ff6N3418U7Yj9VJ91bOw5lZcnnnhtleyrlhaHyMa1zS0EkA8wPQf1KIr6wr/ODdPqun+1lVixlFvKJqpimYmIx24+ULuR+0uVXdHmYfv6LGREUruCIiAiIgIiICIiAiIgKuM6qTXZxbaJx3ioKN9ZweYySOMbHfQQ1ko/RIVY6rjOqY0Ob22ucNoq+jdR8fmEkbjIxv0ktfKf+WVPa/Nhtwn17sVrJcNNTi8FXkWtVAzMaTH7jj2RWQVtZJQUV0uVC2Ojqp2hx4GPDy4cQY4tLmtDgORKsNcpUGjmYMvOLV1fhTK7JLTkzLldcsnukMktxp+lkG0DS7iawMka7o3cAaItmhxKpu9cqqpwzV023Wy3X7JJLZZ7BkF4oYq026a+0dE11BHO13C8F5eHOa124c9rC0bHnyUcwLW++ZM3Pu/sPvLGWO4VkFNLSRU2xZE2PhhIdUbun8pzvMzb+EOpfGlVtznSqkgwk4e272WnuU7qfIobnDHH3rNUPlLpInfGdKwSOHC1pDiB5Q33WXhGP5TiWTZ7Z5sfNTZb5dKq70t8hrIRG3pYWDoXxFwkDg5hG4HDz33RHE1Thj4GO640dHgmDSSMveZZBf7cK2CmoLfDHWTxtaC+eSMSCKJo4mg+XtuQBus93dDY9NRY9LQ229XSrvk1VS09upaQd8xVFP8A5aCVj3t6N7ee/EeEcJJcBsTA8L08zTTOk04yClxv4cuVuxXwdu1ljroIp4Txxytkje93Rv2cxzXDiHIgjfZZGD6SZXac0w3ILnQwxzS3y+Xy7Q09Qx7Lf33CGxRAkgyEcLQS0Eb7nq5rLWKrmqPh5LgwHPaDUOz1FdQwVdFJS1ctDV0VfGI56aeM7PjeASNxuDuCQQQQVm5XO6gsdRcov8vbdq+MgbneLyyB/SALT9DiorpJit0xiuz+S5UvezLpk9RcaM9Ix/SwOgga1/kk7buY8bHY8urmFKsrgdX2Oe2xf5e5bUEYB2O8vkEj+iCXH6GlT5P+NR8YTY40Tnrka4PaHNO7SNwR51+r8a0MaGtGzQNgB5l+rR5cREQEREBERBTWDfNK2f7r+8rerRYN80rZ/uv7ytPPrbp1TTSQzZ9jEUsbix8b7zTBzXA7EEF/IhcPK4mcpuYcU+L5zepqqvV5sY658U1Vd5VrZbcZvVxttPYr/kL7Wxr7nPZaJs0VBxN4wJC57SXcBDuFgc4Agkcws5+uOnEb3MfqBizXtOxa69UwIPo+WqZuWlTfDrKMiptNbDq1ZMoliudtur6ukDqZxiYx0b3y78URLQ9ro+LYOPIqGiiMftNrNqMZ0sYbujxwWXcO6DskVyNFaLNfcok+Cae+NfZqVkjH0c3HwyBz5GDcdH8k7OPEOEO2dw5N015x6mt2M1FqpLpk9VkdL39b7dZqYSVD6fZpdK8Pc1sbW8TQS5w5nYblY2KYBV49q7e7lTWmG245JjdvtlG2ndGI2SRSVBdE1gO4DWyM2PCBz5dRVbad6cZ5pTDp7fafFxfaylxfwdu1njr4Ip6Vwn6Zksb3O6N43LmuAd/FI322W0U0Ski3ZnZ7unbqWf3P+cXTUHCrhdrs+Z0wvdxp4o6mBsMsMMdS9sUb2NA2c1oDTvz3HMkqy1S2k99odJcVrKLUC6WbDbvcrzcrnHQXG7U7SYpqp72ua7jHENnDny+kA8lMvHnpvtv4wcW29Pw1TffWldMzVObGpDdtzNyqaKdWPRsTdfWFf5wbp9V0/wBrKtBjWeYzmjqhuPZFab66nDTMLZXRVBi4t+Hi4HHbfY7b9exW/wAK/wA4N0+q6f7WVdD2fGFyrHhnydH2VE05VETulYyIi6b2oiIgIiICIiAiIgIiIC1mRWGDJLVLRTOMTiQ+KdgBfDI07te3fluD5jyI3B3BIWzRbUzNM4wzEzE4wqSsrZLBVtor41tDUF3DFUu8mnqvQY3E7An+I48Q2PWNnHNB3G46lZNVSw1tO+CohjngeNnxytDmuHoIPIqNSaWYm8ktsVLCD/BgBib+ppAW+FqrXOMfDX5xh3urRl2EYVwjaKQ+KjFOx4/WyfeTxUYp2PH62T7yZlninsj6knL6eFHkUh8VGKdjx+tk+8g0pxQf6njP6ZJD/wDsmZZ4p7I+o5fTwolX3ekthY2eYCaTlHBG0vllPoZG0Fzj9DQSpLiGLVL66O9XWLoZYwRRUTgC6nBBDnvI3HG4HbYfJBI5klb+yYlZcbLzarTR297+T308DWPf/ScBuf7VtkxoojC32z8ujtlUvZXVdjNiMIERFEoCIiAiIgIiIKawb5pWz/df3lbU0FMSSaeIk+fgCkfioxMb7WaJoJ32bI8D9QcnipxTshnrZPvKveyS1duVXM+YxmZ+7HT/ALPNXPY8111V6TbOOz1Rz4Ppf5ND6sL3a0MaGtAa0DYADYBbzxU4p2Qz1sn3k8VOKdkM9bJ95RcgtdZP8Y+pHzJPWd3q0iLd+KnFOyGetk+8nipxTshnrZPvJyC11k/xj6jmSes7vVH5aaGcgyRMkI6i9oK+Pg+l/k0PqwpH4qcU7IZ62T7yeKnFOyGetk+8nILXWT/GPqOZJ6zu9Wgip4oN+iiZHv18DQN17YV/nBun1XT/AGsq3PipxTshnrZPvLZ2HDbNjE801soGUkszQyR7XOcXNBJA5k+k/rVixk9vJ5qqiuZmYw2YecruSezZyW7pJrx/b1bpERSu4IiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiD/9k=", + "image/jpeg": "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", "text/plain": [ "" ] @@ -589,6 +649,8 @@ } ], "source": [ + "from IPython.display import Image, display\n", + "\n", "try:\n", " display(Image(graph.get_graph().draw_mermaid_png()))\n", "except:\n", @@ -606,41 +668,67 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 15, "id": "051dc374-67cc-4371-9dd1-221e07593148", "metadata": {}, "outputs": [ { - "name": "stdout", + "name": "stdin", "output_type": "stream", "text": [ - "User: What sets langgraph apart?\n" + "User: whats langgraph all about?\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Assistant: [{'id': 'toolu_01H54JZhgQMGzbKq54PoNQL6', 'input': {'query': 'langgraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n", - "Assistant: [{\"url\": \"https://github.com/langchain-ai/langgraph/blob/main/README.md\", \"content\": \"Define the nodes\\nWe now need to define a few different nodes in our graph.\\\\nIn langgraph, a node can be either a function or a runnable.\\\\nThere are two main nodes we need for this:\\nWe will also need to define some edges.\\\\nSome of these edges may be conditional.\\\\nThe reason they are conditional is that based on the output of a node, one of several paths may be taken.\\\\nThe path that is taken is not known until that node is run (the LLM decides).\\n LangChain.\\\\nIt extends the LangChain Expression Language with the ability to coordinate multiple chains (or actors) across multiple steps of computation in a cyclic manner.\\\\nIt is inspired by Pregel and Apache Beam.\\\\nThe current interface exposed is one inspired by NetworkX.\\nThe main use is for adding cycles to your LLM application.\\\\nCrucially, this is NOT a DAG framework.\\\\nIf you want to build a DAG, you should use just use LangChain Expression Language.\\n This is a special node representing the end of the graph.\\\\nThis means that anything passed to this node will be the final output of the graph.\\\\nIt can be used in two places:\\nWhen to Use\\nWhen should you use this versus LangChain Expression Language?\\n This method adds a node to the graph.\\\\nIt takes two arguments:\\n.add_edge\\nCreates an edge from one node to the next.\\\\nThis means that output of the first node will be passed to the next node.\\\\nIt takes two arguments.\\n Assuming you have done the above Quick Start, you can build off it like:\\nHere, we manually define the first tool call that we will make.\\\\nNotice that it does that same thing as agent would have done (adds the agent_outcome key).\\\\nThis is so that we can easily plug it in.\\n\"}, {\"url\": \"https://blog.langchain.dev/langgraph-multi-agent-workflows/\", \"content\": \"As a part of the launch, we highlighted two simple runtimes: one that is the equivalent of the AgentExecutor in langchain, and a second that was a version of that aimed at message passing and chat models.\\n It's important to note that these three examples are only a few of the possible examples we could highlight - there are almost assuredly other examples out there and we look forward to seeing what the community comes up with!\\n LangGraph: Multi-Agent Workflows\\nLinks\\nLast week we highlighted LangGraph - a new package (available in both Python and JS) to better enable creation of LLM workflows containing cycles, which are a critical component of most agent runtimes. \\\"\\nAnother key difference between Autogen and LangGraph is that LangGraph is fully integrated into the LangChain ecosystem, meaning you take fully advantage of all the LangChain integrations and LangSmith observability.\\n As part of this launch, we're also excited to highlight a few applications built on top of LangGraph that utilize the concept of multiple agents.\\n\"}]\n", - "Assistant: Based on the search results, here are the key things that set LangGraph apart:\n", + "Assistant: [{'id': 'toolu_01L1TABSBXsHPsebWiMPNqf1', 'input': {'query': 'langgraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n", + "Assistant: [{\"url\": \"https://langchain-ai.github.io/langgraph/\", \"content\": \"LangGraph is framework agnostic (each node is a regular python function). It extends the core Runnable API (shared interface for streaming, async, and batch calls) to make it easy to: Seamless state management across multiple turns of conversation or tool usage. The ability to flexibly route between nodes based on dynamic criteria.\"}, {\"url\": \"https://blog.langchain.dev/langgraph-multi-agent-workflows/\", \"content\": \"As a part of the launch, we highlighted two simple runtimes: one that is the equivalent of the AgentExecutor in langchain, and a second that was a version of that aimed at message passing and chat models.\\n It's important to note that these three examples are only a few of the possible examples we could highlight - there are almost assuredly other examples out there and we look forward to seeing what the community comes up with!\\n LangGraph: Multi-Agent Workflows\\nLinks\\nLast week we highlighted LangGraph - a new package (available in both Python and JS) to better enable creation of LLM workflows containing cycles, which are a critical component of most agent runtimes. \\\"\\nAnother key difference between Autogen and LangGraph is that LangGraph is fully integrated into the LangChain ecosystem, meaning you take fully advantage of all the LangChain integrations and LangSmith observability.\\n As part of this launch, we're also excited to highlight a few applications built on top of LangGraph that utilize the concept of multiple agents.\\n\"}]\n", + "Assistant: Based on the search results, LangGraph is a framework-agnostic Python and JavaScript library that extends the core Runnable API from the LangChain project to enable the creation of more complex workflows involving multiple agents or components. Some key things about LangGraph:\n", "\n", - "1. LangGraph extends the LangChain Expression Language by enabling the coordination of multiple \"chains\" or \"actors\" across multiple steps of computation in a cyclic manner. This allows for the creation of more complex workflows that involve cycles, rather than just directed acyclic graphs (DAGs).\n", + "- It makes it easier to manage state across multiple turns of conversation or tool usage, and to dynamically route between different nodes/components based on criteria.\n", "\n", - "2. LangGraph is inspired by frameworks like Pregel and Apache Beam, which support cyclic computations. In contrast, LangChain Expression Language is more focused on building DAG-based workflows.\n", + "- It is integrated with the LangChain ecosystem, allowing you to take advantage of LangChain integrations and observability features.\n", "\n", - "3. The main use case for LangGraph is to add cycles to LLM applications, where the path through the workflow is not known until runtime, as the LLM decides which path to take.\n", + "- It enables the creation of multi-agent workflows, where different components or agents can be chained together in more flexible and complex ways than the standard LangChain AgentExecutor.\n", "\n", - "4. LangGraph provides a custom interface inspired by NetworkX for defining nodes (functions or runnables) and edges (including conditional edges) in the workflow graph.\n", + "- The core idea is to provide a more powerful and flexible framework for building LLM-powered applications and workflows, beyond what is possible with just the core LangChain tools.\n", "\n", - "5. LangGraph is fully integrated with the LangChain ecosystem, allowing it to leverage all the integrations and observability features provided by LangChain.\n", - "\n", - "In summary, LangGraph extends the capabilities of LangChain by enabling the creation of more complex, cyclic workflows involving multiple agents or components, rather than being limited to directed acyclic graphs.\n" + "Overall, LangGraph seems to be a useful addition to the LangChain toolkit, focused on enabling more advanced, multi-agent style applications and workflows powered by large language models.\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "User: neat!\n" ] }, { "name": "stdout", "output_type": "stream", + "text": [ + "Assistant: I'm afraid I don't have enough context to provide a substantive response to \"neat!\". As an AI assistant, I'm designed to have conversations and provide information to users, but I need more details or a specific question from you in order to give a helpful reply. Could you please rephrase your request or provide some additional context? I'd be happy to assist further once I understand what you're looking for.\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "User: waht?\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Assistant: I'm afraid I don't have enough context to provide a meaningful response to \"waht?\". Could you please rephrase your request or provide more details about what you are asking? I'd be happy to try to assist you further once I have a clearer understanding of your query.\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", "text": [ "User: q\n" ] @@ -677,12 +765,12 @@ "Our chatbot still can't remember past interactions on its own, limiting its ability to have coherent, multi-turn conversations. In the next part, we'll add **memory** to address this.\n", "\n", "\n", - "The full code for the graph we've created in this section is reproduced below:" + "The full code for the graph we've created in this section is reproduced below, replacing our `BasicToolNode` for the prebuilt [ToolNode](https://langchain-ai.github.io/langgraph/reference/prebuilt/#toolnode), and our `route_tools` condition with the prebuilt [tools_condition](https://langchain-ai.github.io/langgraph/reference/prebuilt/#tools_condition)" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 17, "id": "8755d551-160e-4f8f-afac-0e4e07ca79ff", "metadata": {}, "outputs": [], @@ -696,7 +784,7 @@ "\n", "from langgraph.graph import StateGraph\n", "from langgraph.graph.message import add_messages\n", - "from langgraph.prebuilt import ToolNode\n", + "from langgraph.prebuilt import ToolNode, tools_condition\n", "\n", "\n", "class State(TypedDict):\n", @@ -750,7 +838,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 1, "id": "6baafdf6-6803-4305-9381-9dc970468a4d", "metadata": {}, "outputs": [], @@ -767,15 +855,24 @@ "source": [ "**Notice** that we've specified `:memory` as the Sqlite DB path. This is convenient for our tutorial (it saves it all in-memory). In a production application, you would likely change this to connect to your own DB and/or use one of the other checkpointer classes.\n", "\n", - "Next define the graph. The following is all copied from Part 2." + "Next define the graph. Now that you've already built your own `BasicToolNode`, we'll replace it with LangGraph's prebuilt `ToolNode` and `tools_condition`, since these do some nice things like parallel API execution. Apart from that, the following is all copied from Part 2." ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 2, "id": "e6a51f1e-00de-4701-8931-de8cf19294ae", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/wfh/code/lc/langchain/libs/core/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: The method `ChatAnthropic.bind_tools` is in beta. It is actively being worked on, so the API may change.\n", + " warn_beta(\n" + ] + } + ], "source": [ "from typing import Annotated, Union\n", "\n", @@ -786,7 +883,7 @@ "\n", "from langgraph.graph import StateGraph\n", "from langgraph.graph.message import add_messages\n", - "from langgraph.prebuilt import ToolNode\n", + "from langgraph.prebuilt import ToolNode, tools_condition\n", "\n", "\n", "class State(TypedDict):\n", @@ -831,7 +928,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 3, "id": "a06548bf-81fa-4436-b4c1-f68601fb4187", "metadata": {}, "outputs": [], @@ -849,13 +946,13 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 6, "id": "761d15fb-d5e2-4d50-a630-126d77e77294", "metadata": {}, "outputs": [ { "data": { - "image/jpeg": "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", + "image/jpeg": "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", "text/plain": [ "" ] @@ -865,6 +962,8 @@ } ], "source": [ + "from IPython.display import Image, display\n", + "\n", "try:\n", " display(Image(graph.get_graph().draw_mermaid_png()))\n", "except:\n", @@ -882,7 +981,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 5, "id": "be7b5abb-04ef-4d53-83d1-d4d3139cc43a", "metadata": {}, "outputs": [], @@ -900,19 +999,32 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 6, "id": "dba1b168-f8e0-496d-9bd6-37198fb4776e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "Hi there! My name is Will.\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "It's nice to meet you, Will! I'm an AI assistant created by Anthropic. I'm here to help you with any questions or tasks you may have. Please let me know how I can assist you today.\n" + ] + } + ], "source": [ "user_input = \"Hi there! My name is Will.\"\n", "\n", "# The config is the **second positional argument** to stream() or invoke()!\n", - "events = graph.stream({\"messages\": [(\"user\", user_input)]}, config)\n", + "events = graph.stream(\n", + " {\"messages\": [(\"user\", user_input)]}, config, stream_mode=\"values\"\n", + ")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value, BaseMessage):\n", - " print(\"Assistant:\", value.content)" + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -927,7 +1039,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 8, "id": "f5447778-53d7-47f3-801b-f47bcf2185a0", "metadata": {}, "outputs": [ @@ -935,7 +1047,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: Yes, I remember your name is Will. It's nice to meet you, Will!\n" + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "Remember my name?\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "Of course, your name is Will. It's nice to meet you again!\n" ] } ], @@ -943,11 +1060,11 @@ "user_input = \"Remember my name?\"\n", "\n", "# The config is the **second positional argument** to stream() or invoke()!\n", - "events = graph.stream({\"messages\": [(\"user\", user_input)]}, config)\n", + "events = graph.stream(\n", + " {\"messages\": [(\"user\", user_input)]}, config, stream_mode=\"values\"\n", + ")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -962,7 +1079,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 9, "id": "4527cf9a-b191-4bde-858a-e33a74a48c55", "metadata": {}, "outputs": [ @@ -970,19 +1087,24 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: I'm afraid I don't actually have any information about your name stored. As an AI assistant created by Anthropic, I don't have a persistent memory of previous conversations or personal details about users. I'm happy to try to assist you, but I don't have the capability to \"remember\" your name from previous interactions. Could you please let me know your name again so I can refer to you appropriately?\n" + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "Remember my name?\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "I'm afraid I don't actually have the capability to remember your name. As an AI assistant, I don't have a persistent memory of our previous conversations or interactions. I respond based on the current context provided to me. Could you please restate your name or provide more information so I can try to assist you?\n" ] } ], "source": [ "# The only difference is we change the `thread_id` here to \"2\" instead of \"1\"\n", "events = graph.stream(\n", - " {\"messages\": [(\"user\", user_input)]}, {\"configurable\": {\"thread_id\": \"2\"}}\n", + " {\"messages\": [(\"user\", user_input)]},\n", + " {\"configurable\": {\"thread_id\": \"2\"}},\n", + " stream_mode=\"values\",\n", ")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -997,17 +1119,17 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 10, "id": "0be77c25-1423-4f2d-9b2d-28530cc761a4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "StateSnapshot(values={'messages': [HumanMessage(content='Hi there! My name is Will.', id='4de66d5f-2bcf-451e-8913-8d0939bdf3aa'), AIMessage(content=\"It's nice to meet you, Will! I'm an AI assistant created by Anthropic to be helpful, harmless, and honest. I'm happy to chat with you about anything you'd like - feel free to ask me questions or let me know if there's anything I can assist with.\", response_metadata={'id': 'msg_01NK3eHWMzScBWg4aPhxHgBe', 'model': 'claude-3-haiku-20240307', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 375, 'output_tokens': 64}}, id='run-f6ad0a33-e5dd-4f09-8947-23e48805e483-0'), HumanMessage(content='Remember my name?', id='eb778872-1114-4974-a0c8-37c8d8d8eaa3'), AIMessage(content=\"Yes, I remember your name is Will. It's nice to meet you, Will!\", response_metadata={'id': 'msg_01Q9FjFhHs63kgEytVmZeova', 'model': 'claude-3-haiku-20240307', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 446, 'output_tokens': 21}}, id='run-7e4976a1-5a21-4b7d-ba4d-55da1c33fa72-0')]}, next=(), config={'configurable': {'thread_id': '1', 'thread_ts': '2024-04-18T07:28:57.722029+00:00'}}, parent_config=None)" + "StateSnapshot(values={'messages': [HumanMessage(content='Hi there! My name is Will.', id='aad97d7f-8845-4f9e-b723-2af3b7c97590'), AIMessage(content=\"It's nice to meet you, Will! I'm an AI assistant created by Anthropic. I'm here to help you with any questions or tasks you may have. Please let me know how I can assist you today.\", response_metadata={'id': 'msg_01VCz7Y5jVmMZXibBtnECyvJ', 'model': 'claude-3-haiku-20240307', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 375, 'output_tokens': 49}}, id='run-66cf1695-5ba8-4fd8-a79d-ded9ee3c3b33-0'), HumanMessage(content='Remember my name?', id='ac1e9971-dbee-4622-9e63-5015dee05c20'), AIMessage(content=\"Of course, your name is Will. It's nice to meet you again!\", response_metadata={'id': 'msg_01RsJ6GaQth7r9soxbF7TSpQ', 'model': 'claude-3-haiku-20240307', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 431, 'output_tokens': 19}}, id='run-890149d3-214f-44e8-9717-57ec4ef68224-0')]}, next=(), config={'configurable': {'thread_id': '1', 'thread_ts': '2024-05-06T22:23:20.430350+00:00'}}, parent_config=None)" ] }, - "execution_count": 28, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -1019,7 +1141,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 11, "id": "c106bd09-f155-4e15-9120-c60c834106e5", "metadata": {}, "outputs": [ @@ -1029,7 +1151,7 @@ "()" ] }, - "execution_count": 29, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -1054,7 +1176,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 12, "id": "9c50a794-3ae5-484c-8edd-50e0d54da982", "metadata": {}, "outputs": [], @@ -1120,10 +1242,19 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 1, "id": "5a81608a-373a-4339-b1c6-65b73a92b983", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/wfh/code/lc/langchain/libs/core/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: The method `ChatAnthropic.bind_tools` is in beta. It is actively being worked on, so the API may change.\n", + " warn_beta(\n" + ] + } + ], "source": [ "from typing import Annotated, Union\n", "\n", @@ -1135,7 +1266,7 @@ "from langgraph.checkpoint.sqlite import SqliteSaver\n", "from langgraph.graph import MessageGraph, StateGraph\n", "from langgraph.graph.message import add_messages\n", - "from langgraph.prebuilt import ToolNode\n", + "from langgraph.prebuilt import ToolNode, tools_condition\n", "\n", "memory = SqliteSaver.from_conn_string(\":memory:\")\n", "\n", @@ -1181,7 +1312,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 2, "id": "b0883e32-1a39-4ce9-ae32-bbd66708fd84", "metadata": {}, "outputs": [], @@ -1197,7 +1328,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 3, "id": "9f318020-ab7e-415b-a5e2-eddec6d9f3a6", "metadata": {}, "outputs": [ @@ -1205,7 +1336,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: [{'text': \"Okay, let's look into LangGraph for you. Here is a summary of the key information I was able to find:\", 'type': 'text'}, {'id': 'toolu_01XayS5zo1ZHaQMYpWX5x8fQ', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n" + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "I'm learning LangGraph. Could you do some research on it for me?\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "[{'text': \"Okay, let's do some research on LangGraph:\", 'type': 'text'}, {'id': 'toolu_01Be7aRgMEv9cg6ezaFjiCry', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n", + "Tool Calls:\n", + " tavily_search_results_json (toolu_01Be7aRgMEv9cg6ezaFjiCry)\n", + " Call ID: toolu_01Be7aRgMEv9cg6ezaFjiCry\n", + " Args:\n", + " query: LangGraph\n" ] } ], @@ -1213,11 +1354,12 @@ "user_input = \"I'm learning LangGraph. Could you do some research on it for me?\"\n", "config = {\"configurable\": {\"thread_id\": \"1\"}}\n", "# The config is the **second positional argument** to stream() or invoke()!\n", - "events = graph.stream({\"messages\": [(\"user\", user_input)]}, config)\n", + "events = graph.stream(\n", + " {\"messages\": [(\"user\", user_input)]}, config, stream_mode=\"values\"\n", + ")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -1230,7 +1372,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 4, "id": "9bb7af46-9b4f-4bb1-b8b9-e9ddf7dbc82c", "metadata": {}, "outputs": [ @@ -1240,7 +1382,7 @@ "('action',)" ] }, - "execution_count": 34, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -1260,7 +1402,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 5, "id": "3facda0a-e6ad-4b28-b627-753ad8c90c15", "metadata": {}, "outputs": [ @@ -1269,10 +1411,10 @@ "text/plain": [ "[{'name': 'tavily_search_results_json',\n", " 'args': {'query': 'LangGraph'},\n", - " 'id': 'toolu_01XayS5zo1ZHaQMYpWX5x8fQ'}]" + " 'id': 'toolu_01Be7aRgMEv9cg6ezaFjiCry'}]" ] }, - "execution_count": 35, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -1294,7 +1436,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 6, "id": "effb95d9-b7d5-40c5-9253-253d193b23b2", "metadata": {}, "outputs": [ @@ -1302,28 +1444,30 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: [{\"url\": \"https://blog.langchain.dev/langgraph/\", \"content\": \"Some of the things we are looking to implement in the near future:\\nIf any of these resonate with you, please feel free to add an example notebook in the LangGraph repo, or reach out to us at hello@langchain.dev for more involved collaboration!\\n See this notebook for how to get started\\nModifications\\nOne of the big benefits of LangGraph is that it exposes the logic of AgentExecutor in a far more natural and modifiable way. An example of this could be that after a model is called we either exit the graph and return to the user, or we call a tool - depending on what a user decides! This function/LCEL should accept a dictionary in the same form as the State object as input, and output a dictionary with keys of the State object to update.\\n In this case, it's often ideal if the LLM can reason that the results returned from the retriever are poor, and maybe issue a second (more refined) query to the retriever, and use those results instead.\"}, {\"url\": \"https://blog.langchain.dev/langgraph-multi-agent-workflows/\", \"content\": \"As a part of the launch, we highlighted two simple runtimes: one that is the equivalent of the AgentExecutor in langchain, and a second that was a version of that aimed at message passing and chat models.\\n It's important to note that these three examples are only a few of the possible examples we could highlight - there are almost assuredly other examples out there and we look forward to seeing what the community comes up with!\\n LangGraph: Multi-Agent Workflows\\nLinks\\nLast week we highlighted LangGraph - a new package (available in both Python and JS) to better enable creation of LLM workflows containing cycles, which are a critical component of most agent runtimes. \\\"\\nAnother key difference between Autogen and LangGraph is that LangGraph is fully integrated into the LangChain ecosystem, meaning you take fully advantage of all the LangChain integrations and LangSmith observability.\\n As part of this launch, we're also excited to highlight a few applications built on top of LangGraph that utilize the concept of multiple agents.\\n\"}]\n", - "Assistant: Based on the search results, LangGraph seems to be a new package developed as part of the LangChain ecosystem. It is designed to enable the creation of more advanced LLM workflows that can contain cycles, which is an important feature for agent-based models.\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", "\n", - "Some key points about LangGraph:\n", + "[{\"url\": \"https://github.com/langchain-ai/langgraph\", \"content\": \"LangGraph is a Python package that extends LangChain Expression Language with the ability to coordinate multiple chains across multiple steps of computation in a cyclic manner. It is inspired by Pregel and Apache Beam and can be used for agent-like behaviors, such as chatbots, with LLMs.\"}, {\"url\": \"https://python.langchain.com/docs/langgraph/\", \"content\": \"LangGraph is a library for building stateful, multi-actor applications with LLMs, built on top of (and intended to be used with) LangChain . It extends the LangChain Expression Language with the ability to coordinate multiple chains (or actors) across multiple steps of computation in a cyclic manner. It is inspired by Pregel and Apache Beam .\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "- It exposes the logic of the AgentExecutor in LangChain in a more modifiable way, allowing for customization of behavior after a model is called.\n", - "- It supports multi-agent workflows, enabling the creation of applications with multiple interacting agents.\n", - "- It is integrated with the broader LangChain ecosystem, allowing it to take advantage of existing LangChain integrations and observability tools.\n", + "Based on the search results, LangGraph seems to be a Python library that extends the LangChain library to enable more complex, multi-step interactions with large language models (LLMs). Some key points:\n", "\n", - "The search results indicate that LangGraph is a relatively new development, and the blog post mentions there are plans to implement additional features in the near future. Overall, it seems like an interesting tool for building more sophisticated LLM-powered applications, especially those involving agent-based models or multi-agent interactions.\n", + "- LangGraph allows coordinating multiple \"chains\" (or actors) over multiple steps of computation, in a cyclic manner. This enables more advanced agent-like behaviors like chatbots.\n", + "- It is inspired by distributed graph processing frameworks like Pregel and Apache Beam.\n", + "- LangGraph is built on top of the LangChain library, which provides a framework for building applications with LLMs.\n", "\n", - "Let me know if you have any other questions! I'm happy to provide more details on LangGraph or do additional research if needed.\n" + "So in summary, LangGraph appears to be a powerful tool for building more sophisticated applications and agents using large language models, by allowing you to coordinate multiple steps and actors in a flexible, graph-like manner. It extends the capabilities of the base LangChain library.\n", + "\n", + "Let me know if you need any clarification or have additional questions!\n" ] } ], "source": [ "# `None` will append nothing new to the current state, letting it resume as if it had never been interrupted\n", - "events = graph.stream(None, config)\n", + "events = graph.stream(None, config, stream_mode=\"values\")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -1342,7 +1486,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 7, "id": "a7228caf-a5aa-4f68-b775-81ea5402aca8", "metadata": {}, "outputs": [], @@ -1416,15 +1560,16 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 2, "id": "faa345c6-38a2-42e8-9035-9cf56f7bb5b1", "metadata": {}, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "Assistant: [{'text': \"Okay, let's look up some information on LangGraph:\", 'type': 'text'}, {'id': 'toolu_016HGEqpk5m2wiAD98c3Gwcx', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n" + "/Users/wfh/code/lc/langchain/libs/core/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: The method `ChatAnthropic.bind_tools` is in beta. It is actively being worked on, so the API may change.\n", + " warn_beta(\n" ] } ], @@ -1439,7 +1584,7 @@ "from langgraph.checkpoint.sqlite import SqliteSaver\n", "from langgraph.graph import MessageGraph, StateGraph\n", "from langgraph.graph.message import add_messages\n", - "from langgraph.prebuilt import ToolNode\n", + "from langgraph.prebuilt import ToolNode, tools_condition\n", "\n", "\n", "class State(TypedDict):\n", @@ -1476,7 +1621,7 @@ " checkpointer=memory,\n", " # This is new!\n", " interrupt_before=[\"action\"],\n", - " # Note: can also interrupt __after__ actions, if desired.\n", + " # Note: can also interrupt **after** actions, if desired.\n", " # interrupt_after=[\"action\"]\n", ")\n", "\n", @@ -1485,14 +1630,13 @@ "# The config is the **second positional argument** to stream() or invoke()!\n", "events = graph.stream({\"messages\": [(\"user\", user_input)]}, config)\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 3, "id": "a6b3bcae-dd04-49da-a4ef-e05634657faf", "metadata": {}, "outputs": [ @@ -1502,7 +1646,12 @@ "text": [ "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "[{'text': \"Okay, let's look up some information on LangGraph:\", 'type': 'text'}, {'id': 'toolu_016HGEqpk5m2wiAD98c3Gwcx', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n" + "[{'id': 'toolu_01DTyDpJ1kKdNps5yxv3AGJd', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n", + "Tool Calls:\n", + " tavily_search_results_json (toolu_01DTyDpJ1kKdNps5yxv3AGJd)\n", + " Call ID: toolu_01DTyDpJ1kKdNps5yxv3AGJd\n", + " Args:\n", + " query: LangGraph\n" ] } ], @@ -1526,7 +1675,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 4, "id": "6a44bedc-ea91-4c22-976c-98b3d5a5e4a7", "metadata": {}, "outputs": [ @@ -1540,24 +1689,30 @@ "\n", "\n", "Last 2 messages;\n", - "[AIMessage(content=[{'text': \"Okay, let's look up some information on LangGraph:\", 'type': 'text'}, {'id': 'toolu_016HGEqpk5m2wiAD98c3Gwcx', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], response_metadata={'id': 'msg_01WgZjuqwL2gR1JnwJ2Ugxg8', 'model': 'claude-3-haiku-20240307', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 384, 'output_tokens': 75}}, id='run-ba7aa4d5-6269-4682-888e-5f505fc7ec23-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': 'LangGraph'}, 'id': 'toolu_016HGEqpk5m2wiAD98c3Gwcx'}]), AIMessage(content='LangGraph is a library for building stateful, multi-actor applications with LLMs.', id='e58607fd-43c4-416e-99dc-4c4575eddcdf')]\n" + "[ToolMessage(content='LangGraph is a library for building stateful, multi-actor applications with LLMs.', id='14589ef1-15db-4a75-82a6-d57c40a216d0', tool_call_id='toolu_01DTyDpJ1kKdNps5yxv3AGJd'), AIMessage(content='LangGraph is a library for building stateful, multi-actor applications with LLMs.', id='1c657bfb-7690-44c7-a26d-d0d22453013d')]\n" ] } ], "source": [ "from langchain_core.messages import AIMessage, ToolMessage\n", "\n", - "new_message = AIMessage(\n", - " content=\"LangGraph is a library for building stateful, multi-actor applications with LLMs.\"\n", + "answer = (\n", + " \"LangGraph is a library for building stateful, multi-actor applications with LLMs.\"\n", ")\n", + "new_messages = [\n", + " # The LLM API expects some ToolMessage to match its tool call. We'll satisfy that here.\n", + " ToolMessage(content=answer, tool_call_id=existing_message.tool_calls[0][\"id\"]),\n", + " # And then directly \"put words in the LLM's mouth\" by populating its response.\n", + " AIMessage(content=answer),\n", + "]\n", "\n", - "new_message.pretty_print()\n", + "new_messages[-1].pretty_print()\n", "graph.update_state(\n", " # Which state to update\n", " config,\n", " # The updated values to provide. The messages in our `State` are \"append-only\", meaning this will be appended\n", " # to the existing state. We will review how to update existing messages in the next section!\n", - " {\"messages\": [new_message]},\n", + " {\"messages\": new_messages},\n", ")\n", "\n", "print(\"\\n\\nLast 2 messages;\")\n", @@ -1585,7 +1740,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 5, "id": "d16d95c3-b465-42ac-8015-26b669d45d1f", "metadata": {}, "outputs": [ @@ -1593,10 +1748,10 @@ "data": { "text/plain": [ "{'configurable': {'thread_id': '1',\n", - " 'thread_ts': '2024-04-18T07:45:58.218035+00:00'}}" + " 'thread_ts': '2024-05-06T22:27:57.350721+00:00'}}" ] }, - "execution_count": 42, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -1621,13 +1776,13 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 6, "id": "f4009ba6-dc0b-4216-ab0c-fbb104616f73", "metadata": {}, "outputs": [ { "data": { - "image/jpeg": "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", + "image/jpeg": "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", "text/plain": [ "" ] @@ -1637,6 +1792,8 @@ } ], "source": [ + "from IPython.display import Image, display\n", + "\n", "try:\n", " display(Image(graph.get_graph().draw_mermaid_png()))\n", "except:\n", @@ -1654,7 +1811,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 7, "id": "d420e813-a8c7-415d-ab31-5298d42491e4", "metadata": {}, "outputs": [ @@ -1662,7 +1819,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "[AIMessage(content=[{'text': \"Okay, let's look up some information on LangGraph:\", 'type': 'text'}, {'id': 'toolu_016HGEqpk5m2wiAD98c3Gwcx', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], response_metadata={'id': 'msg_01WgZjuqwL2gR1JnwJ2Ugxg8', 'model': 'claude-3-haiku-20240307', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 384, 'output_tokens': 75}}, id='run-ba7aa4d5-6269-4682-888e-5f505fc7ec23-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': 'LangGraph'}, 'id': 'toolu_016HGEqpk5m2wiAD98c3Gwcx'}]), AIMessage(content='LangGraph is a library for building stateful, multi-actor applications with LLMs.', id='e58607fd-43c4-416e-99dc-4c4575eddcdf'), AIMessage(content=\"I'm an AI expert!\", id='82bbd2aa-b3c7-48cf-abeb-33f7938e98ae')]\n", + "[ToolMessage(content='LangGraph is a library for building stateful, multi-actor applications with LLMs.', id='14589ef1-15db-4a75-82a6-d57c40a216d0', tool_call_id='toolu_01DTyDpJ1kKdNps5yxv3AGJd'), AIMessage(content='LangGraph is a library for building stateful, multi-actor applications with LLMs.', id='1c657bfb-7690-44c7-a26d-d0d22453013d'), AIMessage(content=\"I'm an AI expert!\", id='acd668e3-ba31-42c0-843c-00d0994d5885')]\n", "()\n" ] } @@ -1682,14 +1839,14 @@ "\n", "#### What if you want to **overwrite** existing messages? \n", "\n", - "The `add_messages` function we used to annotate our graph's `State` above controls how updates are made to the `messages` key. This function looks at any message IDs in the new `messages` list. If the ID matches a message in the existing state, `add_messages` overwrites the existing message with the new content. \n", + "The [`add_messages`](https://langchain-ai.github.io/langgraph/reference/graphs/?h=add+messages#add_messages) function we used to annotate our graph's `State` above controls how updates are made to the `messages` key. This function looks at any message IDs in the new `messages` list. If the ID matches a message in the existing state, [`add_messages`](https://langchain-ai.github.io/langgraph/reference/graphs/?h=add+messages#add_messages) overwrites the existing message with the new content. \n", "\n", "As an example, let's update the tool invocation to make sure we get good results from our search engine! First, start a new thread:" ] }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 8, "id": "9fc99c7e-b61d-4aec-9c62-042798185ec3", "metadata": {}, "outputs": [ @@ -1697,18 +1854,29 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: [{'id': 'toolu_01YQjNFesoHt4yFzg53xSLgb', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n" + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "I'm learning LangGraph. Could you do some research on it for me?\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "[{'id': 'toolu_013MvjoDHnv476ZGzyPFZhrR', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n", + "Tool Calls:\n", + " tavily_search_results_json (toolu_013MvjoDHnv476ZGzyPFZhrR)\n", + " Call ID: toolu_013MvjoDHnv476ZGzyPFZhrR\n", + " Args:\n", + " query: LangGraph\n" ] } ], "source": [ "user_input = \"I'm learning LangGraph. Could you do some research on it for me?\"\n", "config = {\"configurable\": {\"thread_id\": \"2\"}} # we'll use thread_id = 2 here\n", - "events = graph.stream({\"messages\": [(\"user\", user_input)]}, config)\n", + "events = graph.stream(\n", + " {\"messages\": [(\"user\", user_input)]}, config, stream_mode=\"values\"\n", + ")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -1721,7 +1889,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 9, "id": "7215533a-b7e2-4b2d-bc1d-5122b1d06b8b", "metadata": {}, "outputs": [ @@ -1730,10 +1898,11 @@ "output_type": "stream", "text": [ "Original\n", - "{'name': 'tavily_search_results_json', 'args': {'query': 'LangGraph'}, 'id': 'toolu_01YQjNFesoHt4yFzg53xSLgb'}\n", + "Message ID run-59283969-1076-45fe-bee8-ebfccab163c3-0\n", + "{'name': 'tavily_search_results_json', 'args': {'query': 'LangGraph'}, 'id': 'toolu_013MvjoDHnv476ZGzyPFZhrR'}\n", "Updated\n", - "{'name': 'tavily_search_results_json', 'args': {'query': 'LangGraph human-in-the-loop workflow'}, 'id': 'toolu_01YQjNFesoHt4yFzg53xSLgb'}\n", - "Message ID run-4507ef72-6c8e-4fc3-9521-6e9e856c62a8-0\n", + "{'name': 'tavily_search_results_json', 'args': {'query': 'LangGraph human-in-the-loop workflow'}, 'id': 'toolu_013MvjoDHnv476ZGzyPFZhrR'}\n", + "Message ID run-59283969-1076-45fe-bee8-ebfccab163c3-0\n", "\n", "\n", "Tool calls\n" @@ -1744,10 +1913,10 @@ "text/plain": [ "[{'name': 'tavily_search_results_json',\n", " 'args': {'query': 'LangGraph human-in-the-loop workflow'},\n", - " 'id': 'toolu_01YQjNFesoHt4yFzg53xSLgb'}]" + " 'id': 'toolu_013MvjoDHnv476ZGzyPFZhrR'}]" ] }, - "execution_count": 46, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -1758,6 +1927,7 @@ "snapshot = graph.get_state(config)\n", "existing_message = snapshot.values[\"messages\"][-1]\n", "print(\"Original\")\n", + "print(\"Message ID\", existing_message.id)\n", "print(existing_message.tool_calls[0])\n", "new_tool_call = existing_message.tool_calls[0].copy()\n", "new_tool_call[\"args\"][\"query\"] = \"LangGraph human-in-the-loop workflow\"\n", @@ -1791,7 +1961,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 10, "id": "03a09bfc-3d90-4e54-878f-22e3cb28a418", "metadata": {}, "outputs": [ @@ -1799,25 +1969,27 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: [{\"url\": \"https://langchain-ai.github.io/langgraph/how-tos/human-in-the-loop/\", \"content\": \"Human-in-the-loop\\u00b6 When creating LangGraph agents, it is often nice to add a human in the loop component. This can be helpful when giving them access to tools. ... from langgraph.graph import MessageGraph, END # Define a new graph workflow = MessageGraph # Define the two nodes we will cycle between workflow. add_node (\\\"agent\\\", call_model) ...\"}, {\"url\": \"https://langchain-ai.github.io/langgraph/how-tos/agent_executor/human-in-the-loop/\", \"content\": \"Human in the Loop\\u00b6 In this notebook we will go over how to add a human-in-the-loop workflow to the base agent executor. We will use the human to approve ... In langgraph, a node can be either a function or a runnable. There are two main nodes we need for this: The agent: responsible for deciding what (if any) actions to take. ...\"}]\n", - "Assistant: Based on the search results, LangGraph appears to be a framework for building AI agents that can interact with humans in a loop. Some key points:\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", "\n", - "- LangGraph allows you to define \"nodes\" that represent different components of an AI agent, such as a language model, a tool executor, or a human-in-the-loop component.\n", - "- The human-in-the-loop feature lets you incorporate human feedback and approval into the agent's decision-making process. This can be helpful for sensitive applications where you want a human to review the agent's proposed actions.\n", - "- LangGraph provides examples of how to set up a workflow with an agent node and a human-in-the-loop node, allowing the agent to cycle between making decisions and getting human approval.\n", + "[{\"url\": \"https://langchain-ai.github.io/langgraph/how-tos/human-in-the-loop/\", \"content\": \"Human-in-the-loop\\u00b6 When creating LangGraph agents, it is often nice to add a human in the loop component. This can be helpful when giving them access to tools. ... from langgraph.graph import MessageGraph, END # Define a new graph workflow = MessageGraph # Define the two nodes we will cycle between workflow. add_node (\\\"agent\\\", call_model) ...\"}, {\"url\": \"https://langchain-ai.github.io/langgraph/how-tos/chat_agent_executor_with_function_calling/human-in-the-loop/\", \"content\": \"Human-in-the-loop. In this example we will build a chat executor that has a human in the loop. We will use the human to approve specific actions. This examples builds off the base chat executor. It is highly recommended you learn about that executor before going through this notebook. You can find documentation for that example here.\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "Overall, LangGraph seems to be a flexible framework for building AI agents that can interact with humans in a controlled and transparent way. It could be useful for applications where you want to leverage large language models while maintaining human oversight and control.\n", + "Based on the search results, LangGraph appears to be a framework for building AI agents that can interact with humans in a conversational way. The key points I gathered are:\n", "\n", - "Let me know if you have any other questions! I'm happy to dig deeper into the LangGraph framework.\n" + "- LangGraph allows for \"human-in-the-loop\" workflows, where a human can be involved in approving or reviewing actions taken by the AI agent.\n", + "- This can be useful for giving the AI agent access to various tools and capabilities, with the human able to provide oversight and guidance.\n", + "- The framework includes components like \"MessageGraph\" for defining the conversational flow between the agent and human.\n", + "\n", + "Overall, LangGraph seems to be a way to create conversational AI agents that can leverage human input and guidance, rather than operating in a fully autonomous way. Let me know if you need any clarification or have additional questions!\n" ] } ], "source": [ - "events = graph.stream(None, config)\n", + "events = graph.stream(None, config, stream_mode=\"values\")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -1825,25 +1997,48 @@ "id": "090b680b-f53f-4af2-a432-45f8c5a10779", "metadata": {}, "source": [ - "Check out the [trace](https://smith.langchain.com/public/2d633326-14ad-4248-a391-2757d01851c4/r/6464f2f2-edb4-4ef3-8f48-ee4e249f2ad0) to see the toolc all and later LLM response. **Notice** that now the graph queries the search engine using our updated query term - we were able to manually override the LLM's search here!\n", + "Check out the [trace](https://smith.langchain.com/public/2d633326-14ad-4248-a391-2757d01851c4/r/6464f2f2-edb4-4ef3-8f48-ee4e249f2ad0) to see the tool call and later LLM response. **Notice** that now the graph queries the search engine using our updated query term - we were able to manually override the LLM's search here!\n", "\n", "All of this is reflected in the graph's checkpointed memory, meaning if we continue the conversation, it will recall all the _modified_ state." ] }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 15, "id": "11d5b934-6d8b-4f52-a3bc-b3daa7207e00", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "Remember what I'm learning about?\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "Ah yes, now I remember - you mentioned earlier that you are learning about LangGraph.\n", + "\n", + "LangGraph is the framework I researched in my previous response, which is for building conversational AI agents that can incorporate human input and oversight.\n", + "\n", + "So based on our earlier discussion, it seems you are currently learning about and exploring the LangGraph system for creating human-in-the-loop AI agents. Please let me know if I have the right understanding now.\n" + ] + } + ], "source": [ "events = graph.stream(\n", - " {\"messages\": (\"user\", \"Guess what I'm learning about these days?\")}, config\n", + " {\n", + " \"messages\": (\n", + " \"user\",\n", + " \"Remember what I'm learning about?\",\n", + " )\n", + " },\n", + " config,\n", + " stream_mode=\"values\",\n", ")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value, BaseMessage):\n", - " print(\"Assistant:\", value.content)" + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -1874,7 +2069,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 1, "id": "3cf7e042-1718-4625-ae30-a9917f595449", "metadata": {}, "outputs": [], @@ -1889,7 +2084,7 @@ "from langgraph.checkpoint.sqlite import SqliteSaver\n", "from langgraph.graph import MessageGraph, StateGraph\n", "from langgraph.graph.message import add_messages\n", - "from langgraph.prebuilt import ToolNode\n", + "from langgraph.prebuilt import ToolNode, tools_condition\n", "\n", "\n", "class State(TypedDict):\n", @@ -1908,7 +2103,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 2, "id": "e5192e54-6a28-42fe-a8a7-62d45d61f994", "metadata": {}, "outputs": [], @@ -1935,10 +2130,19 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 3, "id": "fa59b266-14e5-4c75-8b3d-54fac28e8290", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/wfh/code/lc/langchain/libs/core/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: The method `ChatAnthropic.bind_tools` is in beta. It is actively being worked on, so the API may change.\n", + " warn_beta(\n" + ] + } + ], "source": [ "tool = TavilySearchResults(max_results=2)\n", "tools = [tool]\n", @@ -1968,7 +2172,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 4, "id": "3f4464d2-288b-4689-aaf0-329a55dcb85c", "metadata": {}, "outputs": [], @@ -1989,11 +2193,14 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 5, "id": "1d70b5a4-ce50-47dc-aa43-ffb5c48c46fc", "metadata": {}, "outputs": [], "source": [ + "from langchain_core.messages import AIMessage, ToolMessage\n", + "\n", + "\n", "def create_response(response: str, ai_message: AIMessage):\n", " return ToolMessage(\n", " content=response,\n", @@ -2033,7 +2240,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 6, "id": "586a0d07-8303-47f4-b3cf-3bdd043e762b", "metadata": {}, "outputs": [], @@ -2062,7 +2269,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 7, "id": "84101737-0048-4635-9f68-45b0c508b6b6", "metadata": {}, "outputs": [], @@ -2089,13 +2296,13 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 8, "id": "b3220ae2-cba0-4447-96d1-eb0be4684e59", "metadata": {}, "outputs": [ { "data": { - "image/jpeg": "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mLXSSkVBHVMA4SGhzuJr9g4cJNxqp8ptOR47rhTZhbrF38stXYmWesdHWw076IsqXS9c4SuaHM4ZHfJJPk9nNSDx6abf/cHFf/3VN9dU3rpZTSO7uWVto5xaU4XxXv8A0LX/AIvJ/ZKirtctOGOLXagYs1wOxBvVNuD+2pTeXB9krnNIc008hBHYfJKxh1tXErnHfC3Sid0p9h32o2T8Rg/dtXYXHw77UbJ+Iwfu2rsL3uL6dvfLx87xERVsCIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICg2qv8njH5Xb/DzqcrjZRitJllJT09XJUQinnFRFJTSdW9rw1zd9/mc5SjKc4nviY8YmFuFaKXi09yGyRMmbwyMa9vocNwvV3vpf8AdofdhdrxU0Pri9/Tf7k8VND64vf03+5ef7In1seEu11/C4S48dJBE8OZDGxw7C1gBXuXS8VND64vf03+5PFTQ+uL39N/uTsf+7HhJ2hhcJc1FWnSvpa3SHQu+5Tjt7ukd2o5qNkTqio6xgElVFG7dpHPyXuVu+Kmh9cXv6b/AHJ2P/djwlntDC4S5hG42PYvR3BS/wC7Q/sBdrxU0Pri9/Tf7k8VND64vf03+5OyP7seEsdoYXCXF7gpf92h/YC9V75WWv8AxeT+yV3/ABU0Pri9/Tf7l4y6SW6eJ8cl2vTmPBa5pre0HtHYp0/pOjaLTixs9knX8LhKQYd9qNk/EYP3bV2F89BRRW2hpqSEEQ08bYmAnc8LQAP+QX0LvXnStMw4M7xERQYEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQZ36f/APNXyr8Zt38dAtELO/T/AP5q+VfjNu/joFohAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQZ36f8A/NXyr8Zt38dAtELJnTx1Zwe59HzL8co8yx+ryGKto4ZLTBdIH1bHx10PWNMQfxgs4XcQ23HCd9tlonFdVsJzuvfRY1mNgyGtZG6Z9NarpBUyNjBaC8tjcSGgvYCezdw9IQSpERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEXxXi9UVgoX1lfUNp6dpA4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", + "image/jpeg": "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", "text/plain": [ "" ] @@ -2105,6 +2312,8 @@ } ], "source": [ + "from IPython.display import Image, display\n", + "\n", "try:\n", " display(Image(graph.get_graph().draw_mermaid_png()))\n", "except:\n", @@ -2124,7 +2333,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 9, "id": "c1955d79-a1e4-47d0-ba79-b45bd5752a23", "metadata": {}, "outputs": [ @@ -2132,7 +2341,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: [{'id': 'toolu_01Myt1z6DUfyeiWh8UZBcrog', 'input': {'request': 'I need some expert guidance for building this AI agent.'}, 'name': 'RequestAssistance', 'type': 'tool_use'}]\n" + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "I need some expert guidance for building this AI agent. Could you request assistance for me?\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "[{'id': 'toolu_017XaQuVsoAyfXeTfDyv55Pc', 'input': {'request': 'I need some expert guidance for building this AI agent.'}, 'name': 'RequestAssistance', 'type': 'tool_use'}]\n", + "Tool Calls:\n", + " RequestAssistance (toolu_017XaQuVsoAyfXeTfDyv55Pc)\n", + " Call ID: toolu_017XaQuVsoAyfXeTfDyv55Pc\n", + " Args:\n", + " request: I need some expert guidance for building this AI agent.\n" ] } ], @@ -2140,11 +2359,12 @@ "user_input = \"I need some expert guidance for building this AI agent. Could you request assistance for me?\"\n", "config = {\"configurable\": {\"thread_id\": \"1\"}}\n", "# The config is the **second positional argument** to stream() or invoke()!\n", - "events = graph.stream({\"messages\": [(\"user\", user_input)]}, config)\n", + "events = graph.stream(\n", + " {\"messages\": [(\"user\", user_input)]}, config, stream_mode=\"values\"\n", + ")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -2157,7 +2377,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 10, "id": "5320ba05-5696-4194-8278-5385c571264d", "metadata": {}, "outputs": [ @@ -2167,7 +2387,7 @@ "('human',)" ] }, - "execution_count": 58, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -2191,7 +2411,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 11, "id": "2cbac924-61ce-4282-9b1c-77f9090ea1f5", "metadata": {}, "outputs": [ @@ -2199,10 +2419,10 @@ "data": { "text/plain": [ "{'configurable': {'thread_id': '1',\n", - " 'thread_ts': '2024-04-18T08:01:43.135440+00:00'}}" + " 'thread_ts': '2024-05-06T22:31:39.973392+00:00'}}" ] }, - "execution_count": 59, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -2227,19 +2447,19 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 12, "id": "4b986c66-1c65-4da8-a404-db7e28f8364e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[HumanMessage(content='I need some expert guidance for building this AI agent. Could you request assistance for me?', id='750761ad-0167-4ea7-ab0f-b0dfd31d0483'),\n", - " AIMessage(content=[{'id': 'toolu_01Myt1z6DUfyeiWh8UZBcrog', 'input': {'request': 'I need some expert guidance for building this AI agent.'}, 'name': 'RequestAssistance', 'type': 'tool_use'}], response_metadata={'id': 'msg_013Vcz6mu7NRgERryEva379N', 'model': 'claude-3-haiku-20240307', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 486, 'output_tokens': 63}}, id='run-701f97ee-585e-4663-bde3-3de75c0dbc9a-0', tool_calls=[{'name': 'RequestAssistance', 'args': {'request': 'I need some expert guidance for building this AI agent.'}, 'id': 'toolu_01Myt1z6DUfyeiWh8UZBcrog'}]),\n", - " ToolMessage(content=\"We, the experts are here to help! We'd recommend you check out LangGraph to build your agent. It's much more reliable and extensible than simple autonomous agents.\", id='ed36c843-12b2-4842-894a-85a87b8e7171', tool_call_id='toolu_01Myt1z6DUfyeiWh8UZBcrog')]" + "[HumanMessage(content='I need some expert guidance for building this AI agent. Could you request assistance for me?', id='ab75eb9d-cce7-4e44-8de7-b0b375a86972'),\n", + " AIMessage(content=[{'id': 'toolu_017XaQuVsoAyfXeTfDyv55Pc', 'input': {'request': 'I need some expert guidance for building this AI agent.'}, 'name': 'RequestAssistance', 'type': 'tool_use'}], response_metadata={'id': 'msg_0199PiK6kmVAbeo1qmephKDq', 'model': 'claude-3-haiku-20240307', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 486, 'output_tokens': 63}}, id='run-ff07f108-5055-4343-8910-2fa40ead3fb9-0', tool_calls=[{'name': 'RequestAssistance', 'args': {'request': 'I need some expert guidance for building this AI agent.'}, 'id': 'toolu_017XaQuVsoAyfXeTfDyv55Pc'}]),\n", + " ToolMessage(content=\"We, the experts are here to help! We'd recommend you check out LangGraph to build your agent. It's much more reliable and extensible than simple autonomous agents.\", id='19f2eb9f-a742-46aa-9047-60909c30e64a', tool_call_id='toolu_017XaQuVsoAyfXeTfDyv55Pc')]" ] }, - "execution_count": 60, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -2258,7 +2478,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 13, "id": "6b32914d-4d60-491f-8e11-1e6867e38ffd", "metadata": {}, "outputs": [ @@ -2266,16 +2486,20 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: Based on your request, I've requested assistance from our expert team. They suggest looking into LangGraph as a more reliable and extensible solution for building your AI agent, compared to simpler autonomous agents. Please let me know if you need any other guidance as you work on this project.\n" + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "\n", + "We, the experts are here to help! We'd recommend you check out LangGraph to build your agent. It's much more reliable and extensible than simple autonomous agents.\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "It looks like the experts have provided some guidance on how to build your AI agent. They suggested checking out LangGraph, which they say is more reliable and extensible than simple autonomous agents. Please let me know if you need any other assistance - I'm happy to help coordinate with the expert team further.\n" ] } ], "source": [ - "events = graph.stream(None, config)\n", + "events = graph.stream(None, config, stream_mode=\"values\")\n", "for event in events:\n", - " for value in event.values():\n", - " if value[\"messages\"] and isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -2294,7 +2518,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 26, "id": "6516baf8-bbb6-4400-b867-0add1a087342", "metadata": {}, "outputs": [], @@ -2310,7 +2534,7 @@ "from langgraph.checkpoint.sqlite import SqliteSaver\n", "from langgraph.graph import MessageGraph, StateGraph\n", "from langgraph.graph.message import add_messages\n", - "from langgraph.prebuilt import ToolNode\n", + "from langgraph.prebuilt import ToolNode, tools_condition\n", "\n", "\n", "class State(TypedDict):\n", @@ -2421,7 +2645,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 2, "id": "bb8a02de-a21b-4ef6-a714-7d6e44435e3a", "metadata": {}, "outputs": [], @@ -2430,14 +2654,14 @@ "\n", "from langchain_anthropic import ChatAnthropic\n", "from langchain_community.tools.tavily_search import TavilySearchResults\n", - "from langchain_core.messages import BaseMessage\n", + "from langchain_core.messages import AIMessage, BaseMessage, ToolMessage\n", "from langchain_core.pydantic_v1 import BaseModel\n", "from typing_extensions import TypedDict\n", "\n", "from langgraph.checkpoint.sqlite import SqliteSaver\n", "from langgraph.graph import MessageGraph, StateGraph\n", "from langgraph.graph.message import add_messages\n", - "from langgraph.prebuilt import ToolNode\n", + "from langgraph.prebuilt import ToolNode, tools_condition\n", "\n", "\n", "class State(TypedDict):\n", @@ -2530,13 +2754,13 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 3, "id": "a7debb4a-2a3a-40b9-a48c-7052ec2c2726", "metadata": {}, "outputs": [ { "data": { - "image/jpeg": "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mLXSSkVBHVMA4SGhzuJr9g4cJNxqp8ptOR47rhTZhbrF38stXYmWesdHWw076IsqXS9c4SuaHM4ZHfJJPk9nNSDx6abf/cHFf/3VN9dU3rpZTSO7uWVto5xaU4XxXv8A0LX/AIvJ/ZKirtctOGOLXagYs1wOxBvVNuD+2pTeXB9krnNIc008hBHYfJKxh1tXErnHfC3Sid0p9h32o2T8Rg/dtXYXHw77UbJ+Iwfu2rsL3uL6dvfLx87xERVsCIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICg2qv8njH5Xb/DzqcrjZRitJllJT09XJUQinnFRFJTSdW9rw1zd9/mc5SjKc4nviY8YmFuFaKXi09yGyRMmbwyMa9vocNwvV3vpf8AdofdhdrxU0Pri9/Tf7k8VND64vf03+5ef7In1seEu11/C4S48dJBE8OZDGxw7C1gBXuXS8VND64vf03+5PFTQ+uL39N/uTsf+7HhJ2hhcJc1FWnSvpa3SHQu+5Tjt7ukd2o5qNkTqio6xgElVFG7dpHPyXuVu+Kmh9cXv6b/AHJ2P/djwlntDC4S5hG42PYvR3BS/wC7Q/sBdrxU0Pri9/Tf7k8VND64vf03+5OyP7seEsdoYXCXF7gpf92h/YC9V75WWv8AxeT+yV3/ABU0Pri9/Tf7l4y6SW6eJ8cl2vTmPBa5pre0HtHYp0/pOjaLTixs9knX8LhKQYd9qNk/EYP3bV2F89BRRW2hpqSEEQ08bYmAnc8LQAP+QX0LvXnStMw4M7xERQYEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQZ36f/APNXyr8Zt38dAtELO/T/AP5q+VfjNu/joFohAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQZ36f8A/NXyr8Zt38dAtELJnTx1Zwe59HzL8co8yx+ryGKto4ZLTBdIH1bHx10PWNMQfxgs4XcQ23HCd9tlonFdVsJzuvfRY1mNgyGtZG6Z9NarpBUyNjBaC8tjcSGgvYCezdw9IQSpERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEXxXi9UVgoX1lfUNp6dpA4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", + "image/jpeg": "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", "text/plain": [ "" ] @@ -2546,6 +2770,8 @@ } ], "source": [ + "from IPython.display import Image, display\n", + "\n", "try:\n", " display(Image(graph.get_graph().draw_mermaid_png()))\n", "except:\n", @@ -2563,7 +2789,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 4, "id": "69071b02-c011-4b7f-90b1-8e89e032322d", "metadata": {}, "outputs": [ @@ -2571,16 +2797,36 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: [{'id': 'toolu_01KXR18uvvs2eBoYPU43YyAL', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n", - "Assistant: [{\"url\": \"https://blog.langchain.dev/langgraph/\", \"content\": \"Some of the things we are looking to implement in the near future:\\nIf any of these resonate with you, please feel free to add an example notebook in the LangGraph repo, or reach out to us at hello@langchain.dev for more involved collaboration!\\n See this notebook for how to get started\\nModifications\\nOne of the big benefits of LangGraph is that it exposes the logic of AgentExecutor in a far more natural and modifiable way. An example of this could be that after a model is called we either exit the graph and return to the user, or we call a tool - depending on what a user decides! This function/LCEL should accept a dictionary in the same form as the State object as input, and output a dictionary with keys of the State object to update.\\n In this case, it's often ideal if the LLM can reason that the results returned from the retriever are poor, and maybe issue a second (more refined) query to the retriever, and use those results instead.\"}, {\"url\": \"https://python.langchain.com/docs/langgraph/\", \"content\": \"LangGraph is a library for building stateful, multi-actor applications with LLMs, built on top of (and intended to be used with) LangChain . It extends the LangChain Expression Language with the ability to coordinate multiple chains (or actors) across multiple steps of computation in a cyclic manner. It is inspired by Pregel and Apache Beam .\"}]\n", - "Assistant: Based on the search results, LangGraph is a library built on top of LangChain that allows for building more complex, stateful, and multi-actor applications using large language models (LLMs). Some key things I learned about LangGraph:\n", + "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", - "- It extends the LangChain Expression Language (LCEL) to coordinate multiple computational \"chains\" or \"actors\" across multiple steps, allowing for more advanced and cyclic workflows.\n", - "- It aims to make the logic of the AgentExecutor in LangChain more modifiable and natural to work with. For example, you can decide whether to exit the graph and return to the user, or call another tool, after a model is called.\n", - "- It provides the ability to reason about the quality of retriever results and issue more refined queries if needed.\n", - "- It is inspired by distributed computing frameworks like Pregel and Apache Beam.\n", + "I'm learning LangGraph. Could you do some research on it for me?\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "Overall, LangGraph seems to be a useful library for building more complex, stateful, and multi-faceted applications using large language models, built on top of the LangChain framework. Let me know if you have any other questions!\n" + "[{'text': \"Okay, let me look into LangGraph for you. Here's what I found:\", 'type': 'text'}, {'id': 'toolu_011AQ2FT4RupVka2LVMV3Gci', 'input': {'query': 'LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n", + "Tool Calls:\n", + " tavily_search_results_json (toolu_011AQ2FT4RupVka2LVMV3Gci)\n", + " Call ID: toolu_011AQ2FT4RupVka2LVMV3Gci\n", + " Args:\n", + " query: LangGraph\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", + "\n", + "[{\"url\": \"https://langchain-ai.github.io/langgraph/\", \"content\": \"LangGraph is framework agnostic (each node is a regular python function). It extends the core Runnable API (shared interface for streaming, async, and batch calls) to make it easy to: Seamless state management across multiple turns of conversation or tool usage. The ability to flexibly route between nodes based on dynamic criteria.\"}, {\"url\": \"https://blog.langchain.dev/langgraph-multi-agent-workflows/\", \"content\": \"As a part of the launch, we highlighted two simple runtimes: one that is the equivalent of the AgentExecutor in langchain, and a second that was a version of that aimed at message passing and chat models.\\n It's important to note that these three examples are only a few of the possible examples we could highlight - there are almost assuredly other examples out there and we look forward to seeing what the community comes up with!\\n LangGraph: Multi-Agent Workflows\\nLinks\\nLast week we highlighted LangGraph - a new package (available in both Python and JS) to better enable creation of LLM workflows containing cycles, which are a critical component of most agent runtimes. \\\"\\nAnother key difference between Autogen and LangGraph is that LangGraph is fully integrated into the LangChain ecosystem, meaning you take fully advantage of all the LangChain integrations and LangSmith observability.\\n As part of this launch, we're also excited to highlight a few applications built on top of LangGraph that utilize the concept of multiple agents.\\n\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "Based on the search results, here's what I've learned about LangGraph:\n", + "\n", + "- LangGraph is a framework-agnostic tool that extends the Runnable API to make it easier to manage state and routing between different nodes or agents in a conversational workflow. \n", + "\n", + "- It's part of the LangChain ecosystem, so it integrates with other LangChain tools and observability features.\n", + "\n", + "- LangGraph enables the creation of multi-agent workflows, where you can have different \"nodes\" or agents that can communicate and pass information to each other.\n", + "\n", + "- This allows for more complex conversational flows and the ability to chain together different capabilities, tools, or models.\n", + "\n", + "- The key benefits seem to be around state management, flexible routing between agents, and the ability to create more sophisticated and dynamic conversational workflows.\n", + "\n", + "Let me know if you need any clarification or have additional questions! I'm happy to do more research on LangGraph if you need further details.\n" ] } ], @@ -2593,16 +2839,16 @@ " ]\n", " },\n", " config,\n", + " stream_mode=\"values\",\n", ")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 5, "id": "acbec099-e5d2-497f-929e-c548d7bcbf77", "metadata": {}, "outputs": [ @@ -2610,21 +2856,36 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: [{'text': \"That's a great idea! Building an autonomous agent using LangGraph sounds like an exciting project. LangGraph seems well-suited for that kind of task. Here are a few additional thoughts on how you could approach building an autonomous agent with LangGraph:\", 'type': 'text'}, {'id': 'toolu_019QCT4KxdEMKtGwXC2kvK4P', 'input': {'query': 'building autonomous agents with LangGraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n", - "Assistant: [{\"url\": \"https://www.langchain.com/agents\", \"content\": \"Plan-and-execute\\nFunction Calling\\nCritique Revise\\nReAct\\nSelf-ask\\nTools for every task\\nLangChain offers an extensive library of off-the-shelf tools\\nand an intuitive framework for customizing your own.\\n Resources for LangChain Agents\\nGet started building\\nAgent Cognitive Architectures\\nLangGraph\\nReady to start shipping\\nreliable GenAI apps faster?\\nLangChain and LangSmith are critical parts of the reference\\narchitecture to get you from prototype to production. Choose the right cognitive architecture for your application\\nIdentify and implement the best prompting strategies\\nand architectures so that your LLMs perform as intended.\\n Go autonomous\\nwith LangChain Agents\\nTurn your LLMs into reasoning engines that take action, responsibly.\\n Customize your Agent Runtime with LangGraph\\nLangGraph puts you in control of your agent loop, with easy primitives for tracking state, cycles, streaming, and human-in-the-loop response.\"}, {\"url\": \"https://blog.langchain.dev/langgraph-multi-agent-workflows/\", \"content\": \"As a part of the launch, we highlighted two simple runtimes: one that is the equivalent of the AgentExecutor in langchain, and a second that was a version of that aimed at message passing and chat models.\\n It's important to note that these three examples are only a few of the possible examples we could highlight - there are almost assuredly other examples out there and we look forward to seeing what the community comes up with!\\n LangGraph: Multi-Agent Workflows\\nLinks\\nLast week we highlighted LangGraph - a new package (available in both Python and JS) to better enable creation of LLM workflows containing cycles, which are a critical component of most agent runtimes. \\\"\\nAnother key difference between Autogen and LangGraph is that LangGraph is fully integrated into the LangChain ecosystem, meaning you take fully advantage of all the LangChain integrations and LangSmith observability.\\n As part of this launch, we're also excited to highlight a few applications built on top of LangGraph that utilize the concept of multiple agents.\\n\"}]\n", - "Assistant: A few ideas to consider:\n", + "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", - "1. **Modular Agent Architecture**: LangGraph seems well-suited for building a modular agent architecture, where you can have different \"actors\" or sub-agents responsible for different tasks like planning, execution, self-reflection, and so on. This could allow for more sophisticated and autonomous behavior.\n", + "Ya that's helpful. Maybe I'll build an autonomous agent with it!\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "2. **Cyclic Workflows**: LangGraph's ability to coordinate multiple \"chains\" in a cyclic manner could be useful for building agents that can iteratively refine their understanding and actions through multiple steps.\n", + "[{'text': \"That's great that you're interested in building an autonomous agent using LangGraph! Here are a few additional thoughts on how you could approach that:\", 'type': 'text'}, {'id': 'toolu_01L3V9FhZG5Qx9jqRGfWGtS2', 'input': {'query': 'building autonomous agents with langgraph'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]\n", + "Tool Calls:\n", + " tavily_search_results_json (toolu_01L3V9FhZG5Qx9jqRGfWGtS2)\n", + " Call ID: toolu_01L3V9FhZG5Qx9jqRGfWGtS2\n", + " Args:\n", + " query: building autonomous agents with langgraph\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", "\n", - "3. **State Management**: Being able to easily manage the state of your agent across multiple steps and actors could be crucial for building truly autonomous behavior. LangGraph's state management capabilities could be very helpful here.\n", + "[{\"url\": \"https://github.com/langchain-ai/langgraphjs\", \"content\": \"LangGraph is a library for building stateful, multi-actor applications with LLMs, built on top of (and intended to be used with) LangChain.js.It extends the LangChain Expression Language with the ability to coordinate multiple chains (or actors) across multiple steps of computation in a cyclic manner. It is inspired by Pregel and Apache Beam.The current interface exposed is one inspired by ...\"}, {\"url\": \"https://github.com/langchain-ai/langgraph\", \"content\": \"LangGraph is a library for building stateful, multi-actor applications with LLMs. It extends the LangChain Expression Language with the ability to coordinate multiple chains (or actors) across multiple steps of computation in a cyclic manner. It is inspired by Pregel and Apache Beam.The current interface exposed is one inspired by NetworkX.. The main use is for adding cycles to your LLM ...\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "4. **Integration with LangChain Tools**: Since LangGraph is built on top of LangChain, you can leverage the extensive library of tools and integrations that LangChain provides to equip your autonomous agent with a wide range of capabilities.\n", + "The key things to keep in mind:\n", "\n", - "5. **Observability and Monitoring**: The LangSmith observability mentioned in the blog post could also be valuable for monitoring the behavior and performance of your autonomous agent as it operates.\n", + "1. LangGraph is designed to help coordinate multiple \"agents\" or \"actors\" that can pass information back and forth. This allows you to build more complex, multi-step workflows.\n", "\n", - "I'd recommend reviewing the LangChain and LangGraph documentation, playing with some of the example notebooks, and experimenting to see how you can best leverage these tools to build your autonomous agent. Let me know if you have any other questions!\n" + "2. You'll likely want to define different nodes or agents that handle specific tasks or capabilities. LangGraph makes it easy to route between these agents based on the state of the conversation.\n", + "\n", + "3. Make sure to leverage the LangChain ecosystem - things like prompts, memory, agents, tools etc. LangGraph integrates with these to give you a powerful set of building blocks.\n", + "\n", + "4. Pay close attention to state management - LangGraph helps you manage state across multiple interactions, which is crucial for an autonomous agent.\n", + "\n", + "5. Consider how you'll handle things like user intent, context, and goal-driven behavior. LangGraph gives you the flexibility to implement these kinds of complex behaviors.\n", + "\n", + "Let me know if you have any other specific questions as you start prototyping your autonomous agent! I'm happy to provide more guidance.\n" ] } ], @@ -2636,11 +2897,11 @@ " ]\n", " },\n", " config,\n", + " stream_mode=\"values\",\n", ")\n", "for event in events:\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, { @@ -2653,7 +2914,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 6, "id": "6c0dbed5-210d-40ad-b002-0bc52ef28fac", "metadata": {}, "outputs": [ @@ -2702,7 +2963,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 7, "id": "de8d5521-8d71-4093-a657-4920c790802f", "metadata": {}, "outputs": [ @@ -2711,7 +2972,7 @@ "output_type": "stream", "text": [ "('action',)\n", - "{'configurable': {'thread_id': '1', 'thread_ts': '2024-04-18T08:05:06.546155+00:00'}}\n" + "{'configurable': {'thread_id': '1', 'thread_ts': '2024-05-06T22:33:10.211424+00:00'}}\n" ] } ], @@ -2730,7 +2991,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 8, "id": "85f17be3-eaf6-495e-a846-49436916b4ab", "metadata": {}, "outputs": [ @@ -2738,27 +2999,37 @@ "name": "stdout", "output_type": "stream", "text": [ - "Assistant: [{\"url\": \"https://www.langchain.com/agents\", \"content\": \"Plan-and-execute\\nFunction Calling\\nCritique Revise\\nReAct\\nSelf-ask\\nTools for every task\\nLangChain offers an extensive library of off-the-shelf tools\\nand an intuitive framework for customizing your own.\\n Resources for LangChain Agents\\nGet started building\\nAgent Cognitive Architectures\\nLangGraph\\nReady to start shipping\\nreliable GenAI apps faster?\\nLangChain and LangSmith are critical parts of the reference\\narchitecture to get you from prototype to production. Choose the right cognitive architecture for your application\\nIdentify and implement the best prompting strategies\\nand architectures so that your LLMs perform as intended.\\n Go autonomous\\nwith LangChain Agents\\nTurn your LLMs into reasoning engines that take action, responsibly.\\n Customize your Agent Runtime with LangGraph\\nLangGraph puts you in control of your agent loop, with easy primitives for tracking state, cycles, streaming, and human-in-the-loop response.\"}, {\"url\": \"https://blog.langchain.dev/langgraph-multi-agent-workflows/\", \"content\": \"As a part of the launch, we highlighted two simple runtimes: one that is the equivalent of the AgentExecutor in langchain, and a second that was a version of that aimed at message passing and chat models.\\n It's important to note that these three examples are only a few of the possible examples we could highlight - there are almost assuredly other examples out there and we look forward to seeing what the community comes up with!\\n LangGraph: Multi-Agent Workflows\\nLinks\\nLast week we highlighted LangGraph - a new package (available in both Python and JS) to better enable creation of LLM workflows containing cycles, which are a critical component of most agent runtimes. \\\"\\nAnother key difference between Autogen and LangGraph is that LangGraph is fully integrated into the LangChain ecosystem, meaning you take fully advantage of all the LangChain integrations and LangSmith observability.\\n As part of this launch, we're also excited to highlight a few applications built on top of LangGraph that utilize the concept of multiple agents.\\n\"}]\n", - "Assistant: - Leverage LangGraph's ability to coordinate multiple \"chains\" or \"actors\" to create an agent with distinct capabilities that can work together in a cyclical workflow. For example, you could have one actor responsible for high-level planning, another for executing tasks, and another for monitoring and evaluating performance.\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: tavily_search_results_json\n", "\n", - "- Use LangGraph's LCEL to define the logic for how your agent's different components interact, including decisions around when to exit the graph, call additional tools, or loop back to previous steps.\n", + "[{\"url\": \"https://valentinaalto.medium.com/getting-started-with-langgraph-66388e023754\", \"content\": \"Sign up\\nSign in\\nSign up\\nSign in\\nMember-only story\\nGetting Started with LangGraph\\nBuilding multi-agents application with graph frameworks\\nValentina Alto\\nFollow\\n--\\nShare\\nOver the last year, LangChain has established itself as one of the most popular AI framework available in the market. This new library, introduced in January\\u2026\\n--\\n--\\nWritten by Valentina Alto\\nData&AI Specialist at @Microsoft | MSc in Data Science | AI, Machine Learning and Running enthusiast\\nHelp\\nStatus\\nAbout\\nCareers\\nBlog\\nPrivacy\\nTerms\\nText to speech\\nTeams Since the concept of multi-agent applications \\u2014 the ones exhibiting different agents, each having a specific personality and tools to access \\u2014 is getting real and mainstream (see the rise of libraries projects like AutoGen), LangChain\\u2019s developers introduced a new library to make it easier to manage these kind of agentic applications. Nevertheless, those chains were lacking the capability of introducing cycles into their runtime, meaning that there is no out-of-the-box framework to enable the LLM to reason over the next best action in a kind of for-loop scenario. The main feature of LangChain \\u2014 as the name suggests \\u2014 is its ability to easily create the so-called chains.\"}, {\"url\": \"https://blog.langchain.dev/langgraph-multi-agent-workflows/\", \"content\": \"As a part of the launch, we highlighted two simple runtimes: one that is the equivalent of the AgentExecutor in langchain, and a second that was a version of that aimed at message passing and chat models.\\n It's important to note that these three examples are only a few of the possible examples we could highlight - there are almost assuredly other examples out there and we look forward to seeing what the community comes up with!\\n LangGraph: Multi-Agent Workflows\\nLinks\\nLast week we highlighted LangGraph - a new package (available in both Python and JS) to better enable creation of LLM workflows containing cycles, which are a critical component of most agent runtimes. \\\"\\nAnother key difference between Autogen and LangGraph is that LangGraph is fully integrated into the LangChain ecosystem, meaning you take fully advantage of all the LangChain integrations and LangSmith observability.\\n As part of this launch, we're also excited to highlight a few applications built on top of LangGraph that utilize the concept of multiple agents.\\n\"}]\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "- Explore LangGraph's features for tracking and managing state across the agent's different components and iterations. This could be key for building more complex, long-running autonomous agents.\n", + "The key things I gathered are:\n", "\n", - "- Take advantage of LangChain's existing tools and integrations, which can provide your agent with a wide range of capabilities to draw upon.\n", + "- LangGraph is well-suited for building multi-agent applications, where you have different agents with their own capabilities, tools, and personality.\n", "\n", - "- Consider using LangGraph's flexibility to implement more advanced agent architectures, like the ones mentioned in the search results (e.g. plan-and-execute, critique-revise, self-ask).\n", + "- It allows you to create more complex workflows with cycles and feedback loops, which is critical for building autonomous agents that can reason about their next best actions.\n", "\n", - "The combination of LangGraph's multi-agent coordination and LangChain's robust tool ecosystem could be a powerful foundation for building sophisticated autonomous agents. Let me know if you have any other questions as you dive into this project!\n" + "- The integration with LangChain means you can leverage other useful features like state management, observability, and integrations with various language models and data sources.\n", + "\n", + "Some tips for building an autonomous agent with LangGraph:\n", + "\n", + "1. Define the different agents/nodes in your workflow and their specific responsibilities/capabilities.\n", + "2. Set up the connections and routing between the agents so they can pass information and decisions back and forth.\n", + "3. Implement logic within each agent to assess the current state and determine the optimal next action.\n", + "4. Use LangChain features like memory and toolkits to give your agents access to relevant information and abilities.\n", + "5. Monitor the overall system behavior and iteratively improve the agent interactions and decision-making.\n", + "\n", + "Let me know if you have any other questions! I'm happy to provide more guidance as you start building your autonomous agent with LangGraph.\n" ] } ], "source": [ "# The `thread_ts` in the `to_replay.config` corresponds to a state we've persisted to our checkpointer.\n", - "for event in graph.stream(None, to_replay.config):\n", - " for value in event.values():\n", - " if isinstance(value[\"messages\"][-1], BaseMessage):\n", - " print(\"Assistant:\", value[\"messages\"][-1].content)" + "for event in graph.stream(None, to_replay.config, stream_mode=\"values\"):\n", + " if \"messages\" in event:\n", + " event[\"messages\"][-1].pretty_print()" ] }, {