Delta Stream vs Append Stream

Delta Stream 和 Append Stream 表面上都"只返回增量",但增量对象完全不同——Delta 增量的是同一文本字段,Append 增量的是事件日志中的新增记录。

#type / synthesis #status / evergreen #tech / ai #tech / architecture

[!info] related notes

Delta Stream vs Append Stream

范围

对比 LLM Streaming 的两种最主流协议模式:Delta Stream(文本增量流)和 Append Event Stream(事件追加流)。它们表面上都”只返回增量”,但增量的对象、前端的消费方式、适用场景完全不同。

为什么要放在一起理解

很多开发者混淆这两种协议,因为它们都”只传增量”。但选错协议会导致:

  • 用 Delta Stream 做 Agent 系统 → 无法优雅表达工具调用和结构化数据
  • 用 Append Stream 做简单聊天 → 前端 reducer 过度复杂,打字机效果难实现

理解它们的本质区别,才能在正确场景选择正确的协议。

核心区别:增量对象不同

Delta Stream:增量的是 content

// 前端操作
message.content += delta.content

事件示例:

{ "type": "text.delta", "content": "你" }
{ "type": "text.delta", "content": "好" }
{ "type": "text.delta", "content": "世界" }

所有 delta 都在扩展同一段文本。最终结果:

message.content = "你好世界"

Append Stream:增量的是 event

// 前端操作
events.push(event)

事件示例:

{ "type": "message.append", "content": "你好" }
{ "type": "tool_call", "name": "symptom_extract", "args": {...} }
{ "type": "extracted_info", "data": { "symptom": "头痛" } }
{ "type": "message.append", "content": "根据你的描述..." }

每个事件是独立的结构化记录,可能有不同的类型和目标。

一句话判断标准

// 如果前端收到事件后主要做:
currentMessage += content
// → Delta Stream

// 如果前端收到事件后主要做:
switch (event.type) {
  case "message.append":
  case "tool_call":
  case "extracted_info":
  case "status":
}
// → Append Stream

对比表

对比点Delta StreamAppend Stream
增量对象同一个文本字段新事件 / 新片段 / 新消息项
前端操作content += deltaevents.push(event) 或 reducer 分发
关注点一条消息怎么逐步生成一个 AI 流程产生了哪些事件
数据形态偏 text diff偏 event log
UI 效果打字机输出多步骤状态展示
典型用途ChatGPT 回答生成Agent / workflow / tool call
带宽⭐ 最低
延迟⭐ 最低
前端复杂度中(维护 buffer)中(reducer 分发)

依赖路径 / 演进链

简单聊天 → Delta Stream 就够
    ↓ 增加 function calling
需要表达工具调用 → 在 Delta 基础上扩展事件类型
    ↓ 增加结构化提取、多步骤流程
事件类型越来越多 → 自然演进为 Append Stream
    ↓ 需要统一事件格式
加 Structured Streaming 封装 → 工业级协议

实际系统的做法

大多数生产系统不是纯 Delta 或纯 Append,而是组合使用

外层用 Append 管理流程,内层用 Delta 管理文本生成。

{ "type": "message.started", "message_id": "m1" }        // ← Append
{ "type": "text.delta", "message_id": "m1", "content": "你好" }  // ← Delta
{ "type": "tool_call", "name": "symptom_extract" }         // ← Append
{ "type": "extracted_info", "data": {...} }                // ← Append
{ "type": "text.delta", "message_id": "m1", "content": ",我已经整理了你的症状。" }  // ← Delta
{ "type": "message.completed", "message_id": "m1" }       // ← Append

易混淆点

  • “都是增量”不等于”一样”:Delta 的增量是文本扩展,Append 的增量是事件追加。
  • Append 不排斥文本效果:Append Stream 也可以实现打字机效果,只是需要额外处理(比如 message.append 事件的 content 字段逐字到达)。
  • 选择标准不是”哪个更好”而是”场景需要什么”:只做聊天选 Delta,做 Agent 选 Append,做复杂系统选组合。
创建于 2026/6/29 更新于 2026/7/15