LangGraph 工作流中的 create_agent 如何实时逐 token 输出?
结论
可以继续使用 create_agent 实现实时流式输出。agent 作为工作流中的子图运行时,父图默认不会转发子图内部的 messages 事件。调用 compiled_workflow.stream() 时设置 subgraphs=True,并将 agent 图直接加入工作流,就能接收其内部模型生成的消息块。LangGraph 文档说明,messages 模式支持流式输出子图中的 LLM 消息;启用 subgraphs=True 后,事件会带有标识来源的命名空间。LangGraph 流式输出文档
修改工作流
同步节点如果通过 agent.invoke() 等待完整结果再返回,就会先完成整个 agent 调用,外层工作流无法实时转发这次调用产生的消息块。可以把 agent 直接添加为节点,并在父图的流式调用中启用子图事件:
workflow = StateGraph(MessagesState)
workflow.add_node("agent", agent)
workflow.add_edge(START, "agent")
compiled_workflow = workflow.compile(checkpointer=checkpointer)
def response(user_input, workflow, config):
inputs = {"messages": [("human", user_input)]}
for namespace, data in workflow.stream(
inputs,
config,
stream_mode="messages",
subgraphs=True,
):
token, metadata = data
# 只转发名为 agent 的子图消息。
if namespace and namespace[0].startswith("agent:") and token.content:
print(token.content, end="", flush=True)
namespace 用来区分消息来自父图还是哪个子图。示例中的条件只输出 agent 子图的消息。如果工作流中还有其他面向用户的 agent,可以按节点名添加相应的筛选条件。messages 模式会在模型生成时返回消息块,可以直接转发生成过程中的内容。LangGraph 子图流式输出说明
中间节点与工具调用
如果中间 agent 也作为子图运行,可以过滤它们的命名空间,避免把它们的消息转发给语音机器人。它们会照常执行,工作流也会等节点完成后再继续。
面向用户的 agent 如果会调用工具,messages 可能包含与工具调用相关的模型消息块。应结合 metadata 和应用的输出约定筛选适合展示的消息。多个节点都会调用 LLM 时,也可以根据 metadata 中的节点信息进一步限定输出来源。
版本注意
示例按 stream_mode="messages" 返回 (namespace, data) 的接口编写,其中 data 是 (token, metadata)。不同 LangGraph 版本的流式输出格式和可用参数可能不同。如果本地调用无法按上述结构解包,请参照当前安装版本的流式输出文档调整。该方案能否满足语音机器人的吞吐要求,还取决于模型服务、网络和下游传输;启用流式输出本身无法保证具体吞吐量。
备注:内容仅供参考。
