第 9 章:实时体验优化:流式传输与运行时上下文
流式传输与精细的运行时上下文管理能显著提升交互流畅度与响应感知。
流式传输的必要性:改善用户体验
流式传输系统在增强基于大语言模型(LLM, Large Language Model)应用程序的响应性方面至关重要。通过渐进式显示输出,即使完整响应尚未准备好,流式传输也能显著改善用户体验,尤其是在处理 LLM 固有延迟时。
智能体通常执行多个步骤(如模型调用、工具执行),这些操作可能耗时较长。流式传输可以显示中间进度,让用户实时了解智能体正在做什么,从而提升交互的流畅度和透明度。
智能体的多模式流式输出
LangChain 的流式传输系统允许应用程序获得智能体运行的实时反馈。智能体支持多种流式传输模式,用户可根据需求选择希望接收的更新类型。
下表对比了三种主流流式模式及其用途:
| 流模式 | 目的 | 传输内容 |
|---|---|---|
| updates | 流式传输智能体执行进度 | 每个智能体步骤后发出事件(如 LLM 节点、工具节点) |
| messages | 流式传输 LLM Token | 流式传输语言模型生成的 Token 和元数据 |
| custom | 流式传输自定义更新 | 发出用户定义的信号(如工具执行的实时反馈) |
可以通过将流模式作为列表传递来指定多个流模式,例如 stream_mode=["updates", "custom"]。
updates 模式:流式传输智能体执行进度
updates 模式用于流式传输智能体执行的进度。使用 stream_mode="updates" 的 stream 或 astream 方法将在每个智能体步骤后发出一个事件。
如果智能体调用了一次工具,典型的更新流程如下:
- LLM 节点:带有工具调用请求的
AIMessage - 工具节点:带有执行结果的
ToolMessage - LLM 节点:最终的 AI 响应
messages 模式:流式传输 LLM Token
messages 模式用于流式传输由 LLM 产生的 Token。使用 stream_mode="messages" 时,输出将流式传输工具调用和最终响应的 Token,返回 AIMessageChunk 对象,可组合成完整消息对象。
custom 模式:流式传输自定义更新
custom 模式允许从工具执行过程中流式传输用户定义的信号或自定义更新。这对于向用户提供关于工具正在做什么的实时反馈非常有用(如“已获取 10/100 条记录”)。
工具可通过访问 ToolRuntime 中的 stream_writer 来流式传输自定义更新。
运行时上下文(Runtime Context):依赖注入与静态配置
运行时上下文是 LangGraph 运行时对象暴露的信息之一。它包含静态信息,如用户 ID、数据库连接或其他智能体调用所需的依赖项。
运行时上下文属于不可变配置,在智能体执行过程中保持不变,属于对话范围的数据源。通过运行时上下文,工具和中间件可实现依赖注入,避免硬编码或全局状态,使工具更具可测试性、可重用性和灵活性。
在创建智能体时,可使用 context_schema 定义运行时上下文结构,并在调用智能体时通过 context 参数传递相关配置。
工具对运行时上下文的访问:ToolRuntime 的使用
工具可以访问运行时信息,以获取执行期间所需的配置或依赖项。通过 ToolRuntime 参数,工具可访问以下信息:
- Context:不可变配置,如用户 ID、会话详情或应用特定配置
- State:可变数据,如消息和计数器
- Store:跨对话的持久性长期记忆
- Stream Writer:用于工具执行时流式传输自定义更新
只需在工具签名中添加 runtime: ToolRuntime,即可自动注入运行时信息,且不会暴露给 LLM。
以下代码展示了工具访问运行时上下文的典型方式:
# 工具通过 ToolRuntime[Context] 访问运行时上下文
@tool
def get_user_location(runtime: ToolRuntime[Context]) -> str:
"""Retrieve user information based on user ID."""
user_id = runtime.context.user_id # 访问运行时上下文中的 user_id
return "Florida" if user_id == "1" else "SF"
总结
针对实时应用,合理选择流式模式和运行时上下文策略,能在用户体验与系统稳定性间取得平衡。