mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-17 21:25:46 +02:00
update notebooks
This commit is contained in:
@@ -68,7 +68,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": 1,
|
||||
"id": "f04c6778-403b-4b49-9b93-678e910d5cec",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -97,7 +97,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": 2,
|
||||
"id": "c4823dd9-26bd-4e1a-8117-b97b2860211a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -106,11 +106,10 @@
|
||||
"from langchain_core.messages import BaseMessage, HumanMessage\n",
|
||||
"from langchain_openai import ChatOpenAI\n",
|
||||
"\n",
|
||||
"from langgraph.graph import END, StateGraph\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def create_worker_node(\n",
|
||||
" workflow: StateGraph, name: str, llm: ChatOpenAI, tools: list, system_prompt: str\n",
|
||||
"def create_agent(\n",
|
||||
" llm: ChatOpenAI, tools: list, system_prompt: str\n",
|
||||
"):\n",
|
||||
" # Each worker node will be given a name and some tools.\n",
|
||||
" prompt = ChatPromptTemplate.from_messages(\n",
|
||||
@@ -135,67 +134,38 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a07d507f-34d1-4f1b-8dde-5e58d17b2166",
|
||||
"id": "b7c302b0-cd57-4913-986f-5dc7d6d77386",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Construct Graph\n",
|
||||
"\n",
|
||||
"We're ready to start building the graph. Below, define the state and worker nodes using the function we just defined."
|
||||
"We can also define a function that we will use to be the nodes in the graph - it takes care of converting the agent response to a human message. This is important because that is how we will add it the global state of the graph"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "6a430af7-8fce-4e66-ba9e-d940c1bc48e8",
|
||||
"execution_count": 3,
|
||||
"id": "80862241-a1a7-4726-bce5-f867b233832e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import operator\n",
|
||||
"from typing import Annotated, Any, Dict, List, Optional, Sequence, TypedDict\n",
|
||||
"\n",
|
||||
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# The agent state is the input to each node in the graph\n",
|
||||
"class AgentState(TypedDict):\n",
|
||||
" # The annotation tells the graph that new messages will always\n",
|
||||
" # be added to the current states\n",
|
||||
" messages: Annotated[Sequence[BaseMessage], operator.add]\n",
|
||||
" # The 'next' field indicates where to route to next\n",
|
||||
" next: str\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"workflow = StateGraph(AgentState)\n",
|
||||
"\n",
|
||||
"llm = ChatOpenAI(model=\"gpt-4-1106-preview\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"create_worker_node(\n",
|
||||
" workflow, \"Researcher\", llm, [tavily_tool], \"You are a web researcher.\"\n",
|
||||
")\n",
|
||||
"# NOTE: THIS PERFORMS ARBITRARY CODE EXECUTION. PROCEED WITH CAUTION\n",
|
||||
"create_worker_node(\n",
|
||||
" workflow,\n",
|
||||
" \"Coder\",\n",
|
||||
" llm,\n",
|
||||
" [python_repl_tool],\n",
|
||||
" \"You may generate safe python code to analyze data \"\n",
|
||||
" \"and generate charts using matplotlib.\",\n",
|
||||
")"
|
||||
"def agent_node(state, agent, name):\n",
|
||||
" result = agent.invoke(state)\n",
|
||||
" return {\"messages\": [HumanMessage(content=result[\"output\"], name=name)]}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d6374825-912f-40c9-910d-afa267b401bf",
|
||||
"id": "d32962d2-5487-496d-aefc-2a3b0d194985",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Almost done, now create create the team supervisor. It will use function calling to choose the next worker node OR finish processing."
|
||||
"### Create Agent Supervisor\n",
|
||||
"\n",
|
||||
"It will use function calling to choose the next worker node OR finish processing."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "17c108a0-6dc3-46fd-a5e6-a1fcfad5458a",
|
||||
"id": "311f0a58-b425-4496-adac-dc4cd8ffb912",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -249,6 +219,57 @@
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a07d507f-34d1-4f1b-8dde-5e58d17b2166",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Construct Graph\n",
|
||||
"\n",
|
||||
"We're ready to start building the graph. Below, define the state and worker nodes using the function we just defined."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "6a430af7-8fce-4e66-ba9e-d940c1bc48e8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import operator\n",
|
||||
"from typing import Annotated, Any, Dict, List, Optional, Sequence, TypedDict\n",
|
||||
"import functools\n",
|
||||
"\n",
|
||||
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
|
||||
"from langgraph.graph import StateGraph, END\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# The agent state is the input to each node in the graph\n",
|
||||
"class AgentState(TypedDict):\n",
|
||||
" # The annotation tells the graph that new messages will always\n",
|
||||
" # be added to the current states\n",
|
||||
" messages: Annotated[Sequence[BaseMessage], operator.add]\n",
|
||||
" # The 'next' field indicates where to route to next\n",
|
||||
" next: str\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"llm = ChatOpenAI(model=\"gpt-4-1106-preview\")\n",
|
||||
"\n",
|
||||
"research_agent = create_agent(llm, [tavily_tool], \"You are a web researcher.\")\n",
|
||||
"research_node = functools.partial(agent_node, agent=research_agent, name=\"Researcher\")\n",
|
||||
"\n",
|
||||
"# NOTE: THIS PERFORMS ARBITRARY CODE EXECUTION. PROCEED WITH CAUTION\n",
|
||||
"code_agent = create_agent(llm, [python_repl_tool], \"You may generate safe python code to analyze data and generate charts using matplotlib.\")\n",
|
||||
"code_node = functools.partial(agent_node, agent=code_agent, name=\"Coder\")\n",
|
||||
"\n",
|
||||
"workflow = StateGraph(AgentState)\n",
|
||||
"workflow.add_node(\"Researcher\", research_node)\n",
|
||||
"workflow.add_node(\"Coder\", code_node)\n",
|
||||
"workflow.add_node(\"supervisor\", supervisor_chain)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2c1593d5-39f7-4819-96d2-4ad7d7991d72",
|
||||
@@ -259,14 +280,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 13,
|
||||
"id": "14778e86-077b-4e6a-893c-400e59b0cdbf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"workflow.add_node(\"supervisor\", supervisor_chain)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"for member in members:\n",
|
||||
" # We want our workers to ALWAYS \"report back\" to the supervisor when done\n",
|
||||
" workflow.add_edge(member, \"supervisor\")\n",
|
||||
@@ -293,10 +311,18 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 14,
|
||||
"id": "56ba78e9-d9c1-457c-a073-d606d5d3e013",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'supervisor': {'next': 'Coder'}}\n",
|
||||
"----\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
@@ -308,30 +334,29 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"================================\u001b[1m Human Message \u001b[0m=================================\n",
|
||||
"\n",
|
||||
"The code `print('Hello, World!')` was executed, and the output is:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"Hello, World!\n",
|
||||
"```\n"
|
||||
"{'Coder': {'messages': [HumanMessage(content=\"The code `print('Hello, World!')` was executed, and it printed `Hello, World!` to the terminal.\", name='Coder')]}}\n",
|
||||
"----\n",
|
||||
"{'supervisor': {'next': 'FINISH'}}\n",
|
||||
"----\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"results = graph.invoke(\n",
|
||||
"for s in graph.stream(\n",
|
||||
" {\n",
|
||||
" \"messages\": [\n",
|
||||
" HumanMessage(content=\"Code hello world and print it to the terminal\")\n",
|
||||
" ]\n",
|
||||
" }\n",
|
||||
")\n",
|
||||
"results[\"messages\"][-1].pretty_print()"
|
||||
"):\n",
|
||||
" if \"__end__\" not in s:\n",
|
||||
" print(s)\n",
|
||||
" print(\"----\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"execution_count": 16,
|
||||
"id": "45a92dfd-0e11-47f5-aad4-b68d24990e34",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -339,51 +364,27 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"================================\u001b[1m Human Message \u001b[0m=================================\n",
|
||||
"\n",
|
||||
"# Research Report on Pikas\n",
|
||||
"\n",
|
||||
"Pikas are small, mountain-dwelling mammals that are closely related to rabbits. They are known for their distinctive chirps and typically inhabit boulder fields at high elevations, up to 14,000 feet in treeless slopes like those found in the Southern Rockies. These animals are recognized for their ability to adapt to some of the most inhospitable climates.\n",
|
||||
"\n",
|
||||
"## Climate Change Impact\n",
|
||||
"\n",
|
||||
"Pikas have been a topic of interest in climate change research due to their sensitivity to high temperatures and reliance on cold habitats. They have historically responded to climate shifts by moving to higher elevations or latitudes to find suitable cooler environments. For instance, pikas were once found in the Appalachian Mountains and even in the Mojave Desert, but as the Earth's climate warmed, they moved to cooler, high-elevation areas where they live today.\n",
|
||||
"\n",
|
||||
"Recent studies suggest that pikas are showing remarkable adaptability to climate change. Despite predictions that they might become endangered due to rising temperatures, these animals are displaying resilience. Some research indicates that pikas can adjust certain genes to make better use of oxygen in higher altitudes where the air is thinner, which could be a potential hope for their survival as climate change drives them to higher elevations.\n",
|
||||
"\n",
|
||||
"However, there have been reports of pikas disappearing from parts of the Great Basin, and in Colorado, pikas have retracted upslope by about 1,160 feet. It's been noted that while climate change may be a factor, it might not be the sole cause for these local disappearances.\n",
|
||||
"\n",
|
||||
"## Adaptation Strategies\n",
|
||||
"\n",
|
||||
"Pikas exhibit several interesting behaviors that help them cope with their challenging environment. During the summer, they engage in activities like \"making hay\" — collecting and storing vegetation in preparation for the harsh winters. Their diet and caching behavior are essential for their survival during the months when food is scarce.\n",
|
||||
"\n",
|
||||
"## Conservation and Research\n",
|
||||
"\n",
|
||||
"Conservationists and scientists continue to study pikas to understand their adaptation mechanisms and how they might inform broader climate change mitigation strategies. For example, studies have been conducted on pikas at different elevations to observe genetic changes and their effects on adaptation. Such research is crucial for predicting the future of pikas and potentially other species affected by climate change.\n",
|
||||
"\n",
|
||||
"## Conclusion\n",
|
||||
"\n",
|
||||
"Pikas serve as an important indicator species for the impacts of climate change on wildlife. Their ability to adapt to changing climates offers hope and also highlights the importance of understanding genetic adaptability in the face of environmental challenges. Conservation efforts and further research are essential to ensure the survival of pikas and to learn from their resilience.\n",
|
||||
"\n",
|
||||
"### Sources\n",
|
||||
"- [The Conversation: Pikas are adapting to climate change remarkably well](https://theconversation.com/pikas-are-adapting-to-climate-change-remarkably-well-contrary-to-many-predictions-150726)\n",
|
||||
"- [Stanford Sustainability: It's in the genes – potential hope for pikas hit by climate change](https://sustainability.stanford.edu/news/its-genes-potential-hope-pikas-hit-climate-change)\n",
|
||||
"- [Colorado Sun: Colorado pika population and climate change](https://coloradosun.com/2023/08/27/colorado-pika-population-climate-change/)\n",
|
||||
"- [PetaPixel: Photographing the American Pika – a tiny indicator of climate change](https://petapixel.com/2022/01/03/photographing-the-american-pika-a-tiny-indicator-of-climate-change/)\n",
|
||||
"- [The Wildlife Society: Can pikas survive climate change after all?](https://wildlife.org/can-pikas-survive-climate-change-after-all/)\n"
|
||||
"{'supervisor': {'next': 'Researcher'}}\n",
|
||||
"----\n",
|
||||
"{'Researcher': {'messages': [HumanMessage(content='## Research Report on Pikas\\n\\nPikas are small, mountain-dwelling mammals native to Asia and North America. They are characterized by their short limbs, rounded ears, and stout bodies. Unlike rodents, with which they are sometimes confused, pikas are more closely related to rabbits and hares, belonging to the order Lagomorpha.\\n\\n### Physical Description\\nPikas are typically 15 to 23 cm (5.9 to 9.1 inches) in body length. They have an even coat of fur, no external tail, and resemble their close relatives, the rabbits, but with short, rounded ears. Their thick fur and small ears are adaptations to their cold habitats.\\n\\n### Habitat and Distribution\\nPikas inhabit mountainous regions where they have adapted to life in rocky terrains. These creatures can be found at high altitudes, with the large-eared pika of the Himalayas living at elevations of more than 6,000 meters.\\n\\n### Diet and Behavior\\nPikas are herbivorous and primarily feed on plants. They are known for their diligent behavior of collecting and storing food in their tunnels for winter. During the warmer months, pikas spend their days gathering grass in montane meadows and creating hay piles. These animals are also remarkable for their distinctive vocalizations used for communication.\\n\\n### Reproduction and Lifespan\\nDetails on pika reproduction and lifespan were not provided in the immediate search results, but like many small mammals, pikas would typically have a breeding season and a relatively short lifespan in the wild.\\n\\n### Conservation\\nPikas are currently facing challenges due to environmental changes. As their habitats are affected by the expansion of agriculture and the increasing temperatures due to climate change, pikas may find themselves in competition for resources. They are notably heat intolerant, which makes them particularly vulnerable to global warming.\\n\\n### Conclusion\\nPikas are fascinating creatures with unique adaptations to their high-altitude environments. Their role in the ecosystem, distinctive behaviors, and close relation to the rabbit make them an interesting subject for further study, especially in the context of environmental conservation.\\n\\n**Sources:**\\n- [Animals.net - Pika](https://animals.net/pika/)\\n- [OneKindPlanet - American Pika](https://www.onekindplanet.org/animal/american-pika/)\\n- [Facts.net - 12 Facts About Pika](https://facts.net/nature/animals/12-facts-about-pika/)\\n- [Wikipedia - Pika](https://en.wikipedia.org/wiki/Pika)\\n- [HowStuffWorks - Pikas](https://animals.howstuffworks.com/mammals/pika.htm)', name='Researcher')]}}\n",
|
||||
"----\n",
|
||||
"{'supervisor': {'next': 'FINISH'}}\n",
|
||||
"----\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"results = graph.invoke(\n",
|
||||
"for s in graph.stream(\n",
|
||||
" {\n",
|
||||
" \"messages\": [\n",
|
||||
" HumanMessage(content=\"Write a brief research report on pikas.\")\n",
|
||||
" ]\n",
|
||||
" },\n",
|
||||
" {\"recursion_limit\": 100},\n",
|
||||
")\n",
|
||||
"results[\"messages\"][-1].pretty_print()"
|
||||
"):\n",
|
||||
" if \"__end__\" not in s:\n",
|
||||
" print(s)\n",
|
||||
" print(\"----\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -411,7 +412,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.2"
|
||||
"version": "3.11.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": 5,
|
||||
"id": "e09fb60f-1aac-455b-b67d-8d2e4ccfd747",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -100,13 +100,10 @@
|
||||
"from langgraph.graph import END, StateGraph\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def create_worker_agent(\n",
|
||||
" graph_builder: StateGraph,\n",
|
||||
" name: str,\n",
|
||||
"def create_agent(\n",
|
||||
" llm: ChatOpenAI,\n",
|
||||
" tools: list,\n",
|
||||
" system_prompt: str,\n",
|
||||
" prelude: Optional[Union[Runnable, Callable]] = None, # Optional required steps\n",
|
||||
") -> str:\n",
|
||||
" \"\"\"Create a function-calling agent and add it to the graph.\"\"\"\n",
|
||||
" system_prompt += \"\\nWork autonomously according to your specialty, using the tools available to you.\"\n",
|
||||
@@ -125,22 +122,25 @@
|
||||
" )\n",
|
||||
" agent = create_openai_functions_agent(llm, tools, prompt)\n",
|
||||
" executor = AgentExecutor(agent=agent, tools=tools)\n",
|
||||
" chain = executor | (\n",
|
||||
" lambda x: {\"messages\": [HumanMessage(content=x[\"output\"], name=name)]}\n",
|
||||
" )\n",
|
||||
" if prelude is not None:\n",
|
||||
" chain = prelude | chain\n",
|
||||
" graph_builder.add_node(name, chain)\n",
|
||||
" return name\n",
|
||||
" return executor\n",
|
||||
" # chain = executor | (\n",
|
||||
" # lambda x: {\"messages\": [HumanMessage(content=x[\"output\"], name=name)]}\n",
|
||||
" # )\n",
|
||||
" # if prelude is not None:\n",
|
||||
" # chain = prelude | chain\n",
|
||||
" # graph_builder.add_node(name, chain)\n",
|
||||
" # return name\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def agent_node(state, agent, name):\n",
|
||||
" result = agent.invoke(state)\n",
|
||||
" return {\"messages\": [HumanMessage(content=result[\"output\"], name=name)]}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def create_team_supervisor(\n",
|
||||
" graph_builder: StateGraph, llm: ChatOpenAI, system_prompt: str\n",
|
||||
" llm: ChatOpenAI, system_prompt, members\n",
|
||||
") -> str:\n",
|
||||
" \"\"\"An LLM-based router.\"\"\"\n",
|
||||
" supervisor_id = uuid.uuid4().hex[:4]\n",
|
||||
" supervisor_name = f\"supervisor - {supervisor_id}\"\n",
|
||||
" members = list(graph_builder.nodes)\n",
|
||||
" options = [\"FINISH\"] + members\n",
|
||||
" function_def = {\n",
|
||||
" \"name\": \"route\",\n",
|
||||
@@ -175,16 +175,17 @@
|
||||
" | llm.bind_functions(functions=[function_def], function_call=\"route\")\n",
|
||||
" | JsonOutputFunctionsParser()\n",
|
||||
" )\n",
|
||||
" graph_builder.add_node(supervisor_name, chain)\n",
|
||||
" conditional_map = {k: k for k in members}\n",
|
||||
" conditional_map[\"FINISH\"] = END\n",
|
||||
" return chain\n",
|
||||
" # graph_builder.add_node(supervisor_name, chain)\n",
|
||||
" # conditional_map = {k: k for k in members}\n",
|
||||
" # conditional_map[\"FINISH\"] = END\n",
|
||||
"\n",
|
||||
" for member in members:\n",
|
||||
" graph_builder.add_edge(member, supervisor_name)\n",
|
||||
" graph_builder.add_conditional_edges(\n",
|
||||
" supervisor_name, lambda x: x[\"next\"], conditional_map\n",
|
||||
" )\n",
|
||||
" return supervisor_name"
|
||||
" # for member in members:\n",
|
||||
" # graph_builder.add_edge(member, supervisor_name)\n",
|
||||
" # graph_builder.add_conditional_edges(\n",
|
||||
" # supervisor_name, lambda x: x[\"next\"], conditional_map\n",
|
||||
" # )\n",
|
||||
" # return supervisor_name"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -203,7 +204,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": 6,
|
||||
"id": "f04c6778-403b-4b49-9b93-678e910d5cec",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -234,7 +235,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 11,
|
||||
"id": "53db0c78-e357-48ba-ae5f-3fc04735a3b7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -244,6 +245,7 @@
|
||||
"\n",
|
||||
"from langchain_core.messages import AIMessage, BaseMessage, HumanMessage\n",
|
||||
"from langchain_openai.chat_models import ChatOpenAI\n",
|
||||
"import functools\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Research team graph state\n",
|
||||
@@ -258,47 +260,56 @@
|
||||
" next: str\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"research_graph = StateGraph(State)\n",
|
||||
"llm = ChatOpenAI(model=\"gpt-4-1106-preview\")\n",
|
||||
"create_worker_agent(\n",
|
||||
" research_graph,\n",
|
||||
" \"Search\",\n",
|
||||
" llm,\n",
|
||||
" [tavily_tool],\n",
|
||||
" \"You are a research assistant who can search for up-to-date info\"\n",
|
||||
" \" using the tavily search engine.\",\n",
|
||||
")\n",
|
||||
"create_worker_agent(\n",
|
||||
" research_graph,\n",
|
||||
" \"Web Scraper\",\n",
|
||||
" llm,\n",
|
||||
" [scrape_webpages],\n",
|
||||
" \"You are a research assistant who can scrape\"\n",
|
||||
" \" specified urls for more detailed information using\"\n",
|
||||
" \" the scrape_webpages function.\",\n",
|
||||
")\n",
|
||||
"supervisor_node = create_team_supervisor(\n",
|
||||
" research_graph,\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"search_agent = create_agent(llm, [tavily_tool], \"You are a research assistant who can search for up-to-date info using the tavily search engine.\")\n",
|
||||
"search_node = functools.partial(agent_node, agent=search_agent, name=\"Search\")\n",
|
||||
"\n",
|
||||
"research_agent = create_agent(llm, [scrape_webpages], \"You are a research assistant who can scrape specified urls for more detailed information using the scrape_webpages function.\")\n",
|
||||
"research_node = functools.partial(agent_node, agent=research_agent, name=\"Web Scraper\")\n",
|
||||
"\n",
|
||||
"supervisor_agent = create_team_supervisor(\n",
|
||||
" llm,\n",
|
||||
" \"You are a supervisor tasked with managing a conversation between the\"\n",
|
||||
" \" following workers: {team_members}. Given the following user request,\"\n",
|
||||
" \" following workers: Search, Web Scraper. Given the following user request,\"\n",
|
||||
" \" respond with the worker to act next. Each worker will perform a\"\n",
|
||||
" \" task and respond with their results and status. When finished,\"\n",
|
||||
" \" respond with FINISH.\",\n",
|
||||
" [\"Search\", \"Web Scraper\"],\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"research_graph.set_entry_point(supervisor_node)\n",
|
||||
"\n",
|
||||
"research_graph = StateGraph(State)\n",
|
||||
"research_graph.add_node(\"Search\", search_node)\n",
|
||||
"research_graph.add_node(\"Web Scraper\", research_node)\n",
|
||||
"research_graph.add_node(\"supervisor\", supervisor_agent)\n",
|
||||
"\n",
|
||||
"research_graph.add_edge(\"Search\", \"supervisor\")\n",
|
||||
"research_graph.add_edge(\"Web Scraper\", \"supervisor\")\n",
|
||||
"research_graph.add_conditional_edges(\n",
|
||||
" \"supervisor\",\n",
|
||||
" lambda x: x[\"next\"],\n",
|
||||
" {\n",
|
||||
" \"Search\": \"Search\",\n",
|
||||
" \"Web Scraper\": \"Web Scraper\",\n",
|
||||
" \"FINISH\": END\n",
|
||||
" }\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"research_graph.set_entry_point(\"supervisor\")\n",
|
||||
"\n",
|
||||
"chain = research_graph.compile()\n",
|
||||
"\n",
|
||||
"# The following functions interoperate between the top level graph state\n",
|
||||
"# and the state of the research sub-graph\n",
|
||||
"# this makes it so that the states of each graph don't get intermixed\n",
|
||||
"def enter_chain(message: str, members: Optional[list] = None):\n",
|
||||
"def enter_chain(message: str):\n",
|
||||
" results = {\n",
|
||||
" \"messages\": [HumanMessage(content=message)],\n",
|
||||
" }\n",
|
||||
" if members:\n",
|
||||
" results[\"team_members\"] = \"\\n\".join(sorted(members))\n",
|
||||
" return results\n",
|
||||
"\n",
|
||||
"\n",
|
||||
@@ -307,12 +318,47 @@
|
||||
"\n",
|
||||
"\n",
|
||||
"research_chain = (\n",
|
||||
" functools.partial(enter_chain, members=research_graph.nodes)\n",
|
||||
" | research_graph.compile()\n",
|
||||
" enter_chain\n",
|
||||
" | chain\n",
|
||||
" | return_final_response\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "912b0604-a178-4246-a36f-2dedae606680",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "GraphRecursionError",
|
||||
"evalue": "Recursion limit of 25 reachedwithout hitting a stop condition. You can increase the limitby setting the `recursion_limit` config key.",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[0;31mGraphRecursionError\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[0;32mIn[12], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43ms\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mresearch_chain\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mwhat is temperature in SF right now?\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[1;32m 2\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m__end__\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43ms\u001b[49m\u001b[43m:\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mprint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43ms\u001b[49m\u001b[43m)\u001b[49m\n",
|
||||
"File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/base.py:2416\u001b[0m, in \u001b[0;36mRunnableSequence.stream\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 2410\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mstream\u001b[39m(\n\u001b[1;32m 2411\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 2412\u001b[0m \u001b[38;5;28minput\u001b[39m: Input,\n\u001b[1;32m 2413\u001b[0m config: Optional[RunnableConfig] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 2414\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Optional[Any],\n\u001b[1;32m 2415\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Iterator[Output]:\n\u001b[0;32m-> 2416\u001b[0m \u001b[38;5;28;01myield from\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtransform(\u001b[38;5;28miter\u001b[39m([\u001b[38;5;28minput\u001b[39m]), config, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
|
||||
"File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/base.py:2403\u001b[0m, in \u001b[0;36mRunnableSequence.transform\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 2397\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mtransform\u001b[39m(\n\u001b[1;32m 2398\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 2399\u001b[0m \u001b[38;5;28minput\u001b[39m: Iterator[Input],\n\u001b[1;32m 2400\u001b[0m config: Optional[RunnableConfig] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 2401\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Optional[Any],\n\u001b[1;32m 2402\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Iterator[Output]:\n\u001b[0;32m-> 2403\u001b[0m \u001b[38;5;28;01myield from\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_transform_stream_with_config(\n\u001b[1;32m 2404\u001b[0m \u001b[38;5;28minput\u001b[39m,\n\u001b[1;32m 2405\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_transform,\n\u001b[1;32m 2406\u001b[0m patch_config(config, run_name\u001b[38;5;241m=\u001b[39m(config \u001b[38;5;129;01mor\u001b[39;00m {})\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_name\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mname),\n\u001b[1;32m 2407\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[1;32m 2408\u001b[0m )\n",
|
||||
"File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/base.py:1497\u001b[0m, in \u001b[0;36mRunnable._transform_stream_with_config\u001b[0;34m(self, input, transformer, config, run_type, **kwargs)\u001b[0m\n\u001b[1;32m 1495\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 1496\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m-> 1497\u001b[0m chunk: Output \u001b[38;5;241m=\u001b[39m \u001b[43mcontext\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43miterator\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# type: ignore\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[38;5;28;01myield\u001b[39;00m chunk\n\u001b[1;32m 1499\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m final_output_supported:\n",
|
||||
"File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/base.py:2367\u001b[0m, in \u001b[0;36mRunnableSequence._transform\u001b[0;34m(self, input, run_manager, config)\u001b[0m\n\u001b[1;32m 2358\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m step \u001b[38;5;129;01min\u001b[39;00m steps:\n\u001b[1;32m 2359\u001b[0m final_pipeline \u001b[38;5;241m=\u001b[39m step\u001b[38;5;241m.\u001b[39mtransform(\n\u001b[1;32m 2360\u001b[0m final_pipeline,\n\u001b[1;32m 2361\u001b[0m patch_config(\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 2364\u001b[0m ),\n\u001b[1;32m 2365\u001b[0m )\n\u001b[0;32m-> 2367\u001b[0m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43moutput\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mfinal_pipeline\u001b[49m\u001b[43m:\u001b[49m\n\u001b[1;32m 2368\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43moutput\u001b[49m\n",
|
||||
"File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/base.py:3435\u001b[0m, in \u001b[0;36mRunnableLambda.transform\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 3428\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mtransform\u001b[39m(\n\u001b[1;32m 3429\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 3430\u001b[0m \u001b[38;5;28minput\u001b[39m: Iterator[Input],\n\u001b[1;32m 3431\u001b[0m config: Optional[RunnableConfig] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 3432\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Optional[Any],\n\u001b[1;32m 3433\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Iterator[Output]:\n\u001b[1;32m 3434\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfunc\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m-> 3435\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43moutput\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_transform_stream_with_config\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 3436\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3437\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_transform\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3438\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_config\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfunc\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3439\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3440\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[1;32m 3441\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43moutput\u001b[49m\n\u001b[1;32m 3442\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n",
|
||||
"File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/base.py:1497\u001b[0m, in \u001b[0;36mRunnable._transform_stream_with_config\u001b[0;34m(self, input, transformer, config, run_type, **kwargs)\u001b[0m\n\u001b[1;32m 1495\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 1496\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m-> 1497\u001b[0m chunk: Output \u001b[38;5;241m=\u001b[39m context\u001b[38;5;241m.\u001b[39mrun(\u001b[38;5;28mnext\u001b[39m, iterator) \u001b[38;5;66;03m# type: ignore\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[38;5;28;01myield\u001b[39;00m chunk\n\u001b[1;32m 1499\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m final_output_supported:\n",
|
||||
"File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/base.py:3380\u001b[0m, in \u001b[0;36mRunnableLambda._transform\u001b[0;34m(self, input, run_manager, config, **kwargs)\u001b[0m\n\u001b[1;32m 3372\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_transform\u001b[39m(\n\u001b[1;32m 3373\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 3374\u001b[0m \u001b[38;5;28minput\u001b[39m: Iterator[Input],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 3377\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any,\n\u001b[1;32m 3378\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Iterator[Output]:\n\u001b[1;32m 3379\u001b[0m final: Optional[Input] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m-> 3380\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43michunk\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m:\u001b[49m\n\u001b[1;32m 3381\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mfinal\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mis\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m:\u001b[49m\n\u001b[1;32m 3382\u001b[0m \u001b[43m \u001b[49m\u001b[43mfinal\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43michunk\u001b[49m\n",
|
||||
"File \u001b[0;32m~/workplace/permchain/langgraph/pregel/__init__.py:567\u001b[0m, in \u001b[0;36mPregel.transform\u001b[0;34m(self, input, config, output_keys, input_keys, **kwargs)\u001b[0m\n\u001b[1;32m 558\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mtransform\u001b[39m(\n\u001b[1;32m 559\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 560\u001b[0m \u001b[38;5;28minput\u001b[39m: Iterator[Union[\u001b[38;5;28mdict\u001b[39m[\u001b[38;5;28mstr\u001b[39m, Any], Any]],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 565\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any,\n\u001b[1;32m 566\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Iterator[Union[\u001b[38;5;28mdict\u001b[39m[\u001b[38;5;28mstr\u001b[39m, Any], Any]]:\n\u001b[0;32m--> 567\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mchunk\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_transform_stream_with_config\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 568\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 569\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_transform\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 570\u001b[0m \u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 571\u001b[0m \u001b[43m \u001b[49m\u001b[43moutput_keys\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moutput_keys\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 572\u001b[0m \u001b[43m \u001b[49m\u001b[43minput_keys\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minput_keys\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 573\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 574\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[1;32m 575\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mchunk\u001b[49m\n",
|
||||
"File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/base.py:1497\u001b[0m, in \u001b[0;36mRunnable._transform_stream_with_config\u001b[0;34m(self, input, transformer, config, run_type, **kwargs)\u001b[0m\n\u001b[1;32m 1495\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 1496\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m-> 1497\u001b[0m chunk: Output \u001b[38;5;241m=\u001b[39m context\u001b[38;5;241m.\u001b[39mrun(\u001b[38;5;28mnext\u001b[39m, iterator) \u001b[38;5;66;03m# type: ignore\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[38;5;28;01myield\u001b[39;00m chunk\n\u001b[1;32m 1499\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m final_output_supported:\n",
|
||||
"File \u001b[0;32m~/workplace/permchain/langgraph/pregel/__init__.py:299\u001b[0m, in \u001b[0;36mPregel._transform\u001b[0;34m(self, input, run_manager, config, input_keys, output_keys)\u001b[0m\n\u001b[1;32m 297\u001b[0m \u001b[38;5;28;01mbreak\u001b[39;00m\n\u001b[1;32m 298\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m step \u001b[38;5;241m==\u001b[39m config[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrecursion_limit\u001b[39m\u001b[38;5;124m\"\u001b[39m]:\n\u001b[0;32m--> 299\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m GraphRecursionError(\n\u001b[1;32m 300\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRecursion limit of \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mconfig[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrecursion_limit\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m reached\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 301\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mwithout hitting a stop condition. You can increase the limit\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 302\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mby setting the `recursion_limit` config key.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 303\u001b[0m )\n\u001b[1;32m 305\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdebug:\n\u001b[1;32m 306\u001b[0m print_step_start(step, next_tasks)\n",
|
||||
"\u001b[0;31mGraphRecursionError\u001b[0m: Recursion limit of 25 reachedwithout hitting a stop condition. You can increase the limitby setting the `recursion_limit` config key."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for s in research_chain.stream(\"what is temperature in SF right now?\"):\n",
|
||||
" if \"__end__\" not in s:\n",
|
||||
" print(s)\n",
|
||||
" print(\"---\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "749b99ab-f6f0-4c5d-a90b-10102465d186",
|
||||
@@ -634,7 +680,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.2"
|
||||
"version": "3.11.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user