拓冰建站拓冰建站
首页 / 资讯中心 / 正文

多Agent并行失控?用TASK.md与契约冻结为Vibe Coding上锁

一个人同时开四个 Claude Code / Codex 终端听起来像是效率焦虑晚期。为了一个“到处着火”的版本验收我真这么干了三周。最后想明白一件事Vibe Coding 这类工具的瓶颈早就不在单条 prompt 的生成质量上而在多路 Agent 并行时的契约与收口。更直白地说单一 Agent 在窄任务上确实能打真正瓦解工程秩序的是 N 个 Agent 互相不知道对方改了什么。这篇文章不会跟你讲“Vibe Coding 多牛”或“AI 要替代程序员”而是记录我如何在同一个仓库上同时跑 Claude Code 和 Codex、怎么踩坑、怎么算账以及最后总结出的那套“给 Agent 上锁”的工作方式。1. 为什么我会被逼到同时开四个 Agent1.1 接了个“到处着火”的验收任务事情起源于一个不算大的项目版本订单服务的事务补偿有 bugDashboard 状态映射错了旧 Python 模块要迁到结构化日志Node SDK 还有一组回归测试在 CI 上红着。这些活儿单个拆开都不算难但都有一个共同点分散在仓库的不同区域改起来容易互相踩脚。我当时的第一反应是“串行处理”因为过去一直觉得 AI 编码工具只适合“一个人慢慢聊”。可那天真的没时间如果按顺序来光是等每个任务跑完测试、再手动切换上下文三天都未必收得完。于是我把任务拆成了四份同时开了四个终端。实际分工如下终端入口工具任务AClaude Code订单服务事务补偿逻辑修复BClaude CodeDashboard 状态字段与图表映射调整CCodex CLI旧 Python 日志模块迁移到结构化 loggingDCodex IDE 插件Node SDK 回归测试失败定位用两个 Claude Code、两个 Codex不是追求“全家桶”而是想对比同一类改动在不同工具下的表现。跑完以后我发现了一个更关键的问题这四个任务虽然表面上互不相关但它们都隐式依赖同一份订单状态枚举。这个隐患在第三天集中爆发了后面我会细讲。1.2 开工前先做工作区隔离并行开发最怕的不是 Agent 写错代码而是几个 Agent 在同一份工作区里互相把文件改乱。我开工前给每个任务建了独立工作树避免它们共享 node_modules、共享未提交改动、甚至互相污染对话上下文。我的做法是对同一个 git 仓库使用git worktree。具体命令大概是git worktree add ../repo-fix-orders -b fix/orders-tx git worktree add ../repo-fix-dashboard -b fix/dashboard-status git worktree add ../repo-migrate-logging -b chore/structured-logging git worktree add ../repo-debug-sdk -b fix/sdk-regression这样每个 Agent 都有一个独立的物理目录互不干扰。提醒一句如果仓库里有node_modules或vendor这类重目录不要图省事直接做软链接共享。表面上能省磁盘实际上多个 Agent 同时跑安装、锁文件变更时会把依赖状态搞得很乱。我第一轮就吃了这个亏之后都是让每个 worktree 自己装依赖。另外每个目录里我都放了一份TASK.md里面写清楚任务边界、输入输出、验证命令。然后 Claude Code 和 Codex 启动时我都会加一句“先读 TASK.md。”这一步后来被证明是整套流程里最重要的决定。2. 并行跑了三天后瓶颈从“生成”变成了“合流”2.1 每个 Agent 都很有道理合在一起就是事故三个星期里最让我醒脑的不是某个 Agent 写出了糟糕代码而是每个 Agent 单独看都逻辑自洽测试也过一旦合流就崩。复盘一个典型事故Agent A 在订单领域里重构了OrderStatus枚举把原先的PAYMENT_SENT改成了PAYMENT_SETTLED工具链没有报错因为它按 TASK 里的局部目标把调用点都改了。Agent B 在 Dashboard 图表任务里看到的还是旧枚举于是按旧状态名写了新的展示分支。两边各自跑单测都是绿的。等到合并时TypeScript 编译直接炸了。代码本身没有“谁对谁错”的问题但 B 不知道 A 动了共享枚举A 也不知道 B 正在依赖这个枚举。人写代码遇到这种情况会去问一圈Agent 不会它只会基于当前 prompt 和当前文件“自信地”继续写。那一刻我才意识到多 Agent 并行时上下文隔离的好处同时也是一种诅咒。每个 Agent 都是信息孤岛物理上分开了逻辑上的共享知识也断了。2.2 局部自信 vs 全局不确定性这背后有个很反直觉的点LLM 在做局部任务时非常自信因为它只看得到那一小块代码但一旦任务涉及公共契约、跨模块约定、API 兼容性它的“自信”就会变成危险。我后来用了一个类比来理解这件事四 Agent 并行就像四个人跑接力每个人单跑 100 米都很快但接力棒交接的瞬间才是决定比赛胜负的地方。Vibe Coding 早期大家只关心“起点到终点这一段代码能不能生成”多 Agent 并行以后真正的瓶颈变成了交接点也就是接口、类型、数据流、测试约定这些容易被忽略的“缝隙”。如果你把这些缝隙交给 Agent 自己临场发挥结果就是合流时一片混乱。所以新瓶颈不是“模型不懂我的业务”而是“模型们没有一个统一的业务契约”。这直接改变了我后续的整个工作方式。2.3 那几天低效到什么程度我做了一个统计最多的时候四个 Agent 同时跑但真正能并入主干的“有效产出”比我自己串行写还慢。问题集中在三类失败类型具体表现主要原因Git 合流冲突两个 Agent 都在同一个公共工具文件里加了 helper没有提前划清文件边界共享契约被破坏共享枚举、类型、接口被单方面改动没有共享的接口冻结机制上下文重复消耗每个 Agent 都要重新扫读仓库没有一个统一的任务描述文件前两类是工程秩序问题第三类是成本问题。也就是说真正让“同时跑 4 个 Agent”这件事翻车的不是算力不是模型智商而是工程约束。模型越强局部产出越多合流的冲突爆炸半径就越大。3. 给每个 Agent 上锁Vibe Coding 要进入 Harness 阶段3.1 Vibe Coding 和 Spec-Driven 不是对立的可能有人会问Vibe Coding 不就是“开着 vibe 大胆让 AI 写”吗加一堆规则不是又退回传统开发了吗我的看法恰恰相反。Vibe Coding 适合做原型、做探索、做“我不确定代码长什么样”的东西但当你同时在跑四个 Agent、还要把结果并回主干时就必须从 vibe 模式切到 Spec-Driven 模式。简单说Vibe 是“需求靠感觉”Spec-Driven 是“需求靠契约”。这两者区别可以用一个例子讲清楚Vibe 式 prompt“帮我把登录页做得好看一点。”模型会自由发挥效果可能惊喜也可能惊吓。Spec-Driven 式 prompt“登录页在移动端 375px 宽度下不允许出现横向滚动密码错误时在输入框下方展示文案‘密码错误请重试’表单提交后按钮进入 loading 状态完成后列出你修改的文件。”前者适合一个人玩后者才是多人并行协作的入场券。四个 Agent 并行时如果任务描述里全是“优化”“完善”“正常处理”这种词Agent 们就会各自脑补一套标准最后合并时必然打架。3.2 TASK.md把“感受”翻译成“可验收”第二周我开始强制给每个任务写TASK.md。这不只是给 Agent 看也是给未来的自己看。一份合格的 TASK 至少要包含以下内容# TASK: 修复订单事务补偿 ## 背景 - 事务补偿在支付回调超时后未正确触发。 - 相关代码services/order/compensation.ts - 现象数据库出现悬挂订单状态。 ## 输入/输出契约 - 函数compensate(orderId: string): PromiseCompensateResult - 返回结果必须包含 status 字段取值只能是 COMPENSATED | RETRYING | FATAL。 - 不允许修改 order 表结构只能通过补偿接口写状态。 ## 不允许改动范围 - Dashboard 目录、webhook 回调目录、数据库迁移目录。 - 如果发现问题扩散到了这些目录停下来写说明不要自己扩大改动。 ## 完成标准 - [ ] 新增测试补偿事件在超时后触发且状态正确。 - [ ] pnpm test services/order 全部通过。 - [ ] 无无关文件的 diff。写完后启动命令也变成固定格式。Claude Code 我用claude -p 先读 TASK.md然后按照 TASK.md 完成任务。完成标准里的验收项全部通过后列出你修改的文件和理由。Codex CLI 我试过类似的codex exec 先读 TASK.md完成标准全绿后再总结你改了哪些文件和每个改动的意图。这里的核心不是格式而是让“完成”这件事可验证。Agent 默认认为它写完代码就算完成了但你的标准是“测试通过 文件范围不越界 diff 可审”。这条规则刚开始执行会有点啰嗦但它消除了多 Agent 互相踩脚的最大隐患每个人对“做完”的定义不同。3.3 在 CLAUDE.md / AGENTS.md 里设置硬规则光有 TASK.md 还不够因为很多 Agent 会参考仓库根目录里的CLAUDE.md或AGENTS.md来决定自己的行为。我利用这个机制写了几条全局规则# 总纪律 - 只修改当前任务允许范围内的文件。 - 如果发现共享接口、公共数据类型需要变更先停止并提交一份“接口变更说明”不要直接修改公共文件。 - 提交前必须运行 lint 和当前模块测试。 - 禁止为了通过测试而硬编码返回值。 - 遇到依赖缺失或环境问题直接把错误信息和复现步骤写入 REPO 日志文件不要自行大面积安装依赖。这些规则本质上是在给 Agent 划“安全区”。很多人担心规则写太多会限制模型的发挥但根据我的实测对于同一个仓库的并行任务约束带来的稳定性收益远大于自由度损失。真正会写复杂业务的人应该明白最好的 Agent 不是最自由的 Agent而是最懂得在哪里停下来的 Agent。3.4 引入“审查 Agent”角色后面我把四个 Agent 里的一个改成了“审查 Agent”专门负责读其他 Agent 的 diff。它不写代码只做两件事检查 TASK 完成标准是否全部满足检查是否改了超出任务范围的文件。这个“对立面”设计非常有效。一个 Agent 写完代码时它自己看自己的改动永远觉得合理但让一个没有嵌入那段上下文的新 Agent 去看 diff它反而能挑出很多“看似合理但破坏了整体设计”的问题。我一般会给审查 Agent 一句固定 promptcodex exec 只读 /tmp 下其他 Agent 输出的 git diff重点找共享接口破坏、无关文件改动、硬编码测试绕过。按严重程度输出问题清单不要直接改代码。这算是我从 Harness 这个概念里获得的启发不要指望一个 Agent 既当运动员又当裁判。把开发任务和审查任务拆给不同角色比让同一个 Agent 自查可靠得多。4. 算清 Token 账四个并发到底贵在哪4.1 你以为 N 个并发是 N 倍速度其实是 N 倍重复上下文并行工作的成本问题很多人一开始没算明白。表面上看四个 Agent 同时跑理论上产出速度是四倍但由于每个 Agent 都要把仓库结构、TASK 说明、相关代码片段读进上下文它们在信息获取上的重复度非常高。我截取过一段真实记录Agent A 在修复订单补偿时把compensation.ts整个文件读了六遍Agent B 为了确认枚举定义也扫描了同一份领域文件。这些行为在单 Agent 模式下只是浪费时间在多 Agent 模式下是成倍放大的成本。所以我的第一个调整是不要觉得自己在“省时间”要把并行理解成“用更多 token 换取更低的墙钟时间”。如果你的任务价值不高或者任务之间耦合太紧并行只会让 token 账单变得很难看。4.2 控制上下文成本的几个操作习惯经过不断试错我沉淀了一套控制上下文成本的做法按优先级排列如下每个任务只给它“够用的上下文”。不要把一个 10 万行仓库的说明全部塞进 prompt。利用 TASK.md 里写清文件路径让 Agent 用 grep/ls 等工具按需查而不是一开始就把所有相关文件都读一遍。完成一个独立单元后主动/clear或新开会话不要让 Agent 背着前面几轮对话继续干。很多 token 浪费不是花在代码上而是花在反复重放老旧的对话历史上。不要让 Agent 输出冗长的中间解释。如果只是改一个小函数直接让它“给出 diff说明不超过三行”。尽量让任务按文件边界切分。文件之间依赖越少Agent 需要互相读取的知识就越少重复成本就越低。使用独立的“决策日志”。让每个 Agent 完成后把关键变更追加到一个 markdown 文件里下一个 Agent 如果需要了解公共接口变化只需要读这个日志不需要把整个分支都拉起来。做到这些以后我的并发成本大概下降了三分之一质量反而更稳了。因为 Agent 不再被大量冗余上下文干扰注意力更集中。4.3 本地模型的取舍便宜但别滥用由于搜索热词里一直有人问“Claude Code cc-switch Ollama”这类组合我也在中间阶段试过把一些低难度子任务丢给本地模型。思路很简单把 Ollama 跑起来拉个代码模型然后用 cc-switch 这类工具把请求端点切到本地服务先拿一个轻量问题验证链路是否通。这里我建议用通用的 OpenAI 兼容接口先测试例如ollama pull qwen2.5-coder:7b ollama serve # 在 cc-switch 中新增一个本地 Provider # Base URL: http://127.0.0.1:11434/v1 # Model: qwen2.5-coder:7b不过我实测后的结论是本地模型更适合做“挖掘型”任务比如搜日志、找报错位置、总结文档不太适合做需要跨文件推理的代码合流。架构性修改和公共类型变更这类高风险任务我会留给更聪明的模型。正确姿势是给不同任务配不同梯度的模型而不是追求全本地或全云端。4.4 什么样的任务才值得四路并行算完账之后我给自己定了一个判断标准允许并行的任务必须同时满足三个条件。任务之间没有共享的公共文件或者共享部分已经通过 TASK.md 冻结。每个任务都有明确的验收标准而不是“优化一下”“看看为什么会崩”这种开放题。我有足够的时间去做 Code Review。并行只是在压缩写代码的时间并不会压缩评审和合流的时间。如果这三个条件不满足我会直接把任务数量减到两个甚至一个。看似慢实际上是唯一能稳定收口的方式。5. 翻车现场多 Agent 操作里的高频报错排查5.1 Claude Code 提示“model 不是本版本能识别的模型”跑多终端时我遇到过好几次这种报错通常是在切换了模型配置之后出现。比如你明明在本地的 provider 里配了一个模型名但 Claude Code 启动时还是报类似not a model this version of Claude Code recognizes。这不一定代表模型不存在多半是三种情况CLI 版本太旧模型白名单没更新环境变量里的模型名和实际 provider 返回的模型名不一致旧会话继承了之前 session 的模型配置。排查步骤我建议这样走claude update claude --version # 查当前是否设置了模型相关环境变量 env | grep -i anthropic env | grep -i model如果发现ANTHROPIC_MODEL这类变量指向了旧模型把它清掉或改成新模型名然后新开会话再试。还有一个容易被忽略的细节不要在同一个终端里复用之前的会话去测试新模型旧会话的元数据可能会继续用旧配置。直接重启一个新会话干净得多。5.2 IDE 插件报“找不到 Codex CLI 二进制文件”Codex IDE 插件或 ChatGPT 客户端在启动时有时会报类似unable to locate the codex cli binary或者failed to start ... set codex cli path。这种问题在并行开多个 Codex 环境时更常见因为插件和服务端不一定共用同一个 shell 环境变量。解决办法是显式把 CLI 路径告诉插件。先确认 CLI 装在哪里which codex # 示例输出/usr/local/bin/codex然后去 IDE 插件的设置里找到 Codex CLI Path把这个绝对路径填进去重启插件。我在 macOS 上遇到过 Homebrew 安装路径和 shell 的 PATH 不一致的情况插件在 GUI 环境里拿不到~/.zshrc里的 PATH所以必须显式填路径。这个坑和 Claude Code 没关系纯粹是桌面端应用读取环境变量的方式不同。5.3 Codex 请求/responses端点一直失败并行尝试不同 provider 时如果切换过本地或第三方模型服务可能会看到与codex endpoint /responses相关的失败。不要急着重装 CLI更不要反复重启插件先按顺序确认这几件事。第一确认当前 Codex CLI 版本和你想要连的后端服务版本是否匹配。很多新老版本对/responses和/chat/completions这类端点的支持并不一样。第二查看当前环境变量里是否残留了旧的 base URL 或模型名。我遇到过切换 provider 后环境变量仍指向旧服务的情况最终请求发到了错误地址。env | grep -i codex codex --version第三用一行最小请求验证目标服务的连通性。如果服务本身通再回到 CLI 排查配置如果服务都不通那问题根本不在 Codex 本身。这个错误给到我的教训是多 Agent 并行时环境配置最好以文件形式固化不要依赖终端里手工 export 的临时变量。因为一旦开了四个终端每个终端的 shell 环境都可能不一样问题定位难度会成倍上升。5.4 合流时的代码冲突排查除命令行报错外真正的重灾区其实在 Git 合流阶段。四个分支合并进主干时经常会出现冲突标记遍布文件的情况。我的处理顺序是先跑一遍git diff --check看有没有空白错误再用全文搜索找出未处理完的冲突标记rg -n ^(||) .找到冲突文件后不要直接让某个 Agent 去自动解决。我的经验是让最了解那个模块的人/Agent 单独处理而不是让合并工具盲选。因为冲突往往不是代码层面谁对谁错而是接口语义变化引起的连锁反应。让一个不掌握全局上下文的 Agent 去强行解冲突等于制造下一轮 bug。6. 折腾完之后我现在怎么排兵布阵6.1 先冻结契约再放开并行现在我不再一上来就四个 Agent 一起跑。遇到多任务时我会先花半小时把公共契约冻结下来哪些枚举、类型、接口属于共享层这轮迭代谁可以改谁不能碰。然后把 TASK.md 写好再考虑并行。这个“先串行讨论、再并行执行”的顺序很关键。契约讨论阶段本质上是在建立全局知识这一部分必须由人来主导至少也得由一个掌握全局上下文的 Agent 来主导一旦契约冻结后续执行阶段就可以放心地把任务丢给多个 Agent。6.2 我给并发度定了个经验值任务耦合度低的时候我最多开三个执行 Agent 加一个审查 Agent共四个。任务涉及共享模型或公共 API 时并发度压到两个其中一个还是审查角色。如果任务本身只有一个人清楚上下文那最好只开一个 Agent避免为了“看起来并行”而制造更多合流成本。说白了Vibe Coding 的下一个阶段不再是比谁能生成更多代码而是比谁能让多路 Agent 的产出在合流时仍然保持一致。这个问题靠模型本身解决不了只能靠工作流纪律来解决。6.3 给新上手的人一个最小可复制流程如果你也想试我建议从最简单的一组任务开始同一时间只跑两个 Agent一个修改模块 A一个修改模块 BA 和 B 彼此不依赖。跑通之后再逐步扩展到三个、四个。每个 Agent 都配上 TASK.md每个分支做完都让审查 Agent 过一遍 diff然后再合主干。这个流程看起来没有“让 AI 全自动跑 4 个终端”那么惊艳但它才是真正能稳定交付的姿势。我后来把并发量降回两个整体交付速度和代码稳定性反而提升了。有意思的是控制住规模之后我自己对 Vibe Coding 的信任度增加了不少——因为我终于知道它什么时候可靠什么时候需要人进场。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门