LAYER 03 · 追踪 Agent 主干
SessionEvent:唯一真源
消息历史不是被保存的数组,而是从仅追加、可扩展、无损 JSON 日志派生的投影
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 认领一次工作。