LangChain 前端流式输出(Frontend Streaming)
LangChain 与 LangGraph 提供了强大的前端流式支持,主要通过 React Hook useStream 实现。该 Hook 与 LangGraph 的流式功能无缝集成,处理流式传输、状态管理以及分支逻辑的复杂性,帮助开发者专注于构建优秀的生成式 UI 体验。
useStream 的核心特性包括:
- 消息流式传输:处理消息片段流,形成完整消息。
- 自动状态管理:管理消息、中断、加载状态和错误。
- 对话分支:从聊天历史中的任意点创建备用对话路径。
- UI 无关设计:支持自定义组件和样式。
本文档基于 LangChain 官方文档(Frontend Streaming),系统介绍 useStream Hook 的安装、使用方法及高级特性。
安装
在 React 应用中使用 useStream Hook 前,需要安装 LangGraph SDK:
pip install langgraph-sdk # 或通过 npm/yarn 安装对应的 JS 包(文档中未明确指定,但通常为 @langchain/langgraph-sdk)useStream 可连接本地运行的 LangGraph 图,或通过 LangSmith 部署的生产环境。
基本用法
import{ useStream }from"@langchain/langgraph-sdk/react";functionChat(){const stream =useStream({ assistantId:"agent",// 本地开发 apiUrl:"http://localhost:2024",// 生产部署(LangSmith 托管)// apiUrl: "https://your-deployment.us.langgraph.app"});consthandleSubmit=(message:string)=>{ stream.submit({ messages:[{ content: message, type:"human"}]});};return(<div>{stream.messages.map((message, idx)=>(<div key={message.id ?? idx}>{message.type}:{message.content}</div>))}{stream.isLoading &&<div>Loading...</div>}{stream.error &&<div>Error:{stream.error.message}</div>}</div>);}建议将代理部署到 LangSmith 以获得生产级托管、观测性、认证和扩展能力。
useStream 参数详解
| 参数名 | 类型 | 默认值/必填 | 说明 |
|---|---|---|---|
assistantId | string | 必填 | 连接的代理 ID。在 LangSmith 部署中需与仪表板一致。 |
apiUrl | string | localhost:2024 | LangGraph 服务器 URL。 |
apiKey | string | - | LangSmith 部署时的认证密钥。 |
threadId | string | - | 连接现有线程,用于恢复对话。 |
onThreadId | (id: string) => void | - | 新线程创建时的回调,用于持久化线程 ID。 |
reconnectOnMount | boolean | (() => Storage) | - |
onCreated | (run: Run) => void | - | 新运行创建时的回调。 |
onError | (error: Error) => void | - | 错误回调。 |
onFinish | (state: StateType, run?: Run) => void | - | 流完成回调。 |
onCustomEvent | (data: unknown, context: { mutate }) => void | - | 处理自定义事件。 |
messagesKey | string | “messages” | 状态中消息数组的键名。 |
throttle | boolean | true | 是否批量更新状态以提升渲染性能。 |
initialValues | StateType | null | - |
useStream 返回值
| 属性名 | 类型 | 说明 |
|---|---|---|
messages | Message[] | 当前线程的所有消息。 |
values | StateType | 当前图状态值(类型推断)。 |
isLoading | boolean | 是否正在流式传输。 |
error | Error | null |
interrupt | Interrupt | undefined |
toolCalls | ToolCallWithResult[] | 所有工具调用及其结果。 |
submit | 函数 | 提交新输入,支持分支、乐观更新等选项。 |
stop | 函数 | 立即停止当前流。 |
joinStream | 函数 | 通过 run ID 恢复现有流。 |
setBranch | 函数 | 切换到对话历史的不同分支。 |
线程管理
通过 threadId 和 onThreadId 回调管理对话线程,便于持久化和恢复。
const[threadId, setThreadId]=useState<string|null>(null);const stream =useStream({// ... threadId, onThreadId: setThreadId,});推荐将 threadId 存储到 URL 参数或 localStorage。
页面刷新后恢复
设置 reconnectOnMount: true 可自动恢复运行流:
const stream =useStream({// ... reconnectOnMount:true,// 默认使用 sessionStorage});支持自定义存储,或手动通过 onCreated 和 joinStream 控制恢复。
乐观更新(Optimistic Updates)
在网络请求前乐观更新客户端状态,提供即时反馈。
stream.submit({ messages:[newMessage]},{optimisticValues:(prev)=>({...prev, messages:[...(prev.messages ??[]), newMessage]})});乐观线程创建
预先生成线程 ID,实现即时导航。
const optimisticThreadId = crypto.randomUUID(); stream.submit({ messages:[...]},{ threadId: optimisticThreadId });缓存线程显示
使用 initialValues 立即显示缓存数据。
分支(Branching)
通过编辑历史消息或重新生成 AI 响应创建分支。使用 getMessagesMetadata() 获取检查点信息。
类型安全流式(Type-safe Streaming)
支持与 createAgent、StateGraph 和 Annotation 类型结合,实现类型推断。
高级特性
- 渲染工具调用:显示工具调用状态。
- 自定义流式事件:通过
writer发送自定义数据。 - 事件处理:多种回调处理更新、元数据等。
- 多代理流式:支持多代理协作。
- 人与循环(Human-in-the-Loop):处理中断和用户输入。
- 自定义状态类型与传输:灵活扩展。
总结
useStream Hook 极大简化了 LangGraph 在前端的流式集成,提供完整的消息管理、线程持久化、分支持和乐观更新等功能。开发者可结合 LangSmith 部署快速构建生产级生成式聊天界面。建议参考官方示例(如 session-persistence)进行实践。
参考文档:https://docs.langchain.com/oss/python/langchain/streaming/frontend