这两件事看起来无关——streaming 给"实时输出",interrupt 给"暂停 + HITL"。它们其实共享同一个底层物理基础:runtime 把"事件"拆成可观察、可注入的细颗粒。
建议先读《Durable Execution / 持久化执行》;如果你是跳读,至少先看本章索引与本页 TL;DR。
runtime 认知层,用来分清编排、执行、持久化与产品边界。
这两件事看起来无关——streaming 给"实时输出",interrupt 给"暂停 + HITL"。 它们其实共享同一个底层物理基础:runtime 把"事件"拆成可观察、可注入的细颗粒 。
先分清谁负责编排、谁负责执行、谁负责产品化,再评估复杂度。
课程主线:稳定 runtime 机制 + 官方实现。
"Streaming" 这个词在 agent 圈被用得很糊。其实它有 4 层不同粒度,每层有不同的消费者和场景:
| 层次 | 颗粒 | 典型消费者 | 典型场景 |
|---|---|---|---|
| ① Token | 每个 LLM 输出 token | UI 实时打字效果 | Chat UI / 文档生成 |
| ② Message | 完整 message 单元(assistant message / tool result) | UI 渲染对话块、日志 | 大多数 agent 对话 UI |
| ③ Event | 节点开始 / 结束 / 工具调用 / 路由判定 | 开发者调试 / 监控 / tracing | LangSmith / OpenTelemetry / 自定义观测面板 |
| ④ State | state 字段每次变化 | UI 渲染 todos / files / 计数器 | Claude Code 的 todo 列表实时更新、Cursor 的"agent 在做什么"侧栏 |
4 层的关键区别:颗粒越细,事件越多 + 消费者越窄;颗粒越粗,事件越稳 + 消费者越广。一个成熟 agent runtime 通常 4 层都暴露,由消费者决定订阅哪几层(LangGraph 的 stream_mode 就是 4 选项)。
# LangGraph 风格的 4 层 streaming 订阅
async for chunk in agent.astream(input, stream_mode="messages"):
print(chunk) # ② message-level:完整 assistant / tool message
async for chunk in agent.astream(input, stream_mode="updates"):
print(chunk)