认知结算——Run 结束时 Agent 的“做笔记”

2026-10-05·编排与协作·TaskMemory
Agent 完成任务后还需要做什么?答案是'做笔记'——回顾整个对话,产出四类认知产物:会话连续性快照、长期记忆、反思、经验教训。这个叫做'认知结算'的阶段是 Run 生命周期的强制终态——不是可选的后处理,是必须完成的闭环。
一个被忽视的时刻
Agent 完成了用户的请求——代码重构做完了、测试通过了、结果发给用户了。
然后呢?
在大多数 Agent 框架中,"然后"就是——什么都不做。Run 结束,资源释放,等下一次请求。
但这个"什么都不做"的瞬间,有价值的信息正在消失:
- 模型此刻对整个任务有最完整的理解——它知道所有步骤的细节、所有决策的理由、所有走过的弯路。这些信息分散在 200+ 条消息中。下一次 Session 开始时,这些消息会被丢弃或压缩为一段模糊的摘要。
- 模型此刻能做出最好的"认知提炼"——它知道哪些发现值得长期记住("这个代码库的 DAO 层普遍缺少参数化查询"),哪些只是过程噪声("第 47 个文件的 grep 结果是空的")。
- 模型此刻能识别模式和教训——"每次涉及 BaseDAO 的修改都需要同时改测试基类"是一个跨任务的规律,但模型只有在完成整个任务后才能看到这个全貌。
如果不在 Run 结束时"做笔记",这些认知产物就会随着对话上下文的释放而永久丢失。

什么是认知结算
认知结算(CognitiveSettlement)是 Run 生命周期中工作阶段之后、真正结束之前的一个强制阶段。
Run = 工作阶段 + 认知结算
工作阶段(面向用户):
for {
组装上下文 → LLM → 工具调用 → 执行 → 继续
组装上下文 → LLM → 文本回复 → 交付给用户
}
→ 工作阶段结束
认知结算(面向系统,用户不可见):
→ 一次 LLM 调用(同一模型、同一上下文、无工具)
→ 产出四类认知产物
→ 校验 + 持久化
→ Run 真正结束
关键设计选择:
- 使用主对话模型——不是辅助模型、不是规则引擎。只有做过这个任务的模型才知道哪些决策是重要的。
- 用户不可见——Settlement 的 LLM 调用不通过 SSE 推送到前端。用户看到的是"任务完成"——背后的笔记过程是透明的。
- 强制执行——不依赖模型"记得做笔记"。无论模型怎么结束工作阶段(正常完成、用户取消、超时、循环检测),Settlement 都会执行。唯一的例外是进程级崩溃(panic)——此时无法做 LLM 调用。
- 有降级——Settlement 可能失败(模型超时、返回格式错误)。失败后三次重试,穷尽后退到"机械 fallback"——从即将被丢弃的消息中提取工具证据作为保底。

四类认知产物
产物一:SessionState——会话连续性快照
SessionState 是对当前 Session 的结构化认知快照——"我们在做什么、做到哪了、关键决策是什么、还有什么没做"。
包含的字段(概念描述):
- pending_task:当前还没完成的任务描述
- goal:最终目标
- current_phase:当前处于什么阶段
- completed_actions:已完成的动作列表(每个带文件路径和摘要)
- key_decisions:关键决策列表
- rejected_paths:被否定的备选方案
- open_questions:未解决的问题
- plan_snapshot:Plan 的当前状态快照
- action_items:待办事项
SessionState 是下一轮上下文的唯一历史来源。 当下一个 Run 开始时,系统提示词中的历史信息仅从 SessionState 注入——不从旧消息推断。这意味着即使旧消息被完全丢弃,SessionState 中记录的信息仍然保留。
与"Plan 作为外部工作记忆"一章的关系:SessionState 和 Plan 是互补的——Plan 记录"接下来做什么"的步骤,SessionState 记录"做过什么"和"为什么"的认知快照。
产物二:MemoryEntries——长期记忆候选
Settlement 从整个对话中提取值得长期记住的信息——用户偏好、领域知识、工作惯例。
示例:
- kind: preference, content: "用户偏好使用 Repository 模式而非 Active Record"
- kind: fact, content: "项目 X 的 DAO 层普遍缺少参数化查询"
- kind: correction, content: "UserDAO.findByEmail() 有 admin 路径,迁移时不能删除"
这些候选条目走标准的记忆写入管线——质量门控、重复检测、安全扫描(凭据泄漏检查、不可见字符检测)。通过门控的才成为持久记忆。
与 TaskMemory 的 Learnings 的区别:Learnings 是 Agent 自己总结的"经验教训"(元认知),MemoryEntries 是从对话中提取的"事实和偏好"(客观知识)。两者在 Settlement 中同时产出,但流向不同的存储。
产物三:Reflections——自我反思
Reflections 是 Agent 对自身工作质量的反思——"哪里做得好、哪里走了弯路、下次可以怎么改进"。
示例:
- "步骤 3 花了太多时间在分析 CacheDAO 的自定义连接池上——
下次遇到非标准组件时应该先检查是否可以跳过"
- "Decision 2.2(SQL 注入修复纳入迁移步骤)被证明是正确的——
没有增加额外工作量"
Reflections 不进入持久记忆——它们存储在 Run 级别的记录中,供可观测面板和后续分析使用。运维人员可以通过 Reflections 了解 Agent 的"思考过程"——哪些策略有效、哪些不有效。
产物四:Learnings——从 TaskMemory 到经验积累
Learnings 是从整个任务中提炼的可复用经验——不是对某一步的发现(那是 Finding),是对整体模式的认识。
示例:
- "Java 项目中含 BaseDAO 基类时,Repository 模式迁移效率显著高于 Active Record"
- "DAO 层的 SQL 注入修复可以和接口迁移合并进行,不需要单独一轮"
Learnings 走记忆写入管线晋升为持久记忆——但不是直接写入。它们经过去重(是否已经记过类似的教训)、质量评估(是否足够具体和可操作)、时效性检查(是否和已有知识矛盾)后才被接纳。
为什么是 Run 结束时,不是过程中

"过程中做笔记"的问题
一个替代设计是:Agent 在工作过程中随时调用 memory tool 记录发现和决策。不需要等到 Run 结束。
Claude Code 和 Anthropic 的 Memory Tool(memory_20250818)就是这种设计——模型可以随时在 /memories 目录写笔记。
这种设计有效——但不可靠。
问题在于:模型经常"忘了"记笔记。 在 200 轮的密集工具调用中,模型的注意力完全在"完成当前步骤"上——调用 memory tool 去记录一个发现是"额外工作",模型可能判断"这不紧急,等会儿再说"然后永远不说。
这不是模型的缺陷——是激励结构的问题。调用 memory tool 需要一轮额外的 LLM 调用,有 token 成本,而模型的核心目标是"完成用户请求"而非"维护自己的记忆"。在有限的预算下,模型合理地优先完成任务。
Settlement 是"架构保证"
Settlement 不依赖模型主动做笔记——它在 Run 结束时强制执行。这是一个架构层面的保证,不是提示词层面的建议。
类比:公司的周报制度。你不能指望所有人在工作过程中随手记录自己的进展——但你可以要求所有人周五交周报。Settlement 就是 Agent 的"周报"——Run 结束时必须交。
"全部终止路径"都执行 Settlement
Settlement 不只在正常完成时执行——在所有终止路径上都执行:
- 正常完成(end_turn)→ Settlement → EventDone
- 用户中断(interrupt)→ 工作阶段终止 → Settlement 仍执行(带中断标记)
- 异常检测(CycleDetector / ErrorStreak)→ 异常处理 → Settlement 仍执行
- 预算用尽(BudgetCheckFn 返回 Exhausted)→ Settlement 仍执行
唯一例外:panic_stop(进程级崩溃)——此时整个进程在恢复中,无法做 LLM 调用。
中断后仍执行 Settlement 是一个破坏性变更——之前用户中断后 Run 立即终止。现在中断后会有一个短暂的 Settlement 阶段(一次 LLM 调用,通常 2-5 秒)。这个延迟是值得的——中断时 Agent 可能已经完成了 80% 的工作,Settlement 保存了这些工作的认知快照,下次恢复时不用从零开始。
Settlement 的降级机制
Settlement 是一次 LLM 调用——可能失败。
三次重试
每次重试使用"升级的提示词"(escalating prompt)——第一次失败后提示词变得更明确、更约束,帮助模型产出正确格式的输出。
mechanicalFallback
三次重试穷尽后,退到"机械 fallback"——从即将被丢弃的消息中提取工具证据(tool evidence),作为 Pinned system message 注入到下一轮上下文中。
机械 fallback 不产出 SessionState——它只保留工具调用的关键结果("编辑了 auth.go"、"测试通过了"),不产出认知层面的摘要("选了方案 B 因为...")。
信息保全的首选是认知交班(Settlement 产出的 SessionState),不可用时机械压缩提供确定性 fallback。 不是"纯靠容量保全"——那样 Settlement 失败时证据蒸发。也不是"纯靠机械保全"——那样丢掉了认知层面的理解。
降级标记
Settlement 降级后写入 degraded=true + degraded_reason(分类常量)到日志。运维人员可以通过监控 degraded 率来判断 Settlement 的健康状况。
Settlement 失败不触发新的终止——Run 已经在结束过程中了。降级只是意味着下次 Session 的初始上下文质量会低一些——不是 Run 失败。
行业中类似的机制
Claude Code:没有显式 Settlement
Claude Code 在 Run 结束时没有专门的"做笔记"阶段。会话状态的保存依赖两个机制:
- Auto Memory:模型可以主动在
/memories目录写笔记——但这是可选的 - Session Memory Compaction:自动摘要——但这是"压缩"而非"认知结算",摘要的目的是释放空间而非提炼知识
Claude Code 的 GitHub issue #70555 中一个用户描述了缺乏 Settlement 的后果:"the long-session 'goes dumb' problem"——长会话后 Agent "变蠢",因为关键认知产物在压缩中丢失了,没有一个专门的阶段把它们从对话中提炼出来。
Anthropic 在 Claude Cookbook 中推荐了 "structured note-taking" 模式——Agent 维护一个小文件(当前目标、决策历史、下一步),定期更新。这和 Settlement 的 SessionState 本质相同——都是结构化的认知快照。但 Cookbook 的方案依赖模型主动维护文件,Settlement 是架构层面的强制执行。
LangGraph Checkpointer:结构化但不认知
LangGraph 的 Checkpointer 在每个节点执行后自动保存 State——这是架构保证。但保存的是 State 对象的结构化快照,不是"LLM 对完整对话的认知审视"。
区别在于:Checkpointer 保存的是"数据"(变量值、列表内容),Settlement 保存的是"理解"(为什么选了方案 B、哪些弯路值得避免)。
"数据"可以被机械地保存。"理解"需要 LLM 的认知能力。 这是为什么 Settlement 必须是一次 LLM 调用——而不是简单地序列化 TaskMemory 到磁盘。
Microsoft Foundry State Store:持久化但不智能
Microsoft Foundry 的 Durable State Store 提供了跨崩溃持久化——append-only checkpoints + progress pointer。但它是一个 key-value store——存什么完全由开发者决定。
如果开发者不在代码中显式保存决策理由和认知快照,State Store 中就只有步骤状态和中间数据——丢失了认知层面的信息。
Settlement 的价值在于它把"保存什么"的决策也交给 LLM——由做过任务的模型自己判断什么值得长期记住。 开发者不需要预定义"哪些信息重要"——模型在认知结算时自主提取。
认知结算 vs 压缩:不同的目的
容易混淆的两个操作:
| 维度 | 压缩(Compaction) | 认知结算(Settlement) |
|---|---|---|
| 目的 | 释放上下文窗口空间 | 提炼认知产物 |
| 时机 | token 超限时触发 | Run 结束时强制执行 |
| 操作 | 摘要旧消息、丢弃细节 | 产出四类结构化认知产物 |
| 对象 | 对话消息 | 完整的对话上下文 |
| 产出 | 压缩摘要(替换旧消息) | SessionState + Memories + Reflections + Learnings |
| 是否有损 | 有损(设计如此) | 尽量无损(关键信息应完整保留) |
| 模型 | 可以是辅助模型 | 必须是主对话模型 |
执行顺序:Settlement 在压缩之前——先提取认知产物,再做容量清理。保证 Settlement 的输入是主模型的"认知最高点"(完整上下文),而不是压缩后的残骸。
一个更大的图景
把 TaskMemory 四篇文章串起来看:
Agent 的三种记忆(心智模型)
→ 任务执行态必须搬出来(压缩的破坏性)
→ 五种制品(结构化的工作便签)
→ 认知结算(制品变成持久知识的闭环)
这四层构成了一个完整的闭环:
- 识别问题:Agent 在长任务中"忘事"
- 分析根因:关键信息泡在可压缩的消息中
- 设计方案:五种结构化制品、物理解耦于消息
- 闭合循环:Run 结束时强制做笔记,制品晋升为持久知识
这个闭环的每一环都有对应的行业验证——Geodocs 的状态分层规范、Claude Code 社区的痛点报告、Anthropic Cookbook 的 Note-Taking 推荐、Microsoft Foundry 的 Durable State Store。
差别在于:大多数方案解决了一环或两环。完整的闭环——从识别问题到认知结算——是我们在 1.3M token 企业客户事故之后被逼出来的。
不是"我们有多好"——是"被逼到这个程度后必须做到这样才行"。
你现在能做什么
1. 每次长对话结束时主动做"结算"。 在最后一条消息中加:"在结束之前,请总结这次对话的关键成果:完成了什么、做了哪些重要决策(及理由)、还有什么没做完、学到了什么经验。写入 session-summary.md。"
2. 新对话开始时注入上次的总结。 开头消息加:"请先读取 session-summary.md 了解上次的工作成果,然后继续。"这是手动版的 SessionState 注入——不依赖框架支持。
3. "做笔记"用主对话模型,不用辅助模型。 如果你在建 Agent 框架——让做过任务的那个模型自己总结(它知道什么重要)。用另一个模型总结等于让没参加会议的人写会议纪要——可以写,但质量低。
4. 结算失败要有 fallback。 结算是一次 LLM 调用,可能失败。失败后保底方案:从最近 N 轮对话中提取工具调用的关键结果(文件修改了什么、测试结果如何),作为最低限度的进度记录。不完美,但比什么都不留好。
引用来源
- Anthropic Claude Cookbook, "Context engineering: memory, compaction, and tool clearing" — Context engineering: memory, compaction, and tool clearing | Claude Cookbook
- Claude Code GitHub issue #70555, "Working-state continuity" — "the long-session 'goes dumb' problem"
- Anthropic Memory Tool (
memory_20250818) — https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/memory - LangGraph Checkpointer documentation — Redirecting to LangGraph Documentation
- Microsoft Learn, "Manage state for long-running agents" — Durable State Store + checkpoint patterns
- Geodocs.dev, "Agent State Management Patterns Specification" — 四类状态分层
- IBM Granite Agent Cookbook, "Context Management" — Note-Taking 策略
- hidekazu-konishi.com, "AI Agent Memory Design Guide" — structured note-taking 作为第四机制
更多推荐


所有评论(0)