
1. 从单兵作战到团队协作我为什么开始折腾 AI 开发团队最早用 Codex 那会儿我的用法跟大多数人一样——打开一个会话窗口把需求丢进去等它吐代码复制粘贴跑测试报错了再贴回去。这套流程在写小脚本、改单个函数的时候确实爽但一旦项目稍微复杂一点问题就全冒出来了。最典型的就是上下文爆炸一个模块改到一半前面聊过的接口约定、数据库字段、错误码规范全被挤出了窗口AI 开始一本正经地胡说八道我也得反复把同样的背景信息重新喂进去。那段时间我每天干得最多的事不是写代码而是给 AI 复述需求。后来我开始琢磨一件事既然真实团队里前端、后端、测试、评审是分工协作的那我能不能把 AI 也拆成几个角色让它们各管一摊通过某种机制互相传递信息这个念头就是我做 Codex Team Runtime 的起点。所谓 Team Runtime说白了就是一套让多个 AI 角色在同一个项目里协同工作的运行框架它要解决的核心问题有三个角色怎么划分、上下文怎么隔离又怎么共享、任务怎么在角色之间流转。这三个问题不解决多 AI 协作就只是把一个人的混乱变成一群人的混乱。这篇文章是这个系列的第七篇前六篇分别讲了角色定义、上下文管理、任务编排、工具接入、错误恢复和成本控制。到了这一篇我想跳出具体实现聊聊这半年多实践下来哪些设计是对的哪些是我一开始想当然、后来被现实打脸的。如果你正在做 AI Agent 相关的项目或者单纯想用 AI 提效但被上下文问题折磨过这篇应该能帮你少走点弯路。我不会只讲结论每个判断背后我都会说清楚为什么以及我是怎么验证的。2. 团队运行时的整体设计角色、上下文与任务流转2.1 为什么是团队而不是一个更强的单体很多人第一反应是与其搞一堆 AI 角色不如把单个 AI 的上下文窗口做大、能力做强。这个思路在理论上没错但实际用下来有几个绕不过去的坎。第一是注意力稀释上下文越长模型对中间部分的关注度越低这是目前架构层面的通病你把一万行代码塞进去它真正看见的可能还是开头和结尾那部分。第二是职责混淆一个 AI 同时扮演架构师和测试工程师它在写代码的时候会不自觉地替测试开脱写出的测试往往覆盖不到真正的边界。第三是并行效率单体 AI 只能串行处理而团队模式下前端角色和后端角色可以同时开工。我做过一个对比实验同一个需求——给一个已有的订单系统加优惠券功能涉及数据库迁移、接口改造、前端展示和单元测试。单体模式下我花了大约四十分钟中间因为上下文丢失重述了三次需求最后测试覆盖率只有六成左右。团队模式下我把需求拆给四个角色总耗时三十五分钟但测试覆盖率到了八成五而且接口约定在前端和后端之间没有出现不一致。时间上差距不大但质量差距明显。这个实验让我确信团队模式的价值不在速度而在结构化的质量控制。当然团队模式不是没有代价。角色之间的通信开销、上下文同步的复杂度、任务调度的逻辑这些都是实打实的工程成本。所以我的建议是小任务、一次性脚本单体就够了中大型项目、需要长期维护的代码库团队模式才划算。这个判断标准我后面还会展开讲。2.2 角色划分的底层逻辑按关注点切不按技术栈切一开始我是按技术栈分角色的——前端 Agent、后端 Agent、数据库 Agent。用了一段时间发现不对劲。问题出在技术栈是横切的而一个功能需求往往是纵切的。比如用户下单后发短信通知这个需求它横跨了后端逻辑、消息队列、第三方接口调用你按技术栈分每个角色都只看到自己那一小块谁来保证整条链路是通的后来我改成了按关注点划分核心角色变成四个需求解析者负责把模糊的自然语言需求拆成可执行的任务清单实现者负责写代码它不关心测试只管把功能做出来验证者负责挑刺专门找实现者的漏洞它的提示词里明确写了你的目标是找到至少三个问题集成者负责把各个实现者的产出拼到一起处理接口对齐和冲突。这四个角色里需求解析者和集成者是纵向的实现者和验证者是横向的一纵一横覆盖就比较完整了。这个划分方式的好处是每个角色的提示词可以写得非常聚焦。实现者的提示词里全是编码规范、设计模式、性能要求验证者的提示词里全是边界条件、异常路径、安全漏洞。你让一个 AI 同时记住这两套东西它必然顾此失彼。分开之后每个角色的输出质量都上了一个台阶。2.3 上下文隔离与共享的平衡术这是整个 Runtime 里最难的部分也是我踩坑最多的地方。上下文给少了角色之间信息不通集成的时候全是冲突给多了又退化成单体模式注意力稀释的问题又回来了。我的解法是分层上下文。最底层是项目级上下文包括技术栈、目录结构、编码规范、公共依赖这部分所有角色共享但只读。中间层是任务级上下文每个任务有自己的上下文包包含这个任务相关的接口定义、数据结构、依赖模块只有参与这个任务的角色能读写。最上层是会话级上下文就是角色之间的即时通信记录用完即弃不进入长期记忆。这里有个关键设计任务级上下文是显式声明的不是自动继承的。也就是说实现者要拿到某个接口定义必须在任务描述里明确引用Runtime 才会把这段上下文注入进去。这个显式引用的机制一开始我觉得很麻烦但后来发现它恰恰是控制上下文膨胀的关键。自动继承看起来很智能实际上会让上下文像滚雪球一样越滚越大最后谁也说不清某个角色到底看到了什么。提示上下文隔离的粒度不是越细越好。我试过把每个函数都做成独立的上下文单元结果角色之间通信开销大到无法忍受。最后稳定在任务这个粒度一个任务通常对应一个可独立验证的功能点。3. 核心机制拆解任务编排、工具接入与错误恢复3.1 任务编排从需求到任务清单的自动化需求解析者这个角色我给它设计的输出格式是结构化的任务清单每个任务包含五个字段任务 ID、描述、依赖任务、验收标准、所需上下文引用。这个格式是反复迭代出来的最早我只让它输出任务描述结果实现者拿到之后经常理解偏差因为它不知道这个任务的边界在哪、做到什么程度算完成。验收标准这个字段特别重要。我要求需求解析者用给定-当-那么的格式写验收标准比如给定一个已登录用户当他提交超过库存数量的订单那么系统返回库存不足错误且不扣减库存。这种格式逼着解析者把边界条件想清楚实现者拿到之后也知道该测什么。实测下来加了验收标准之后验证者发现的需求理解偏差类问题减少了大约七成。任务之间的依赖关系用有向无环图管理。这个图不是静态的Runtime 会根据实现者的反馈动态调整。比如实现者发现某个任务比预想的复杂需要拆成两个它会向编排器发一个拆分请求编排器重新计算依赖关系。这个动态调整能力是团队模式相对单体模式的一大优势单体模式下你只能推倒重来。3.2 工具接入MCP 协议带来的标准化红利工具接入这块我早期是每个工具写一套适配代码Git 操作一套、文件读写一套、执行命令一套维护起来很痛苦。后来转向 MCP 协议之后情况好了很多。MCP 本质上是一套标准化的工具描述和调用协议工具提供方按照协议暴露自己的能力Agent 按照协议去发现和调用双方解耦。我目前接入的工具大概分三类。第一类是代码操作类包括文件读写、代码搜索、Git 操作这类工具用得最频繁几乎每个角色都要用。第二类是执行验证类包括运行测试、执行构建、静态检查主要是验证者在使用。第三类是信息查询类包括查文档、查依赖版本、查接口定义需求解析者和实现者用得比较多。MCP 的好处是我换一个代码搜索工具不需要改 Agent 的代码只需要换一个 MCP Server 就行。这个解耦在早期不明显但当你接入的工具超过十个之后价值就体现出来了。不过 MCP 也有坑最大的坑是工具描述的质量参差不齐。有些 MCP Server 的工具描述写得很模糊Agent 不知道该在什么场景下调用它结果要么不用要么乱用。我的经验是接入一个新工具之前先自己把工具描述读一遍如果连你都觉得描述不清楚Agent 肯定也用不好。3.3 错误恢复让团队自己从失败中爬起来多 Agent 协作最怕的就是一个角色卡住整个流程停摆。我遇到过好几次这样的情况实现者写出的代码编译不过验证者反复报同一个错误两个角色陷入死循环token 哗哗地烧。后来我加了三层错误恢复机制。第一层是角色内重试同一个角色在遇到可恢复错误时自动重试最多三次每次重试会带上上一次的错误信息。第二层是角色间升级如果一个角色重试三次还搞不定任务会被升级给协调者角色协调者会分析失败原因决定是换一个实现方案、还是把任务拆得更细、还是标记为阻塞。第三层是人工介入协调者判断无法自动解决时会生成一份问题报告包含失败上下文、已尝试的方案、建议的排查方向然后暂停流程等我处理。这三层机制里第二层是最有价值的。协调者这个角色我一开始没设觉得多余后来发现它是整个团队的急诊医生。它不写代码专门处理异常它的提示词里全是故障排查的思路。有了它之后需要我人工介入的比例从大约三成降到了一成以下。注意错误恢复机制一定要设 token 上限。我有一次忘了设两个 Agent 互相甩锅一晚上烧掉了一大笔额度。现在每个角色的单任务 token 消耗都有硬上限超了就强制升级。4. 实操全流程从零跑通一个多角色协作任务4.1 环境准备与 Runtime 初始化先说环境。我用的是一台普通的开发机配置不算高因为主要的计算都在云端。本地需要装的东西不多一个代码编辑器、Git、以及 Runtime 本身的命令行工具。Runtime 我是用 Node.js 写的所以需要 Node 环境版本建议 18 以上低版本有些异步特性支持不好。初始化一个项目很简单在项目根目录执行初始化命令Runtime 会生成一个配置文件里面定义了角色、工具、上下文策略这些。配置文件我建议用 YAML 写比 JSON 好读注释也方便。下面是一个精简版的配置示例roles: - name: requirement-parser model: gpt-4-class tools: [file-read, doc-search] max_tokens_per_task: 8000 - name: implementer model: gpt-4-class tools: [file-read, file-write, code-search, git] max_tokens_per_task: 20000 - name: verifier model: gpt-4-class tools: [file-read, test-runner, static-check] max_tokens_per_task: 12000 - name: integrator model: gpt-4-class tools: [file-read, file-write, git] max_tokens_per_task: 15000 context: project_level: ./context/project.md task_level_dir: ./context/tasks/ session_ttl: 3600 recovery: max_retries: 3 escalate_on_failure: true token_hard_limit: 50000这个配置里每个角色的工具权限是分开的。实现者有写文件的权限验证者没有这是故意的。验证者的职责是挑刺不是改代码如果它能改代码它就会倾向于顺手修一下而不是把问题报出来。这个权限隔离是我踩了坑之后加的之前验证者老是自作主张改代码导致实现者的工作被覆盖集成的时候一团乱。4.2 一个真实任务的完整执行记录我拿一个真实任务来演示给一个博客系统加文章草稿自动保存功能。需求描述就一句话用户编辑文章时每隔三十秒自动保存草稿刷新页面后草稿还在。需求解析者拿到这句话输出了四个任务。任务一是设计草稿存储方案包括存储位置和数据结构任务二是实现前端定时保存逻辑任务三是实现后端草稿读写接口任务四是实现页面加载时的草稿恢复。每个任务都带了验收标准比如任务四的验收标准是给定一个存在草稿的文章编辑页当页面加载完成那么编辑器内容自动填充为草稿内容且提示用户草稿已恢复。实现者先做任务一它读了项目级上下文发现这个项目用的是关系型数据库于是设计了草稿表字段包括文章 ID、草稿内容、更新时间。这里有个细节它没有直接复用文章表而是新建了草稿表理由是草稿和正式文章的生命周期不同混在一起会让查询变复杂。这个判断我认为是对的说明它真的读了上下文。任务二和任务三可以并行前端实现者和后端实现者同时开工。前端这边实现者用了防抖加定时器的组合每三十秒触发一次保存同时在用户手动保存时清除定时器。后端这边实现者写了两个接口一个写草稿一个读草稿都带了权限校验。两个实现者之间没有直接通信它们各自引用了任务一里定义的草稿数据结构所以接口是对齐的。验证者拿到产出后报了三个问题。第一个是前端定时器在页面隐藏时没有暂停用户切到别的标签页还在发请求浪费资源。第二个是后端接口没有做频率限制恶意用户可能刷接口。第三个是草稿恢复时没有处理草稿内容为空的情况。这三个问题都很实在尤其是第一个我自己都没注意到。集成者最后把代码合并处理了一处冲突——前端和后端对草稿时间戳的格式理解不一致前端用的是毫秒后端存的是秒。集成者发现之后统一成了毫秒并在项目上下文里加了一条约定避免以后再犯。整个流程跑下来从需求到可运行代码大约二十五分钟。中间验证者报问题、实现者修复、集成者合并这些环节都是自动的我只在最后 review 了一遍代码。4.3 关键参数的选择与计算Runtime 里有几个参数需要根据项目情况调整我一个个说。单任务 token 上限。这个值怎么定我的方法是先跑几个典型任务记录实际消耗然后取平均值的一点五倍。比如实现者的典型任务消耗大约一万二 token我就设成一万八。设太低会导致任务频繁被截断设太高又失去了限制的意义。这个值不是一成不变的项目变复杂了要往上调。会话 TTL。会话级上下文保留多久我设的是一小时。太短了角色之间还没沟通完上下文就过期了太长了过期的上下文会污染新的会话。一小时这个值是根据我的任务平均时长定的我的任务大多在二十分钟到四十分钟之间一小时留了足够的余量。重试次数。三次是我试出来的。一次太少很多临时性错误比如网络抖动重试一次就好了五次太多有些错误重试多少次都一样纯粹浪费 token。三次是个平衡点而且第三次重试的时候我会让 Runtime 把前两次的错误信息都带上帮助 Agent 换个思路。并行任务数。这个取决于你的 API 配额和项目依赖关系。我一般同时跑两到三个实现者再多的话集成冲突的概率会明显上升。并行不是越多越好协调成本是随并行数非线性增长的。5. 踩过的坑与常见问题排查5.1 角色串味为什么你的验证者开始写代码了这是我遇到的最普遍的问题。验证者本该只挑刺但它经常忍不住直接改代码。原因有两个一是提示词没写清楚二是工具权限没隔离。提示词里如果只说验证代码质量Agent 会理解成让代码质量变好那它自然就去改了。正确的写法是明确它的输出格式比如输出一个 JSON 数组每个元素包含问题描述、严重程度、建议修复方向把它的输出限制在报告这个形态上。工具权限隔离是第二道防线。验证者不给写文件的权限它就算想改也改不了。这个隔离在配置里一行就能搞定但效果立竿见影。我加了这个隔离之后验证者的行为规范了很多。5.2 上下文串台任务之间的信息污染有一次我发现实现者在写任务三的时候引用了任务一里已经废弃的接口定义。排查下来是任务级上下文没有正确隔离任务一的上下文被任务三继承了。原因是我的上下文注入逻辑写得太宽松只要任务 ID 有前缀匹配就注入。后来改成了精确匹配只有显式声明的上下文引用才会注入问题就解决了。这个坑的教训是上下文注入宁可保守不可激进。多注入一点上下文看起来是帮了 Agent实际上是给它增加了干扰。Agent 不像人它不会主动忽略无关信息你给它什么它就消化什么。5.3 死循环两个 Agent 互相甩锅怎么办前面提过实现者和验证者可能陷入死循环。除了 token 上限和升级机制我还有一个技巧给验证者设一个问题预算。每个任务最多报五个问题报满了就必须给出通过或不通过的结论。这个预算逼着验证者按严重程度排序先报最严重的而不是逮着一个格式问题反复纠缠。另外实现者修复问题时我会要求它逐条回应验证者的问题说明每条是修了还是没修、为什么。这个逐条回应的机制让修复过程变得可追溯也防止实现者漏修。5.4 常见问题速查表问题现象可能原因排查方向解决手段角色输出偏离职责提示词边界模糊检查提示词是否明确了输出格式收紧输出格式明确禁止行为任务间信息污染上下文注入过宽检查上下文匹配逻辑改为显式引用精确匹配死循环烧 token缺少重试上限检查恢复配置设 token 硬上限加升级机制集成冲突频繁接口约定不统一检查任务级上下文在项目上下文里固化接口约定验证者漏报问题提示词缺乏对抗性检查验证者提示词明确要求找至少三个问题任务拆分过粗需求解析粒度不够检查验收标准要求用给定-当-那么格式并行任务互相阻塞依赖图计算错误检查任务依赖声明动态重算依赖支持任务拆分这张表是我这半年遇到问题的浓缩每一条背后都有至少一次真实的翻车经历。新手最容易忽略的是验证者漏报问题这一条很多人以为验证者会主动挑刺实际上如果你不明确要求它对抗它会倾向于说看起来不错。6. 半年实践后的几点真实体会6.1 团队模式不是银弹选对场景比选对工具重要我见过不少人一上来就想搞全自动的多 Agent 开发结果被复杂度劝退。我的建议是分阶段来。第一阶段先用单体 AI 把日常开发跑顺熟悉它的脾气。第二阶段引入验证者这一个角色就一个专门帮你 review 代码这一步的收益最明显成本也最低。第三阶段再引入需求解析者和集成者把流程串起来。第四阶段才考虑并行和动态编排。每一步都跑稳了再往下走别跳步。判断要不要上团队模式我的标准是如果这个项目你会维护超过一个月或者涉及三个以上的模块团队模式就值得投入。反之一次性的脚本、demo、实验性代码单体模式足够了。6.2 提示词的质量决定团队的上限Runtime 的机制再精巧最终干活的还是每个角色的提示词。我这半年花在调提示词上的时间比写 Runtime 代码的时间还多。一个好的角色提示词我总结要包含四部分角色定位你是谁、职责边界你做什么、不做什么、输出格式你的产出长什么样、质量标准做到什么程度算好。这四部分缺一不可尤其是不做什么这部分很多人会漏掉但它恰恰是防止角色串味的关键。提示词不是写一次就完事的要跟着实际表现迭代。我有个习惯每次发现角色行为不对先不改代码先改提示词看看能不能解决。大部分情况下提示词改对了问题就没了。6.3 成本控制要贯穿始终多 Agent 协作的 token 消耗是单体的好几倍这是事实。控制成本的手段有几个一是上下文分层别什么都往上下文里塞二是 token 硬上限每个角色每个任务都有额度三是任务粒度适中太细了通信开销大太粗了返工成本高四是缓存项目级上下文这种不变的内容可以缓存不用每次都重新注入。我算过一笔账团队模式跑一个中等复杂度的功能token 成本大约是单体模式的三到四倍但返工率降低了一半以上。综合下来如果算上我自己的时间成本团队模式反而是更划算的。但这个账的前提是你的流程跑顺了。流程没跑顺的时候团队模式就是纯烧钱。最后分享一个我最近在试的扩展方向把 Runtime 和代码仓库的 CI 流程打通让验证者的检查结果直接变成 CI 的一个环节实现者和验证者的对话记录作为 PR 的评论附上。这样整个团队的协作过程就完全透明了review 的时候能看到每个决策是怎么来的。这个方向我还在摸索等跑通了再单独写一篇。