MemoryLake
返回全部文章
Tutorial2026 年 8 月 11 日·11 分钟阅读

为什么 Claude Code 子智能体不共享记忆——以及如何解决(2026)

上周,你的代码审查子智能体(reviewer subagent)发现支付模块有一个自定义的错误包装器。但你的测试编写子智能体(test-writer subagent)并不知道这一点,结果写了三个捕获错误异常的测试。它们都在同一个仓库、同一个项目、同一个 `CLAUDE.md` 下运行,却对彼此的发现一无所知。

直接的答案是:这是设计使然,而且这只是部分问题。Claude Code 为每个子智能体分配了独立的上下文窗口,并且只将摘要返回给主对话——这种隔离正是子智能体发挥作用的根本原因。现在,子智能体也可以通过其定义中的 `memory` 字段拥有真正的持久记忆。但它们没有的是共享记忆:每个子智能体的记忆都是以其自身名称命名的独立目录,主会话的自动记忆根本不会加载到子智能体中,而且这些记忆都不会离开写入它们的机器。

本文将详细介绍这些壁垒的具体位置、哪些壁垒应该保留,以及如何为智能体团队提供一个它们都能读取的统一数据源。

为什么 Claude Code 子智能体不共享记忆

隔离正是你所付费购买的核心功能

首先来看看子智能体的用途。Claude Code 的官方文档将该用例描述为一个侧面任务,否则这些任务会用你不会再次引用的搜索结果、日志或文件内容淹没你的主对话:“子智能体在自己的上下文中完成该工作,并且只返回摘要。”每一个子智能体都“在自己独立的上下文窗口中运行,拥有自定义的系统提示词、特定的工具访问权限和独立的权限”。

这是一个很好的权衡,你不应该希望打破它。一万行测试输出留在了它们该在的地方,而你的主对话只得到了三句话。但请注意这句话所暗示的:子智能体在过程中理解的任何内容——错误包装器、命名奇癖、两个模块不一致的事实——都只存在于一个已经消失的上下文窗口中。返回的只是摘要,而摘要只是子智能体认为值得说出来的部分。

主会话的记忆不会跨越边界

Claude Code 拥有默认开启的自动记忆功能,Claude 会在工作时写入自己的笔记:构建命令、调试见解、发现的偏好。这些内容按仓库保存在 ~/.claude/projects/<project>/memory/ 下,并在每次对话开始时加载 MEMORY.md 索引。

也就是说,除了子智能体之外的每一次对话都是如此。文档直接指出:“主会话的自动记忆不会加载到子智能体中。”唯一的例外是 fork(分支),它会直接继承父会话和系统提示词。因此,你的主会话上周二学到的关于这个仓库的知识,并不会呈现在你今天派出的子智能体面前。

每个子智能体的记忆都是独立的目录

子智能体可以保留自己的笔记,这非常值得启用。在子智能体定义中添加 memory 字段,它就会获得一个跨对话持久存在的目录,文档将其描述为“随着时间的推移积累知识,例如代码库模式、调试见解和架构决策”的地方。有三种作用域可用:user 写入 ~/.claude/agent-memory/<name-of-agent>/project 写入 .claude/agent-memory/<name-of-agent>/ 且可以通过版本控制共享,local 写入 .claude/agent-memory-local/<name-of-agent>/ 且不纳入 git。

仔细阅读这些路径,因为我们问题的答案就在目录名称中。记忆的作用域是按智能体名称划分的。审查智能体积累的知识在审查智能体的文件夹中;测试编写智能体有自己的文件夹;并且没有它们都能读取的共享文件夹。该功能还带来了两个有用的特性,同时也暗示了其局限性:子智能体的系统提示词会包含其 MEMORY.md 的前 200 行或 25KB(以先到者为准),并且整个机制是自动记忆的一部分——如果使用 autoMemoryEnabledCLAUDE_CODE_DISABLE_AUTO_MEMORY 关闭自动记忆,memory 字段将完全不起作用。

两个内置子智能体也会跳过你的 CLAUDE.md

还有一个让人感到意外的差距,文档中也有记载:“Explore 和 Plan 会跳过你的 CLAUDE.md 文件和父会话的 git 状态,以保持研究的快速和低成本。其他所有内置和自定义子智能体都会加载这两者。”

Explore 是去读取你代码库的子智能体。它是你最希望了解你规范的智能体——但它偏偏是故意不了解的那一个。这是一个合理的性能决策,但这意味着为你的主对话提供支持的研究工作是由一个没有阅读过你标准的东西完成的。

而且这些记忆都不会离开机器

自动记忆是本地机器专有的。文档非常明确:一个仓库中的所有工作树和子目录共享一个目录,并且“文件不会跨机器或云环境共享”。按智能体划分的目录也是如此,除非你提交了 project 作用域的目录。

因此,你的智能体团队积累的知识只存在于一台笔记本电脑上,分布在按智能体划分的文件夹中,对你的其他工具和团队成员是不可见的,除非你刻意将其中一部分提交。这对于构建命令来说没问题。但对于某个模块为什么不能触碰这种关键原因来说,这就不行了。

人们尝试过的方案

把所有内容都放进 `CLAUDE.md`。 这是正确的第一步,它确实能触及除 Explore 和 Plan 之外的每个子智能体。限制在于大小:文档建议每个文件控制在 200 行以内,因为更长的文件会消耗更多上下文并降低遵循度。一个大到足以容纳四个子智能体所学知识的 CLAUDE.md,将是一个没有任何智能体能遵守的 CLAUDE.md

编写更长的子智能体提示词。 这对固定指令有效,但对新发现无效。一旦你知道了错误包装器,你可以告诉测试编写智能体——但问题在于,之前是审查智能体知道而你不知道。

告诉子智能体写入文件。 “把你学到的东西保存到 notes/review-findings.md。” 这很有效,本质上是手动实现记忆功能。在你有四个智能体、四个文件,并且没有关于谁读取哪个文件的规范之前,这都没问题。

改用 fork。 fork 会继承父会话和系统提示词,这确实解决了“它不知道我们讨论了什么”的问题——代价是你原本想要的上下文节省。这是继续你个人思考的正确工具,但对于隔离嘈杂任务来说是错误的工具。

启用按智能体划分的记忆并寄希望于此。 确实应该启用它;project 作用域是文档推荐的做法,因为它使这些知识可以通过版本控制共享。只是不要指望它能成为一个共享的大脑。它只是一个按智能体划分的笔记本,文档也正是这样描述它的。

运行更少的子智能体。 人们在遇到第三次冲突后往往会走到这一步。这确实有效,但也是一个真正的损失——你付出了上下文的代价,仅仅是为了避免协调上的鸿沟。

解决方案:为每个智能体提供一个统一读取的存储库

隔离应该保留。需要改变的是,目前“隔离的上下文”和“隔离的知识”是同一回事,而它们本不必如此。

行之有效的模式是一个主会话和每个子智能体都可以读写的共享存储库,它与按智能体划分的记忆并存,而不是取代它。超出单个任务范围的重要发现——错误包装器、决策、已废弃的辅助函数——都存放在那里,并且每个智能体都读取相同的版本。按智能体划分的记忆则继续保留真正属于该智能体专业领域的本地内容。

MemoryLake 就是为此设计的记忆层——一个存放你的决策、规范和源文档的统一存储库,可以通过 MCP 从 Claude Code 及其子智能体、Codex 以及通过 API 从 ChatGPT 访问。它不是每个智能体的另一个笔记本:而是一个拥有多个读取者的统一记录。

步骤 1:创建 API 密钥

生成密钥并在大约 30 秒内发出你的第一次请求。将其保存在你的环境变量或机密管理器中,而不是直接粘贴到会话中。

创建 MemoryLake API 密钥
创建 MemoryLake API 密钥

步骤 2:上传你的第一批记忆

放入你的智能体不断重复发现的文档、图像和文件:规范、架构决策、规则背后的事件记录、API 契约,以及附带原因的“请勿触碰”列表。上传源文件而不是摘要——摘要是子智能体已经提供给你的东西,而信息压缩正是你正在解决的问题。

上传你的第一批记忆到 MemoryLake
上传你的第一批记忆到 MemoryLake

步骤 3:连接你的 AI 和智能体

让 Claude、Codex、OpenClaw 和其他 AI 智能体通过 MCP 或 API 访问记忆。Claude Code 会在读取你的 CLAUDE.md 文件的同时通过 MCP 读取它,并且你可以按子智能体划分访问范围:文档指出,在子智能体的 mcpServers 字段中内联声明 MCP 服务器,可以将其工具描述完全排除在主会话的上下文之外——子智能体获得了工具,而父会话没有。这就是你如何让审查智能体和测试编写智能体共享相同记忆,而无需为此消耗父会话上下文的方法。

通过 MCP 连接你的 AI 和智能体
通过 MCP 连接你的 AI 和智能体

这在实践中带来了什么改变

第一个区别是,发现的生命周期超越了产生它的任务。审查智能体注意到了错误包装器,将其写入共享存储库,测试编写智能体在一小时后读取它——而无需你充当两个互不见面的智能体之间的消息总线。

第二个区别是,你的 CLAUDE.md 可以保持足够简短以发挥作用。与其让文件膨胀到遵循度下降的程度,不如将固定规则保留在文件中,而将积累的细节转移到检索中。这也是在每个会话中重新读取代码库的智能体成本高昂的相同原因:知识确实存在,只是不在智能体寻找的地方。

第三个区别是,知识在笔记本电脑之外得以存续。自动记忆和按智能体划分的记忆在设计上是本地机器专有的;而共享存储库则是你团队所需的部分——决策、原因、规范——不再仅仅是某个开发人员的本地文件。这就是同事能够直接查询“为什么这里不能碰”与必须亲自询问你之间的区别。

而且它不会与 Claude Code 的原生功能发生冲突。自动记忆继续按仓库写入构建命令和调试笔记。按智能体划分的记忆继续积累每个子智能体的专业知识。它们都不必成为记录系统(system of record),而这正是它们最不适合扮演的角色——这也是让多个智能体共享一个记忆完全可行的相同分工方式。

子智能体记忆的最佳实践

开启项目作用域的按智能体记忆

memory: project 是文档推荐的做法,原因显而易见:该目录会被提交到版本控制中,因此子智能体积累的知识可以由你的团队进行审查,而不是被困在你的家目录中。仅对确实不应提交的笔记使用 local

显式要求读取和写入记忆

文档正是这样建议的:提示子智能体在开始前咨询其记忆(“检查你的记忆中是否有以前见过的模式”),并在完成后进行更新(“保存你学到的东西”)。更好的是,将这些指令放在子智能体自己的 markdown 正文中,这样它就可以在不需要你提醒的情况下进行自我维护。

将 MEMORY.md 保持为索引,而不是仓库

只有 MEMORY.md 的前 200 行或 25KB 会被加载——超出该范围的内容在会话开始时不会被加载。保持每条记录占一行,并将细节推送到主题文件中,Claude 会根据需要读取这些文件。一个默默溢出的记忆索引比一个简短的索引更糟糕,因为你会误以为它存在于上下文中。

假设 Explore 没有阅读过你的规范

由于 Explore 和 Plan 在设计上会跳过 CLAUDE.md,因此不要将它们的研究结果视为已知晓规范。如果研究结果将推动某项修改,请在执行时重新阐述相关规则——或者给 Explore 一个它可以查询的共享记忆,这是同一种修复方案中更持久的版本。

不要将任何一种记忆与强制执行混淆

Claude Code 的文档指出,指令文件和自动记忆是“上下文,而不是强制配置”,无法保证严格遵守。任何每次都必须为真的事情——绝不触碰生成的文件、始终运行 linter——都属于 hook 或 CI 检查的范畴。记忆是为了知晓;hook 是为了保证。任何向你推销将记忆作为合规手段的人,都只是在推销概念。

写下原因,而不仅仅是发现

“支付模块使用自定义错误包装器”是一个会被质疑的事实。而“支付模块使用自定义错误包装器,因为上游客户端吞掉了状态码——参见 3 月份的事件”则是一个经得起下一个智能体和下一个工程师质疑的事实。

结论

Claude Code 子智能体不共享记忆,因为它们不共享上下文,而这种隔离正是其核心特性:每个子智能体都在自己的窗口中工作,并且只返回摘要。记忆的情况比“它们没有记忆”更为微妙。它们可以拥有持久记忆,按智能体划分,保存在以智能体命名的目录中,作用域可以是 user、project 或 local。不存在的是一个共享的界面:主会话的自动记忆不会加载到子智能体中,按智能体划分的目录不会互相读取,Explore 和 Plan 会完全跳过你的 CLAUDE.md,并且所有这些都保留在单台机器上。

因此,保留隔离并解决共享问题。在项目作用域启用按智能体划分的记忆,保持 MEMORY.md 为索引,将 Explore 视为对规范盲目的智能体,并将对多个智能体都至关重要的知识放入它们都能读取的统一存储库中。这样,第二个智能体就可以从第一个智能体学到的知识开始,而你也不再需要充当自己子智能体之间的集成层。

常见问题

Claude Code 子智能体到底有没有记忆?

有的。在子智能体定义中添加 memory 字段会为其提供一个跨对话持久存在的目录,作用域可以是 userprojectlocal。它是自动记忆的一部分,因此禁用自动记忆也会禁用它。但它并不是共享的——该目录是以智能体的名称命名的。

子智能体能看到我的主对话吗?

不能,除非它是 fork。文档指出,主会话的自动记忆不会加载到子智能体中,fork 是个例外,因为它们会继承父会话和系统提示词。普通的子智能体拥有自己的系统提示词、自己的上下文窗口以及你在其提示词中放入的任何内容。

为什么我的子智能体没有遵循 CLAUDE.md?

如果是 Explore 或 Plan,这是文档中记载的行为:两者都会跳过你的 CLAUDE.md 文件和父会话的 git 状态,以保持研究的快速。其他所有内置和自定义子智能体都会加载这两者。如果是自定义子智能体,更可能的原因是普遍原因——指令文件是上下文而不是强制配置,因此具体程度和长度非常重要。

子智能体的记忆会在我的多台机器之间共享吗?

不会。自动记忆(包括子智能体记忆)是本地机器专有的;文档指出,文件不会跨机器或云环境共享。你可以控制的例外是 project 作用域,它会写入仓库中,因此可以通过版本控制传输给你的团队成员和你的其他检出版本。

我应该直接用 fork 代替子智能体吗?

只有当你需要父会话的上下文时才应该这样做。fork 会继承对话和系统提示词,这适合并行继续你自己的推理,但不适合子智能体旨在解决的场景——将嘈杂任务的输出排除在主窗口之外。如果你发现自己为了避免重新解释而进行 fork,这就是一个信号,表明你应该将知识放入共享存储库中。

这与会话之间不共享上下文有什么不同?

边界不同,但根本原因相同。在独立的 Claude Code 会话之间共享上下文是指可以传递消息但不能传递历史记录的独立会话。而这是指单个会话的委派工作者,它们之间起初根本没有通道。在这两种情况下,持久的解决方案都是会话之外的存储库,而不是更好的消息传递。