☰
Codex多Agent协同实战:从单Agent上下文失控到职责拆分的完整复盘
2026/10/5 12:37:59 网站建设 项目流程

前阵子有一个迁移任务,我本来打算让 Codex 一个人从头扛到尾。项目是一个老仓库,跨了几个模块,还牵扯到数据格式兼容。前一半干得挺利索,到了中后段就开始不对劲:它开始重复改同一个文件,把前面确定好的方案推翻了一半,甚至把两个模块的接口改得对不上。我盯着对话记录,发现问题不在代码生成,而在上下文,它把自己早期的结论渐渐“忘”了,或者说是被后续讨论冲刷掉了。那次之后我再也没有把一个完整大型任务单独交给 Codex 过。解决办法是把它放进一个多 Agent 流程里,让不同角色各管一段,Codex 只干它最擅长的那部分。这篇文章就是那次实战的完整复盘,讲讲为什么要拆、怎么拆、以及拆完之后遇到的坑。

1. 为什么单个 Agent 会在系统性任务上卡住

1.1 瓶颈不是 Token 长度,而是上下文职责半径

很多人的第一反应是“上下文太短”,但实际上当前模型几十万 Token 的窗口并不小。真正的问题是单 Agent 在长时间任务里要同时承担太多职责:它需要记住最初目标,需要维护已经做过的所有决策,需要理解最新的文件内容,还需要判断下一步动作。这些信息挤在一起,模型不会优先保证“最初目标”,它会优先响应最近几轮对话里的信息。

我在那次重构里观察到一个典型场景:第三轮时 Codex 定义了一个统一的 DTO 结构,第七轮它又在某个模块里生成了一套几乎重复的类型定义。不是它偷懒,是早期定义已经被大量中间内容冲淡了。单 Agent 的上下文就像一张白板,写满了前面的内容,你让拿着这块白板的人继续做全局设计,他只能基于最上面几行字来做判断。

这就是我一直强调的“责任半径”概念。一个 Agent 能处理的任务大小,取决于它需要同时维护多少决策变量,而不是窗口有多大。把需求列表、方案取舍、代码实现、测试反馈全塞给一个 Agent,它相当于同时扮演产品经理、架构师、开发者和测试员,那上下文里必然互相污染。

1.2 设计和实现混在一个上下文里,是混乱的起点

单 Agent 更隐蔽的问题,是设计和实现被放在同一个推理过程里。当你对 Codex 说“帮我重构 A 模块,顺便把 B 模块的调用改掉”,它会在生成代码的过程中自己做出设计决策。这些决策没有经过显式的讨论,也没有被记录成文档,它就是凭当前上下文“顺手”定了。

小任务无所谓,大任务就会有连锁反应。A 模块设计错了,B 模块基于错误设计继续写,等发现的时候,两个模块的改动已经纠缠在一起。回滚哪个都不干净,最好的办法是让设计决策从实现过程中剥离出来,由一个 Agent 专门产出方案,另一个 Agent 专门落实方案。

我有一次故意做了对比实验,同一个任务,一半用单 Agent 直接执行,一半拆成“设计 Agent + 实现 Agent”两步做。单 Agent 版本的第一次输出看起来更快,但后续修修补补迭代了四轮;拆成两步的版本,设计阶段多花了几分钟,实现阶段一次通过,总耗时反而更短。多 Agent 不是说让多个模型并行跑,而是让一个复杂过程被拆成多个职责单一的阶段。

2. 多 Agent 协同的核心心智模型

2.1 三种常用的编排拓扑

搞多 Agent 之前,先说清楚编排结构。我实际尝试过三种,各有适用场景。

第一种是流水线式,就是 A 的输出直接成为 B 的输入,像工厂流水线一样。适合任务步骤之间有明确顺序的场景,比如先做数据分析、再做方案设计、最后写代码。好处是上下文传递很干净,坏处是一旦中间某一步失败,整条线都得重新跑。

第二种是主管/下属式,一个 Supervisor Agent 负责任务拆分和结果验收,下面挂几个 Worker Agent 分别执行。这是编码任务里最常用的一种结构。主管不写业务代码,它只负责维护任务列表、派发工作、检查产出是否达标。工人之间不直接通信,所有交互都通过主管中转,上下文隔离做得很好。

第三种是黑板式,所有 Agent 读写同一块共享状态,比如同一个文件、同一个数据库记录。这种方式很适合协同调试,多个 Agent 各看各的错误,但要做好并发控制,否则互相覆盖。

我自己在编排编码任务时最常用的是主管/下属式。原因很现实:编码任务里最贵的不是生成代码,而是保证上下文一致性。主管维护全局目标,工人只看到被派发的那一小块任务,就不会出现“各改各的,最后接不上”的问题。

2.2 角色不是“更聪明”,而是“更窄”

很多人误解多 Agent 的价值,以为多个 Agent 并行能更快出结果。实际上,把任务拆给多个 Agent,如果每个 Agent 的角色定义得不够窄,协同效率反而比单 Agent 更低。多个模糊的 Agent 只是把“一个模糊的上下文”复制成了好几份。

真正的要点是用上下文隔离换取行为稳定。每个 Agent 不需要知道全局,它只需要知道自己负责的那一小块。我通常会定义三类角色:

  • 规划 Agent:负责分析需求,拆解任务清单,明确验收标准。它不写代码,只产出方案文档和任务列表。
  • 执行 Agent:负责按任务清单逐个实现。它不讨论方案,只按规划 Agent 给出的规格写代码。
  • 审查 Agent:负责检查执行结果,跑测试、看 diff、指出问题。它不直接改代码,只把问题列表返回给执行 Agent。

这三个角色如果让同一个 Agent 干,权限就互相污染了。写代码的时候顺手改了方案,审查的时候又不好意思挑自己毛病。分开以后,每个 Agent 的上下文里只需要装自己角色的规则和当前任务,输出质量会明显稳定下来。

3. 把 Codex 放进多 Agent 团队的正确姿势

3.1 Codex 最适合扮演“执行工人”而非“总指挥”

很多人把 Codex 当成一个万能入口,什么任务都从一个对话框发起。在多 Agent 协同里,我建议反过来:把 Codex 当作一个可编程调用的执行单元,通过命令行工具调用它,让它完成被明确指派的任务,而不是给它一个超大目标让它自由发挥。

Codex CLI 本身支持非交互模式,这意味着你可以把它嵌进脚本,由外部编排器分配任务。它在多 Agent 团队里的定位,应该是写代码的那个角色。你给它一份干净的任务描述,它返回一份代码改动,仅此而已。

我实际用下来最顺手的调用方式是这样的:

codex exec --full-autonomy \ -C /path/to/project \ "实现 user_service 模块中的 get_user_profile 方法,要求基于 schema.sql 中定义的 users 表结构,返回完整资料对象,不需要写测试。"

注意任务描述里包含了三样东西:明确的操作对象、明确的参考文件、明确的验收边界。这比说“帮我实现用户服务”要好用得多,因为后者把设计决策又抛给了 Codex。任务描述越窄,Codex 的行为越可预测,外部编排器就越容易判断它有没有完成任务。

3.2 上下文由编排器统一管理,而不是靠 Codex 自己记

单 Agent 工作流里,Codex 会尝试记住整个对话历史。多 Agent 工作流里,这段历史应该由外部编排器来记,每次调用 Codex 都是一个新的会话,只携带本次任务需要的上下文。

用一个具体的例子说明。假设有一个全栈功能,涉及前端页面、后端接口、数据库迁移三块工作。如果让 Codex 一口气做完,它可能在后端接口里设计了某个字段,但前端页面还在用旧字段名,最后花了很长时间才发现两边不一致。

在多 Agent 流程里,我会先让规划 Agent 产出一份接口文档,把字段名、类型、边界都定义清楚。然后执行阶段,前端任务调一次 Codex,后端任务再调一次 Codex,但每次都把同一份接口文档塞进任务描述。Codex 不需要记得前端改了什么,它只需要按文档实现后端,这个字段名就不会错。

从实际操作上讲,编排器要维护一份可识别的“当前工作版本”。不管哪个 Agent 做了改动,最终都要以文件系统里的代码为准。Agent 与 Agent 之间千万别直接传自然语言描述,传文件路径、传结构化文档、传 commit 记录,都比传一段描述可靠。

4. 多 Agent 协同编排的工程细节

4.1 编写 Agent 职责提示词的模板

既然要让多个 Agent 各司其职,职责提示词就是整个系统的地基。我总结了一套模板,用下来效果不错:

你是一个 [角色名称]。 你的职责是 [具体职责描述]。 你不需要 [明确不做的事情]。 你有以下输入: [列出输入文件、输入数据结构] 你必须输出: [列出输出格式、输出文件路径、验收标准] 约束条件: [列出版本要求、代码风格、禁止事项]

看起来很简单,但每一步都有讲究。“你不需要做什么”这一条特别值得强调。比如执行 Agent 不需要讨论方案,那么我就在约束里写“收到任务后直接实现代码,不要输出方案分析”。一旦模型开始输出方案分析,上下文就开始膨胀了,没过几轮又会忘记最初的任务目标。

职责提示词要放在每次调用的 system prompt 或者任务描述开头,而不是放在一个全局配置里设置一次。因为 Agent 服务端通常不会保存跨会话的角色记忆,你每次调用都得显式声明这个 Agent 的角色。重复写这些规则虽然看起来笨拙,但它是保证多次调用行为一致的唯一办法。

4.2 任务交接:用文件系统当通信总线

多 Agent 协同最大的坑,是 Agent 之间直接传长文本。A 的输出是一段描述,B 拿这段描述当输入,描述经过两次传播就失真了。我现在的做法是,让 Agent 之间的交互以文件系统为中介。

具体做法是建一个工作目录,规划 Agent 的输出写入tasks/task-001.md,执行 Agent 的产出写入outputs/task-001.patch,审查 Agent 的结论写入reviews/task-001.review。不管哪个 Agent 需要信息,都去对应目录下读文件,而不是从前一个 Agent 的输出文本里粘。

文件命名也要讲究。不要用final.md、report.md这种没有版本概念的名字,要用带编号或带 commit 的命名。因为审查 Agent 是有可能打回任务的,执行 Agent 改完之后,文件要能区分是第几版。我通常把执行 Agent 的每次修改都提交为一次本地 git commit,审查 Agent 读取的是 commit 列表和最新 diff,打回时指定 commit 号,这样整个流程都可以回退。

4.3 编排器本身也要有提示词

很多人搭了多 Agent 结构,却忘了编排器本身也是需要提示词的。我在早期犯过这个错:规划 Agent、执行 Agent、审查 Agent 的提示词写得挺好,但安排它们干活的那个“主管循环”完全没有提示,导致任务被错误地拆解、派发顺序混乱。

主管 Agent 的提示词核心是任务列表管理。它要能读取用户目标,拆解成任务,然后逐个派发。我会给它一个非常机械的流程提示:

你是任务协调器。你的工作流程: 1. 读取用户提供的目标描述。 2. 将目标拆解为若干独立任务,每个任务写入 tasks/ 目录。 3. 每次只派发一个任务给执行 Agent,等待执行结果。 4. 将执行结果交给审查 Agent 检查。 5. 审查通过则标记完成,不通过则将问题反馈给执行 Agent。 6. 全部任务完成时,汇总所有任务状态。

这一段的作用,是让主管 Agent 的行为保持可控。虽然理论上它可以自由发挥,但不给它发挥空间反而更安全。多 Agent 系统的稳定性,从来不靠某个 Agent 的聪明,而靠流程的确定性。

5. 实战中踩到的坑和排查过程

5.1 配置项报错:“忽略 1 个无法识别的配置设置”

实际部署多 Agent 流程时,我遇到过一遍 Codex CLI 启动时输出一条提示:ignoring 1 unrecognized configuration setting,翻译过来就是配置里有它不认识的键。这看起来只是警告,但一定要当成错误排查。

大多数情况下,是config.toml里手写的键名拼错了,或者某个配置项在升级后改了名。这个警告意味着你认为生效的某个配置实际上没有生效。我那次就是这样,配置里写了一个模型参数,但键名拼错了,结果 Codex 一直在用默认参数跑,行为表现完全不是预期的那种。

排查步骤很简单:先检查~/.codex/config.toml(Linux/macOS)或者%USERPROFILE%\.codex\config.toml(Windows),把报错里提到的配置项单独拎出来确认拼写。对照官方文档核对一遍,不要凭记忆写配置。如果确认没有问题,再检查是不是本地装了多个版本的 Codex,导致读到了旧版配置模板里的键。

5.2 登录态和授权问题的现场处理

多 Agent 流程里,经常要并发调用 Codex,这时最容易遇到的是auth token is unavailable或者登录态失效的问题。单 Agent 用的时候,弹窗登录一次能用很久,并发场景一多,多个子任务同时凑齐了触发登录请求,整个流程就会卡住。

我的处理思路是,在编排器启动前,先把 Codex 的登录态验证好,不要等到任务派发了再处理。跑一行命令确认登录状态,确认无误后再拉起多 Agent 任务。如果任务跑了一半遇到 token 失效,优先停止派发新任务,把已完成的子任务做好提交记录,修复登录态后分批重试,绝不带着失效 token 硬试。

还有一次出现过“组织设置加载失败”的提示,但本地任务是能跑的。这种情况多数是在企业网络环境里,CLI 访问组织配置的时候遇到了一时性的网络问题。我当时的处理是跳过组织配置同步,用默认配置继续本地执行,成功了。但如果是企业强制要求组织策略,那就不能跳过,需要先恢复网络链路再继续。

5.3 长任务对话断裂与上下文丢失

另一个常见坑是执行 Agent 在长任务里,因为某种原因对话会话被打断了。Codex CLI 非交互模式下,任务执行到一半,如果网络中断或者本地进程被杀,整个会话就废了,之前所有推理过程全部丢失。

一开始遇到这个问题,我会尝试重发同样的任务,然后发现结果和之前跑的不完全一样。模型的随机性决定了,只要上下文有细微变化,输出就不可能精确复现。后来我学到的做法是,把大任务拆成小块,每一块的任务描述都自带验收标准,就算中途断了,重跑的成本也可控。

这种场景建议多利用文件系统里已有的代码状态。如果执行 Agent 在断线前已经修改了部分代码,不要重新从头生成,而是告诉新会话“代码已经在文件里,你检查当前状态,只做剩余部分”。把这个原则写进编排器提示词,能省不少重试的时间。

5.4 并发执行时的问题:多个 Agent 互相干扰

多 Agent 听起来就该是并行的,但编码任务我不建议真的让多个执行 Agent 同时写同一个仓库。它们会各自读取当前代码状态,各自修改,最后写回时互相覆盖,产生根本排查不出来的竞态问题。

安全的做法是,多个执行 Agent 并行写不同的模块,但如果它们之间存在共享文件,那就必须串行执行。判断标准很简单:有没有可能两个任务修改同一个文件?只要存在这种可能,就把它们放进同一个队列。

我做过一个折中方案:允许审查 Agent 在执行 Agent 干活的过程中并行跑静态检查,因为它们两个不写同一个文件。规划 Agent 也可以提前准备后续任务,但它只能写任务文档,不能动代码。真正写代码的执行 Agent,一次只跑一个。

5.5 模型选择和路由的错误

最后一个值得记录的问题,是编排器里配置了多个模型,但某些模型根本不支持被 Codex CLI 调用。我遇到一次报错,提示某个模型名称不被当前方式支持,排查下来是编排配置里写错了模型标识符。这种情况去模型提供方核对一下准确模型名,别在配置里手动猜。另外要注意,多 Agent 流程中不同 Agent 走不同模型是常态,但主管 Agent 的模型最好和工人的模型分开。主管对推理能力要求高,工人的模型更追求执行速度和成本。我的经验是,主管用更强的模型,工人用响应更快的模型,不要全部混成一个。

6. 我现在的多 Agent 标准流水线

把这轮实战沉淀下来之后,我搭了一套固定的参考流程,分享出来给大家抄作业。

整条流水线按这个顺序执行:

  1. 需求收集阶段:把用户需求写入requirements.md,不做任何技术方案。
  2. 规划阶段:规划 Agent 读取requirements.md,产出技术方案文档design.md,里面必须包含模块拆分、接口定义、数据变更、验收标准。
  3. 任务拆解阶段:主管 Agent 基于design.md拆分任务,每个任务是一个独立 markdown 文件,包含任务说明、涉及文件、输出要求。
  4. 执行阶段:执行 Agent(通常是 Codex)按任务文件逐个实现。每完成一个任务,自动创建一次 git 提交。
  5. 审查阶段:审查 Agent 读取最近一次提交的 diff,运行测试和静态检查,输出审查结论。
  6. 反馈阶段:审查不通过,把问题列表交给执行 Agent 重新修改;通过后,任务标记完成。

这套流水线的最大好处,是每个 Agent 的上下文都被控制住了。规划 Agent 不关心具体代码怎么改,执行 Agent 不关心整体方案怎么定,审查 Agent 不关心最初需求是什么。每个环节都有明确的输入和输出,代码状态始终可回退、可追踪。

不要把这套东西理解成只在复杂大项目里才能用,小任务也可以简化。哪怕是修一个 bug,我也会让规划 Agent 先写一句话的定位,再让 Codex 去改,最后让审查 Agent 看一眼 diff。就是多花几十秒的事,但质量稳定性比直接跟 Codex 说“帮我修一下”要强太多。

根据自己的实际经验,我不推荐一上来就搭一个很重的多 Agent 系统,那会把自己淹没在配置和管理里。选一个你经常做的中型任务,先手动拆两步走:一次规划、一次执行。感受一下上下文分离带来的变化,然后再逐步添加审查角色和文件通信机制。多 Agent 协同并不是什么神秘的技术,它就是把你平时在团队里分配工作的逻辑,搬到了模型调用层面而已。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询