产品细节会随版本变化,下文对照公开文档与撰写时的使用体验整理;具体字段、路径和限额以各产品官网为准。

Agent Memory 是一套跨会话保存、选择、更新和取回上下文的工程机制。它要解决的不是“把所有历史都记住”,而是把用户偏好、项目规则、任务状态、历史经验和可复用流程放到正确位置,并在未来任务中以可控、可审查、可删除的方式重新进入上下文。

Agent Memory 是 harness 中的长期层:它负责决定哪些信息应该跨会话保留,保留成什么形态,什么时候被检索回来,以及如何避免旧记忆污染新任务。

它不是一个单独的prompt,而是一组机制:

  • 显式项目说明:例如 AGENTS.mdCLAUDE.md.hermes.md
  • 自动长期记忆:例如项目 memory、用户 memory、历史摘要。
  • 程序性记忆:例如 Skills、rules、playbooks、custom commands。
  • 治理机制:例如查看、编辑、合并、删除、来源标注、权限隔离。

Agent Memory 想解决什么问题

LLM 的默认工作方式是上下文窗口。上下文窗口像短期工作台:用户任务、系统指令、工具输出、文件片段、搜索结果都临时放在这里。问题是,任务结束后这些内容不会自然变成下一次可用的长期知识。

这会导致几个典型痛点:

  1. 用户反复说明同样偏好。
  2. Agent 反复重新探索同一个项目,例如测试命令、目录结构、代码规范。
  3. 长任务中断后难以恢复,例如已经排查过哪些假设、哪些命令失败过。
  4. 过去的失败没有沉淀,例如某类 bug 的根因、某个工具的坑。
  5. 把全部历史塞进 prompt 又会增加成本、延迟和噪声。

所以 Agent Memory 的核心目标是:

  • 减少用户重复解释。
  • 提升跨会话连续性。
  • 让 agent 更稳定遵守项目规则。
  • 把失败经验转成未来行为改进。
  • 让长期信息可审查、可撤销、可迁移。

Agent Memory 的核心概念

1. 短期记忆

当前上下文窗口里的内容。

2. 长期记忆

跨会话保留的信息。

3. 显式记忆

这里的“显式记忆”是广义说法,更准确地说是人类可见、可编辑、可版本控制的显式长期上下文。很多产品不会把它直接叫 memory,但它确实承担了长期影响 agent 行为的作用。

典型形式:

  • AGENTS.md
  • CLAUDE.md
  • .hermes.md
  • README
  • 架构文档
  • 项目规则文件

显式记忆适合团队共享的稳定规则。它的优点是可审查、可讨论、可迁移。

4. 隐式或自动记忆

自动记忆是 agent 或系统从会话中自动提炼出来的内容。(每个系统不同)

典型形式:

text
自动生成的 memory 文件。
历史摘要。
用户画像。
provider 里的长期记忆。
对话结束后的 memory extraction。

Agent Memory 系统中的 Memory 生命周期

一个完整的 memory 系统,至少要包含下面几个阶段。

1. 观察

系统从对话、工具调用、文件变更、测试结果、用户反馈中观察候选信息。

2. 提取

从原始历史中提取稳定结论。

3. 路由

判断这条 memory 应该放在哪里。

候选内容推荐路由
团队共享规则AGENTS.md / CLAUDE.md
个人偏好用户 memory / USER.md
项目调试经验项目 memory topic
反复执行流程Skill / playbook
大量历史对话、Memory Cards、项目经验RAG / memory provider
实时状态MCP / API / 搜索

4. 写入

写入时要尽量保留下面这些元素:

text
结论。
来源。
适用范围。
更新时间。
可信度。
是否经过用户确认。

5. 检索

未来任务中,系统要判断哪些 memory 相关。

检索可以基于:

text
项目路径。
当前任务类型。
用户身份。
关键词。
embedding 相似度。
最近使用情况。
显式引用。

6. 注入

取回的 memory 不能原样无限塞入 prompt。要考虑:

  • 顺序:硬规则优先,证据和背景靠后。
  • 长度:越常驻越短。
  • 冲突:较新、较近、较明确的规则通常优先。
  • 来源:自动推断要弱于用户明确说明。

7. 更新和遗忘

Memory显然需要支持更新和遗忘

典型操作包括:

  • 合并重复记忆。
  • 删除过期记忆。
  • 替换错误记忆。
  • 降低不可靠记忆权重。
  • 把个人 memory 提升为项目规则。
  • 把散乱经验整理成 Skill。

只会写入、不会遗忘的 memory 系统,长期一定会退化。

Memory 是无权重更新的学习

Agent 可以不训练模型,也能在行为上“学会”某些东西。方式就是把过去的反馈转成未来上下文。

例如:

text
用户纠正一次:当前任务修正。
用户纠正多次:形成长期偏好。
某类错误反复出现:形成工作流规则。
某个流程被证明有效:沉淀为 Skill。

这就是无权重更新意义上的“学习”(in-context / prompt-level learning),改变的是未来上下文,而不是模型参数。

好的 Agent Memory 应该满足什么

1. 可见

用户应该能知道系统记了什么。

不可见的 memory 会带来两个问题:一是用户无法纠错,二是 agent 的行为变化无法解释。

2. 可编辑

Memory 不可能永远正确。用户应该能修改错误结论、删除过期偏好、合并重复内容。

3. 可撤销

尤其是个人偏好、身份信息、工作资料和历史对话,必须能删除。

4. 可分层

团队规则、个人偏好、项目经验、工作流、外部事实不能混成一层。

5. 可追溯

重要 memory 最好知道来源:

  • 是用户明确说过?
  • 是系统推断?
  • 是某次任务失败的复盘?
  • 是外部文档里的事实?

来源不同,可信度也不同。

6. 可评估

Memory 是否有效,要看它是否改善任务,而不是看记了多少条。

可以看这些维度:

维度要看什么
个性化是否更符合用户长期偏好,比如表达风格、格式、决策偏好
连续性跨会话后是否能接上之前的任务、项目和背景
任务成功率有 memory 后,任务完成率是否提升
重复解释减少用户是否少重复说明同样背景和要求
错误减少是否减少同类错误、重复踩坑、错误假设
检索相关性取回的 memory 是否真的和当前任务相关
记忆准确性memory 是否忠实反映用户说过或做过的事
过期控制旧偏好、旧项目状态是否会被及时更新或废弃
冲突处理新旧记忆冲突时,是否能优先采用更可靠、更近期、更明确的信息
安全与隐私是否避免保存敏感信息,是否能查看、删除、撤销
上下文污染是否把不相关历史带进当前任务,导致误导
成本与延迟memory 检索和注入是否显著增加响应成本或变慢

更简单地说,通用 Agent 的 memory 评估可以分成四类:

  1. 效果
    • 任务成功率是否提高
    • 用户满意度是否提高
    • 是否减少重复说明
    • 是否更符合用户偏好
  2. 质量
    • 记忆是否准确
    • 是否相关
    • 是否不过期
    • 是否能处理冲突
  3. 安全
    • 是否避免记录敏感信息
    • 用户是否能查看、编辑、删除
    • 是否会跨用户、跨项目泄漏
  4. 成本
    • 是否增加太多 token
    • 是否拖慢响应
    • 是否引入太多无关上下文

Claude Code、Codex 与 Hermes 的 Memory 设计

下面我找了三个我自己用的主要的agent 产品如何实现 Agent Memory。

三个产品的总体差异

系统核心 memory 形态设计取向适合承载
Claude CodeCLAUDE.md、auto memory 目录、API memory tool文件化、分层说明、按需读取项目规则、个人偏好、调试经验
CodexAGENTS.md、Memories、Skills;MCP 作为外部上下文接口指令、历史、流程、外部上下文分层repo 规则、跨线程经验、可复用工作流
Hermes AgentMEMORY.mdUSER.md、memory providers、skills小容量核心记忆 + 可插拔外部 provider用户画像、环境事实、provider 级长期用户建模

Claude Code 的 Memory 设计

Claude Code 的官方 memory 文档把核心机制分成两类:CLAUDE.md 和 auto memory。

CLAUDE.md:显式项目说明

显式项目说明,没啥好说的,值得一提的是Claude Code 支持多层级 CLAUDE.md

Auto memory:项目记忆目录

Claude Code 的 auto memory 会在项目维度保存记忆。官方文档描述的典型结构是:

text
~/.claude/projects/<project>/memory/
├── MEMORY.md
├── debugging.md
├── api-conventions.md
└── ...

MEMORY.md 是入口和索引,topic 文件保存更细的主题内容。这个结构很像“小型知识库”:入口负责导航,细节按需读取。

官方文档还把 auto memory 描述为按仓库共享、每个会话加载,但启动时只加载前 200 行或 25KB。这一点很关键:auto memory 不是无限常驻上下文,而是需要保持索引化和高密度。

为什么是“前 200 行或 25KB”?

因为 memory 可能越写越多。所以它采用一种“索引 + 按需读取”的设计。

text
MEMORY.md
= 目录 / 索引 / 摘要(每次启动先加载的就是这个)
还有一些其他具体主题md文档(Claude 需要时再读)
debugging.md
api-conventions.md
deployment.md

Claude API memory tool:客户端侧记忆目录

Claude API 的 memory tool 允许 Claude 通过客户端提供的工具,对 /memories 目录中的文件执行创建、读取、更新和删除。

它背后的核心思想是 just-in-time context retrieval:不是一开始加载所有相关信息,而是在任务需要时把记忆取回来。官方文档也强调这是 client-side tool,Claude 发起工具调用,应用侧负责在本地执行存储操作。

具体生成方式没有更详细的说明了

Skills 与 legacy custom commands:程序性流程

Claude Code 的产品语境里,custom commands 已经合并进 skills。官方文档说明,.claude/commands/deploy.md.claude/skills/deploy/SKILL.md 都可以创建 /deploy,旧的 .claude/commands/ 文件仍然可用,但 skills 提供更多能力,例如支持文件夹、frontmatter、自动加载和跨工具的 Agent Skills 标准。

因此在提到 Claude Code 的 custom commands 时,应理解为一种兼容旧形式的 slash-command 入口;更现代、更完整的程序性流程载体是 skills。

Claude Code 的设计取向

Claude Code 的取向可以概括为:

  • CLAUDE.md 承载明确、可审查、团队可共享的规则。

  • 用 auto memory 承载项目中逐渐学到的经验。

  • 用 skills / slash commands 承载可复用流程。

  • 用 topic 文件拆分长期记忆,避免一个大文件无限膨胀。

    • 就是上面说的

      text
      MEMORY.md
      = 目录 / 索引 / 摘要(每次启动先加载的就是这个)
      还有一些其他具体主题md文档(Claude 需要时再读)
      debugging.md
      api-conventions.md
      deployment.md

      topic 文件就是把长期记忆按主题分文件保存;MEMORY.md 做目录,细节放到各个主题文件,避免所有记忆挤在一个大文件里。

  • 用客户端 memory tool 保持用户对存储位置和执行权限的控制。

Codex 的 Memory 设计

Codex 的设计更像分层上下文系统。官方 customization 文档把 Codex 的可定制面分成 AGENTS.md、Memories、Skills、MCP、Subagents 等部分。

AGENTS.md:项目规则和工作约定

内容基本和claude.md差不多

Memories:跨 thread 的历史上下文

Codex 的 Memories 默认关闭。启用后,Codex 可以把先前 thread 中稳定有用的信息带到未来工作里。

官方文档说明,Codex 会把 memory 存在 Codex home 下:

text
~/.codex/memories/

其中包含 summaries、durable entries、recent inputs 和 supporting evidence 等生成状态。官方还说明,Codex 会跳过仍活跃或过短的会话,会对生成的 memory 字段做 secret redaction,并在后台更新 memory,而不是每个 thread 结束后立刻更新。

summaries 对过去 thread / 对话 / 工作过程的摘要 durable entries 被认为比较稳定、未来还能用的长期记忆条目 recent inputs 最近的用户输入或任务片段 supporting evidence 支撑这条记忆的证据,例如它是从哪些对话或上下文里总结出来的 generated state 这些都是系统自动生成和维护的状态,不是你主要手写编辑的文件

举个例子。

假设你多次在 Codex 里说:

text
这个项目不要用 npm,用 pnpm。

Codex 的 memory 系统可能会形成:

summary

text
用户在多个前端项目中偏好使用 pnpm。

durable entry

text
在该项目中,安装依赖和运行脚本优先使用 pnpm。

recent input

text
“不要用 npm,这个项目一直用 pnpm。”

supporting evidence

text
来自某几个 thread 中用户纠正 npm 用法的记录。

它们共同构成 Codex 自动生成 memory 时的本地状态,并帮助 Codex 判断:

  • 这条记忆是不是稳定?
  • 它从哪里来的?
  • 以后要不要继续用?
  • 是否需要合并成更长期的记忆?

Skills:程序性记忆

从本文的分类看,Codex Skills 可以看作“怎么做”的程序性记忆。官方文档说 Skills 使用 progressive disclosure:Codex 一开始只看到 skill 的名称、描述和文件路径,只有判断需要使用时才加载完整 SKILL.md

这解决了一个经典问题:如果每个技能的完整说明都常驻上下文,prompt 会很快被挤满;但如果只暴露 skill 元数据,agent 仍然能在需要时选择合适技能。官方文档还提到,初始 skills 列表会控制在模型上下文窗口的 2% 以内,或在未知上下文窗口时控制在 8,000 字符以内。

MCP:外部上下文和实时事实

Codex 的 memory 不应该替代 MCP。MCP 更适合接入实时、私有、授权的数据源,例如 GitHub、Slack、Notion、数据库、文档系统、日历等。

Codex 的设计取向

Codex 的取向可以概括为:

  • AGENTS.md 管显式项目规则。
  • Memories 管跨 thread 的历史经验。
  • Skills 管可复用工作流。
  • MCP 管外部事实和私有系统上下文。只有当 MCP 暴露的是长期记忆库、历史决策或项目经验时,它才参与 Agent Memory;否则它只是外部上下文接口。

Hermes Agent 的 Memory 设计

Hermes Agent 的设计非常有辨识度:核心 memory 极小,但外部 provider 很开放。

MEMORY.mdUSER.md

Hermes 的内置 memory 由两个文件组成:

文件用途官方限制
MEMORY.mdAgent 的个人笔记,例如环境事实、项目约定、学到的东西2,200 字符,约 800 tokens
USER.md用户画像,例如偏好、沟通风格、期待1,375 字符,约 500 tokens

它们默认存放在:

text
~/.hermes/memories/

这两个文件会在会话开始时作为 frozen snapshot 注入 system prompt。会话中写入的 memory 会保存到文件,但不会立刻改变当前 system prompt,需要到下一次会话才生效。

这个设计的优点是:

  • 核心 memory 很小,促使 agent 只保留高价值内容。

  • system prompt 稳定,有利于 prompt caching 和行为一致性。

  • 不自动压缩,避免静默丢信息。

  • 写满时报错,让 agent 显式合并、删除或缩短。

    系统不会偷偷压缩或丢掉记忆,而是明确告诉 agent 写不下了,这时候agent 必须明确做一个动作(合并、删除或缩短)也就是说既对agent显式,也在会话中显式展示

Hermes 官方文档还提到,memory entries 在进入系统提示前会做 injection 和 exfiltration pattern 扫描,并拒绝一些威胁模式或不可见 Unicode 字符。这说明 memory 因为会进入高优先级上下文,本身也是安全边界的一部分。

Hermes memory tool:少而明确的编辑动作

Hermes 的 memory tool 主要是:

  • add
  • replace
  • remove

这说明 Hermes 把核心 memory 设计成短小的长期自我说明,而不是一个随时搜索的大目录。

需要注意的是,Hermes 的核心 memory tool 没有 read 动作,因为内置 memory 会在会话开始时自动注入 system prompt。

Memory providers:外部长期记忆层

Hermes 官方文档提供可插拔的外部 memory provider,例如 Honcho、OpenViking、Mem0、Hindsight、Holographic、RetainDB、ByteRover、Supermemory 等(列表会随版本增减)。外部 provider 一次通常只启用一个,但内置 MEMORY.md / USER.md 会一直同时存在。

外部 provider 激活后,Hermes 可以:

  • 把 provider context 注入 system prompt。

  • 每轮之前预取相关 memories。

    每次你发新消息之前或 agent 回复前,Hermes 会提前从 provider 搜索和当前问题相关的记忆。

  • 每次响应后同步 conversation turns。

    一轮对话结束后,Hermes 会把这一轮对话同步给 provider。

  • 会话结束时抽取 memories。

  • 给 agent 增加 provider-specific 的搜索、存储和管理工具。

    不同 provider 有自己的能力。接入 provider 后,agent 可能多出一些专门工具。

官方特别强调:内置 MEMORY.md / USER.md 始终存在,外部 provider 是 additive,不是替代。

provider 是一个记忆服务/插件,内部可能调用 LLM,但它本身更像数据库 + 检索 + 抽取/更新逻辑的组合。

Hermes 的设计取向

Hermes 的取向可以概括为:

  • 核心 memory 小而硬,强制信息密度。

  • MEMORY.mdUSER.md 分离 agent 环境事实与用户画像。

  • 会话启动时注入 frozen snapshot,保持行为稳定。

  • 外部 provider 承担复杂长期记忆和用户建模。

  • skills 和 context files 承担项目规则与工作流知识。Hermes 的 context files 文档还说明,.hermes.md / HERMES.mdAGENTS.mdCLAUDE.md 等会按优先级作为项目上下文加载,且同一会话只选择一种项目 context type。

    同一会话只选择一种项目 context type的意思是.hermes.md / HERMES.mdAGENTS.mdCLAUDE.md这些是多种类型的context type,但是一个会话只限制加载一种,防止混乱冲突等问题

三个产品给出的设计启发

启发一:显式规则和自动记忆要分开

Claude Code 和 Codex 都把项目规则放在显式文件中,而不是只依赖自动 memory。这是对的。

团队共享规则应该可审查、可版本控制、可迁移。自动 memory 适合补充经验,不适合承载团队硬规则。

启发二:核心 memory 要短

Hermes 的小容量设计很有启发。越常驻的 memory,越要短、稳、密度高。

长期 memory 不应该成为“第二个聊天记录”。它应该像一张高价值索引卡。

启发三:程序性知识应该做成 Skill

很多经验不是“事实”,而是“流程”。例如如何写周报、如何做代码审查、如何排查线上告警、如何发布一个版本。

这类内容更适合 Skill,而不是普通 memory。

启发四:外部事实应该用工具查

实时状态、最新文档、issue / PR、价格、版本等信息不适合长期固化。它们应该通过 MCP、搜索或 API 获取。

启发五:Memory 产品的关键能力是治理

真正好的 memory 产品,不是偷偷多记一点,而是让用户清楚:

  • 记了什么。
  • 为什么记。
  • 存在哪里。
  • 什么时候生效。
  • 如何修改或删除。