把 LangGraph 的流式输出拆成 values、updates、messages、custom 等几种事件,看清 v2 StreamPart 到底统一了什么。
这篇建议和 LangChain 的流式输出一起对照着看:LangChain 更偏模型/agent 侧,LangGraph 更偏整张图的运行时事件。
可结合LangChain的流一起看
1. 介绍
在入门章节,我们就用到了Graph的stream_mode,提到和agent的有所不同。
LangGraph 图提供stream(同步)和astream(异步)方法,以迭代器形式生成流式输出。传入一个或多个流模式来控制接收的数据内容。
Python3
点击展开代码
展开代码
Status: thinking of a joke...Node generate_joke updated: {'joke': 'Why did the ice cream go to school? To get a sundae education!'}2. 流输出格式 (v2)
(1) stream mode
向version="v2"传入stream()或astream()以获取统一的输出格式。每个数据块均为一个StreamPart字典,具有固定结构:
{ "type": "values" | "updates" | "messages" | "custom" | "checkpoints" | "tasks" | "debug", "ns": (), # namespace tuple, populated for subgraph events "data": ..., # the actual payload (type varies by stream mode)}每种流模式都有对应的TypedDict,包含ValuesStreamPart、UpdatesStreamPart、MessagesStreamPart、CustomStreamPart、CheckpointStreamPart、TasksStreamPart、DebugStreamPart(对应7种streammode)
在 v1 版本(默认)中,输出格式会根据你的流式传输选项而变化(单模式返回原始数据,多模式返回(mode, data) 元组,子图返回(namespace, data) 元组)。在 v2 版本中,格式始终保持一致。
可以看到,这里的v1、v2区别,实际和LangChain Agent的模式选择一样,v2都是有更格式化的输出(即StreamPart)。当时提到但是还不够详细,这里细致拆解一下StreamPart:
- type="values":每一步后的完整状态快照;data 是完整 state(full state)。
- type="updates":节点执行后对 state 的增量更新;data 形如 {"node_name": {"changed_key": value}}。
- type="messages":LLM 消息流;data 通常是 (message_chunk, metadata)。
- type="custom":来自 get_stream_writer() 主动写出的自定义事件;data 就是 writer({…}) 传入的内容。
- type="checkpoints":checkpoint 事件流;data 是检查点快照信息(类似 get_state 返回结构)。
- type="tasks":任务生命周期事件(开始/结束/结果/错误);data 是任务执行信息。
- type="debug":最全量调试事件;data 包含更完整的执行上下文与诊断信息。
下面,我放一个最小的message用法示例,它定义了图状态,用stream执行图,然后实现了逐token输出:
Python3
点击展开代码
展开代码

至于ns 是事件来源的命名空间路径,用来标识这个 stream chunk 来自哪一层图。比如:
- ns == ():来自主图(root graph)
- ns == ("node_2:<task_id>",):来自 node_2 调用的子图
- ns == ("child:
", "child_1: "):来自更深层嵌套子图
我们可以通过 chunk["type"] 过滤数据块,并获得正确的负载类型。每个分支都会将 part["data"] 收窄为对应模式的特定类型:
Python3
点击展开代码
展开代码
(2) 过滤
我们之前在LangChain核心组件Models中就学过,init_chat_model的时候用config参数,添加额外字典,从而对运行时的行为控制。
不过这里是不同的层级,直接在init_model_model里面加入tags,是专门给模型实例设置默认标签,每次调用都会带上。我们可以通过这个元信息,直接过滤:
Python3
点击展开代码
展开代码
或者,我们还可以按照node name过滤,或者按照自定义的字段过滤……总之,就是简单的python逻辑。
(3) nostream
使用 nostream 标签可将大语言模型的输出完全排除在流式传输之外。标记为 nostream 的调用仍会正常执行并生成输出,只是其词元不会在 messages 模式下发送。(这里nostream是写在config字段下面的)
该功能适用于以下场景:
- 需要大语言模型输出用于内部处理(例如结构化输出),但不希望将其流式传输给客户端
- 通过其他通道(例如自定义界面消息)流式传输相同内容,且希望避免 messages 流中出现重复输出
举例如下:
Python3
点击展开代码
展开代码
专题阅读
LangGraph
这篇文章属于同一条阅读链。你可以直接在这里切换,不用再回到列表页重新找。
部分信息可能已经过时
留言区
留言
欢迎纠错、补充、交流。昵称和评论内容必填;如果你愿意,也可以留下联系方式,仅站主可见。