LAYER 03 · 追踪 Agent 主干

SessionEvent:唯一真源

消息历史不是被保存的数组,而是从仅追加、可扩展、无损 JSON 日志派生的投影

20 min3 处源码锚点upstream@47f9438
append-only facts → surface projection → derived messages
本章要解决的问题

为什么连原始 assistant/chunk 都要持久化,而不是只存最终消息?

先建立直觉

会话日志像飞行数据记录器:乘客广播只是其中一个投影;调查、回放、计量和仪表盘都从更细粒度的原始事实重新构建。

MECHANISM

机制拆解

SessionEventMap 通过 declaration merging 扩展;核心 turn/step/message/tool 事件与 goal、approval、compaction、schedule 等领域事件共存。

deriveMessages() 从当前 surface 位置顺序投影模型历史;替换节点的 seq 可以更大但位置更靠前,所以不能把 seq 数值当表面顺序。

第 1 步 / 共 5 步

提交事件

先校验无损 JSON,再分配连续 seq。

INVARIANTS

无论怎么扩展,都不能破坏

  • 模型可见即已记录
  • seq 连续但不等于表面位置
  • 提交点与观察者错误隔离
FAILURE MODES

最容易踩中的坑

  • ×另存一份 messages 作为真源
  • ×重放时跳过 log-only 事件造成领域状态漂移
  • ×把 UI 临时状态写成模型可见消息
VERIFY IN SOURCE

不要相信结论,去源码里复核

以下链接固定到官方 deepseek-harness@47f9438;查看当前上游时请留意后续 breaking changes。

KNOWLEDGE CHECK

先停十秒,再揭晓答案

为什么 compaction summary 要用新的 user/message 替换表面,而不是修改旧事件?

为什么下一章紧接在这里

有了事实日志,Turn 与 Step 才能成为清晰的持久边界。下一章沿 Inbox 认领一次工作。

Learn DeepSeek Harness

独立教学项目。解释力来自源码,判断边界以官方仓库为准。