1. 两个代理为什么总是“鸡同鸭讲”
1.1 多代理协作“开箱即乱”的三个现场
我在一个真实项目里同时跑了 Claude Code 和 Codex,本以为双代理能打出两倍效率,结果前三天全耗在“对齐上下文”上。左边用 Claude Code 改完接口参数,右边切到 Codex 继续写调用方时,它还在按旧的函数签名生成代码,一编译全是红叉。这不是工具的问题,而是两个代理各自维护一套完全独立的会话记忆,彼此之间没有任何同步机制。
这种记忆割裂会带来三个典型现场。第一个是接口契约漂移,Claude Code 把getUser(id)改成getUser(id, withProfile),但 Codex 不知道,继续按老签名生成调用方,等代码合并时才发现两边不一致。第二个是重复劳动,同一个任务被两个代理各实现一遍,因为它们都在自己的会话里认为自己还没做过这件事。第三个是文件冲突,两个代理同时改同一个文件的不同位置,git 合并时变成灾难现场。
1.2 多代理协作的真正模型:状态共享
很多人以为多代理协作就是“开两个终端,一个写前端、一个写后端”,然后等着它们各干各的。这个理解从一开始就错了。多代理协作的本质不是多个人分工,而是多个“临时员工”共享同一份项目状态——谁改了什么、哪些任务已经完成、当前架构是什么、下一步该做什么。如果这些状态没有同步,那开 10 个代理就是开 10 个不同步的大脑,互相覆盖彼此的工作成果。
正确姿势是:把项目状态从各个代理的私有上下文中抽离出来,放到一个共享层。这个共享层必须满足几个条件:可读可写、结构化、能被不同工具原生解析、最好还能用 git 做版本管理。我最后选的是 Atlas,它的做法很简单却非常有效:把共享记忆做成工作目录里的一组 Markdown 文件,然后通过 CLAUDE.md 和 AGENTS.md 这两个入口,让 Claude Code 和 Codex 启动时都能自动加载。
2. Atlas 是怎么解决共享记忆的
2.1 先纠正一个同名问题
搜“Atlas”的时候容易混进硬件信息,比如 Atlas 300V 24G 是另一款 AI 推理加速卡,和文本里这套工具完全不是一回事。如果你是为了解决推理卡驱动的问题搜到这里,可以直接关掉页面。这里的 Atlas 是一个面向 Claude Code、Codex 这类 CLI 编程代理的记忆协作工具,核心功能就是建立一套统一的记忆文件系统,让多个代理共享上下文。
搞清楚这一点很重要,因为在配置过程中如果你去搜硬件相关的资料,会被带到完全错误的方向。我一开始也踩过这个坑,排查了半天才发现根本不是同一个东西。这类工具其实还有别的选择,但我最终用 Atlas,看中的就是它把“共享记忆”实现得非常朴素:文件系统、透明、可直接 diff,不引入额外的服务进程。
2.2 记忆工作区:把脑子放到仓库里
Atlas 初始化后会在项目根目录生成一个.atlas/memory/目录,里面按模块拆成几个文件:
my-project/ ├── .atlas/ │ └── memory/ │ ├── project.md # 项目背景、目标、当前阶段 │ ├── architecture.md # 架构决策、模块拆分、接口约定 │ ├── conventions.md # 编码规范、命名约定、提交规范 │ ├── tasks/ │ │ ├── todo.md # 待办任务 │ │ └── done.md # 已完成任务记录 │ └── session_log/ │ └── 2025-06-12.md # 每次会话的关键结论 ├── CLAUDE.md ├── AGENTS.md └── src/这套目录结构就是整个团队的“共享大脑”。Claude Code 负责维护架构决策,Codex 负责实现具体任务,两个代理通过读写这些文件来完成信息交接。注意,这些文件最好是提交到 git 仓库里的,因为一旦记忆写错或写乱,你可以随时回滚到上一个可用版本。这比数据库方案强太多了——数据库里的状态变更很难直观审查,而 Markdown 文件里的每一次改动都能在 git diff 里看得清清楚楚。
2.3 入口文件挂载:CLAUDE.md 和 AGENTS.md
Claude Code 启动时会自动读取项目根目录的CLAUDE.md,Codex 则读取AGENTS.md。Atlas 做的事情其实非常简单:把“去.atlas/memory/读取共享记忆”这条指令写进这两个文件里。我项目里的CLAUDE.md现在开头是这样:
项目当前状态以 .atlas/memory/project.md 为准。 - 开始任务前,先读取 .atlas/memory/tasks/todo.md。 - 修改接口或架构前,先更新 .atlas/memory/architecture.md。 - 完成任务后,把结果追加到 .atlas/memory/tasks/done.md,并更新 todo.md。AGENTS.md里也是类似的措辞。这样每次启动 Claude Code 或 Codex,它们都会先读到这句话,然后主动去加载共享记忆。这个机制的精妙之处在于:Atlas 没有去黑掉任何工具的内部存储,而是利用了两个代理都保留的“项目级指令文件”作为桥梁,所以非常稳定。
2.4 同步策略与读写权限
光有共享文件还不够,还需要约定谁在什么时候写。我的策略是:让 Claude Code 做架构设计和技术选型,它负责更新architecture.md和conventions.md;让 Codex 专注实现功能,它负责更新tasks/下的文件。项目背景和阶段目标由我手动维护,尽量不让代理改这块内容,因为代理对项目大方向的判断并不可靠。
Atlas 提供了几个简单的命令来规范写入行为,比如atlas sync --agent claude --message "..."可以把当前会话的关键结论追加到session_log/,atlas status可以查看当前记忆文件的状态,atlas diff可以对比某个记忆文件在前一次同步前后的差异。这些命令的核心目的只有一个:让“写入共享记忆”变成一个显式的动作,而不是代理自己想写就写。
2.5 为什么选文件而不是数据库
有人会问,为什么不把共享记忆放到 SQLite、向量数据库或者一个常驻的内存服务里?我的答案是:对两个 CLI 代理来说,文件系统是不可替代的最优解。首先,Claude Code 和 Codex 天生就能直接读文本文件,不需要任何额外适配层。其次,文本文件可以放进 git,每一次修改都有历史、有作者、有 diff,这是数据库难以实现的审计能力。第三,数据库和向量库需要维护额外服务,方案越重越容易出问题。
文件方案的代价是检索效率不如向量库,但考虑到一个项目的共享记忆最多也就几百 KB,这个代价完全可以忽略。真正需要向量检索的场景是海量历史决策,那属于另一个量级的问题,至少对于日常开发协作来说,Markdown 文件已经足够好用了。
3. 实战:让 Claude Code 和 Codex 共用一本“记账本”
3.1 环境准备:装好两个 CLI
开始之前,你需要先确保两个 CLI 工具都能正常跑起来。Claude Code 的安装通常一条命令搞定:
npm install -g @anthropic-ai/claude-code claude --versionCodex CLI 也一样:
npm install -g @openai/codex codex --version如果你在 Windows 上遇到“安装未完成”的情况,多半是 Node.js 版本太低或者 PowerShell 执行策略限制,先确认node -v在 18 以上,然后以管理员身份运行 PowerShell 执行Set-ExecutionPolicy RemoteSigned,再重新安装。装完之后建议先在各自的默认目录跑一次最简单的对话,确认登录和网络都没问题,再进项目里做共享记忆配置。这一步省不得,否则后面出了问题根本分不清是 Atlas 的配置问题还是 CLI 本身没装好。
3.2 初始化 Atlas 工作区
进入项目目录后,执行:
atlas init它会扫描当前项目,生成.atlas/目录和默认的记忆模板,然后交互式地问你项目里有哪些代理工具,把claude和codex都勾上。初始化完成后,Atlas 会自动更新CLAUDE.md和AGENTS.md,在文件末尾追加记忆挂载指令。
如果你是在 VSCode 里用自带的终端跑 Claude Code,流程完全一样,因为 CLI 读取的是项目目录下的文件,跟终端环境无关。这一步完成后,先手动看一下生成的CLAUDE.md和AGENTS.md,确认内容是正确的。很多时候用户的挂载指令被老版本的配置文件覆盖,所以我会再检查一遍。
3.3 让 Claude Code 把状态写进共享记忆
Claude Code 是规划能力很强的那类代理,适合做设计、拆任务、写技术方案。我在实际使用中会给它下这样的指令:
claude > 请读取 .atlas/memory/tasks/todo.md,把“用户登录改造”拆成子任务,并更新 todo.md。 > 拆完后把本次的设计结论同步到 .atlas/memory/architecture.md。注意,我刻意让 Claude Code 只负责“写规划和架构”,不让它直接改业务代码。这样做的好处是:当 Codex 下午开工时,todo.md 里已经有了清晰的任务清单和验收标准,它不需要再问“这个功能到底要怎么做”。另外,Claude Code 每完成一个阶段,我会手动执行atlas sync --agent claude --message "登录改造方案已确定",把会话摘要固化到当天日志里。这相当于给这次会话写了一份会议纪要。
3.4 让 Codex 开工前先读共享记忆
Codex 是偏执行的代理,让它直接按todo清单干活比较顺手。启动 Codex 时,我会在第一条指令里明确要求它先读共享记忆:
codex > 请先读取 .atlas/memory/project.md、.atlas/memory/architecture.md 和 .atlas/memory/tasks/todo.md, > 然后实现 todo 中第一个标记为 [pending] 的任务。实现完成后更新 todo.md。这一步最容易犯的错是:Codex 虽然读取了AGENTS.md,但它在长任务里可能会忘掉开头提到的约束。我的经验是,在任务做到一半、快要改接口或者改数据结构时,再补一句“请重新读取 .atlas/memory/architecture.md,确保新代码与架构保持一致”。让代理在关键决策点重新加载记忆,比只读一次要可靠得多。从这里能看出,共享记忆不是一劳永逸的,它需要持续的同步节奏来保证信息新鲜。
3.5 一个完整的双代理协作流程
我把一个典型工作日的协作流程写在下面,你可以直接照搬:
# 早上:Claude Code 负责规划 claude > 读取 .atlas/memory/tasks/todo.md 和 project.md。 > 今天的目标:完成支付模块的重构。 > 请拆解任务、定义接口,并更新 todo.md 和 architecture.md。 # 午间:手动同步一次记忆 atlas sync --agent claude --message "支付模块接口定义完成,待 Codex 实现" # 下午:Codex 负责实现 codex > 读取 .atlas/memory/architecture.md 和 tasks/todo.md。 > 实现 [pending] 中标记为“支付模块-接口层”的任务,完成后更新 done.md 和 todo.md。整个过程里,我只在中午做了一次显式同步,其他时间都是两个代理通过共享文件自动交接。跑了一个星期之后,这个流程明显减少了沟通成本:Claude Code 不需要再向 Codex 解释接口设计,Codex 也不需要反复问“这个函数是干嘛的”,打开 todo.md 全都写着。
3.6 扩展玩法:接第三方模型也不冲突
很多人在用 Codex 或 Claude Code 时并不一定用官方模型,比如网上常见的“codex 接入 deepseek”“claude code 接入 deepseek”就是这么来的。用第三方模型时,记忆机制完全没有区别,因为 Atlas 挂载的是AGENTS.md和CLAUDE.md这两个入口文件,跟模型供应商无关。但要注意,第三方端点通常有自己支持的模型白名单,如果你在配置里写了一个端点不认识的模型名,就会出现类似the 'gpt-5.6-sol' model is not supported when using codex with a...的报错。解决办法是查看端点文档里支持的模型列表,改成对应的模型名,比如换成提供商实际部署的gpt-5或者其自定义名称,再重启会话。
4. 常见问题与排查技巧实录
4.1 cc switch 之后 Codex endpoint 报错
热词里有一个很典型的报错:cc switch local proxy failed while handling codex endpoint /responses。这个问题一般出现在你通过cc switch切换了本地代理端点之后,Codex 把请求转发给本地端点的/responses接口,但该端点返回异常,导致整条链路中断。排查思路分三步:第一步,检查你本地端点的地址和 Codex 配置里的base_url是否一致,比如本地服务监听在127.0.0.1:8081,那 Codex 的配置里就要写http://127.0.0.1:8081/v1,多一个/v1或少一个/v1都会出问题。第二步,用 curl 直接请求一次/responses,看端点本身是否正常。第三步,确认cc switch切换后有没有触发 Codex 的配置重载,有时需要重启 Codex 会话才能生效。
4.2 提示“当前地区不可用”怎么办
运行 Claude Code 时,如果出现claude code might not be available in your country之类的提示,说明当前环境不在官方支持范围内。这种提示是官方基于区域可用性做的限制,不是简单改个配置文件就能绕过的。我自己遇到这种情况时,思路是:要么换一个官方支持的运行环境来执行 CLI,保证合规;要么走 API 兼容接口,用其他通道接入能力。至少不要试图去改本地区域相关的系统设置,那既不稳定也可能带来其他风险。Atlas 的记忆文件机制不会受这个问题影响,只要 CLI 能启动,挂载逻辑都是一样的。
4.3 跑着跑着说 Context 不够了
Codex 报codex ran out of room in the model's context是长任务里最常见的问题。原因是随着对话进行,历史 token 越来越多,最终超过了模型上下文窗口。解决办法有三个层次。第一层,用 Atlas 的压缩命令把已完成的小任务折叠成一行摘要,比如把“重构登录模块、抽离 token 校验、补充单测”压缩成“登录模块已重构完成,见 git log 3f2a1b”,释放上下文空间。第二层,让代理只加载跟当前任务相关的记忆文件,不要默认全量读取整个.atlas/memory/。第三层,把大任务拆小,一个会话只做一个任务,做完就同步记忆并开新会话,不要硬攒一个大会话。这三层手段配合使用,基本可以避免 context 爆掉。
4.4 模型名不支持的坑
前面说过,用第三方端点时容易碰到模型名不支持的问题。还有一种情况是本身用的官方服务,但你在配置里写错了模型名,比如codex配置里写了gpt-5.6-sol,而这个模型在当前端点根本不存在。排查的时候先确认当前 CLI 用的配置模型和代码里请求的模型是否一致,再看端点支持的模型列表。如果你是接的本地网关或者第三方转发,通常需要在配置里把模型名映射成端点实际部署的模型名。这个错很容易被误判成“网络问题”或者“密钥问题”,其实本质就是名字对不上。
4.5 记忆文件越写越乱
共享记忆用了一段时间后,文件会变得越来越长,直到代理每次读取都要花大量 token。这个问题是必然的,所以我给自己定了一个清理节奏:每周把todo.md里已经完成的内容移到done.md,把architecture.md里已经稳定不变的方案压缩成一段摘要,把session_log/按照周归档。如果发现某个记忆文件超过 100 行,就要主动精简。另外,我强烈建议把记忆文件纳入 git 管理,每次代理改动记忆后都提交一次,一旦发现它写了一堆垃圾进去,可以直接回滚。这比让代理“自己清理自己”可靠得多。
4.6 Atlas 启动后一直卡住不动
如果你执行atlas status或者初始化命令后一直卡住,优先检查是不是项目目录权限导致它无法读写.atlas目录。在部分共享挂载目录或者云盘目录下,文件监控事件可能不会正常触发,也会表现出“下不动”的现象。解决办法是先把项目复制到本地目录再执行初始化,确认没问题后再考虑放回挂载盘。和 2.1 里提到的硬件 Atlas 也没关系,不要混在一起排查。
5. 进阶经验:共享记忆的边界与方法论
5.1 底层还是“人”的问题
配置好 Atlas 之后,并不能指望两个代理突然变成完美搭档。它们依然会犯错误、会误判、会写一些不符合预期的代码。共享记忆解决的只是“信息不同步”这一件事,它不解决“任务分配不合理”和“验收标准不明确”的问题。我在实际使用中最大的感悟是,多代理协作里最重要的角色不是 Claude Code 也不是 Codex,而是你自己——作为唯一一个能从全局视角审视项目的人,你要负责制定规则、明确验收标准、在关键时刻做决策。共享记忆只是把你的决策更高效地传递给两个代理的工具。
5.2 一套可复用的记忆模板
如果你不想用 Atlas 默认的模板,可以参考我这套经过多次迭代的简化版,直接复制到.atlas/memory/下即可:
# project.md - 项目名称: - 当前阶段:需求设计 / 开发中 / 联调中 - 本轮目标: # architecture.md - 技术栈: - 模块划分: - 关键接口: - 最近变更:按时间倒序记录 # conventions.md - 命名规范: - 提交规范: - 禁止事项: # tasks/todo.md - [ ] 任务描述(责任人:Claude Code / Codex / 我) - [ ] 下一个待办任务(责任人:Codex) # tasks/done.md - [x] 已完成任务(完成时间、提交号、备注)这套模板的侧重点是“责任人和完成状态”。每次打开 todo.md 都能一眼看出当前轮到谁干活,这对双代理协作模式来说非常关键。如果只有一个任务列表而不标明责任人,两个代理会互相等,效率反而降低。
5.3 让两个代理互相 Review
共享记忆还有一个衍生玩法:让 Codex 实现完功能后,再让 Claude Code 去 review 代码。做法很简单,Claude Code 在开工前读一遍done.md和git diff,针对最近一次提交给出设计层面的意见,然后把 Review 结论写回session_log/。Codex 在下一次任务里读到这些意见,就会主动调整自己的实现方式。这相当于给团队加了一个“代码评审”环节,而不用你去逐行盯着看。实测下来,这个方法对代码一致性提升非常明显,但要注意别让两个代理陷入无限互相挑刺的循环,所以我会限制 Review 只做一轮。
5.4 我最想分享的一句话
跑通这套方案之后,我最深的体会是:不要追求“完全自动化的智能体协作”。真正好用的多代理协作是“半自动”的——你需要手动控制什么时候让哪个代理出场,什么时候同步记忆,什么时候清理上下文。Atlas 解决的是最后一个环节:当你需要切换代理时,有一个可靠的记忆机制帮你完成交接。这个机制不复杂,甚至可以说朴素,但它让 Claude Code 和 Codex 从“两个互不相识的临时工”变成了“一个配合默契的小团队”。如果你也在被多代理协作的上下文问题折磨,不妨从一套共享记忆文件开始,先跑通最小流程,再逐步迭代出适合自己的协作节奏。