mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-11 04:07:52 +02:00
docs(agents): use list of messages format (#4378)
This commit is contained in:
@@ -29,7 +29,9 @@ agent = create_react_agent(
|
||||
)
|
||||
|
||||
# Run the agent
|
||||
agent.invoke({"messages": "what is the weather in sf"})
|
||||
agent.invoke(
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]}
|
||||
)
|
||||
```
|
||||
|
||||
1. Define a tool for the agent to use. Tools can be defined as vanilla Python functions. For more advanced tool usage and customization, check the [tools](./tools.md) page.
|
||||
@@ -85,7 +87,7 @@ agent = create_react_agent(
|
||||
)
|
||||
|
||||
agent.invoke(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -113,7 +115,7 @@ agent = create_react_agent(
|
||||
)
|
||||
|
||||
agent.invoke(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
config={"configurable": {"user_name": "John Smith"}}
|
||||
)
|
||||
@@ -150,12 +152,12 @@ agent = create_react_agent(
|
||||
# highlight-next-line
|
||||
config = {"configurable": {"thread_id": "1"}}
|
||||
sf_response = agent.invoke(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
config # (2)!
|
||||
)
|
||||
ny_response = agent.invoke(
|
||||
{"messages": "what about new york?"},
|
||||
{"messages": [{"role": "user", "content": "what about new york?"}]},
|
||||
# highlight-next-line
|
||||
config
|
||||
)
|
||||
@@ -189,7 +191,9 @@ agent = create_react_agent(
|
||||
response_format=WeatherResponse # (1)!
|
||||
)
|
||||
|
||||
response = agent.invoke({"messages": "what is the weather in sf"})
|
||||
response = agent.invoke(
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]}
|
||||
)
|
||||
|
||||
# highlight-next-line
|
||||
response["structured_response"]
|
||||
|
||||
@@ -36,7 +36,7 @@ for this purpose:
|
||||
|
||||
```python
|
||||
agent.invoke(
|
||||
{"messages": "hi!"},
|
||||
{"messages": [{"role": "user", "content": "hi!"}]},
|
||||
# highlight-next-line
|
||||
config={"configurable": {"user_id": "user_123"}}
|
||||
)
|
||||
@@ -183,7 +183,7 @@ Tools can access context through special parameter **annotations**.
|
||||
)
|
||||
|
||||
agent.invoke(
|
||||
{"messages": "look up user information"},
|
||||
{"messages": [{"role": "user", "content": "look up user information"}]},
|
||||
# highlight-next-line
|
||||
config={"configurable": {"user_id": "user_123"}}
|
||||
)
|
||||
@@ -278,7 +278,7 @@ agent = create_react_agent(
|
||||
)
|
||||
|
||||
agent.invoke(
|
||||
{"messages": "greet the user"},
|
||||
{"messages": [{"role": "user", "content": "greet the user"}]},
|
||||
# highlight-next-line
|
||||
config={"configurable": {"user_id": "user_123"}}
|
||||
)
|
||||
|
||||
@@ -70,7 +70,7 @@ config = {
|
||||
}
|
||||
|
||||
for chunk in agent.stream(
|
||||
{"messages": "book a stay at McKittrick hotel"},
|
||||
{"messages": [{"role": "user", "content": "book a stay at McKittrick hotel"}]},
|
||||
# highlight-next-line
|
||||
config
|
||||
):
|
||||
@@ -194,7 +194,7 @@ config = {"configurable": {"thread_id": "1"}}
|
||||
|
||||
# Run the agent
|
||||
for chunk in agent.stream(
|
||||
{"messages": "book a stay at McKittrick hotel"},
|
||||
{"messages": [{"role": "user", "content": "book a stay at McKittrick hotel"}]},
|
||||
# highlight-next-line
|
||||
config
|
||||
):
|
||||
|
||||
@@ -40,8 +40,12 @@ async with MultiServerMCPClient(
|
||||
# highlight-next-line
|
||||
client.get_tools()
|
||||
)
|
||||
math_response = await agent.ainvoke({"messages": "what's (3 + 5) x 12?"})
|
||||
weather_response = await agent.ainvoke({"messages": "what is the weather in nyc?"})
|
||||
math_response = await agent.ainvoke(
|
||||
{"messages": [{"role": "user", "content": "what's (3 + 5) x 12?"}]}
|
||||
)
|
||||
weather_response = await agent.ainvoke(
|
||||
{"messages": [{"role": "user", "content": "what is the weather in nyc?"}]}
|
||||
)
|
||||
```
|
||||
|
||||
## Custom MCP servers
|
||||
|
||||
@@ -59,14 +59,14 @@ config = {
|
||||
}
|
||||
|
||||
sf_response = agent.invoke(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
config
|
||||
)
|
||||
|
||||
# Continue the conversation using the same thread_id
|
||||
ny_response = agent.invoke(
|
||||
{"messages": "what about new york?"},
|
||||
{"messages": [{"role": "user", "content": "what about new york?"}]},
|
||||
# highlight-next-line
|
||||
config # (4)!
|
||||
)
|
||||
@@ -188,7 +188,7 @@ agent = create_react_agent(
|
||||
|
||||
# Run the agent
|
||||
agent.invoke(
|
||||
{"messages": "look up user information"},
|
||||
{"messages": [{"role": "user", "content": "look up user information"}]},
|
||||
# highlight-next-line
|
||||
config={"configurable": {"user_id": "user_123"}}
|
||||
)
|
||||
@@ -206,7 +206,7 @@ agent.invoke(
|
||||
### Writing
|
||||
|
||||
```python title="Example of a tool that updates user information"
|
||||
from typing import TypedDict
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from langgraph.config import get_store
|
||||
from langgraph.prebuilt import create_react_agent
|
||||
@@ -236,7 +236,7 @@ agent = create_react_agent(
|
||||
|
||||
# Run the agent
|
||||
agent.invoke(
|
||||
{"messages": "My name is John Smith"},
|
||||
{"messages": [{"role": "user", "content": "My name is John Smith"}]},
|
||||
# highlight-next-line
|
||||
config={"configurable": {"user_id": "user_123"}} # (6)!
|
||||
)
|
||||
|
||||
@@ -53,12 +53,22 @@ hotel_assistant = create_react_agent(
|
||||
supervisor = create_supervisor(
|
||||
agents=[flight_assistant, hotel_assistant],
|
||||
model=ChatOpenAI(model="gpt-4o"),
|
||||
prompt="You manage a hotel booking assistant and a flight booking assistant. Assign work to them."
|
||||
prompt=(
|
||||
"You manage a hotel booking assistant and a"
|
||||
"flight booking assistant. Assign work to them."
|
||||
)
|
||||
).compile()
|
||||
|
||||
for chunk in supervisor.stream({
|
||||
"messages": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
|
||||
}):
|
||||
for chunk in supervisor.stream(
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
|
||||
}
|
||||
]
|
||||
}
|
||||
):
|
||||
print(chunk)
|
||||
print("\n")
|
||||
```
|
||||
@@ -110,9 +120,16 @@ swarm = create_swarm(
|
||||
default_active_agent="flight_assistant"
|
||||
).compile()
|
||||
|
||||
for chunk in supervisor.stream({
|
||||
"messages": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
|
||||
}):
|
||||
for chunk in swarm.stream(
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
|
||||
}
|
||||
]
|
||||
}
|
||||
):
|
||||
print(chunk)
|
||||
print("\n")
|
||||
```
|
||||
@@ -253,9 +270,16 @@ multi_agent_graph = (
|
||||
)
|
||||
|
||||
# Run the multi-agent graph
|
||||
for chunk in multi_agent_graph.stream({
|
||||
"messages": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
|
||||
}):
|
||||
for chunk in multi_agent_graph.stream(
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
|
||||
}
|
||||
]
|
||||
}
|
||||
):
|
||||
print(chunk)
|
||||
print("\n")
|
||||
```
|
||||
|
||||
@@ -18,7 +18,7 @@ Agents can be executed in two primary modes:
|
||||
agent = create_react_agent(...)
|
||||
|
||||
# highlight-next-line
|
||||
response = agent.invoke({"messages": "what is the weather in sf"})
|
||||
response = agent.invoke({"messages": [{"role": "user", "content": "what is the weather in sf"}]})
|
||||
```
|
||||
|
||||
=== "Async invocation"
|
||||
@@ -27,7 +27,7 @@ Agents can be executed in two primary modes:
|
||||
|
||||
agent = create_react_agent(...)
|
||||
# highlight-next-line
|
||||
response = await agent.ainvoke({"messages": "what is the weather in sf"})
|
||||
response = await agent.ainvoke({"messages": [{"role": "user", "content": "what is the weather in sf"}]})
|
||||
```
|
||||
|
||||
## Inputs and outputs
|
||||
@@ -82,7 +82,7 @@ Streaming is available in both sync and async modes:
|
||||
|
||||
```python
|
||||
for chunk in agent.stream(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
stream_mode="updates"
|
||||
):
|
||||
print(chunk)
|
||||
@@ -92,7 +92,7 @@ Streaming is available in both sync and async modes:
|
||||
|
||||
```python
|
||||
async for chunk in agent.astream(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
stream_mode="updates"
|
||||
):
|
||||
print(chunk)
|
||||
@@ -122,7 +122,7 @@ To control agent execution and avoid infinite loops, set a recursion limit. This
|
||||
|
||||
try:
|
||||
response = agent.invoke(
|
||||
{"messages": "what's the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what's the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
{"recursion_limit": recursion_limit},
|
||||
)
|
||||
@@ -148,7 +148,7 @@ To control agent execution and avoid infinite loops, set a recursion limit. This
|
||||
|
||||
try:
|
||||
response = agent_with_recursion_limit.invoke(
|
||||
{"messages": "what's the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what's the weather in sf"}]},
|
||||
)
|
||||
except GraphRecursionError:
|
||||
print("Agent stopped due to max iterations.")
|
||||
|
||||
@@ -35,7 +35,7 @@ For example, if you have an agent that calls a tool once, you should see the fol
|
||||
)
|
||||
# highlight-next-line
|
||||
for chunk in agent.stream(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
stream_mode="updates"
|
||||
):
|
||||
@@ -52,7 +52,7 @@ For example, if you have an agent that calls a tool once, you should see the fol
|
||||
)
|
||||
# highlight-next-line
|
||||
async for chunk in agent.astream(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
stream_mode="updates"
|
||||
):
|
||||
@@ -73,7 +73,7 @@ To stream tokens as they are produced by the LLM, use `stream_mode="messages"`:
|
||||
)
|
||||
# highlight-next-line
|
||||
for token, metadata in agent.stream(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
stream_mode="messages"
|
||||
):
|
||||
@@ -91,7 +91,7 @@ To stream tokens as they are produced by the LLM, use `stream_mode="messages"`:
|
||||
)
|
||||
# highlight-next-line
|
||||
async for token, metadata in agent.astream(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
stream_mode="messages"
|
||||
):
|
||||
@@ -125,7 +125,7 @@ To stream updates from tools as they are executed, you can use [get_stream_write
|
||||
)
|
||||
|
||||
for chunk in agent.stream(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
stream_mode="custom"
|
||||
):
|
||||
@@ -154,7 +154,7 @@ To stream updates from tools as they are executed, you can use [get_stream_write
|
||||
)
|
||||
|
||||
async for chunk in agent.astream(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
stream_mode="custom"
|
||||
):
|
||||
@@ -178,7 +178,7 @@ You can specify multiple streaming modes by passing stream mode as a list: `stre
|
||||
)
|
||||
|
||||
for stream_mode, chunk in agent.stream(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
stream_mode=["updates", "messages", "custom"]
|
||||
):
|
||||
@@ -195,7 +195,7 @@ You can specify multiple streaming modes by passing stream mode as a list: `stre
|
||||
)
|
||||
|
||||
async for stream_mode, chunk in agent.astream(
|
||||
{"messages": "what is the weather in sf"},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
# highlight-next-line
|
||||
stream_mode=["updates", "messages", "custom"]
|
||||
):
|
||||
|
||||
@@ -116,7 +116,9 @@ agent = create_react_agent(
|
||||
tools=tools
|
||||
)
|
||||
|
||||
agent.invoke({"messages": "what's 3 + 5 and 4 * 7? make both calculations in parallel"})
|
||||
agent.invoke(
|
||||
{"messages": [{"role": "user", "content": "what's 3 + 5 and 4 * 7?"}]}
|
||||
)
|
||||
```
|
||||
|
||||
## Return tool results directly
|
||||
@@ -137,7 +139,9 @@ agent = create_react_agent(
|
||||
tools=[add]
|
||||
)
|
||||
|
||||
agent.invoke({"messages": "what's 3 + 5?"})
|
||||
agent.invoke(
|
||||
{"messages": [{"role": "user", "content": "what's 3 + 5?"}]}
|
||||
)
|
||||
```
|
||||
|
||||
## Force tool use
|
||||
@@ -161,7 +165,9 @@ agent = create_react_agent(
|
||||
tools=tools
|
||||
)
|
||||
|
||||
agent.invoke({"messages": "Hi, I am Bob"})
|
||||
agent.invoke(
|
||||
{"messages": [{"role": "user", "content": "Hi, I am Bob"}]}
|
||||
)
|
||||
```
|
||||
|
||||
!!! Warning "Avoid infinite loops"
|
||||
@@ -191,7 +197,9 @@ By default, the agent will catch all exceptions raised during tool calls and wil
|
||||
model="anthropic:claude-3-7-sonnet-latest",
|
||||
tools=[multiply]
|
||||
)
|
||||
agent.invoke({"messages": "what's 42 x 7?"})
|
||||
agent.invoke(
|
||||
{"messages": [{"role": "user", "content": "what's 42 x 7?"}]}
|
||||
)
|
||||
```
|
||||
|
||||
=== "Disable error handling"
|
||||
@@ -215,7 +223,9 @@ By default, the agent will catch all exceptions raised during tool calls and wil
|
||||
model="anthropic:claude-3-7-sonnet-latest",
|
||||
tools=tool_node
|
||||
)
|
||||
agent_no_error_handling.invoke({"messages": "what's 42 x 7?"})
|
||||
agent_no_error_handling.invoke(
|
||||
{"messages": [{"role": "user", "content": "what's 42 x 7?"}]}
|
||||
)
|
||||
```
|
||||
|
||||
1. This disables error handling (enabled by default). See all available strategies in the [API reference][langgraph.prebuilt.tool_node.ToolNode].
|
||||
@@ -243,7 +253,9 @@ By default, the agent will catch all exceptions raised during tool calls and wil
|
||||
model="anthropic:claude-3-7-sonnet-latest",
|
||||
tools=tool_node
|
||||
)
|
||||
agent_custom_error_handling.invoke({"messages": "what's 42 x 7?"})
|
||||
agent_custom_error_handling.invoke(
|
||||
{"messages": [{"role": "user", "content": "what's 42 x 7?"}]}
|
||||
)
|
||||
```
|
||||
|
||||
1. This provides a custom message to send to the LLM in case of an exception. See all available strategies in the [API reference][langgraph.prebuilt.tool_node.ToolNode].
|
||||
|
||||
Reference in New Issue
Block a user