流式输出

构建实时响应的 AI 应用:掌握 LangGraph 的多种流式输出模式

📚 学习目标

学完这篇文章后,你将能够:

  • 使用 stream() 方法替代 invoke()
  • 理解并使用不同的 streamMode(values, updates, messages)
  • 实现打字机效果(Token-by-Token Streaming)
  • 发送自定义流式数据(Custom Streaming)

前置知识

在开始学习之前,建议先阅读:


1️⃣ 为什么需要流式输出?

在构建 AI 应用(尤其是聊天机器人)时,等待整个图执行完毕再返回结果会导致极差的用户体验。用户习惯于即时看到反馈。

LangGraph 提供了深度的流式支持,允许我们实时获取:

  1. 状态变化:每当一个节点完成工作。
  2. 生成内容:LLM 生成的每一个字(Token)。
  3. 执行事件:工具调用、节点启动/结束等元数据。

2️⃣ 基础流式:stream()

stream() 方法返回一个异步迭代器,我们可以使用 for await...of 循环来消费它。

// 基本用法
for await (const chunk of await graph.stream(input, config)) {
    console.log(chunk);
}

3️⃣ 流式模式 (streamMode)

LangGraph 支持通过 streamMode 参数配置不同的输出格式。

1. Values 模式(默认)

返回每次状态更新后的完整状态快照

const stream = await graph.stream(input, { streamMode: 'values' });

for await (const state of stream) {
    // 每次节点执行完,都会收到包含所有字段的最新状态
    console.log(state); 
}
  • 适用场景:需要展示任务进度的面板,或者无论哪个节点更新都需要最新上下文的 UI。

2. Updates 模式

只返回增量更新。即只返回节点刚刚修改的那个字段。

const stream = await graph.stream(input, { streamMode: 'updates' });

for await (const update of stream) {
    // 格式:{[nodeName]: { updatedField: value }}
    console.log(update);
}
  • 适用场景:只关心"刚刚发生了什么",例如在聊天列表中追加一条新消息。

3. Messages 模式(打字机效果)

专门用于流式传输 LLM 的生成内容(Token)。

const stream = await graph.stream(input, { streamMode: 'messages' });

for await (const [messageChunk] of stream) {
    if (messageChunk.content) {
        process.stdout.write(messageChunk.content); // 逐字输出
    }
}
  • 适用场景:ChatGPT 风格的实时对话界面。

4️⃣ 自定义流数据 (Custom)

有时你需要在节点内部向前端发送特定的事件(如"正在搜索数据库...")。

// 1. 在节点中使用 ctx.writer
const myNode = async (state, ctx) => {
    // 发送自定义数据
    ctx.writer({ type: 'progress', value: 50 });
    return { ... };
}

// 2. 在客户端接收
const stream = await graph.stream(input, { streamMode: 'custom' });
for await (const customData of stream) {
    console.log(customData); // { type: 'progress', value: 50 }
}

5️⃣ 详细事件流 (streamEvents)

如果你需要极其详细的调试信息(比如 LLM 确切的输入输出、工具调用的参数等),使用 streamEvents

for await (const event of graph.streamEvents(input, { version: 'v2' })) {
    if (event.event === 'on_chat_model_stream') {
        // LLM 正在生成 token
    } else if (event.event === 'on_tool_start') {
        // 工具开始调用
    }
}

💡 练习题

  1. 实操题:编写一个简单的 CLI 程序,使用 messages 模式运行一个 LLM 节点,在控制台实现打字机效果的输出。

📚 参考资源

项目代码


✅ 总结

核心要点

  • stream() 是构建响应式 UI 的基础。
  • 不同的 streamMode 对应不同的消费场景:
    • Messages: 聊天打字机。
    • Updates/Values: 状态同步。
    • Custom: 自定义进度条或通知。

下一步:在下一篇文章《Tool Calling 与 Agent》,我们将进入 ReAct Agent 的世界,让 LLM 学会使用工具。

登录以继续阅读

解锁完整文档、代码示例及更多高级功能。

立即登录

On this page