
1. 从单打独斗到五人小队AI编程协作模式的范式转移如果你最近半年一直在用AI写代码大概率经历过这样的场景打开一个对话窗口把需求描述一遍AI给你吐出一大段代码你复制粘贴、跑一下、报错、再贴回去让它改。来回几轮之后上下文越来越长AI开始失忆前面说过的约束它忘了改到后面把前面的逻辑又改坏了。这种一个AI单打独斗的模式在处理小脚本、单文件函数时还算顺手一旦面对跨模块、多文件、需要同时兼顾前端后端数据库的真实项目就立刻捉襟见肘。所谓AI编程的第四纪元说的就是这个转折点。第一纪元是代码补全你打字它猜下一行第二纪元是对话式生成你描述它给整段第三纪元是带工具调用的Agent能自己读文件、跑命令、看报错。而第四纪元的核心特征是多个Agent同时协作——不再是我指挥一个AI而是我指挥一支AI小队每个Agent有明确分工有的负责写业务逻辑有的负责写测试有的负责审查代码质量有的负责查文档有的负责跑集成验证。它们并行工作最后把成果汇总到你手里。这件事为什么现在才成为可能两个前提条件成熟了。第一是上下文窗口和推理成本的平衡让单个Agent能独立扛起一个子任务而不至于中途断片第二是Agent编排框架的成熟像Claude Code、Codex这类工具已经不只是聊天框而是提供了子任务派发、文件系统隔离、命令执行沙箱这些基础设施让多Agent并行有了落脚点。热搜词里频繁出现的多Agent协作agent框架agent架构git worktree ai编程本质上都是同一件事的不同侧面大家在摸索怎么把一支AI小队组织起来干活。这篇文章适合谁看如果你已经用过Claude Code或Codex能跑通单Agent的基本流程但一遇到大项目就觉得一个AI不够用那这篇就是写给你的。如果你还没入门建议先把单Agent的安装和使用跑顺再来看协作层的东西否则容易一头雾水。下面我会从协作模式的设计、任务拆分的具体方法、并行执行的工程细节、冲突处理、以及我踩过的真实坑这几个角度把5个Agent同时帮你写代码这件事讲透。2. 五个Agent到底怎么分工角色设计与职责边界2.1 为什么是五个而不是越多越好很多人第一反应是既然多Agent好那我开十个二十个不是更快实测下来恰恰相反。Agent数量超过一定阈值后协调成本会指数级上升。每个Agent都要读项目上下文、都要理解任务边界、都要产出结果而结果之间需要合并、需要解决冲突。五个左右是一个比较舒服的平衡点既能覆盖实现、测试、审查、文档、集成这几类典型工作又不至于让合并阶段变成一场灾难。我自己的经验是五个Agent对应五类职责每类职责的产出物形态不同这样合并时不容易打架。如果两个Agent都在改同一类文件那冲突概率会飙升。所以分工的第一原则不是平均分配工作量而是按产出物类型切分。2.2 五类角色的具体定义下面这张表是我在实际项目中反复调整后稳定下来的分工方案你可以直接拿去用也可以根据自己的项目特点微调。Agent角色核心职责主要产出物典型工具权限架构Agent拆解需求、定义接口、确定文件结构接口定义文件、目录结构、任务清单只读代码库可写设计文档实现Agent按接口写业务逻辑源代码文件可写指定模块目录测试Agent针对实现写单元测试和集成测试测试文件可写测试目录可执行测试命令审查Agent检查代码质量、安全隐患、边界条件审查报告、修改建议只读可评论不可直接改集成Agent合并成果、跑端到端验证、修复集成问题合并后的代码、验证报告可写全库可执行构建命令这个分工的关键在于权限隔离。实现Agent只能写自己负责的模块目录测试Agent只能写测试目录审查Agent干脆只读。这样即使某个Agent发疯乱改也不会污染整个代码库。热搜词里提到的git worktree ai编程就是这个思路的工程实现——给每个Agent一个独立的工作树物理隔离互不干扰。2.3 角色之间的信息流怎么设计分工定好了接下来是信息怎么在Agent之间流动。这里有个反直觉的点不要让Agent之间直接对话。听起来很美好——实现Agent写完直接喊测试Agent来测——但实际会让上下文爆炸而且一旦某个Agent的输出格式跑偏整条链路就断了。正确做法是通过文件系统做异步通信。架构Agent把接口定义写成一个interface.md或者api-spec.json实现Agent读这个文件干活测试Agent也读这个文件写测试。所有Agent的输入输出都落在磁盘上由你或者一个协调脚本来控制执行顺序。这样做的好处是每个Agent的上下文是干净的只包含它需要的信息出问题时你能精确知道是哪个环节的产物有问题而且Agent可以并行跑不用互相等待。我通常会在项目根目录建一个.agents/文件夹里面按角色分目录.agents/architect/、.agents/implementer/、.agents/tester/每个目录里放该角色的任务描述、输入引用、输出产物。这个约定一旦建立整个协作流程就变得可追溯、可复现。3. 任务拆分的颗粒度决定多Agent协作成败的隐形手3.1 拆得太粗和拆得太细都会翻车多Agent协作里最容易出问题的地方不是Agent本身的能力而是任务拆分的颗粒度。我见过两种极端。一种是拆得太粗给实现Agent的任务是实现用户模块。结果这个Agent要同时处理注册、登录、权限、密码加密、会话管理上下文塞满写到后面质量直线下降而且测试Agent根本没法针对这么一大坨写测试。另一种是拆得太细把实现登录接口拆成定义请求体结构写参数校验写数据库查询写密码比对返回token五个子任务分给五个Agent。结果每个Agent都要读一遍项目上下文光理解环境就花掉大半预算而且它们之间的接口对不齐合并时全是缝。3.2 一个可操作的拆分标准我的经验标准是一个子任务应该对应一个可独立测试的交付单元。换句话说如果这个子任务完成后你能写一个测试来验证它做对了那这个颗粒度就是合适的。登录接口是一个合适的单元因为你可以写测试验证正确密码能登录、错误密码被拒绝。而写参数校验不是一个合适的单元因为它没法独立验证——你没法脱离登录流程单独测参数校验。按这个标准一个中等规模的Web项目通常能拆出15到30个子任务分给5个Agent每个Agent手上3到6个任务。这个量级下每个Agent的上下文是可控的任务之间的依赖关系也是清晰的。3.3 依赖关系怎么表达拆完任务还要标清楚谁依赖谁。我习惯用一个简单的YAML文件来描述任务图tasks: - id: T01 name: 定义用户数据模型 agent: architect depends_on: [] output: .agents/architect/user-model.md - id: T02 name: 实现用户注册接口 agent: implementer depends_on: [T01] output: src/user/register.ts - id: T03 name: 实现用户登录接口 agent: implementer depends_on: [T01] output: src/user/login.ts - id: T04 name: 编写用户模块测试 agent: tester depends_on: [T02, T03] output: tests/user.test.ts有了这个文件你就可以写一个简单的调度脚本先跑没有依赖的任务跑完检查产物是否存在再跑下一批。T02和T03都只依赖T01所以它们可以并行——这就是多Agent协作真正省时间的地方。两个实现Agent同时开工而不是一个写完另一个再写。提示依赖关系一定要显式写出来不要靠Agent自己猜。我早期偷懒没写依赖结果测试Agent在实现Agent还没写完的时候就开始跑拿到的是一堆空文件白白浪费了一轮预算。4. 并行执行的工程落地从worktree到合并的完整链路4.1 用git worktree给每个Agent一个独立战场多Agent并行最大的工程难题是文件冲突。两个Agent同时改同一个文件后写的覆盖先写的这种事故一旦发生排查起来极其痛苦。解决方案就是热搜词里反复出现的git worktree。git worktree允许你在同一个仓库上挂多个工作目录每个目录对应一个独立的分支。你可以给每个Agent分配一个worktree# 为主仓库创建三个并行工作树 git worktree add ../proj-agent-impl feature/impl git worktree add ../proj-agent-test feature/test git worktree add ../proj-agent-review feature/review这样实现Agent在../proj-agent-impl里改代码测试Agent在../proj-agent-test里写测试物理上就是两个目录根本不可能互相覆盖。等它们都干完活你再把分支合并回主干。这个方案的好处是隔离彻底坏处是合并时要处理冲突。但因为前面已经按产出物类型做了分工实现改src测试改tests冲突通常很少合并起来比较顺。4.2 每个Agent的启动配置怎么写以Claude Code为例给每个Agent启动时关键是把它的上下文限制在它需要的信息内。不要让它读整个项目而是明确告诉它读哪些文件。一个典型的启动提示词结构是这样的你是实现Agent负责以下任务 - 任务ID: T02 - 任务描述: 实现用户注册接口 - 输入: 请先阅读 .agents/architect/user-model.md 了解数据模型 - 输出: 写入 src/user/register.ts - 约束: 只修改 src/user/ 目录下的文件不要动其他模块 - 验收标准: 接口签名与 user-model.md 中定义一致这个提示词里约束和验收标准是最容易被忽略但最重要的两行。约束防止Agent越界改文件验收标准让Agent自己知道什么时候算干完了。我试过不写验收标准结果Agent写完一个半成品就停了因为它不知道完成的定义是什么。4.3 并行调度的实际脚本如果你不想手动一个个启动Agent可以写个简单的调度脚本。下面是一个Python示例用subprocess并行拉起多个Agent进程import subprocess import yaml from concurrent.futures import ThreadPoolExecutor def load_tasks(path): with open(path) as f: return yaml.safe_load(f)[tasks] def run_agent(task): prompt build_prompt(task) # 每个Agent在自己的worktree目录下运行 workdir f../proj-agent-{task[agent]} result subprocess.run( [claude, -p, prompt], cwdworkdir, capture_outputTrue, textTrue ) return task[id], result.returncode def build_prompt(task): return f你是{task[agent]}负责任务{task[id]}{task[name]} 输出到{task[output]} 依赖产物{task.get(depends_on, [])} 只修改你负责的输出文件不要越界。 tasks load_tasks(tasks.yaml) # 按依赖分批同批内并行 ready [t for t in tasks if not t[depends_on]] with ThreadPoolExecutor(max_workers5) as pool: results list(pool.map(run_agent, ready))这个脚本的核心逻辑是同一批没有依赖关系的任务并行跑有依赖的等前一批完成再跑。实际项目中我会在每批跑完后加一个校验步骤检查产物文件是否真的生成了、内容是否非空再决定是否进入下一批。4.4 合并阶段的处理所有Agent跑完后进入合并阶段。这时候集成Agent上场。它的任务是把各个worktree的改动合并到主干跑一遍完整的构建和测试如果失败就尝试修复。合并时最容易出问题的是接口不一致。比如实现Agent按自己的理解定义了函数签名测试Agent按自己的理解调用了这个函数两边对不上。这就是为什么架构Agent的接口定义文件如此重要——它是所有Agent的共同语言。如果接口定义足够清晰合并阶段的冲突会少很多。我通常会让集成Agent先跑一遍git merge --no-commit看看有哪些冲突文件然后逐个分析。如果是简单的格式冲突直接解决如果是逻辑冲突说明前面的接口定义有歧义需要回到架构Agent重新明确。5. 踩坑实录多Agent协作中那些文档不会告诉你的事5.1 上下文污染Agent读到了不该读的东西这是我踩的第一个大坑。早期我没做目录隔离实现Agent在干活时顺手读了测试目录里的文件结果它自作聪明地按测试的预期去改实现而不是按接口定义去实现。表面上看测试通过了实际上实现逻辑是错的——它只是刚好满足了测试用例。解决办法就是前面说的权限隔离。实现Agent的工作目录里测试目录要么不存在要么是只读的。Claude Code支持配置允许访问的路径Codex也有类似的沙箱机制。把Agent能看到的文件范围收窄它就不会被无关信息带偏。5.2 预算失控五个Agent同时烧钱是什么体验多Agent并行意味着成本也是并行的。单Agent跑一个任务花10分钟五个Agent并行跑五个任务理论上还是10分钟但成本是五倍。如果任务拆分不合理某个Agent反复重试成本会迅速失控。我的控制手段有三个。第一是给每个Agent设置最大轮次比如最多20轮工具调用超过就停避免它陷入死循环。第二是在提示词里明确如果遇到无法解决的问题停下来报告不要反复尝试很多Agent的默认行为是死磕到底这在多Agent场景下是灾难。第三是先小规模验证用一两个任务跑通整个流程确认拆分和调度没问题再放大到全部任务。5.3 产物格式漂移说好的JSON变成了散文架构Agent被要求输出接口定义我期望的是结构化的JSON或YAML结果它输出了一大段自然语言描述。下游的实现Agent读这段描述理解得五花八门最后接口全对不上。这个问题的根源是没有给输出格式的硬约束。后来我在提示词里加了明确的格式要求并且要求Agent在输出前后加上标记请严格按以下格式输出不要添加任何额外说明 spec { endpoint: /api/user/register, method: POST, request: {username: string, password: string}, response: {userId: string, token: string} } /spec有了spec标记下游Agent就能精确提取需要的内容不会被散文干扰。这个技巧在热搜词里提到的agent evalsAgent评估中也很关键——评估Agent的输出质量第一步就是看它有没有按格式输出。5.4 审查Agent的老好人问题审查Agent的职责是挑毛病但实测下来它经常太客气报告里全是代码整体不错建议考虑……这种不痛不痒的话。真正的问题——比如SQL注入风险、未处理的空指针、并发竞态——它反而没提。解决办法是给审查Agent一个明确的检查清单而不是让它自由发挥。清单里列出你必须检查的项输入校验、错误处理、边界条件、资源释放、并发安全、日志脱敏。让审查Agent逐项打勾每项都要给出通过/不通过/不适用的结论。这样它就没法含糊其辞了。注意审查Agent的清单要根据项目类型定制。Web后端和嵌入式项目的检查项完全不同别用一套通用清单糊弄所有项目。6. 从单Agent到多Agent的平滑过渡路径6.1 不要一步到位先跑通两个Agent如果你现在还在单Agent阶段别急着上五个。我的建议是先跑通两个Agent的协作一个实现一个测试。这两个角色的产出物天然分离src和tests冲突最少最容易验证协作流程是否顺畅。跑通两个之后再加审查Agent。审查Agent是只读的加进来不会引入新的冲突但能显著提升代码质量。最后再加架构Agent和集成Agent这两个是头和尾加进来之后整个流程才闭环。这个渐进路径的好处是每一步你都能清楚地知道新增的Agent带来了什么价值出了问题也容易定位是哪个环节的锅。一步到位上五个一旦流程跑不通你根本不知道是拆分的问题、调度的问题还是某个Agent本身的问题。6.2 什么项目适合多Agent什么项目不适合多Agent协作不是万能的。它适合模块化程度高、接口清晰、任务可并行的项目。比如一个标准的CRUD后端服务用户模块、订单模块、商品模块之间接口明确非常适合拆给多个Agent并行做。反过来强耦合、需要频繁全局重构、算法密集型的项目就不太适合。比如你在写一个复杂的编译器或者图形渲染引擎各个模块之间耦合极深改一处牵动全身多Agent并行反而会制造大量冲突不如单Agent串行来得稳。判断标准很简单如果你能把项目画成一张清晰的模块依赖图且模块之间的接口是稳定的那就适合多Agent如果模块之间是你中有我我中有你的关系那就先别折腾。6.3 团队协作场景下的多Agent多Agent协作还有一个容易被忽略的应用场景团队里的每个人都有自己的Agent小队。比如前端同学跑一个前端Agent小队后端同学跑一个后端Agent小队两边通过接口定义文件对齐。这样每个人的Agent都在自己的worktree里干活最后通过Git合并本质上和单人多Agent是同一套方法论只是规模更大。这种模式下接口定义文件成了团队协作的核心契约。前端Agent和后端Agent都读同一份接口定义各自实现最后合并时接口天然对齐。这比传统的先对接口文档再各自开发效率高得多因为Agent读文档、写代码、跑测试是全自动的人只需要在接口定义这个关键节点上把关。7. 我个人的一些实操体会折腾多Agent协作这大半年最大的感受是瓶颈从来不在Agent的能力而在人的组织能力。Agent能写代码、能跑测试、能审查这些能力单Agent时代就已经具备了。多Agent真正考验的是你能不能把一个大任务拆成清晰的子任务、能不能定义好接口、能不能设计好隔离和合并的流程。这些事以前是技术Leader干的现在变成了每个用AI写代码的人都要会的技能。另一个体会是别追求全自动。我见过有人想搭一个输入需求五个Agent全自动跑完直接出成品的流水线。实测下来全自动的失败率很高因为中间任何一个环节的偏差都会累积放大。更现实的做法是半自动Agent干活你在关键节点接口定义、合并、最终验收介入把关。这样既享受了并行的效率又保留了人的判断力。最后分享一个小技巧给每个Agent起个名字。听起来很幼稚但实测有效。当你看到日志里实现Agent-A完成了T02测试Agent-B报告T04失败时比看Agent-3Agent-7要直观得多排查问题时脑子不容易乱。这种小细节往往决定了你愿不愿意长期用这套流程。多Agent协作这件事现在还处在能用但不够好用的阶段工具链在快速迭代今天的最佳实践可能下个月就被推翻。但底层的方法论——任务拆分、接口定义、隔离与合并——是稳定的值得花时间打磨。把这套方法论练熟了无论工具怎么变你都能快速搭起自己的AI小队。