[Docs] Update notebooks to use START (#902)

This commit is contained in:
William FH
2024-07-01 21:36:34 -07:00
committed by GitHub
parent 267f5e5234
commit 727e63c01e
67 changed files with 1059 additions and 20258 deletions
+9 -140
View File
@@ -25,10 +25,7 @@
"id": "fdd4ce41-4152-423b-b3f7-be3b4d568cf4",
"metadata": {},
"outputs": [],
"source": [
"%%capture --no-stderr\n",
"%pip install --quiet -U langgraph langchain langchain_openai langchainhub tavily-python"
]
"source": ["%%capture --no-stderr\n%pip install --quiet -U langgraph langchain langchain_openai langchainhub tavily-python"]
},
{
"cell_type": "markdown",
@@ -44,13 +41,7 @@
"id": "6398c4c1-da78-4595-8a5a-051ed2d1de72",
"metadata": {},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")\n",
"os.environ[\"TAVILY_API_KEY\"] = getpass.getpass(\"Tavily API Key:\")"
]
"source": ["import getpass\nimport os\n\nos.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")\nos.environ[\"TAVILY_API_KEY\"] = getpass.getpass(\"Tavily API Key:\")"]
},
{
"cell_type": "markdown",
@@ -66,10 +57,7 @@
"id": "dcbf79ad-4de5-43b0-a3a1-25b33711e46c",
"metadata": {},
"outputs": [],
"source": [
"os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"LangSmith API Key:\")"
]
"source": ["os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\nos.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"LangSmith API Key:\")"]
},
{
"cell_type": "markdown",
@@ -87,23 +75,7 @@
"id": "4499eb16-bca8-4a60-9a3a-2f34ae3f7078",
"metadata": {},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain.agents import create_openai_functions_agent\n",
"from langchain_community.tools.tavily_search import TavilySearchResults\n",
"from langchain_openai.chat_models import ChatOpenAI\n",
"\n",
"tools = [TavilySearchResults(max_results=1)]\n",
"\n",
"# Get the prompt to use - you can modify this!\n",
"prompt = hub.pull(\"hwchase17/openai-functions-agent\")\n",
"\n",
"# Choose the LLM that will drive the agent\n",
"llm = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", streaming=True)\n",
"\n",
"# Construct the OpenAI Functions agent\n",
"agent_runnable = create_openai_functions_agent(llm, tools, prompt)"
]
"source": ["from langchain import hub\nfrom langchain.agents import create_openai_functions_agent\nfrom langchain_community.tools.tavily_search import TavilySearchResults\nfrom langchain_openai.chat_models import ChatOpenAI\n\ntools = [TavilySearchResults(max_results=1)]\n\n# Get the prompt to use - you can modify this!\nprompt = hub.pull(\"hwchase17/openai-functions-agent\")\n\n# Choose the LLM that will drive the agent\nllm = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", streaming=True)\n\n# Construct the OpenAI Functions agent\nagent_runnable = create_openai_functions_agent(llm, tools, prompt)"]
},
{
"cell_type": "markdown",
@@ -126,27 +98,7 @@
"id": "c941fb10-dbe5-4d6a-ab7d-133d01c33cc4",
"metadata": {},
"outputs": [],
"source": [
"import operator\n",
"from typing import Annotated, TypedDict, Union\n",
"\n",
"from langchain_core.agents import AgentAction, AgentFinish\n",
"from langchain_core.messages import BaseMessage\n",
"\n",
"\n",
"class AgentState(TypedDict):\n",
" # The input string\n",
" input: str\n",
" # The list of previous messages in the conversation\n",
" chat_history: list[BaseMessage]\n",
" # The outcome of a given call to the agent\n",
" # Needs `None` as a valid type, since this is what this will start as\n",
" agent_outcome: Union[AgentAction, AgentFinish, None]\n",
" # List of actions and corresponding observations\n",
" # Here we annotate this with `operator.add` to indicate that operations to\n",
" # this state should be ADDED to the existing values (not overwrite it)\n",
" intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]"
]
"source": ["import operator\nfrom typing import Annotated, TypedDict, Union\n\nfrom langchain_core.agents import AgentAction, AgentFinish\nfrom langchain_core.messages import BaseMessage\n\n\nclass AgentState(TypedDict):\n # The input string\n input: str\n # The list of previous messages in the conversation\n chat_history: list[BaseMessage]\n # The outcome of a given call to the agent\n # Needs `None` as a valid type, since this is what this will start as\n agent_outcome: Union[AgentAction, AgentFinish, None]\n # List of actions and corresponding observations\n # Here we annotate this with `operator.add` to indicate that operations to\n # this state should be ADDED to the existing values (not overwrite it)\n intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]"]
},
{
"cell_type": "markdown",
@@ -181,42 +133,7 @@
"id": "d61a970d-edf4-4eef-9678-28bab7c72331",
"metadata": {},
"outputs": [],
"source": [
"from langchain_core.agents import AgentFinish\n",
"\n",
"from langgraph.prebuilt.tool_executor import ToolExecutor\n",
"\n",
"# This a helper class we have that is useful for running tools\n",
"# It takes in an agent action and calls that tool and returns the result\n",
"tool_executor = ToolExecutor(tools)\n",
"\n",
"\n",
"# Define the agent\n",
"def run_agent(data):\n",
" agent_outcome = agent_runnable.invoke(data)\n",
" return {\"agent_outcome\": agent_outcome}\n",
"\n",
"\n",
"# Define the function to execute tools\n",
"def execute_tools(data):\n",
" # Get the most recent agent_outcome - this is the key added in the `agent` above\n",
" agent_action = data[\"agent_outcome\"]\n",
" output = tool_executor.invoke(agent_action)\n",
" return {\"intermediate_steps\": [(agent_action, str(output))]}\n",
"\n",
"\n",
"# Define logic that will be used to determine which conditional edge to go down\n",
"def should_continue(data):\n",
" # If the agent outcome is an AgentFinish, then we return `exit` string\n",
" # This will be used when setting up the graph to define the flow\n",
" if isinstance(data[\"agent_outcome\"], AgentFinish):\n",
" return \"end\"\n",
" # Otherwise, an AgentAction is returned\n",
" # Here we return `continue` string\n",
" # This will be used when setting up the graph to define the flow\n",
" else:\n",
" return \"continue\""
]
"source": ["from langchain_core.agents import AgentFinish\n\nfrom langgraph.prebuilt.tool_executor import ToolExecutor\n\n# This a helper class we have that is useful for running tools\n# It takes in an agent action and calls that tool and returns the result\ntool_executor = ToolExecutor(tools)\n\n\n# Define the agent\ndef run_agent(data):\n agent_outcome = agent_runnable.invoke(data)\n return {\"agent_outcome\": agent_outcome}\n\n\n# Define the function to execute tools\ndef execute_tools(data):\n # Get the most recent agent_outcome - this is the key added in the `agent` above\n agent_action = data[\"agent_outcome\"]\n output = tool_executor.invoke(agent_action)\n return {\"intermediate_steps\": [(agent_action, str(output))]}\n\n\n# Define logic that will be used to determine which conditional edge to go down\ndef should_continue(data):\n # If the agent outcome is an AgentFinish, then we return `exit` string\n # This will be used when setting up the graph to define the flow\n if isinstance(data[\"agent_outcome\"], AgentFinish):\n return \"end\"\n # Otherwise, an AgentAction is returned\n # Here we return `continue` string\n # This will be used when setting up the graph to define the flow\n else:\n return \"continue\""]
},
{
"cell_type": "markdown",
@@ -234,50 +151,7 @@
"id": "c4054dde-4618-49b7-998a-daa0c1d6d6c0",
"metadata": {},
"outputs": [],
"source": [
"from langgraph.graph import END, StateGraph\n",
"\n",
"# Define a new graph\n",
"workflow = StateGraph(AgentState)\n",
"\n",
"# Define the two nodes we will cycle between\n",
"workflow.add_node(\"agent\", run_agent)\n",
"workflow.add_node(\"action\", execute_tools)\n",
"\n",
"# Set the entrypoint as `agent`\n",
"# This means that this node is the first one called\n",
"workflow.set_entry_point(\"agent\")\n",
"\n",
"# We now add a conditional edge\n",
"workflow.add_conditional_edges(\n",
" # First, we define the start node. We use `agent`.\n",
" # This means these are the edges taken after the `agent` node is called.\n",
" \"agent\",\n",
" # Next, we pass in the function that will determine which node is called next.\n",
" should_continue,\n",
" # Finally we pass in a mapping.\n",
" # The keys are strings, and the values are other nodes.\n",
" # END is a special node marking that the graph should finish.\n",
" # What will happen is we will call `should_continue`, and then the output of that\n",
" # will be matched against the keys in this mapping.\n",
" # Based on which one it matches, that node will then be called.\n",
" {\n",
" # If `tools`, then we call the tool node.\n",
" \"continue\": \"action\",\n",
" # Otherwise we finish.\n",
" \"end\": END,\n",
" },\n",
")\n",
"\n",
"# We now add a normal edge from `tools` to `agent`.\n",
"# This means that after `tools` is called, `agent` node is called next.\n",
"workflow.add_edge(\"action\", \"agent\")\n",
"\n",
"# Finally, we compile it!\n",
"# This compiles it into a LangChain Runnable,\n",
"# meaning you can use it as you would any other runnable\n",
"app = workflow.compile()"
]
"source": ["from langgraph.graph import END, StateGraph, START\n\n# Define a new graph\nworkflow = StateGraph(AgentState)\n\n# Define the two nodes we will cycle between\nworkflow.add_node(\"agent\", run_agent)\nworkflow.add_node(\"action\", execute_tools)\n\n# Set the entrypoint as `agent`\n# This means that this node is the first one called\nworkflow.add_edge(START, \"agent\")\n\n# We now add a conditional edge\nworkflow.add_conditional_edges(\n # First, we define the start node. We use `agent`.\n # This means these are the edges taken after the `agent` node is called.\n \"agent\",\n # Next, we pass in the function that will determine which node is called next.\n should_continue,\n # Finally we pass in a mapping.\n # The keys are strings, and the values are other nodes.\n # END is a special node marking that the graph should finish.\n # What will happen is we will call `should_continue`, and then the output of that\n # will be matched against the keys in this mapping.\n # Based on which one it matches, that node will then be called.\n {\n # If `tools`, then we call the tool node.\n \"continue\": \"action\",\n # Otherwise we finish.\n \"end\": END,\n },\n)\n\n# We now add a normal edge from `tools` to `agent`.\n# This means that after `tools` is called, `agent` node is called next.\nworkflow.add_edge(\"action\", \"agent\")\n\n# Finally, we compile it!\n# This compiles it into a LangChain Runnable,\n# meaning you can use it as you would any other runnable\napp = workflow.compile()"]
},
{
"cell_type": "code",
@@ -300,12 +174,7 @@
]
}
],
"source": [
"inputs = {\"input\": \"what is the weather in sf\", \"chat_history\": []}\n",
"for s in app.stream(inputs):\n",
" print(list(s.values())[0])\n",
" print(\"----\")"
]
"source": ["inputs = {\"input\": \"what is the weather in sf\", \"chat_history\": []}\nfor s in app.stream(inputs):\n print(list(s.values())[0])\n print(\"----\")"]
},
{
"cell_type": "code",
@@ -313,7 +182,7 @@
"id": "2eb662bc-de7d-4a57-a3e8-2f00dcf4ff8b",
"metadata": {},
"outputs": [],
"source": []
"source": [""]
}
],
"metadata": {
@@ -30,10 +30,7 @@
"id": "694cfc4c-22a7-495d-930d-56b21d850ff9",
"metadata": {},
"outputs": [],
"source": [
"%%capture --no-stderr\n",
"%pip install --quiet -U langgraph langchain langchain_openai tavily-python"
]
"source": ["%%capture --no-stderr\n%pip install --quiet -U langgraph langchain langchain_openai tavily-python"]
},
{
"cell_type": "markdown",
@@ -49,13 +46,7 @@
"id": "30c06a84-291a-4f58-9d31-53d3b56a3def",
"metadata": {},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")\n",
"os.environ[\"TAVILY_API_KEY\"] = getpass.getpass(\"Tavily API Key:\")"
]
"source": ["import getpass\nimport os\n\nos.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")\nos.environ[\"TAVILY_API_KEY\"] = getpass.getpass(\"Tavily API Key:\")"]
},
{
"cell_type": "markdown",
@@ -71,10 +62,7 @@
"id": "a8fb285a-7e6e-46fc-a273-43ab1a676189",
"metadata": {},
"outputs": [],
"source": [
"os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"LangSmith API Key:\")"
]
"source": ["os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\nos.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"LangSmith API Key:\")"]
},
{
"cell_type": "markdown",
@@ -92,23 +80,7 @@
"id": "4499eb16-bca8-4a60-9a3a-2f34ae3f7078",
"metadata": {},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain.agents import create_openai_functions_agent\n",
"from langchain_community.tools.tavily_search import TavilySearchResults\n",
"from langchain_openai.chat_models import ChatOpenAI\n",
"\n",
"tools = [TavilySearchResults(max_results=1)]\n",
"\n",
"# Get the prompt to use - you can modify this!\n",
"prompt = hub.pull(\"hwchase17/openai-functions-agent\")\n",
"\n",
"# Choose the LLM that will drive the agent\n",
"llm = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", streaming=True)\n",
"\n",
"# Construct the OpenAI Functions agent\n",
"agent_runnable = create_openai_functions_agent(llm, tools, prompt)"
]
"source": ["from langchain import hub\nfrom langchain.agents import create_openai_functions_agent\nfrom langchain_community.tools.tavily_search import TavilySearchResults\nfrom langchain_openai.chat_models import ChatOpenAI\n\ntools = [TavilySearchResults(max_results=1)]\n\n# Get the prompt to use - you can modify this!\nprompt = hub.pull(\"hwchase17/openai-functions-agent\")\n\n# Choose the LLM that will drive the agent\nllm = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", streaming=True)\n\n# Construct the OpenAI Functions agent\nagent_runnable = create_openai_functions_agent(llm, tools, prompt)"]
},
{
"cell_type": "markdown",
@@ -131,27 +103,7 @@
"id": "c941fb10-dbe5-4d6a-ab7d-133d01c33cc4",
"metadata": {},
"outputs": [],
"source": [
"import operator\n",
"from typing import Annotated, TypedDict, Union\n",
"\n",
"from langchain_core.agents import AgentAction, AgentFinish\n",
"from langchain_core.messages import BaseMessage\n",
"\n",
"\n",
"class AgentState(TypedDict):\n",
" # The input string\n",
" input: str\n",
" # The list of previous messages in the conversation\n",
" chat_history: list[BaseMessage]\n",
" # The outcome of a given call to the agent\n",
" # Needs `None` as a valid type, since this is what this will start as\n",
" agent_outcome: Union[AgentAction, AgentFinish, None]\n",
" # List of actions and corresponding observations\n",
" # Here we annotate this with `operator.add` to indicate that operations to\n",
" # this state should be ADDED to the existing values (not overwrite it)\n",
" intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]"
]
"source": ["import operator\nfrom typing import Annotated, TypedDict, Union\n\nfrom langchain_core.agents import AgentAction, AgentFinish\nfrom langchain_core.messages import BaseMessage\n\n\nclass AgentState(TypedDict):\n # The input string\n input: str\n # The list of previous messages in the conversation\n chat_history: list[BaseMessage]\n # The outcome of a given call to the agent\n # Needs `None` as a valid type, since this is what this will start as\n agent_outcome: Union[AgentAction, AgentFinish, None]\n # List of actions and corresponding observations\n # Here we annotate this with `operator.add` to indicate that operations to\n # this state should be ADDED to the existing values (not overwrite it)\n intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]"]
},
{
"cell_type": "markdown",
@@ -186,42 +138,7 @@
"id": "d61a970d-edf4-4eef-9678-28bab7c72331",
"metadata": {},
"outputs": [],
"source": [
"from langchain_core.agents import AgentFinish\n",
"\n",
"from langgraph.prebuilt.tool_executor import ToolExecutor\n",
"\n",
"# This a helper class we have that is useful for running tools\n",
"# It takes in an agent action and calls that tool and returns the result\n",
"tool_executor = ToolExecutor(tools)\n",
"\n",
"\n",
"# Define the agent\n",
"def run_agent(data):\n",
" agent_outcome = agent_runnable.invoke(data)\n",
" return {\"agent_outcome\": agent_outcome}\n",
"\n",
"\n",
"# Define the function to execute tools\n",
"def execute_tools(data):\n",
" # Get the most recent agent_outcome - this is the key added in the `agent` above\n",
" agent_action = data[\"agent_outcome\"]\n",
" output = tool_executor.invoke(agent_action)\n",
" return {\"intermediate_steps\": [(agent_action, str(output))]}\n",
"\n",
"\n",
"# Define logic that will be used to determine which conditional edge to go down\n",
"def should_continue(data):\n",
" # If the agent outcome is an AgentFinish, then we return `exit` string\n",
" # This will be used when setting up the graph to define the flow\n",
" if isinstance(data[\"agent_outcome\"], AgentFinish):\n",
" return \"end\"\n",
" # Otherwise, an AgentAction is returned\n",
" # Here we return `continue` string\n",
" # This will be used when setting up the graph to define the flow\n",
" else:\n",
" return \"continue\""
]
"source": ["from langchain_core.agents import AgentFinish\n\nfrom langgraph.prebuilt.tool_executor import ToolExecutor\n\n# This a helper class we have that is useful for running tools\n# It takes in an agent action and calls that tool and returns the result\ntool_executor = ToolExecutor(tools)\n\n\n# Define the agent\ndef run_agent(data):\n agent_outcome = agent_runnable.invoke(data)\n return {\"agent_outcome\": agent_outcome}\n\n\n# Define the function to execute tools\ndef execute_tools(data):\n # Get the most recent agent_outcome - this is the key added in the `agent` above\n agent_action = data[\"agent_outcome\"]\n output = tool_executor.invoke(agent_action)\n return {\"intermediate_steps\": [(agent_action, str(output))]}\n\n\n# Define logic that will be used to determine which conditional edge to go down\ndef should_continue(data):\n # If the agent outcome is an AgentFinish, then we return `exit` string\n # This will be used when setting up the graph to define the flow\n if isinstance(data[\"agent_outcome\"], AgentFinish):\n return \"end\"\n # Otherwise, an AgentAction is returned\n # Here we return `continue` string\n # This will be used when setting up the graph to define the flow\n else:\n return \"continue\""]
},
{
"cell_type": "markdown",
@@ -250,9 +167,7 @@
"output_type": "execute_result"
}
],
"source": [
"tools[0].name"
]
"source": ["tools[0].name"]
},
{
"cell_type": "code",
@@ -260,21 +175,7 @@
"id": "df25d899-2338-4f31-a8bf-0582a2eec325",
"metadata": {},
"outputs": [],
"source": [
"from langchain_core.agents import AgentActionMessageLog\n",
"\n",
"\n",
"def first_agent(inputs):\n",
" action = AgentActionMessageLog(\n",
" # We force call this tool\n",
" tool=\"tavily_search_results_json\",\n",
" # We just pass in the `input` key to this tool\n",
" tool_input=inputs[\"input\"],\n",
" log=\"\",\n",
" message_log=[],\n",
" )\n",
" return {\"agent_outcome\": action}"
]
"source": ["from langchain_core.agents import AgentActionMessageLog\n\n\ndef first_agent(inputs):\n action = AgentActionMessageLog(\n # We force call this tool\n tool=\"tavily_search_results_json\",\n # We just pass in the `input` key to this tool\n tool_input=inputs[\"input\"],\n log=\"\",\n message_log=[],\n )\n return {\"agent_outcome\": action}"]
},
{
"cell_type": "markdown",
@@ -296,54 +197,7 @@
"id": "c4054dde-4618-49b7-998a-daa0c1d6d6c0",
"metadata": {},
"outputs": [],
"source": [
"from langgraph.graph import END, StateGraph\n",
"\n",
"# Define a new graph\n",
"workflow = StateGraph(AgentState)\n",
"\n",
"# Define the two nodes we will cycle between\n",
"workflow.add_node(\"agent\", run_agent)\n",
"workflow.add_node(\"action\", execute_tools)\n",
"workflow.add_node(\"first_agent\", first_agent)\n",
"\n",
"# Set the entrypoint as `agent`\n",
"# This means that this node is the first one called\n",
"workflow.set_entry_point(\"first_agent\")\n",
"\n",
"# We now add a conditional edge\n",
"workflow.add_conditional_edges(\n",
" # First, we define the start node. We use `agent`.\n",
" # This means these are the edges taken after the `agent` node is called.\n",
" \"agent\",\n",
" # Next, we pass in the function that will determine which node is called next.\n",
" should_continue,\n",
" # Finally we pass in a mapping.\n",
" # The keys are strings, and the values are other nodes.\n",
" # END is a special node marking that the graph should finish.\n",
" # What will happen is we will call `should_continue`, and then the output of that\n",
" # will be matched against the keys in this mapping.\n",
" # Based on which one it matches, that node will then be called.\n",
" {\n",
" # If `tools`, then we call the tool node.\n",
" \"continue\": \"action\",\n",
" # Otherwise we finish.\n",
" \"end\": END,\n",
" },\n",
")\n",
"\n",
"# We now add a normal edge from `tools` to `agent`.\n",
"# This means that after `tools` is called, `agent` node is called next.\n",
"workflow.add_edge(\"action\", \"agent\")\n",
"\n",
"# After the first agent, we want to take an action\n",
"workflow.add_edge(\"first_agent\", \"action\")\n",
"\n",
"# Finally, we compile it!\n",
"# This compiles it into a LangChain Runnable,\n",
"# meaning you can use it as you would any other runnable\n",
"app = workflow.compile()"
]
"source": ["from langgraph.graph import END, StateGraph, START\n\n# Define a new graph\nworkflow = StateGraph(AgentState)\n\n# Define the two nodes we will cycle between\nworkflow.add_node(\"agent\", run_agent)\nworkflow.add_node(\"action\", execute_tools)\nworkflow.add_node(\"first_agent\", first_agent)\n\n# Set the entrypoint as `agent`\n# This means that this node is the first one called\nworkflow.add_edge(START, \"first_agent\")\n\n# We now add a conditional edge\nworkflow.add_conditional_edges(\n # First, we define the start node. We use `agent`.\n # This means these are the edges taken after the `agent` node is called.\n \"agent\",\n # Next, we pass in the function that will determine which node is called next.\n should_continue,\n # Finally we pass in a mapping.\n # The keys are strings, and the values are other nodes.\n # END is a special node marking that the graph should finish.\n # What will happen is we will call `should_continue`, and then the output of that\n # will be matched against the keys in this mapping.\n # Based on which one it matches, that node will then be called.\n {\n # If `tools`, then we call the tool node.\n \"continue\": \"action\",\n # Otherwise we finish.\n \"end\": END,\n },\n)\n\n# We now add a normal edge from `tools` to `agent`.\n# This means that after `tools` is called, `agent` node is called next.\nworkflow.add_edge(\"action\", \"agent\")\n\n# After the first agent, we want to take an action\nworkflow.add_edge(\"first_agent\", \"action\")\n\n# Finally, we compile it!\n# This compiles it into a LangChain Runnable,\n# meaning you can use it as you would any other runnable\napp = workflow.compile()"]
},
{
"cell_type": "code",
@@ -366,12 +220,7 @@
]
}
],
"source": [
"inputs = {\"input\": \"what is the weather in sf\", \"chat_history\": []}\n",
"for s in app.stream(inputs):\n",
" print(list(s.values())[0])\n",
" print(\"----\")"
]
"source": ["inputs = {\"input\": \"what is the weather in sf\", \"chat_history\": []}\nfor s in app.stream(inputs):\n print(list(s.values())[0])\n print(\"----\")"]
},
{
"cell_type": "code",
@@ -379,7 +228,7 @@
"id": "2eb662bc-de7d-4a57-a3e8-2f00dcf4ff8b",
"metadata": {},
"outputs": [],
"source": []
"source": [""]
}
],
"metadata": {
+10 -143
View File
@@ -30,10 +30,7 @@
"id": "3fa9e224-2f00-49e2-bca3-e9cb8d9f3d41",
"metadata": {},
"outputs": [],
"source": [
"%%capture --no-stderr\n",
"%pip install --quiet -U langgraph langchain langchain_openai tavily-python"
]
"source": ["%%capture --no-stderr\n%pip install --quiet -U langgraph langchain langchain_openai tavily-python"]
},
{
"cell_type": "markdown",
@@ -49,13 +46,7 @@
"id": "d180f0d0-385f-4ce3-994c-11e1d64595b5",
"metadata": {},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")\n",
"os.environ[\"TAVILY_API_KEY\"] = getpass.getpass(\"Tavily API Key:\")"
]
"source": ["import getpass\nimport os\n\nos.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")\nos.environ[\"TAVILY_API_KEY\"] = getpass.getpass(\"Tavily API Key:\")"]
},
{
"cell_type": "markdown",
@@ -71,10 +62,7 @@
"id": "72ad0539-ecd8-4eb1-b2c1-2242e5fc556f",
"metadata": {},
"outputs": [],
"source": [
"os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"LangSmith API Key:\")"
]
"source": ["os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\nos.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"LangSmith API Key:\")"]
},
{
"cell_type": "markdown",
@@ -92,23 +80,7 @@
"id": "4499eb16-bca8-4a60-9a3a-2f34ae3f7078",
"metadata": {},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain.agents import create_openai_functions_agent\n",
"from langchain_community.tools.tavily_search import TavilySearchResults\n",
"from langchain_openai.chat_models import ChatOpenAI\n",
"\n",
"tools = [TavilySearchResults(max_results=1)]\n",
"\n",
"# Get the prompt to use - you can modify this!\n",
"prompt = hub.pull(\"hwchase17/openai-functions-agent\")\n",
"\n",
"# Choose the LLM that will drive the agent\n",
"llm = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", streaming=True)\n",
"\n",
"# Construct the OpenAI Functions agent\n",
"agent_runnable = create_openai_functions_agent(llm, tools, prompt)"
]
"source": ["from langchain import hub\nfrom langchain.agents import create_openai_functions_agent\nfrom langchain_community.tools.tavily_search import TavilySearchResults\nfrom langchain_openai.chat_models import ChatOpenAI\n\ntools = [TavilySearchResults(max_results=1)]\n\n# Get the prompt to use - you can modify this!\nprompt = hub.pull(\"hwchase17/openai-functions-agent\")\n\n# Choose the LLM that will drive the agent\nllm = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", streaming=True)\n\n# Construct the OpenAI Functions agent\nagent_runnable = create_openai_functions_agent(llm, tools, prompt)"]
},
{
"cell_type": "markdown",
@@ -131,27 +103,7 @@
"id": "c941fb10-dbe5-4d6a-ab7d-133d01c33cc4",
"metadata": {},
"outputs": [],
"source": [
"import operator\n",
"from typing import Annotated, TypedDict, Union\n",
"\n",
"from langchain_core.agents import AgentAction, AgentFinish\n",
"from langchain_core.messages import BaseMessage\n",
"\n",
"\n",
"class AgentState(TypedDict):\n",
" # The input string\n",
" input: str\n",
" # The list of previous messages in the conversation\n",
" chat_history: list[BaseMessage]\n",
" # The outcome of a given call to the agent\n",
" # Needs `None` as a valid type, since this is what this will start as\n",
" agent_outcome: Union[AgentAction, AgentFinish, None]\n",
" # List of actions and corresponding observations\n",
" # Here we annotate this with `operator.add` to indicate that operations to\n",
" # this state should be ADDED to the existing values (not overwrite it)\n",
" intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]"
]
"source": ["import operator\nfrom typing import Annotated, TypedDict, Union\n\nfrom langchain_core.agents import AgentAction, AgentFinish\nfrom langchain_core.messages import BaseMessage\n\n\nclass AgentState(TypedDict):\n # The input string\n input: str\n # The list of previous messages in the conversation\n chat_history: list[BaseMessage]\n # The outcome of a given call to the agent\n # Needs `None` as a valid type, since this is what this will start as\n agent_outcome: Union[AgentAction, AgentFinish, None]\n # List of actions and corresponding observations\n # Here we annotate this with `operator.add` to indicate that operations to\n # this state should be ADDED to the existing values (not overwrite it)\n intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]"]
},
{
"cell_type": "markdown",
@@ -186,21 +138,7 @@
"id": "2b757f84-1175-445e-8f8c-e5aeb765a03d",
"metadata": {},
"outputs": [],
"source": [
"from langchain_core.agents import AgentFinish\n",
"\n",
"from langgraph.prebuilt.tool_executor import ToolExecutor\n",
"\n",
"# This a helper class we have that is useful for running tools\n",
"# It takes in an agent action and calls that tool and returns the result\n",
"tool_executor = ToolExecutor(tools)\n",
"\n",
"\n",
"# Define the agent\n",
"def run_agent(data):\n",
" agent_outcome = agent_runnable.invoke(data)\n",
" return {\"agent_outcome\": agent_outcome}"
]
"source": ["from langchain_core.agents import AgentFinish\n\nfrom langgraph.prebuilt.tool_executor import ToolExecutor\n\n# This a helper class we have that is useful for running tools\n# It takes in an agent action and calls that tool and returns the result\ntool_executor = ToolExecutor(tools)\n\n\n# Define the agent\ndef run_agent(data):\n agent_outcome = agent_runnable.invoke(data)\n return {\"agent_outcome\": agent_outcome}"]
},
{
"cell_type": "markdown",
@@ -218,30 +156,7 @@
"id": "2fecf5e0-9604-4992-9c82-b9627466cd32",
"metadata": {},
"outputs": [],
"source": [
"# Define the function to execute tools\n",
"def execute_tools(data):\n",
" # Get the most recent agent_outcome - this is the key added in the `agent` above\n",
" agent_action = data[\"agent_outcome\"]\n",
" response = input(prompt=f\"[y/n] continue with: {agent_action}?\")\n",
" if response == \"n\":\n",
" raise ValueError\n",
" output = tool_executor.invoke(agent_action)\n",
" return {\"intermediate_steps\": [(agent_action, str(output))]}\n",
"\n",
"\n",
"# Define logic that will be used to determine which conditional edge to go down\n",
"def should_continue(data):\n",
" # If the agent outcome is an AgentFinish, then we return `exit` string\n",
" # This will be used when setting up the graph to define the flow\n",
" if isinstance(data[\"agent_outcome\"], AgentFinish):\n",
" return \"end\"\n",
" # Otherwise, an AgentAction is returned\n",
" # Here we return `continue` string\n",
" # This will be used when setting up the graph to define the flow\n",
" else:\n",
" return \"continue\""
]
"source": ["# Define the function to execute tools\ndef execute_tools(data):\n # Get the most recent agent_outcome - this is the key added in the `agent` above\n agent_action = data[\"agent_outcome\"]\n response = input(prompt=f\"[y/n] continue with: {agent_action}?\")\n if response == \"n\":\n raise ValueError\n output = tool_executor.invoke(agent_action)\n return {\"intermediate_steps\": [(agent_action, str(output))]}\n\n\n# Define logic that will be used to determine which conditional edge to go down\ndef should_continue(data):\n # If the agent outcome is an AgentFinish, then we return `exit` string\n # This will be used when setting up the graph to define the flow\n if isinstance(data[\"agent_outcome\"], AgentFinish):\n return \"end\"\n # Otherwise, an AgentAction is returned\n # Here we return `continue` string\n # This will be used when setting up the graph to define the flow\n else:\n return \"continue\""]
},
{
"cell_type": "markdown",
@@ -259,50 +174,7 @@
"id": "c4054dde-4618-49b7-998a-daa0c1d6d6c0",
"metadata": {},
"outputs": [],
"source": [
"from langgraph.graph import END, StateGraph\n",
"\n",
"# Define a new graph\n",
"workflow = StateGraph(AgentState)\n",
"\n",
"# Define the two nodes we will cycle between\n",
"workflow.add_node(\"agent\", run_agent)\n",
"workflow.add_node(\"action\", execute_tools)\n",
"\n",
"# Set the entrypoint as `agent`\n",
"# This means that this node is the first one called\n",
"workflow.set_entry_point(\"agent\")\n",
"\n",
"# We now add a conditional edge\n",
"workflow.add_conditional_edges(\n",
" # First, we define the start node. We use `agent`.\n",
" # This means these are the edges taken after the `agent` node is called.\n",
" \"agent\",\n",
" # Next, we pass in the function that will determine which node is called next.\n",
" should_continue,\n",
" # Finally we pass in a mapping.\n",
" # The keys are strings, and the values are other nodes.\n",
" # END is a special node marking that the graph should finish.\n",
" # What will happen is we will call `should_continue`, and then the output of that\n",
" # will be matched against the keys in this mapping.\n",
" # Based on which one it matches, that node will then be called.\n",
" {\n",
" # If `tools`, then we call the tool node.\n",
" \"continue\": \"action\",\n",
" # Otherwise we finish.\n",
" \"end\": END,\n",
" },\n",
")\n",
"\n",
"# We now add a normal edge from `tools` to `agent`.\n",
"# This means that after `tools` is called, `agent` node is called next.\n",
"workflow.add_edge(\"action\", \"agent\")\n",
"\n",
"# Finally, we compile it!\n",
"# This compiles it into a LangChain Runnable,\n",
"# meaning you can use it as you would any other runnable\n",
"app = workflow.compile()"
]
"source": ["from langgraph.graph import END, StateGraph, START\n\n# Define a new graph\nworkflow = StateGraph(AgentState)\n\n# Define the two nodes we will cycle between\nworkflow.add_node(\"agent\", run_agent)\nworkflow.add_node(\"action\", execute_tools)\n\n# Set the entrypoint as `agent`\n# This means that this node is the first one called\nworkflow.add_edge(START, \"agent\")\n\n# We now add a conditional edge\nworkflow.add_conditional_edges(\n # First, we define the start node. We use `agent`.\n # This means these are the edges taken after the `agent` node is called.\n \"agent\",\n # Next, we pass in the function that will determine which node is called next.\n should_continue,\n # Finally we pass in a mapping.\n # The keys are strings, and the values are other nodes.\n # END is a special node marking that the graph should finish.\n # What will happen is we will call `should_continue`, and then the output of that\n # will be matched against the keys in this mapping.\n # Based on which one it matches, that node will then be called.\n {\n # If `tools`, then we call the tool node.\n \"continue\": \"action\",\n # Otherwise we finish.\n \"end\": END,\n },\n)\n\n# We now add a normal edge from `tools` to `agent`.\n# This means that after `tools` is called, `agent` node is called next.\nworkflow.add_edge(\"action\", \"agent\")\n\n# Finally, we compile it!\n# This compiles it into a LangChain Runnable,\n# meaning you can use it as you would any other runnable\napp = workflow.compile()"]
},
{
"cell_type": "code",
@@ -338,12 +210,7 @@
]
}
],
"source": [
"inputs = {\"input\": \"what is the weather in sf\", \"chat_history\": []}\n",
"for s in app.stream(inputs):\n",
" print(list(s.values())[0])\n",
" print(\"----\")"
]
"source": ["inputs = {\"input\": \"what is the weather in sf\", \"chat_history\": []}\nfor s in app.stream(inputs):\n print(list(s.values())[0])\n print(\"----\")"]
},
{
"cell_type": "code",
@@ -351,7 +218,7 @@
"id": "2eb662bc-de7d-4a57-a3e8-2f00dcf4ff8b",
"metadata": {},
"outputs": [],
"source": []
"source": [""]
}
],
"metadata": {
@@ -30,10 +30,7 @@
"id": "aa752131-27e3-4bd8-9f21-d6749a7e74f4",
"metadata": {},
"outputs": [],
"source": [
"%%capture --no-stderr\n",
"%pip install --quiet -U langgraph langchain langchain_openai tavily-python"
]
"source": ["%%capture --no-stderr\n%pip install --quiet -U langgraph langchain langchain_openai tavily-python"]
},
{
"cell_type": "markdown",
@@ -49,13 +46,7 @@
"id": "5732e68f-4ae2-4db9-bf9c-454b4cc9ec01",
"metadata": {},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")\n",
"os.environ[\"TAVILY_API_KEY\"] = getpass.getpass(\"Tavily API Key:\")"
]
"source": ["import getpass\nimport os\n\nos.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")\nos.environ[\"TAVILY_API_KEY\"] = getpass.getpass(\"Tavily API Key:\")"]
},
{
"cell_type": "markdown",
@@ -71,10 +62,7 @@
"id": "652d4600-8f95-493f-b9b9-d4095aed9218",
"metadata": {},
"outputs": [],
"source": [
"os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"LangSmith API Key:\")"
]
"source": ["os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\nos.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"LangSmith API Key:\")"]
},
{
"cell_type": "markdown",
@@ -92,23 +80,7 @@
"id": "4499eb16-bca8-4a60-9a3a-2f34ae3f7078",
"metadata": {},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain.agents import create_openai_functions_agent\n",
"from langchain_community.tools.tavily_search import TavilySearchResults\n",
"from langchain_openai.chat_models import ChatOpenAI\n",
"\n",
"tools = [TavilySearchResults(max_results=1)]\n",
"\n",
"# Get the prompt to use - you can modify this!\n",
"prompt = hub.pull(\"hwchase17/openai-functions-agent\")\n",
"\n",
"# Choose the LLM that will drive the agent\n",
"llm = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", streaming=True)\n",
"\n",
"# Construct the OpenAI Functions agent\n",
"agent_runnable = create_openai_functions_agent(llm, tools, prompt)"
]
"source": ["from langchain import hub\nfrom langchain.agents import create_openai_functions_agent\nfrom langchain_community.tools.tavily_search import TavilySearchResults\nfrom langchain_openai.chat_models import ChatOpenAI\n\ntools = [TavilySearchResults(max_results=1)]\n\n# Get the prompt to use - you can modify this!\nprompt = hub.pull(\"hwchase17/openai-functions-agent\")\n\n# Choose the LLM that will drive the agent\nllm = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", streaming=True)\n\n# Construct the OpenAI Functions agent\nagent_runnable = create_openai_functions_agent(llm, tools, prompt)"]
},
{
"cell_type": "markdown",
@@ -131,27 +103,7 @@
"id": "c941fb10-dbe5-4d6a-ab7d-133d01c33cc4",
"metadata": {},
"outputs": [],
"source": [
"import operator\n",
"from typing import Annotated, TypedDict, Union\n",
"\n",
"from langchain_core.agents import AgentAction, AgentFinish\n",
"from langchain_core.messages import BaseMessage\n",
"\n",
"\n",
"class AgentState(TypedDict):\n",
" # The input string\n",
" input: str\n",
" # The list of previous messages in the conversation\n",
" chat_history: list[BaseMessage]\n",
" # The outcome of a given call to the agent\n",
" # Needs `None` as a valid type, since this is what this will start as\n",
" agent_outcome: Union[AgentAction, AgentFinish, None]\n",
" # List of actions and corresponding observations\n",
" # Here we annotate this with `operator.add` to indicate that operations to\n",
" # this state should be ADDED to the existing values (not overwrite it)\n",
" intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]"
]
"source": ["import operator\nfrom typing import Annotated, TypedDict, Union\n\nfrom langchain_core.agents import AgentAction, AgentFinish\nfrom langchain_core.messages import BaseMessage\n\n\nclass AgentState(TypedDict):\n # The input string\n input: str\n # The list of previous messages in the conversation\n chat_history: list[BaseMessage]\n # The outcome of a given call to the agent\n # Needs `None` as a valid type, since this is what this will start as\n agent_outcome: Union[AgentAction, AgentFinish, None]\n # List of actions and corresponding observations\n # Here we annotate this with `operator.add` to indicate that operations to\n # this state should be ADDED to the existing values (not overwrite it)\n intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]"]
},
{
"cell_type": "markdown",
@@ -186,15 +138,7 @@
"id": "77e3c059-e31f-4c8f-81bf-edb58688e12b",
"metadata": {},
"outputs": [],
"source": [
"from langchain_core.agents import AgentFinish\n",
"\n",
"from langgraph.prebuilt.tool_executor import ToolExecutor\n",
"\n",
"# This a helper class we have that is useful for running tools\n",
"# It takes in an agent action and calls that tool and returns the result\n",
"tool_executor = ToolExecutor(tools)"
]
"source": ["from langchain_core.agents import AgentFinish\n\nfrom langgraph.prebuilt.tool_executor import ToolExecutor\n\n# This a helper class we have that is useful for running tools\n# It takes in an agent action and calls that tool and returns the result\ntool_executor = ToolExecutor(tools)"]
},
{
"cell_type": "markdown",
@@ -212,36 +156,7 @@
"id": "a9f66a3e-aba1-4893-95b1-a433c7091d5e",
"metadata": {},
"outputs": [],
"source": [
"# Define the agent\n",
"def run_agent(data):\n",
" inputs = data.copy()\n",
" if len(inputs[\"intermediate_steps\"]) > 5:\n",
" inputs[\"intermediate_steps\"] = inputs[\"intermediate_steps\"][-5:]\n",
" agent_outcome = agent_runnable.invoke(inputs)\n",
" return {\"agent_outcome\": agent_outcome}\n",
"\n",
"\n",
"# Define the function to execute tools\n",
"def execute_tools(data):\n",
" # Get the most recent agent_outcome - this is the key added in the `agent` above\n",
" agent_action = data[\"agent_outcome\"]\n",
" output = tool_executor.invoke(agent_action)\n",
" return {\"intermediate_steps\": [(agent_action, str(output))]}\n",
"\n",
"\n",
"# Define logic that will be used to determine which conditional edge to go down\n",
"def should_continue(data):\n",
" # If the agent outcome is an AgentFinish, then we return `exit` string\n",
" # This will be used when setting up the graph to define the flow\n",
" if isinstance(data[\"agent_outcome\"], AgentFinish):\n",
" return \"end\"\n",
" # Otherwise, an AgentAction is returned\n",
" # Here we return `continue` string\n",
" # This will be used when setting up the graph to define the flow\n",
" else:\n",
" return \"continue\""
]
"source": ["# Define the agent\ndef run_agent(data):\n inputs = data.copy()\n if len(inputs[\"intermediate_steps\"]) > 5:\n inputs[\"intermediate_steps\"] = inputs[\"intermediate_steps\"][-5:]\n agent_outcome = agent_runnable.invoke(inputs)\n return {\"agent_outcome\": agent_outcome}\n\n\n# Define the function to execute tools\ndef execute_tools(data):\n # Get the most recent agent_outcome - this is the key added in the `agent` above\n agent_action = data[\"agent_outcome\"]\n output = tool_executor.invoke(agent_action)\n return {\"intermediate_steps\": [(agent_action, str(output))]}\n\n\n# Define logic that will be used to determine which conditional edge to go down\ndef should_continue(data):\n # If the agent outcome is an AgentFinish, then we return `exit` string\n # This will be used when setting up the graph to define the flow\n if isinstance(data[\"agent_outcome\"], AgentFinish):\n return \"end\"\n # Otherwise, an AgentAction is returned\n # Here we return `continue` string\n # This will be used when setting up the graph to define the flow\n else:\n return \"continue\""]
},
{
"cell_type": "markdown",
@@ -259,50 +174,7 @@
"id": "c4054dde-4618-49b7-998a-daa0c1d6d6c0",
"metadata": {},
"outputs": [],
"source": [
"from langgraph.graph import END, StateGraph\n",
"\n",
"# Define a new graph\n",
"workflow = StateGraph(AgentState)\n",
"\n",
"# Define the two nodes we will cycle between\n",
"workflow.add_node(\"agent\", run_agent)\n",
"workflow.add_node(\"action\", execute_tools)\n",
"\n",
"# Set the entrypoint as `agent`\n",
"# This means that this node is the first one called\n",
"workflow.set_entry_point(\"agent\")\n",
"\n",
"# We now add a conditional edge\n",
"workflow.add_conditional_edges(\n",
" # First, we define the start node. We use `agent`.\n",
" # This means these are the edges taken after the `agent` node is called.\n",
" \"agent\",\n",
" # Next, we pass in the function that will determine which node is called next.\n",
" should_continue,\n",
" # Finally we pass in a mapping.\n",
" # The keys are strings, and the values are other nodes.\n",
" # END is a special node marking that the graph should finish.\n",
" # What will happen is we will call `should_continue`, and then the output of that\n",
" # will be matched against the keys in this mapping.\n",
" # Based on which one it matches, that node will then be called.\n",
" {\n",
" # If `tools`, then we call the tool node.\n",
" \"continue\": \"action\",\n",
" # Otherwise we finish.\n",
" \"end\": END,\n",
" },\n",
")\n",
"\n",
"# We now add a normal edge from `tools` to `agent`.\n",
"# This means that after `tools` is called, `agent` node is called next.\n",
"workflow.add_edge(\"action\", \"agent\")\n",
"\n",
"# Finally, we compile it!\n",
"# This compiles it into a LangChain Runnable,\n",
"# meaning you can use it as you would any other runnable\n",
"app = workflow.compile()"
]
"source": ["from langgraph.graph import END, StateGraph, START\n\n# Define a new graph\nworkflow = StateGraph(AgentState)\n\n# Define the two nodes we will cycle between\nworkflow.add_node(\"agent\", run_agent)\nworkflow.add_node(\"action\", execute_tools)\n\n# Set the entrypoint as `agent`\n# This means that this node is the first one called\nworkflow.add_edge(START, \"agent\")\n\n# We now add a conditional edge\nworkflow.add_conditional_edges(\n # First, we define the start node. We use `agent`.\n # This means these are the edges taken after the `agent` node is called.\n \"agent\",\n # Next, we pass in the function that will determine which node is called next.\n should_continue,\n # Finally we pass in a mapping.\n # The keys are strings, and the values are other nodes.\n # END is a special node marking that the graph should finish.\n # What will happen is we will call `should_continue`, and then the output of that\n # will be matched against the keys in this mapping.\n # Based on which one it matches, that node will then be called.\n {\n # If `tools`, then we call the tool node.\n \"continue\": \"action\",\n # Otherwise we finish.\n \"end\": END,\n },\n)\n\n# We now add a normal edge from `tools` to `agent`.\n# This means that after `tools` is called, `agent` node is called next.\nworkflow.add_edge(\"action\", \"agent\")\n\n# Finally, we compile it!\n# This compiles it into a LangChain Runnable,\n# meaning you can use it as you would any other runnable\napp = workflow.compile()"]
},
{
"cell_type": "code",
@@ -325,12 +197,7 @@
]
}
],
"source": [
"inputs = {\"input\": \"what is the weather in sf\", \"chat_history\": []}\n",
"for s in app.stream(inputs):\n",
" print(list(s.values())[0])\n",
" print(\"----\")"
]
"source": ["inputs = {\"input\": \"what is the weather in sf\", \"chat_history\": []}\nfor s in app.stream(inputs):\n print(list(s.values())[0])\n print(\"----\")"]
},
{
"cell_type": "code",
@@ -338,7 +205,7 @@
"id": "2eb662bc-de7d-4a57-a3e8-2f00dcf4ff8b",
"metadata": {},
"outputs": [],
"source": []
"source": [""]
}
],
"metadata": {