KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

03. 屏幕上的字为什么不等于运行完成? — keel 龙骨

流式输出让用户更快看到模型生成的内容,但它改变的是传输方式,不是运行完成的含义。

流式输出让用户更快看到模型生成的内容,但它改变的是传输方式,不是运行完成的含义。

增量和完整结果是两种对象

一次流式响应可能分成:

chunk 1: "支付"
chunk 2: "服务"
chunk 3: "发生超时"
chunk 4: done

前几个 chunk 只能用于增量展示或累积,不能直接作为最终答案,更不能因为看到了半个工具名就执行工具。

事件和消息也不是同一个概念

对象 用途 示例
Message 给模型看的协议历史 assistant、tool
Stream Chunk 供应商发来的增量传输 content_delta
Runtime Event 运行时已经发生的事实 tool.started
Final Result 运行对外给出的结论 completed

事件是给 Harness、日志和回放系统看的;消息是给模型协议看的。一个事件可能导致一条消息,但两者不能互相替代。

运行流式示例

python courses/foundation/agent-harness/course/project/examples/02_stream.py

运行前预测:如果流在第三个 chunk 后断开,程序能否把已有文字当成最终答案?如果已经收到部分 tool call 参数,能否执行?

正确处理应类似:

flowchart TD
    A[收到 chunk] --> B[记录 model.delta 事件]
    B --> C[累积 content/tool fields]
    C --> D{流是否完成?}
    D -->|否| A
    D -->|是| E[组装完整响应]
    E --> F[协议校验]
    F --> G[最终回答或工具决定]
    D -->|失败/取消| H[记录 failed/cancelled,不提交半成品]

事件序列为什么需要 sequence

事件可能来自模型、工具、用户取消和后台 worker。每条事件至少应带:

run_id       属于哪次运行
event_id     这条事件的唯一 ID
sequence     在本次运行中的顺序
event_type   发生了什么
occurred_at  什么时候发生

时间戳可能因为并发而相同或乱序,sequence 让回放有明确顺序。项目示例中的事件是内存实现,后续会讨论持久化。

流式 thinking 不等于权限

thinking 是模型生成过程的增量字段。它可以帮助调试,但不能成为工具授权依据,也不应默认展示或进入长期记忆。真正能执行动作的,必须是完整、结构化、经过策略检查的决定。

本章自测

回答下面三个问题:

  1. 为什么不能在收到半个工具参数时执行?
  2. 为什么 model.delta 事件不能直接当作 run.completed?
  3. 为什么取消后仍要处理迟到的 chunk?

下一章把“完整模型输出”进一步变成内部协议对象:Decision、Action 和 Result。

下一章:怎样把模型建议变成程序输入?

进入 keel 阅读