接前面文章
七、运行代理
代理支持同步和异步执行,可以使用 .invoke() / await .invoke() 实现完整响应,或使用 .stream() / .astream() 实现增量流式输出。本节介绍如何提供输入、解释输出、启用流式传输以及控制执行限制。
1.基本用法
代理可以以两种主要模式执行:
- 使用 .invoke() 或 .stream() 同步执行
- 使用 await .invoke() 或 async for .astream() 异步执行
# 同步调用
from langgraph.prebuilt import create_react_agent
#agent = create_react_agent(...)
#response = agent.invoke({"messages": [{"role": "user", "content": "旧金山的天气怎么样"}]})
# 异步调用
from langgraph.prebuilt import create_react_agent
# agent = create_react_agent(...)
# response = await agent.ainvoke({"messages": [{"role": "user", "content": "旧金山的天气怎么样"}]})
2.输入和输出
代理使用需要 list of 作为输入的语言模型。因此,代理的输入和输出将作为 list of 存储在 agent 状态的 key 下。messages,messages,messages
3.输入格式
代理输入必须是带有键的字典。支持的格式包括:messages
格式 | 例 |
---|---|
字符串 | {“messages”: “Hello”}— 解释为 HumanMessage |
消息字典 | {“messages”: {“role”: “user”, “content”: “Hello”}} |
消息列表 | {“messages”: [{“role”: “user”, “content”: “Hello”}]} |
使用自定义状态 | {“messages”: [{“role”: “user”, “content”: “Hello”}], “user_name”: “Alice”}— 如果使用自定义state_schema |
消息会自动转换为 LangChain 的内部消息格式。您可以阅读 有关 LangChain 消息的更多信息,请参阅 LangChain 文档。
使用自定义代理状态
您可以直接在输入字典中提供在代理的状态架构中定义的其他字段。这允许基于运行时数据或先前工具输出的动态行为。
4.输出格式
代理程序输出是一个字典,其中包含:
- messages:执行期间交换的所有消息的列表(用户输入、助手回复、工具调用)。
- (可选),如果配置了结构化输出。structured_response
- 如果使用 custom ,则输出中也可能存在与定义的字段对应的其他键。这些可以保存工具执行或提示逻辑中的更新状态值。state_schema
5.流式输出
代理支持流式处理响应,以实现响应速度更快的应用程序。这包括:
- 每一步后的进度更新
- 生成的 LLM 令牌
- 执行期间的自定义工具消息
# 同步流式输出
for chunk in agent.stream(
{"messages": [{"role": "user", "content": "旧金山的天气怎么样"}]},
stream_mode="updates"
):
print(chunk)
# 异步流式输出
async for chunk in agent.astream(
{"messages": [{"role": "user", "content": "旧金山的天气怎么样"}]},
stream_mode="updates"
):
print(chunk)
6.最大迭代次数
要控制代理执行并避免无限循环,请设置递归限制。这定义了代理在引发 .您可以在运行时或在定义代理时通过以下方式进行配置 :GraphRecursionError, recursion_limit, .with_config()
# 运行
from langgraph.errors import GraphRecursionError
from langgraph.prebuilt import create_react_agent
max_iterations = 3
recursion_limit = 2 * max_iterations + 1
agent = create_react_agent(
model="anthropic:claude-3-5-haiku-latest",
tools=[get_weather]
)
try:
response = agent.invoke(
{"messages": [{"role": "user", "content": "what's the weather in sf"}]},
{"recursion_limit": recursion_limit},
)
except GraphRecursionError:
print("Agent stopped due to max iterations.")
# .with_config()
from langgraph.errors import GraphRecursionError
from langgraph.prebuilt import create_react_agent
max_iterations = 3
recursion_limit = 2 * max_iterations + 1
agent = create_react_agent(
model="anthropic:claude-3-5-haiku-latest",
tools=[get_weather]
)
agent_with_recursion_limit = agent.with_config(recursion_limit=recursion_limit)
try:
response = agent_with_recursion_limit.invoke(
{"messages": [{"role": "user", "content": "what's the weather in sf"}]},
)
except GraphRecursionError:
print("Agent stopped due to max iterations.")
八.Streaming 流式处理
流式处理是构建响应式应用程序的关键。您需要流式传输几种类型的数据:
- Agent progress — 在执行代理图中的每个节点后获取更新。
- LLM tokens — 流式处理由语言模型生成的令牌。
- 自定义更新 — 在执行期间从工具发出自定义数据(例如,“Fetched 10/100 records”)
1.Agent progress 代理进度
要流式传输代理进度,请将 stream() 或 astream() 方法与 stream_mode=“updates” 一起使用。这会在每个代理步骤后发出一个事件。
例如,如果您有一个代理调用了一次工具,您应该会看到以下更新:
- LLM 节点:带有工具调用请求的 AI 消息
- Tool 节点:带有执行结果的工具消息
- LLM 节点:最终 AI 响应
# 同步
agent = create_react_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[get_weather],
)
for chunk in agent.stream(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
stream_mode="updates"
):
print(chunk)
print("\n")
# 异步
agent = create_react_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[get_weather],
)
async for chunk in agent.astream(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
stream_mode="updates"
):
print(chunk)
print("\n")
2.LLM tokens
要流式传输 LLM 生成的tokens,请使用 stream_mode=“messages”:
# 同步
agent = create_react_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[get_weather],
)
# 如果是异步,加上 async,async for token, metadata in agent.astream(
for token, metadata in agent.stream(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
stream_mode="messages"
):
print("Token", token)
print("Metadata", metadata)
print("\n")
3.工具更新
要从执行的工具流式传输更新,可以使用 get_stream_writer。
from langgraph.config import get_stream_writer
def get_weather(city: str) -> str:
"""Get weather for a given city."""
writer = get_stream_writer()
# stream any arbitrary data
writer(f"Looking up data for city: {city}")
return f"It's always sunny in {city}!"
agent = create_react_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[get_weather],
)
# 异步 加上 async,async for chunk in agent.astream(
for chunk in agent.stream(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
stream_mode="custom"
):
print(chunk)
print("\n")
4.流式传输多种模式
您可以通过将流模式作为列表传递来指定多种流模式:stream_mode=[“updates”, “messages”, “custom”]
agent = create_react_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[get_weather],
)
# 异步 加上 async,async for stream_mode, chunk in agent.astream(
for stream_mode, chunk in agent.stream(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
stream_mode=["updates", "messages", "custom"]
):
print(chunk)
print("\n")
5.禁用流式传输
在某些应用程序中,您可能需要为给定模型禁用单个令牌的流式传输。这在多代理系统中可用于控制哪些代理流式传输其输出。