Session 不是一段扁平聊天记录,而是一棵 append-only 的任务树。它保存 header、message、model change、thinking change、compaction、branch summary、label 和 metadata;每个 entry 通过 id 和 parentId 形成分支,当前上下文由 leaf 回溯到 root 后生成。
为什么一个长任务可以中断、恢复、fork 和导出审阅,而不会丢失上下文?
- append-only 让历史可审计。
- parentId 让历史可以分支。
- leaf 表示当前恢复点。
- compaction 和 branch summary 让长历史仍能进入模型上下文。
源码推演(省略版)
Section titled “源码推演(省略版)”下面不是完整源码,而是把本课主线压缩成可以在文档里直接阅读的关键形状。读者即使不打开本地源码,也应该能看出运行时如何组织职责。
function appendEntry(parent: Entry, payload: Payload) { const entry = { id: newId(), parentId: parent.id, payload }; journal.write(entry); return entry;}
function contextForLeaf(leafId: string) { const branch = tree.walkToRoot(leafId).reverse(); return branch.flatMap(expandForModel);}- 这段源码形状说明持久化的核心不是“保存数组”,而是“保存可恢复的树”。
contextForLeaf()只取当前分支,避免不同尝试方向互相污染。- 导出、回放和评审都建立在 append-only journal 上。
设计一个 session browser 的输出,能展示 entry 数量、当前 leaf、分支树和某个 leaf 的上下文摘要。
- 能解释 append-only journal 的价值。
- 能说明 resume、fork、import/export 的关系。
- 能设计 session 元数据用于任务复盘。
- 实践题:基于本课的省略版源码,补出一个最小实现草图,要求写清输入、输出、副作用和错误处理。
- 思考题:本课机制如果只靠 prompt 约束,而不放进 harness 或 runtime,会出现什么工程风险?