LLM 输出四层模型
LLM 流式输出从原始 token 到最终 UI 状态的四层抽象:raw tokens → text deltas → semantic chunks → UI state。
#concept
#evergreen
#ai
#architecture
[!info] related notes
- 所属 MOC: LLM Streaming MOC
- 下游协议: Delta Stream, Append Event Stream, Full State Stream
- 聚合层: Chunk Aggregator
- SSE 基础: SSE
- 关系笔记: LLM Streaming 分层架构
LLM 输出四层模型
一句话定义
LLM 的流式输出可以抽象为四层:raw tokens → text deltas → semantic chunks → UI state,每一层解决不同粒度的问题,它是理解数据处理的教学模型,不要求各层逐一经过,也不规定传输必须选择其中一层。
核心机制
第 1 层:Raw Tokens
模型生成的是 token ID;解码后的片段可能对应词、标点或字节片段。下面只是可读示意,不是某个 tokenizer 的真实切分结果。
token: "你"
token: "好"
token: "世"
token: "界"
应用通常从 Provider 接口拿到已解码的文本片段与结构化事件,而不是原始 token ID。
第 2 层:Text Deltas
将原始 token 组织为文本增量。许多文本生成接口传递这类增量;SSE 本身不规定业务 payload。
delta: "你"
delta: "好"
delta: "世界"
特点:
- 每个 delta 是同一段文本的追加内容
- 前端操作:
content += delta - 对应 Delta Stream 协议
第 3 层:Semantic Chunks
可按文本边界聚合,或消费 Provider 原生的工具/结构化事件。文本分句不会自动变成可靠工具调用;不同目标的碎片须分别累积。
{ "type": "text", "content": "你好世界" }
{ "type": "tool_call", "name": "search", "args": {} }
{ "type": "extracted_info", "data": {} }
特点:
- 每个 chunk 有明确的语义类型
- 前端按类型分发处理
- 可作为 Append Event Stream 的 payload;事件也可以直接携带 text delta
第 4 层:UI State
前端最终渲染的状态。包括消息列表、工具调用状态、结构化信息面板、加载状态等。
{
messages: [...],
toolCalls: [...],
extractedInfo: {...},
status: "streaming"
}
这一层由前端状态管理器(Zustand / Redux / XState)维护。
层级关系
Raw Tokens ← 模型内部 token ID
↓ token 解码与聚合
Text Deltas ← 接口返回已解码的文本增量
↓ 语义切分
Semantic Chunks ← 可选聚合;工具事件也可独立到达
↓ 状态更新
UI State ← Frontend State Manager 管理
设计问题:事件 payload 表达文本变化、业务事件还是某个对象的快照?这些形态可以在同一流中组合。
- 在第 2 层传输 → Delta Stream(打字机效果)
- 在第 3 层传输 → Append Event Stream(多步骤流程)
- 在第 4 层传输 → Full State Stream(编辑器场景)
边界与易混淆点
- SSE 定义基于 HTTP 的事件流格式与浏览器消费机制,但不定义应用的消息、工具和任务状态 schema。
- Token ≠ Delta ≠ Chunk:一个 token 可能是半个字,一个 delta 可能包含多个 token,一个 chunk 可能包含多个 delta。
- 不是每层都必须存在:简单场景可直接将接口文本增量归约到 UI,不必再做语义聚合。