← [ BACK_TO_NOTES ]

LLM Streaming 分层架构

一种 LLM Streaming 职责划分:Token Stream → Chunk Aggregator → Semantic Router → Event Transport Adapter → Frontend State Manager,在稳定契约下隔离改动。

#synthesis #evergreen #ai #architecture

[!info] related notes

LLM Streaming 分层架构

范围

描述一种从 Provider 接口到 UI 投影的职责划分,不是所有生产系统的标准架构;持久化、执行授权与恢复等还需独立设计。

为什么要分层

一个简单的 SSE demo 可以不做分层——直接消费 Provider 的文本增量。但生产系统需要:

  • 聚合:按事件开销与显示延迟选择是否合并文本增量
  • 分流:输出不只有文本,还有工具调用、结构化数据、推理过程
  • 统一协议:前端、日志、监控、回放系统需要统一的事件格式
  • 状态管理:前端需要集中管理流式状态,而不是散落在各组件

五层架构

┌─────────────────────────────────┐
│  ① Token Stream Layer           │  模型层:适配 Provider 事件
│     (OpenAI / Claude / Qwen)    │
└──────────────┬──────────────────┘
               ↓
┌─────────────────────────────────┐
│  ② Chunk Aggregator             │  聚合层:合并同目标文本增量
│     (按标点/Markdown/tool边界)    │
└──────────────┬──────────────────┘
               ↓
┌─────────────────────────────────┐
│  ③ Semantic Router              │  路由层:按类型分流输出
│     (text/tool/thinking/cite)   │
└──────────────┬──────────────────┘
               ↓
┌─────────────────────────────────┐
│  ④ Event Transport Adapter      │  传输层:统一协议输出
│     (Structured Event Stream)   │
└──────────────┬──────────────────┘
               ↓
┌─────────────────────────────────┐
│  ⑤ Frontend State Manager       │  状态层:管理 UI 状态
│     (Zustand / Redux / XState)  │
└─────────────────────────────────┘

各层职责详解

① Token Stream Layer(模型层)

职责:适配 Provider 返回的文本、工具等事件;通常不是原始 token ID。

输入:OpenAI / Claude / Qwen 等 provider 的 streaming API

输出:

delta: "你"
delta: "好"

关键点:

  • 文本片段不必与模型 token 或网络字节块一一对应
  • 有些 provider 已经做了初步聚合
  • 这一层通常由 LLM Provider SDK 封装

② Chunk Aggregator(聚合层)

职责:按目标消息/通道合并文本增量,必要时设置时间与长度上限。

聚合策略:

  • 按标点(句号、换行)
  • 按 Markdown 块(代码块、列表)
  • 按 function call boundary
  • 按时间窗口(每 N ms 发送一次)
  • 按长度(累积 N 个字符后发送)

输出:

chunk: "你好世界。"

详见 Chunk Aggregator。

③ Semantic Router(路由层)

职责:根据内容类型将输出分流到不同处理通道。

分流目标:

通道目标
text主聊天 UI
tool后端执行器 + 工具状态 UI
thinking仅展示接口允许公开的摘要;折叠不是保密机制
citation引用面板
structured专用 UI 组件

详见 Semantic Router。

④ Event Transport Adapter(传输层)

职责:将应用事件编码为 SSE / WebSocket 输出。Event Bus 可以作为内部事件分发机制,但不等同于网络传输。

协议格式(推荐 Structured Streaming):

{ "type": "message.delta", "channel": "text", "data": { "content": "你好" } }
{ "type": "tool_call.started", "channel": "tool", "data": { "name": "search" } }
{ "type": "message.completed", "channel": "text", "data": { "message_id": "m1" } }

传输方式选择:

方式适用场景
SSE基于 HTTP 的服务端事件流格式,可由 EventSource 或 fetch 消费
WebSocket同一连接双向通信;SSE 也可配合另一路 HTTP 控制请求
其他 HTTP Streamingfetch + ReadableStream 消费 JSONL 等格式,需自行解析

⑤ Frontend State Manager(状态层)

职责:集中管理流式状态,供 UI 组件消费。

状态结构示意(Message、ToolCall 由应用定义;并发消息需独立 buffer,任务终态也需另建模):

interface UIState {
  messages: Message[],           // 消息列表
  streamingBuffer: string,       // 当前正在生成的文本 buffer
  toolCalls: ToolCall[],         // 工具调用列表
  extractedInfo: object,         // 结构化提取信息
  status: "idle" | "streaming" | "error"  // 流状态
}

推荐工具:

  • Zustand(轻量,适合中小项目)
  • Redux Toolkit(成熟,适合大型项目)
  • XState(状态机,适合复杂状态流转)

依赖路径

Token Stream → Chunk Aggregator → Semantic Router → Event Transport Adapter → Frontend State Manager
     ↑                ↑                  ↑               ↑              ↑
  LLM Provider    聚合策略          分流规则         传输协议        状态模型

稳定契约可以减少改动范围,但下列隔离均有条件:

  • 换 LLM Provider → 若事件语义兼容,可主要改第 ① 层
  • 优化聚合策略 → 主要改第 ② 层,同时验证延迟与缓冲
  • 增加新的输出类型 → 改第 ③ 层 + 前端 reducer
  • 从 SSE 切到 WebSocket → 修改传输适配及客户端连接/恢复逻辑
  • 换状态管理库 → 主要改第 ⑤ 层

对比与易混淆点

  • 分层不是必须的:简单场景可以跳过某些层(比如不需要 Semantic Router,直接透传 text)。
  • 层与层之间不是严格串行:有些事件可能跳过 Chunk Aggregator 直接到 Semantic Router(比如 tool_call 事件)。
  • 聚合不能保证改善卡顿;需区分 Provider 节奏、代理缓冲和前端渲染瓶颈。
  • 重连不自动恢复业务状态,EOF 不等于任务完成;恢复需要明确的序号范围、保留日志和终态契约。
创建于 2026/6/29 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本