随笔
Claude Code 源码解读 09:可观测性怎样让会话能恢复和复盘
从 transcript、parentUuid 链、content replacement、resume、background task 和 session state 看 Claude Code 的恢复与审计能力。
可观测性不是“有日志”,而是哪些消息能恢复、哪些只是 UI progress、大工具结果如何替代、resume 恢复哪些运行事实。
快速了解
- 可观测性不是有日志,而是有可恢复的消息链。
- progress 是 UI 状态,不应该污染 transcript 恢复链。
- resume 恢复的不只是 messages,还包括 worktree、agent、mode、cost、context collapse 等运行事实。
- content replacement 让大工具输出既不挤爆上下文,又能保持恢复一致性。
如果只想快速理解,可以先读这一节;如果要看源码机制,再往下看“主线与场景插入分类”和机制图。
设问与回应
| 设问 | 回应 |
|---|---|
recordTranscript() 写的是日志,还是可恢复消息链? | recordTranscript() 写的不是普通日志,而是可恢复消息链。它记录用户消息、assistant 输出、附件、system 等可进入恢复轨迹的事实。 |
| 为什么 progress 不属于 transcript message? | progress 不属于 transcript message,因为它是 UI 进度状态,不是会话语义事件。把 progress 写进恢复链,会污染 parentUuid chain,甚至造成恢复分叉。 |
| content replacement 如何同时解决大输出和恢复一致性? | content replacement 的价值在于把大工具输出替换成可引用、可恢复的内容形态:上下文不会被大输出挤爆,恢复时仍能知道原始结果如何被承接。 |
processResumedConversation() 恢复的状态为什么不只是 messages? | processResumedConversation() 恢复的不只是 messages,因为 Harness 行为还依赖 session id、metadata、worktree、agent、mode、cost、context collapse 等运行事实。只恢复文本,系统不一定还能以同样边界继续执行。 |
主线与场景插入分类
| 机制/模块 | 分类 | 我保留的判断 |
|---|---|---|
recordTranscript() | 主线 + 可观测/恢复支撑 | 用户消息、assistant、attachment、system 等可恢复消息写入 JSONL |
isTranscriptMessage() | 主线恢复支撑 | 定义 transcript 可恢复消息类型;progress 不属于恢复链 |
parentUuid chain | 可观测/恢复支撑 | 通过父子链恢复会话轨迹,跳过 progress 防止 chain fork |
processResumedConversation() | 主线恢复支撑 | 恢复 session id、metadata、worktree、agent、mode、cost、context collapse |
notifySessionStateChanged() | 场景插入 + 可观测支撑 | 向 CCR / SDK / bridge 暴露 idle、running、requires_action 等状态 |
恢复不是把历史消息再发一次
真正的 resume 需要恢复运行环境的一部分事实:session id、metadata、worktree、agent、mode、cost、context collapse 等。如果只恢复 messages,模型也许能继续说话,但 Harness 行为已经变了。
系列收束:从 Codex 差异看 Harness 的可恢复性
先找主线功能,再找场景插入,再找治理横切,最后看恢复支撑。这套拆法也适用于 Codex:比较重点不在模型能力,而在 harness 如何组织协议、状态、权限、失败路径和审计材料。
在可观测性这一篇里,Codex 对比应该拆成几个更具体的问题:哪些事件会进入可恢复消息链,哪些只属于 UI progress;resume 恢复的是文本历史,还是 session id、worktree、agent、mode 这类运行事实;大工具结果被替换后,是否还保留足够证据支撑复盘;异常中断后,系统能否沿 parent chain 回到同一条协作轨迹。这个对比带来的设计理解是:agent harness 的可观测性不是记录越多越好,而是把“未来恢复还需要的事实”从“当下展示用的状态”里分离出来。