Agent Memory(Agent 记忆)
Agent 记忆(Agent Memory) 是指将 AI Agent(智能体) 或 Loop Engineering(循环工程) 的运行状态,写入单次对话上下文之外的持久介质中。它可以是 Markdown 状态文件、Linear/Jira 看板、GitHub Issue、PR 评论、数据库记录或运行日志。
核心原则是:Agent 会忘,仓库不会。 模型每一轮运行结束后,不能假设下一轮仍完整记得本轮上下文;长期任务必须把状态落到可读取、可审计、可恢复的位置。
记什么
一个可用的 Agent Memory 至少记录:
- 已完成的任务和验证结果
- 当前卡住的问题与失败原因
- 已经试过但失败的路径,避免下一轮重复
- 下次继续时的入口和优先级
- 需要人工确认的风险点
这些信息不是流水账,而是循环的控制状态。没有它,自动化任务每天早上都会像第一次运行一样重新理解世界。
三段式状态文件模板
实践中最有效的状态文件结构包含三段,职责明确不重叠:
以下示例背景:Agent 正在自动处理一个 Node.js 项目的 GitHub Issue,每天定时扫描新 bug、定位根因、提交修复 PR。每次运行结束后写入状态文件,下次启动时先读它,接着上次的进度继续。
# Project memory
## Verified facts ← 停止猜测这些
- 单元测试命令是 npm test,集成测试是 npm run test:e2e(两个不一样)
- 所有 API 错误码定义在 src/errors.ts,不在各 handler 文件里
- Issue #234 的根因已确认:并发写入时缺少锁,不是数据类型问题
## Lessons learned ← 通用经验提炼进 Skills
- 改 src/config/ 下的文件后必须重启开发服务器,热重载不生效
- 新建 API endpoint 要同时更新 docs/api.md,否则 CI 会失败
## Last session ← 续接,不要重启
2026-06-18 · 修好了 Issue #231 和 #233,#234 的锁方案已验证。
下一步:补 #234 的回归测试三段的分工:Verified facts 是停止重复验证的已知事实;Lessons learned 是等待提炼进 Skill(技能)的通用经验;Last session 是下一轮开始时的精确入口。
Compound Memory 模式
让记忆真正产生复利的三步操作模式:
- 离开前写入:每次运行结束时更新状态文件——记录经验教训、验证过的事实、下一步入口
- 开始时读取:每次运行开始时先读状态文件和相关 Skills,实现续接而非重启
- 蒸馏进 Skills:当某条经验具有普遍性(如"改 config 文件后必须重启服务器"),从状态文件毕业进入 Skill 文件——从此对所有未来项目生效
这三步形成复利:状态文件积累项目专属事实,Skills 积累通用经验,下一轮运行比上一轮更有效。
三种跨周期记忆形态
在 Loop Engineering(循环工程)中,记忆不是"保存聊天记录",而是让下一轮循环比上一轮更少犯错。常见形态有三种:
| 形态 | 存什么 | 作用 |
|---|---|---|
| Append-only execution log | 每轮做了什么、发现什么、验证结果如何 | 提供可审计历史,避免循环忘记已尝试路径 |
| Periodic consolidation | 定期把原始日志压缩为稳定模式、规则或结论 | 防止记忆线性膨胀到无法读取 |
| Explicit belief tracking | 一组可被新证据确认或推翻的显式判断 | 让循环能发现旧假设过期,而不是继续按旧状态行动 |
原始日志解决"记得住",周期性蒸馏解决"读得动",显式信念解决"会更新"。三者一起,记忆才从流水账变成可指导下一轮行动的控制状态。
Claude Managed Agents 的 session log 是这种记忆形态的平台化版本:所有 user events、tool results、status updates 和 harness 进展都以 append-only 事件流保存。harness 崩溃后,新 harness 可以 wake(session_id),读取 session 事件并从最后事件恢复;上下文窗口里是否保留完整历史则由单独的上下文工程策略决定。
循环操作状态文件(Loop Operation State File)
面向自动化 Loop 的状态文件与面向项目记忆的三段式结构侧重点不同——它追踪的是 Loop 本轮的操作运行状态:哪些任务在进行、哪些已完成、哪些被升级给人类、什么停止条件已满足。以 CI 分诊循环为例:
# Loop state · ci-triage
## Last run
2026-06-09 03:30 UTC · 7 failures classified, 3 fixes drafted, 4 escalated
## In progress
- claude/fix-auth-token-refresh — tests passing locally, awaiting CI
- claude/fix-flaky-payment-webhook — retry pattern applied, monitoring
## Completed today
- claude/bump-axios-1.7.4 → merged (CI green, deps loop verified)
- claude/lint-fix-pass-june-9 → merged
## Escalated to humans
- src/billing/refund.ts — tests failing in 3 ways, root cause unclear
- ci/staging-runner — infra timeouts, not a code issue
## Lessons learned (write here, not in chat)
- 2026-06-08: PowerShell hits TLS 1.2 issue on this Windows runner. Use bash.
- 2026-06-07: tests/e2e/checkout requires Stripe webhook secret in env. Skip if missing.
## Stop conditions met since last review
- /goal "all tests pass + lint clean" achieved on commit 3a7b8c1 at 02:14 UTC几个关键设计决策:
Lessons learned (write here, not in chat)是这类状态文件的核心字段——经验必须落到文件,不能只活在对话。对话压缩后下一轮 Agent 读不到;写进仓库的文件才能跨轮存活。Stop conditions met since last review防止 Loop 忘记自己已满足的完成条件,对有多个平行目标的长期循环尤其重要。- 操作状态文件与项目记忆模板可以共存:操作状态每轮更新;通用教训待提炼后迁移进 Skill(技能)。
状态文件的两种存放模式:
| 模式 | 位置 | 适合场景 |
|---|---|---|
| 仓库内 Markdown | STATE.md(项目根目录)或 .claude/ 下 | 版本控制、diff 可读、单人或小团队工作 |
| 外部系统 | Linear、GitHub Issues、数据库 | 跨仓库存活、可查询、需要多人可见性的生产循环 |
状态文件与规格文件配对:
对有 Goal Drift(目标漂移) 风险的长期循环,状态文件需搭配固定的规格文件(VISION.md 或 AGENTS.md):状态文件告诉 Agent 它在哪里,规格文件告诉 Agent 它要去哪里。每轮启动时先读规格文件再读状态文件,能防止约束随上下文轮次压缩而消失。
长时编码 Harness 的三件记忆
Anthropic 的 Long-running Agent Harness 案例把长时编码任务的记忆拆成三件互补产物:
| 产物 | 记忆角色 | 下一轮如何使用 |
|---|---|---|
feature_list.json | 外部规格与完成状态 | 找到最高优先级且 passes: false 的功能 |
claude-progress.txt | 人类可读的会话日志 | 理解上一轮完成了什么、卡在哪里 |
| git history | 可审计代码事实与回滚点 | 查看最近 diff,必要时恢复已知好状态 |
这三件东西分别回答“还有什么没做”“上一轮为什么这么做”“代码事实到底变了什么”。只保留其中一个都不够:纯 progress file 容易变成流水账,纯 git log 不解释任务意图,纯 feature list 则看不出实现过程中的异常和经验。
init.sh 也应视为记忆的一部分:它记录了“如何让项目跑起来”这个可复用事实。长时 Agent 每轮启动先运行基础端到端 smoke test,本质上是在读取记忆之后验证记忆仍然有效,避免在已损坏环境上继续推进。
Codex 的 durable project memory
OpenAI 的 Codex 长程实验把同一原则称为 durable project memory:把 spec、plan、constraints 和 status 写入 Markdown 文件,让 Codex 能在长时间运行中反复回读,防止目标漂移并保持稳定的 “done” 定义。
这组文件不是聊天记录备份,而是任务控制状态:
| 文件 | 记忆内容 |
|---|---|
Prompt.md | 目标、非目标、硬约束、交付物和 “done when” |
Plan.md | milestone、验收标准、验证命令、停止并修复规则、架构决策 |
Implement.md | 执行 runbook:按计划推进、验证每个 milestone、保持 diff scoped、更新文档 |
Documentation.md | 当前状态、决策原因、运行方式、demo 路径、known issues 和 follow-ups |
这个案例补充了 Agent Memory 的一个边界:不是所有记忆都应该由系统自动提取。对长程工程任务来说,最关键的记忆往往是人和 Agent 共同维护的项目文件,因为它们进入版本控制、可 review、可被下一轮执行直接引用。Codex Memories 可以辅助跨线程偏好和经验复用,但不能替代这种受版本控制的项目状态。
Token-Rich vs Token-Poor Loop
Loop 设计的第一个结构性选择,是上下文装多少历史进来。
Token-Rich Loop:每轮上下文包含完整对话记录、详细工具日志、长文档、嵌入式计划。
- 优点:历史可见度高、更少因缺失上下文出错、模型推理透明
- 缺点:Token 成本随轮次累积飙升、响应变慢、上下文窗口溢出风险高、难以多用户/长会话扩展
Token-Poor Loop:每轮上下文只含最近 2–3 条消息、摘要、按需检索的记忆。
- 优点:Token 消耗低、响应快、上下文限制更易管理
- 缺点:幻觉和重复操作风险上升、依赖健壮的记忆/摘要基础设施
这两种极端之间的平衡,正是记忆系统的工程价值所在:把需要"每轮都有"的状态交给记忆层,而不是把全部历史堆进上下文。
Memory-First Design(记忆优先设计)
Memory-First Design 是一种 Agent Loop 组织原则:在每一轮开始时,先检索记忆、再组装上下文,而不是把所有历史直接注入 prompt。
一轮完整循环的推荐顺序:
- 输入捕获:接收用户消息与元数据
- 记忆检索:查询持久记忆层(用户偏好、任务状态、长期约束)
- 上下文组装:把检索结果、近期对话、指令拼成 prompt
- 模型推理:LLM 调用 + 工具调用检测
- 行动执行:API 请求、文件写入、数据库操作
- 记忆更新:把本轮结果中值得保留的内容写回记忆层
这个模式的关键在步骤 2 和步骤 6——记忆在循环开始前被读取、在结束后被写入,而不是只作为"历史消息的附加备份"。
记忆作用域
记忆按粒度分为三类:
| 作用域 | 存什么 | 典型用途 |
|---|---|---|
| 用户级记忆 | 偏好、风格、调度、长期约束 | 个性化助手、跨会话延续 |
| Agent 级记忆 | 工具策略、已尝试的路径、专项技能 | 多 Agent 系统中各 Agent 独立状态 |
| 全局记忆 | 共享知识、团队约定、项目背景 | 多 Agent 协调、产品级知识库 |
在多 Agent 系统中,全局记忆和各 Agent 私有记忆共存:全局记忆用于协调,私有记忆防止 Agent 相互干扰。
Claude Code 的双轨实现
Claude Code 把“人给出的稳定指令”和“Agent 自己积累的经验”明确分成两条轨道:
- CLAUDE.md:由人维护,保存编码规范、工作流和架构约定;可作用于组织、用户或项目
- Auto Memory(自动记忆):由 Claude 维护,保存工作中发现的构建命令、调试经验、偏好和模式;以 Git 仓库为作用域,同仓库的 worktree 共享
Auto Memory 默认写入 ~/.claude/projects/<project>/memory/。其中 MEMORY.md 是精简索引,每次会话只加载前 200 行或 25KB;详细内容拆到主题文件,需要时再读取。这是“索引常驻、细节按需”的 Context Engineering(上下文工程) 设计:既保留跨会话连续性,又避免把全部历史塞进启动上下文。
它也揭示了 Agent Memory 的两个边界。第一,机器本地记忆不会自动跨机器或云环境共享,团队知识仍应进入版本控制下的 CLAUDE.md、规则或项目文档。第二,记忆和指令都只是上下文,不是强制配置;安全边界必须由权限、沙箱或 Hook 执行。可用 Claude Code 的 /memory 命令审计、编辑或删除记忆,避免错误经验长期污染后续决策。
Anthropic 的 containment 经验补充了第三个边界:持久记忆会成为持久 prompt injection 的载体。产品记忆、CLAUDE.md、挂载 workspace、scheduled/long-running agent 的状态目录都会跨会话重新加载;一旦注入内容写入这些位置,它不再是一次性工具输出,而会在每次启动时重新进入上下文。长期 Agent 因此需要 session startup 阶段的记忆扫描、来源标注和人工可审计入口,而不能只在运行中扫描网页或工具结果。
Deep Agents 的可写 AGENTS.md memory
Deep Agents允许在创建 Agent 时通过 memory 参数传入 AGENTS.md。这些文件与按需触发的 Agent Skills不同:memory 在启动时始终加载,并存放在配置的 StateBackend、StoreBackend 或 FilesystemBackend 中。Agent 还可以根据交互与反馈更新 memory,使偏好和模式跨 thread 延续。
这是一种具体产品语义,不能据此把所有 AGENTS.md 都理解为 Agent 自动维护的记忆。许多宿主仍把它当作由人或团队版本控制的项目指令;是否允许模型写入、写到哪个 backend、如何审计和回滚,必须由 harness 明确定义。
Codex 的双轨实现
Codex 同样把两类持久上下文分开:
| 机制 | AGENTS.md | Memories |
|---|---|---|
| 写入者 | 人或团队 | Codex 后台生成 |
| 内容 | 必须遵守的项目约定、命令和验证要求 | 从历史线程提取的偏好、工作流、技术栈和已知陷阱 |
| 存储 | 仓库或 CODEX_HOME 中的指令文件 | 默认位于 ~/.codex/memories/ |
| 加载 | 每次运行开始时构建指令链 | 启用后按配置注入后续线程 |
| 默认状态 | 自动发现并读取 | 默认关闭 |
因此,AGENTS.md 在广义上属于“写在会话之外、供未来运行读取”的外部记忆,但在 Codex 产品语义中应称为项目指令,不能与 Memories 混为一谈。官方建议把必须稳定生效的团队规则放进 AGENTS.md 或版本控制下的文档,把 Memories 当作本机的辅助回忆层,而不是唯一规则来源。
Memories 默认关闭,可在 Codex 设置中开启,或在 ~/.codex/config.toml 中配置:
[features]
memories = true开启后,Codex 不会在每个线程结束时同步写入记忆,而是等待线程空闲后在后台处理符合条件的历史。仍活跃或过短的线程会被跳过;剩余 rate limit 低于阈值时也可能暂缓生成。
flowchart LR
T["符合条件的历史线程"] --> I["等待线程空闲"]
I --> E["后台提取并脱敏"]
E --> M["~/.codex/memories/"]
M --> F["注入后续线程"]
~/.codex/memories/ 中的生成状态包括摘要、持久条目、近期输入和支撑证据。可以检查这些文件,但官方不建议把手工编辑它们作为主要控制方式。Codex 会对生成字段做秘密信息脱敏,但共享 CODEX_HOME 或记忆文件前仍应人工审查。
Codex App 和 TUI 的 /memories 可分别控制当前线程是否读取已有记忆,以及是否允许当前线程用于生成未来记忆;这些线程级选择不会修改全局开关。配置还可分别控制生成与读取、排除使用过 MCP 或 Web Search 等外部上下文的线程、设置生成所需的最低剩余 rate limit,以及覆盖提取和合并所用模型。Chronicle 则可从屏幕活动中恢复近期工作上下文,辅助建立记忆。
没有记忆层的典型问题
生产 Agent 在缺乏专用记忆层时会反复出现同类失效:
- 反复向用户询问同样的偏好或背景
- 长任务跨会话后无法续接,重新从头开始
- 用户约束(格式、禁用工具、截止日期)在几轮后消失
- 反复尝试已经失败的策略,无法跳过
- 跨会话响应风格不一致
长运行循环还会出现三种相互关联的遗忘性失效:细节丢失(遗忘文件路径、参数值等精确细节,每轮重新猜测)、目标漂移(丢失迭代计数和停止条件,循环无法判断自己已跑了多少轮)、灾难性遗忘(经过足够多次压缩后,Agent 甚至忘记自己的 pipeline 是什么)。此外还有自我强化失效:循环将自身的先前输出重新摄入,早期错误被每一轮当作事实,越来越难纠正——坏记忆不只是丢失信息,它把错误洗白成事实。
这些问题的共同根源不是模型能力不足,而是控制状态存在于上下文而非持久层。
Concept Drift(概念漂移)
长期运行的 Agent 记忆面临一个特有挑战:记忆会过期。
用户偏好变了、任务环境变了、之前"最佳路径"的约束已经解除——但记忆里存的还是旧状态。如果记忆系统不主动淘汰旧内容,过期记忆会比没有记忆更糟糕:Agent 会自信地按错误前提决策。
处理 Concept Drift 的策略:
- 为记忆条目添加时间戳和有效期
- 在每轮更新时检测新信息是否与已有记忆矛盾
- 定期让 Agent 或独立 Evaluator 审查并清理过期记忆
- 高优先级信息(如用户明确撤销的约束)立即标记失效
与上下文的区别
Context Engineering(上下文工程) 解决的是"这一轮模型应该看到什么";Agent Memory 解决的是"多轮之间什么不能丢"。上下文是短期工作区,记忆是长期状态层。
把所有历史都塞进上下文会带来 Token 成本和 Context Rot(上下文腐烂);把关键状态落到文件或看板、再由下一轮按需读取,才是可持续的做法。Token-Poor Loop 的可行性,正是建立在有记忆层的前提上——否则减少上下文意味着直接丢失状态。
记忆在循环规模下的现实约束
长运行循环使记忆问题比任何单次 Agent 运行都更难解决,原因有三:
上下文压缩是有损的。当窗口接近上限时,自动 compaction 会摘要历史以腾出空间,且例行丢弃 Agent 之后可能需要的细节。LongMemEval 基准测试(arxiv 2410.10813)量化了代价:商业助手在长期记忆任务上相对短上下文表现平均下降约 30%。循环面临的是二选一:保留全量历史(上下文腐烂)或压缩(丢失细节)。
循环运行到记忆系统的最弱区间。主流记忆 benchmark 上限约 1.5M tokens;一个多周的 Agent 循环可以轻松超越这个量级。Mem0(Mem0) 发布的 BEAM 基准是目前唯一在此规模测量记忆的公开数据:1M tokens 得 64.1 分,10M tokens 降至 48.6 分——越长的循环,记忆系统越弱。
召回不等于使用。MemoryArena(arxiv 2602.16313)发现:即使召回率接近饱和的系统,在记忆需要指导行动时仍然大量失败。循环需要的不是"能否回忆第 12 次尝试",而是"给定第 1 到 46 次的全部历史,第 47 次应该做什么"——这是超出一般召回 benchmark 的更高要求。
Token 成本是真实约束。实践者测算:单 Agent 循环每轮 5 万至 20 万 token,Agent fleet 每轮 50 万至 200 万,定期循环每周数百万。把过期历史带入上下文不只是质量风险,还是每次调用都在付账的成本项。
前沿:记忆作为主动行为
记忆层正在从被动文件演变为循环中的主动步骤:
Cloudflare Agent Memory(2025)在上下文 compaction 时主动干预:不是丢弃旧内容,而是提取并去重值得保留的事实,让多周运行的 Agent 积累记忆而不是在每次压缩时丢失记忆。这把"记忆维护"从运营负担变成了系统级能力。
MemAct / Memory as Action(arxiv 2510.12635)训练 Agent 把编辑自身工作记忆作为一个可主动调用的行动——像调用工具一样调用"更新记忆"。论文报告:14B 模型在平均上下文长度减少 51% 的情况下,性能与约 16 倍大的模型持平。该论文是未经同行评审的预印本,且基于作者自有 benchmark,结论应视为方向性而非定论;但方向本身是明确的:记忆维护成为循环的一个步骤,而非事后的文件操作。
在循环工程中的位置
Agent Memory 是 Loop Engineering(循环工程) 的第六个隐含组件。自动化、工作树、Skill、连接器、子智能体让循环能跑起来;记忆让循环能接着跑。
在无人值守的循环里,记忆尤其关键:Verifier 的结论、CI 失败摘要、PR 状态、人工收件箱都必须写到外部系统,否则循环无法可靠判断"已经做过什么"和"下一步该做什么"。
长运行循环面临的细节丢失、目标漂移、灾难性遗忘和自我强化失效(见"没有记忆层的典型问题"一节),在没有外部记忆层的情况下会随轮次复利到不可控规模。
记忆是调试难点
引入记忆层后,Agent 的行为依赖于记忆内容,而记忆内容在运行时动态变化。这给调试带来新挑战:
- 同样的输入在不同时刻可能触发不同行为(因记忆不同)
- 错误行为的根因可能是若干轮前写入的某条过期记忆
- 多 Agent 系统中全局记忆的写入顺序可能引入竞争条件
因此,健壮的记忆系统需要配合完整的日志(记录每轮写入了什么、检索到了什么),才能在出错时可溯源。
写入质量:什么不该进记忆
引入记忆层后,一个常见陷阱是让 Agent 把所有中间思考都写进去——“我刚刚读了三个文件"“我准备修改某个函数”。短期看很勤奋,长期看全是噪音。
坏记忆比没有记忆更糟糕。错误记忆会在后续任务里反复影响 Agent 判断,且往往难以发现根源(因为记忆内容在运行时动态变化)。写脏的记忆层相当于把错误洗白成事实。
值得写入记忆的标准:下一个会话能否直接用到这条信息?
| 值得写 | 不值得写 |
|---|---|
| 已验证的命令和测试路径 | 中间调试步骤 |
| 项目约定(测试命令、发布流程) | 单次查阅的文件路径 |
| 用户的长期偏好或约束 | 本轮的临时任务状态 |
| 可复用的失败教训 | 已尝试但失败的一次性路径 |
| 决策与选型原因 | 对代码的描述性摘要 |
对应到每次任务结束时的写入模板:任务摘要、涉及的文件或模块、通过/失败的命令或测试、可复用的教训。最后这一条是核心——没有它,记忆只是流水账。
相关概念
- Loop Engineering(循环工程) — Agent Memory 是长期循环的状态层
- Mem0(Mem0) — 提供语义检索和大规模记忆 benchmark 数据的具体工具
- EverOS — 以 Markdown 为事实源的 Agent 记忆工具,Add/Flush/Search 为核心 API
- Skill(技能) — Skill 存稳定规则,Memory 存动态状态
- Context Engineering(上下文工程) — Memory 通过按需读取降低上下文负担
- Context Rot(上下文腐烂) — 长历史不宜直接堆进上下文窗口
- Eval(评估) — 评估器的判断结果是值得写入记忆的典型内容
- Agent Loop(智能体循环) — Memory-First Design 是组织 Agent Loop 的具体模式
- Second Brain(AI 第二大脑) — Agent Memory 在个人知识管理场景的具体实现模式
- Obsidian — 以本地 Markdown Vault 实现 Agent 记忆存储的代表性工具
- Claude Code — 用 CLAUDE.md 与 Auto Memory 实现双轨项目记忆