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

概述

LangChain 的流式处理系统允许你将代理运行的实时反馈呈现到你的应用程序中。 使用 LangChain 流式处理可以实现: 有关更多端到端示例,请参阅下面的常见模式部分。

支持的流式模式

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

代理进度

要流式传输代理进度,请使用 streamastream 方法,并设置 stream_mode="updates"。这会在每个代理步骤后发出一个事件。 例如,如果你有一个调用一次工具的代理,你应该看到以下更新:
  • 大语言模型节点:包含工具调用请求的 AIMessage
  • 工具节点:包含执行结果的 ToolMessage
  • 大语言模型节点:最终的 AI 响应
流式传输代理进度
输出

大语言模型令牌

要流式传输大语言模型生成的令牌,请使用 stream_mode="messages"。下面你可以看到代理流式传输工具调用和最终响应的输出。
流式传输大语言模型令牌
输出

自定义更新

要在工具执行时流式传输更新,你可以使用 get_stream_writer
流式传输自定义更新
输出
如果你在工具内部添加了 get_stream_writer,你将无法在 LangGraph 执行上下文之外调用该工具。

流式传输多种模式

你可以通过将流式模式作为列表传递来指定多种流式模式:stream_mode=["updates", "custom"] 每个流式传输的块都是一个 StreamPart 字典,包含 typensdata 键。使用 chunk["type"] 来确定流式模式,使用 chunk["data"] 来访问有效负载。
流式传输多种模式
输出

常见模式

以下是展示流式处理常见用例的示例。

流式传输思考/推理令牌

一些模型在生成最终答案之前会执行内部推理。你可以通过过滤 标准内容块type"reasoning" 的内容,在生成时流式传输这些思考/推理令牌。
必须在模型上启用推理输出。有关配置详情,请参阅推理部分和你的提供商集成页面要快速检查模型的推理支持情况,请参阅 models.dev
要从代理流式传输思考令牌,请使用 stream_mode="messages" 并过滤推理内容块:
输出
无论模型提供商如何,这都以相同的方式工作——LangChain 通过 content_blocks 属性将提供商特定的格式(Anthropic thinking 块、OpenAI reasoning 摘要等)标准化为标准的 "reasoning" 内容块类型。 要直接从聊天模型(不使用代理)流式传输推理令牌,请参阅使用聊天模型进行流式传输

流式传输工具调用

你可能希望同时流式传输:
  1. 在生成 工具调用 时的部分 JSON
  2. 已执行的、已解析的工具调用
指定 stream_mode="messages" 将流式传输代理中所有大语言模型调用生成的增量消息块。要访问包含已解析工具调用的完整消息:
  1. 如果这些消息在状态中被跟踪(如 create_agent 的模型节点中),请使用 stream_mode=["messages", "updates"] 通过状态更新访问完整消息(如下所示)。
  2. 如果这些消息未在状态中跟踪,请使用自定义更新或在流式循环中聚合块(下一节)。
如果你的代理包含多个大语言模型,请参阅下面关于从子代理流式传输的部分。
输出

访问完整消息

如果完整消息在代理的状态中被跟踪,你可以使用 stream_mode=["messages", "updates"],如流式传输工具调用部分所示,在流式传输期间访问完整消息。
在某些情况下,完整消息不会反映在状态更新中。如果你可以访问代理内部,你可以使用自定义更新在流式传输期间访问这些消息。否则,你可以在流式循环中聚合消息块(见下文)。 考虑下面的示例,我们将一个流式写入器集成到一个简化的护栏中间件中。这个中间件演示了工具调用以生成结构化的“安全/不安全”评估(也可以使用结构化输出来实现):
然后我们可以将这个中间件集成到我们的代理中,并包含其自定义流事件:
输出
或者,如果你无法向流添加自定义事件,你可以在流式循环中聚合消息块:

与人机交互一起流式传输

为了处理人机交互中断,我们基于上面的示例进行构建:
  1. 我们使用人机交互中间件和检查点配置代理
  2. 我们收集在 "updates" 流式模式期间生成的中断
  3. 我们使用命令响应这些中断
输出
接下来,我们为每个中断收集一个决策。重要的是,决策的顺序必须与我们收集的操作顺序相匹配。 为了说明,我们将编辑一个工具调用并接受另一个:
输出
然后我们可以通过将命令传递到同一个流式循环中来恢复:
输出

从子代理流式传输

当代理中的任何点存在多个大语言模型时,通常需要在生成消息时区分消息的来源。 为此,在创建每个代理时传递一个 name。然后,在以 "messages" 模式流式传输时,该名称可通过元数据中的 lc_agent_name 键获得。 下面,我们更新流式传输工具调用示例:
  1. 我们将工具替换为一个 call_weather_agent 工具,该工具内部调用一个代理
  2. 我们为每个代理添加一个 name
  3. 我们在创建流时指定 subgraphs=True
  4. 我们的流处理与之前相同,但我们添加了逻辑以使用 create_agentname 参数跟踪哪个代理处于活动状态
当你为代理设置 name 时,该名称也会附加到该代理生成的任何 AIMessage 上。
首先我们构建代理:
接下来,我们向流式循环添加逻辑以报告哪个代理正在发出令牌:
输出

禁用流式传输

在某些应用程序中,你可能需要禁用给定模型的单个令牌流式传输。这在以下情况下很有用:
  • 使用多代理系统时,控制哪些代理流式传输其输出
  • 混合支持流式传输和不支持流式传输的模型
  • 部署到 LangSmith 并希望防止某些模型输出流式传输到客户端
在初始化模型时设置 streaming=False
部署到 LangSmith 时,在任何不希望其输出流式传输到客户端的模型上设置 streaming=False。这在部署前在你的图代码中配置。
并非所有聊天模型集成都支持 streaming 参数。如果你的模型不支持,请改用 disable_streaming=True。此参数通过基类在所有聊天模型上可用。
有关更多详细信息,请参阅 LangGraph 流式传输指南

v2 流式格式

需要 LangGraph >= 1.1。
version="v2" 传递给 stream()astream() 以获得统一的输出格式。每个块都是一个 StreamPart 字典,包含 typensdata 键——无论流式模式或模式数量如何,形状都相同:
v2 格式还改进了 invoke()——它返回一个 GraphOutput 对象,具有 .value.interrupts 属性,清晰地将状态与中断元数据分开:
有关 v2 格式的更多详细信息,包括类型收窄、Pydantic/dataclass 强制转换和子图流式传输,请参阅 LangGraph 流式传输文档

相关内容