Skip to main content
LangGraph 实现了一个流式系统,用于呈现实时更新。流式处理对于提升基于大语言模型构建的应用程序的响应速度至关重要。通过渐进式地显示输出,甚至在完整响应准备好之前,流式处理显著改善了用户体验(UX),尤其是在处理大语言模型的延迟时。

入门

基本用法

LangGraph 图暴露了 stream(同步)和 astream(异步)方法,以迭代器的形式产生流式输出。传入一个或多个流模式来控制接收的数据。
Output
Output

流输出格式 (v2)

需要 LangGraph >= 1.1。本页所有示例均使用 version="v2"
stream()astream() 传入 version="v2" 以获得统一的输出格式。每个数据块都是一个 StreamPart 字典,具有统一的结构——无论流模式、模式数量或子图设置如何:
每种流模式都有一个对应的 TypedDict,包含 ValuesStreamPartUpdatesStreamPartMessagesStreamPartCustomStreamPartCheckpointStreamPartTasksStreamPartDebugStreamPart。你可以从 langgraph.types 导入这些类型。联合类型 StreamPart 是基于 part["type"] 的可区分联合,可在编辑器和类型检查器中实现完整的类型缩窄。 使用 v1(默认)时,输出格式会根据你的流选项而变化(单模式返回原始数据,多模式返回 (mode, data) 元组,子图返回 (namespace, data) 元组)。使用 v2 时,格式始终相同:
v2 格式还支持类型缩窄,这意味着你可以按 chunk["type"] 过滤数据块,并获得正确的负载类型。每个分支将 part["data"] 缩窄为该模式的特定类型:

流模式

将以下一种或多种流模式作为列表传递给 streamastream 方法:

图状态

使用流模式 updatesvalues 在图执行时流式传输图的状态。
  • updates 在图的每个步骤后流式传输状态的更新
  • values 在图的每个步骤后流式传输状态的完整值
使用此模式仅流式传输节点在每个步骤后返回的状态更新。流式输出包括节点的名称以及更新内容。
Output

LLM tokens

使用 messages 流模式,从图的任何部分(包括节点、工具、子图或任务)逐 token 流式传输大语言模型(LLM)输出。 messages 模式的流式输出是一个元组 (message_chunk, metadata),其中:
  • message_chunk:来自 LLM 的 token 或消息片段。
  • metadata:一个字典,包含有关图节点和 LLM 调用的详细信息。
如果你的 LLM 不是作为 LangChain 集成提供的,你可以改用 custom 模式来流式传输其输出。详情请参阅与任何 LLM 一起使用
Python < 3.11 中异步需要手动配置 在 Python < 3.11 中使用异步代码时,你必须显式地将 RunnableConfig 传递给 ainvoke() 以启用正确的流式传输。详情请参阅Python < 3.11 中的异步,或升级到 Python 3.11+。

按 LLM 调用过滤

你可以将 tags 与 LLM 调用关联,以按 LLM 调用过滤流式 token。

从流中省略消息

使用 nostream 标签完全排除 LLM 输出。标记为 nostream 的调用仍然运行并产生输出;它们的 token 只是在 messages 模式下不会被发出。 这在以下情况下很有用:
  • 你需要 LLM 输出用于内部处理(例如结构化输出),但不想将其流式传输给客户端
  • 你通过不同的通道(例如自定义 UI 消息)流式传输相同的内容,并希望避免在 messages 流中重复输出

按节点过滤

要仅从特定节点流式传输 token,请使用 stream_mode="messages" 并通过流式元数据中的 langgraph_node 字段过滤输出:

自定义数据

要从 LangGraph 节点或工具内部发送自定义用户定义数据,请按照以下步骤操作:
  1. 使用 get_stream_writer 访问流写入器并发出自定义数据。
  2. 在调用 .stream().astream() 时设置 stream_mode="custom" 以在流中获取自定义数据。你可以组合多种模式(例如 ["updates", "custom"]),但至少一种必须是 "custom"
Python < 3.11 中异步没有 get_stream_writer 在 Python < 3.11 上运行的异步代码中,get_stream_writer 将不起作用。 相反,请向你的节点或工具添加一个 writer 参数并手动传递它。 用法示例请参阅Python < 3.11 中的异步

子图输出

要将子图的输出包含在流式输出中,你可以在父图的 .stream() 方法中设置 subgraphs=True。这将流式传输父图和任何子图的输出。 输出将以元组 (namespace, data) 的形式流式传输,其中 namespace 是一个元组,包含调用子图的节点路径,例如 ("parent_node:<task_id>", "child_node:<task_id>")
使用 version="v2" 时,子图事件使用相同的 StreamPart 格式。ns 字段标识来源:
注意,我们不仅接收节点更新,还接收命名空间,这些命名空间告诉我们正在从哪个图(或子图)流式传输。

检查点

使用 checkpoints 流模式在图执行时接收检查点事件。每个检查点事件与 get_state() 的输出格式相同。需要检查点保存器

任务

使用 tasks 流模式在图执行时接收任务开始和完成事件。任务事件包含有关正在运行的节点、其结果和任何错误的信息。需要检查点保存器

调试

使用 debug 流模式在图执行期间流式传输尽可能多的信息。流式输出包括节点的名称以及完整状态。
debug 模式结合了 checkpointstasks 事件以及额外的元数据。如果你只需要调试信息的子集,请直接使用 checkpointstasks

同时使用多种模式

你可以将列表作为 stream_mode 参数传递,以同时流式传输多种模式。 使用 version="v2" 时,每个数据块都是一个 StreamPart 字典。使用 chunk["type"] 区分模式:

高级

与任何 LLM 一起使用

你可以使用 stream_mode="custom"任何 LLM API 流式传输数据——即使该 API 没有实现 LangChain 聊天模型接口。 这让你可以集成原始 LLM 客户端或提供自己流式接口的外部服务,使 LangGraph 在自定义设置中高度灵活。
让我们使用包含工具调用的 AIMessage 调用图:

为特定聊天模型禁用流式传输

如果你的应用程序混合了支持流式传输和不支持流式传输的模型,你可能需要为不支持流式传输的模型显式禁用流式传输。 在初始化模型时设置 streaming=False
并非所有聊天模型集成都支持 streaming 参数。如果你的模型不支持它,请改用 disable_streaming=True。此参数可通过基类在所有聊天模型上使用。

迁移到 v2

v2 流式格式(本页使用)提供了统一的输出格式。以下是主要差异和迁移方法的摘要:

v2 invoke 格式

当你向 invoke()ainvoke() 传递 version="v2" 时,它返回一个 GraphOutput 对象,具有 .value.interrupts 属性:
使用除默认 "values" 之外的任何流模式,invoke(..., stream_mode="updates", version="v2") 返回 list[StreamPart] 而不是 list[tuple]
GraphOutput 上的字典式访问(result["key"]"key" in resultresult["__interrupt__"])仍然有效以保持向后兼容性,但已弃用,将在未来版本中移除。请迁移到 result.valueresult.interrupts
这将状态与中断元数据分离。使用 v1 时,中断嵌入在返回的字典中,位于 __interrupt__ 下:

Pydantic 和 dataclass 状态强制转换

当你的图状态是 Pydantic 模型或 dataclass 时,v2 values 模式会自动将输出强制转换为正确的类型:

Python < 3.11 中的异步

在 Python 版本 < 3.11 中,asyncio 任务不支持 context 参数。 这限制了 LangGraph 自动传播上下文的能力,并以两种关键方式影响 LangGraph 的流式机制:
  1. 必须显式地将 RunnableConfig 传递给异步 LLM 调用(例如 ainvoke()),因为回调不会自动传播。
  2. 不能在异步节点或工具中使用 get_stream_writer——你必须直接传递 writer 参数。