LangGraph入门到实战:第4部分-Agent同步异步执行+多种Streaming流式处理+工具更新

接前面文章

七、运行代理

代理支持同步和异步执行,可以使用 .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.禁用流式传输

在某些应用程序中,您可能需要为给定模型禁用单个令牌的流式传输。这在多代理系统中可用于控制哪些代理流式传输其输出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值