Skip to content

Commit a2effee

Browse files
milanagmhassiebp
andauthored
docs: update LangGraph cookbook for current LangChain/LangGraph APIs (#3103)
Co-authored-by: Hassieb Pakzad <68423100+hassiebp@users.noreply.github.com>
1 parent 8796581 commit a2effee

2 files changed

Lines changed: 52 additions & 64 deletions

File tree

content/guides/cookbook/integration_langgraph.mdx

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -228,17 +228,24 @@ from typing import Annotated
228228
from langchain_community.tools import WikipediaQueryRun
229229
from langchain_community.utilities import WikipediaAPIWrapper
230230
from datetime import datetime
231-
from langchain.tools import Tool
231+
from langchain.tools import tool
232232

233-
# Define a tools that searches Wikipedia
234-
wikipedia_tool = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
233+
# Define a tool that searches Wikipedia
234+
_wikipedia_query = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
235+
236+
@tool("wikipedia")
237+
def wikipedia_tool(query: str) -> str:
238+
"""Search Wikipedia for the given query and return a summary."""
239+
try:
240+
return _wikipedia_query.invoke(query)
241+
except Exception as exc:
242+
return f"Wikipedia lookup failed ({exc}). Answer from your own knowledge instead."
235243

236244
# Define a new tool that returns the current datetime
237-
datetime_tool = Tool(
238-
name="Datetime",
239-
func = lambda x: datetime.now().isoformat(),
240-
description="Returns the current datetime",
241-
)
245+
@tool("current_datetime")
246+
def datetime_tool() -> str:
247+
"""Returns the current datetime."""
248+
return datetime.now().isoformat()
242249
```
243250

244251
### Helper utilities
@@ -247,29 +254,21 @@ Define a helper function below to simplify adding new agent worker nodes.
247254

248255

249256
```python
250-
from langchain.agents import AgentExecutor, create_openai_tools_agent
257+
from langchain.agents import create_agent
251258
from langchain_core.messages import BaseMessage, HumanMessage
252259
from langchain_openai import ChatOpenAI
253260

254-
def create_agent(llm: ChatOpenAI, system_prompt: str, tools: list):
261+
def create_worker_agent(llm: ChatOpenAI, system_prompt: str, tools: list):
255262
# Each worker node will be given a name and some tools.
256-
prompt = ChatPromptTemplate.from_messages(
257-
[
258-
(
259-
"system",
260-
system_prompt,
261-
),
262-
MessagesPlaceholder(variable_name="messages"),
263-
MessagesPlaceholder(variable_name="agent_scratchpad"),
264-
]
263+
return create_agent(
264+
model=llm,
265+
tools=tools,
266+
system_prompt=system_prompt,
265267
)
266-
agent = create_openai_tools_agent(llm, tools, prompt)
267-
executor = AgentExecutor(agent=agent, tools=tools)
268-
return executor
269268

270269
def agent_node(state, agent, name):
271270
result = agent.invoke(state)
272-
return {"messages": [HumanMessage(content=result["output"], name=name)]}
271+
return {"messages": [HumanMessage(content=result["messages"][-1].content, name=name)]}
273272
```
274273

275274
### Create agent supervisor
@@ -278,7 +277,6 @@ It will use function calling to choose the next worker node OR finish processing
278277

279278

280279
```python
281-
from langchain_core.output_parsers.openai_functions import JsonOutputFunctionsParser
282280
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
283281

284282
members = ["Researcher", "CurrentTime"]
@@ -292,7 +290,7 @@ system_prompt = (
292290
# Our team supervisor is an LLM node. It just picks the next agent to process and decides when the work is completed
293291
options = ["FINISH"] + members
294292

295-
# Using openai function calling can make output parsing easier for us
293+
# Using structured output can make routing easier for us
296294
function_def = {
297295
"name": "route",
298296
"description": "Select the next role.",
@@ -327,11 +325,7 @@ prompt = ChatPromptTemplate.from_messages(
327325
llm = ChatOpenAI(model="gpt-4o")
328326

329327
# Construction of the chain for the supervisor agent
330-
supervisor_chain = (
331-
prompt
332-
| llm.bind_functions(functions=[function_def], function_call="route")
333-
| JsonOutputFunctionsParser()
334-
)
328+
supervisor_chain = prompt | llm.with_structured_output(function_def)
335329
```
336330

337331
### Construct graph
@@ -354,11 +348,11 @@ class AgentState(TypedDict):
354348
next: str
355349

356350
# Add the research agent using the create_agent helper function
357-
research_agent = create_agent(llm, "You are a web researcher.", [wikipedia_tool])
351+
research_agent = create_worker_agent(llm, "You are a web researcher.", [wikipedia_tool])
358352
research_node = functools.partial(agent_node, agent=research_agent, name="Researcher")
359353

360354
# Add the time agent using the create_agent helper function
361-
currenttime_agent = create_agent(llm, "You can tell the current time at", [datetime_tool])
355+
currenttime_agent = create_worker_agent(llm, "You can tell the current time.", [datetime_tool])
362356
currenttime_node = functools.partial(agent_node, agent=currenttime_agent, name = "CurrentTime")
363357

364358
workflow = StateGraph(AgentState)

cookbook/integration_langgraph.ipynb

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -396,17 +396,24 @@
396396
"from langchain_community.tools import WikipediaQueryRun\n",
397397
"from langchain_community.utilities import WikipediaAPIWrapper\n",
398398
"from datetime import datetime\n",
399-
"from langchain.tools import Tool\n",
399+
"from langchain.tools import tool\n",
400400
"\n",
401-
"# Define a tools that searches Wikipedia\n",
402-
"wikipedia_tool = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())\n",
401+
"# Define a tool that searches Wikipedia\n",
402+
"_wikipedia_query = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())\n",
403+
"\n",
404+
"@tool(\"wikipedia\")\n",
405+
"def wikipedia_tool(query: str) -> str:\n",
406+
" \"\"\"Search Wikipedia for the given query and return a summary.\"\"\"\n",
407+
" try:\n",
408+
" return _wikipedia_query.invoke(query)\n",
409+
" except Exception as exc:\n",
410+
" return f\"Wikipedia lookup failed ({exc}). Answer from your own knowledge instead.\"\n",
403411
"\n",
404412
"# Define a new tool that returns the current datetime\n",
405-
"datetime_tool = Tool(\n",
406-
" name=\"Datetime\",\n",
407-
" func = lambda x: datetime.now().isoformat(),\n",
408-
" description=\"Returns the current datetime\",\n",
409-
")"
413+
"@tool(\"current_datetime\")\n",
414+
"def datetime_tool() -> str:\n",
415+
" \"\"\"Returns the current datetime.\"\"\"\n",
416+
" return datetime.now().isoformat()"
410417
]
411418
},
412419
{
@@ -428,29 +435,21 @@
428435
},
429436
"outputs": [],
430437
"source": [
431-
"from langchain.agents import AgentExecutor, create_openai_tools_agent\n",
438+
"from langchain.agents import create_agent\n",
432439
"from langchain_core.messages import BaseMessage, HumanMessage\n",
433440
"from langchain_openai import ChatOpenAI\n",
434441
"\n",
435-
"def create_agent(llm: ChatOpenAI, system_prompt: str, tools: list):\n",
442+
"def create_worker_agent(llm: ChatOpenAI, system_prompt: str, tools: list):\n",
436443
" # Each worker node will be given a name and some tools.\n",
437-
" prompt = ChatPromptTemplate.from_messages(\n",
438-
" [\n",
439-
" (\n",
440-
" \"system\",\n",
441-
" system_prompt,\n",
442-
" ),\n",
443-
" MessagesPlaceholder(variable_name=\"messages\"),\n",
444-
" MessagesPlaceholder(variable_name=\"agent_scratchpad\"),\n",
445-
" ]\n",
444+
" return create_agent(\n",
445+
" model=llm,\n",
446+
" tools=tools,\n",
447+
" system_prompt=system_prompt,\n",
446448
" )\n",
447-
" agent = create_openai_tools_agent(llm, tools, prompt)\n",
448-
" executor = AgentExecutor(agent=agent, tools=tools)\n",
449-
" return executor\n",
450449
"\n",
451450
"def agent_node(state, agent, name):\n",
452451
" result = agent.invoke(state)\n",
453-
" return {\"messages\": [HumanMessage(content=result[\"output\"], name=name)]}"
452+
" return {\"messages\": [HumanMessage(content=result[\"messages\"][-1].content, name=name)]}"
454453
]
455454
},
456455
{
@@ -472,7 +471,6 @@
472471
},
473472
"outputs": [],
474473
"source": [
475-
"from langchain_core.output_parsers.openai_functions import JsonOutputFunctionsParser\n",
476474
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
477475
"\n",
478476
"members = [\"Researcher\", \"CurrentTime\"]\n",
@@ -486,7 +484,7 @@
486484
"# Our team supervisor is an LLM node. It just picks the next agent to process and decides when the work is completed\n",
487485
"options = [\"FINISH\"] + members\n",
488486
"\n",
489-
"# Using openai function calling can make output parsing easier for us\n",
487+
"# Using structured output can make routing easier for us\n",
490488
"function_def = {\n",
491489
" \"name\": \"route\",\n",
492490
" \"description\": \"Select the next role.\",\n",
@@ -521,11 +519,7 @@
521519
"llm = ChatOpenAI(model=\"gpt-4o\")\n",
522520
"\n",
523521
"# Construction of the chain for the supervisor agent\n",
524-
"supervisor_chain = (\n",
525-
" prompt\n",
526-
" | llm.bind_functions(functions=[function_def], function_call=\"route\")\n",
527-
" | JsonOutputFunctionsParser()\n",
528-
")"
522+
"supervisor_chain = prompt | llm.with_structured_output(function_def)"
529523
]
530524
},
531525
{
@@ -561,11 +555,11 @@
561555
" next: str\n",
562556
"\n",
563557
"# Add the research agent using the create_agent helper function\n",
564-
"research_agent = create_agent(llm, \"You are a web researcher.\", [wikipedia_tool])\n",
558+
"research_agent = create_worker_agent(llm, \"You are a web researcher.\", [wikipedia_tool])\n",
565559
"research_node = functools.partial(agent_node, agent=research_agent, name=\"Researcher\")\n",
566560
"\n",
567561
"# Add the time agent using the create_agent helper function\n",
568-
"currenttime_agent = create_agent(llm, \"You can tell the current time at\", [datetime_tool])\n",
562+
"currenttime_agent = create_worker_agent(llm, \"You can tell the current time.\", [datetime_tool])\n",
569563
"currenttime_node = functools.partial(agent_node, agent=currenttime_agent, name = \"CurrentTime\")\n",
570564
"\n",
571565
"workflow = StateGraph(AgentState)\n",

0 commit comments

Comments
 (0)