你有没有想过把一个完整开发团队浓缩成几个 AI 智能体让它们像真人同事一样各司其职、互相评审、共同交付我最近就在折腾一个名为 Agency Agents 的多智能体协作系统目标很直接——用一组角色化 Agent 模拟架构师、后端开发、测试和审查去完成一套真实可跑的代码仓库构建。这篇文章把整体的架构设计、落地步骤、运行数据和踩坑实录都摊开讲适合对 Agent 应用感兴趣的开发者和想用 AI 重构研发流程的技术负责人。先说结论多智能体系统能落地关键不在单个 Agent 有多聪明而在怎么让它们不吵起来、不重复劳动、不互相覆盖成果。这听起来像团队管理其实是工程问题。下面我把整个系统的设计思路、代码骨架和运行经验完整拆解你可以直接拿去当参考。1. 多智能体协作系统的整体思路为什么单 Agent 不够用1.1 一个 Agent 包办所有的瓶颈在哪里很多人刚接触 Agent 时会觉得既然大模型能写代码、能写文档、能跑测试那我把这些能力装进一个 Agent给它一个超大 Context 不就行了理论上可行但实际操作你会发现四个致命问题。第一上下文爆炸。一个稍大点的任务需求文档、技术方案、业务代码、测试报告、评审意见全堆进同一个聊天窗口很快就把模型的有效注意力窗口挤满。我在早期的单 Agent 原型里试过到了第 20 轮对话模型已经开始忘记最初的技术约束反复出现前后矛盾的设计。第二工具切换混乱。同一个 Agent 要同时掌握文件编辑、代码执行、检索、文档生成执行动作多的时候它会频繁误选工具而且很难追责。第三角色思维互相干扰。写需求的人、写代码的人和挑毛病的人需要的思维模式完全不同——架构师要宏观抽象测试要抠边界条件开发要关注实现细节。混在一起模型输出的质量会整体下降。第四不可审查。单 Agent 产出的一切混杂在一个对话流里出了问题很难知道是哪个决策导致的。1.2 多智能体带来的是可编排与可追溯把开发流程拆成多个角色 Agent 之后四个问题迎刃而解。每个 Agent 只负责自己的角色域上下文干净了工具集聚焦了产出边界清晰了整个流程变成了可审计的流水线。更重要的是可编排性。架构师 Agent 输出任务工单后后端 Agent 和测试 Agent 可以并行开工审查 Agent 在最后统一把关。任何一步出了问题我可以单独重跑那一个环节而不用把整个系统的上下文重新跑一遍。这种流水线治理思路对应到真实研发团队就是拆任务、分角色、设定验收标准——一个朴素的工程原则但放在 AI 智能体上效果出奇地好。1.3 适合谁参考能解决什么场景如果你正在做一个需要 AI 辅助完成多环节任务的系统——不管它是代码生成、内容生产还是数据清洗——这篇文章的思路都可以套用。尤其适合三类场景一是想把 AI 从问答工具升级成协作员工的团队二是已经试过单 Agent 方案、被上下文爆炸折磨过的开发者三是需要让 AI 产出可审计、可复现的技术负责人。这个系统不能替代人做创造性决策但对付结构化、有验收标准的开发任务非常适合。2. 核心架构拆解调度层、角色层与共享上下文2.1 主控调度层找一条既不僵化也不失控的路多智能体系统的第一个设计决策是主控逻辑怎么做。一开始我试过两种极端方案纯规则调度和全交给管理 Agent 动态调度。纯规则调度就是写死每个任务类型对应哪个 Agent、下一步是什么。它的优点是稳定、可控缺点是一旦遇到没预料到的任务形态整个流水线就断了。全交给管理 Agent 动态调度则正好相反——它能灵活处理新任务但决策不稳定我遇到过管理 Agent 把编码任务分给测试 Agent 的情况来回打回浪费了十几分钟。最后我落地的是规则为主、管理 Agent 为辅的混合方案任务类型和角色对应关系用注册表固定比如 coding 类任务永远派给后端开发 Agent审阅类任务永远派给审查 Agent但任务拆解的粒度由架构师 Agent 决定它可以根据需求灵活调整工单的执行顺序和依赖关系。这套设计跑了一个多月稳定性明显高于动态调度灵活性也比纯规则好得多。主控调度层的核心代码逻辑很简单一个异步循环class Orchestrator: def __init__(self, agents: dict, blackboard: Blackboard): self.agents agents self.blackboard blackboard async def run_task(self, task: Task): if task.owner not in self.agents: raise UnknownAgentError(fno agent registered for {task.owner}) try: result await asyncio.wait_for( self.agents[task.owner].execute(task, self.blackboard), timeouttask.timeout_seconds ) self.blackboard.write(task.output_key, result) return result except TimeoutError: self.blackboard.mark_failed(task.id, agent timeout) self._notify_reviewer(task.id)这代码看起来简单但隐藏了两个关键设定超时保护和失败通知。没有超时一个 Agent 可能因为模型回应卡住而无限挂起整个流水线没有失败通知出错了只能靠人工盯着日志才能发现。2.2 角色 Agent 层每个员工都有一本只属于自己的说明书角色 Agent 的构建是我踩过最多坑的地方。最开始我以为给每个 Agent 写一句你是后端开发就够了后来发现完全不够。一个合格的 Agent 配置需要三样东西角色提示词、工具白名单和记忆分区三者缺一不可。角色提示词不能只有身份描述还要包含该角色的职责边界、输出格式、交付标准和禁止事项。工具白名单决定了这个 Agent 能用什么工具——后端开发 Agent 能用代码执行器和文件编辑器但绝对不能碰需求解析工具架构师 Agent 能调用检索器查资料但不能直接改代码文件。记忆分区则是隔离上下文的关键每个 Agent 只能读自己分区里的历史记录不能全局共享。下面是一份我实际用的 Agent 注册配置agents: architect: role: 系统架构师 prompt_file: ./prompts/architect.md model_profile: high_reasoning tools: [repo_index_search, doc_writer] memory_partition: architecture max_iterations: 3 backend_dev: role: 后端开发 prompt_file: ./prompts/backend_developer.md model_profile: balanced tools: [python_repl, file_editor, dep_checker] memory_partition: backend max_iterations: 5 tester: role: 软件测试 prompt_file: ./prompts/tester.md model_profile: balanced tools: [python_repl, test_runner] memory_partition: testing max_iterations: 4 reviewer: role: 代码审查 prompt_file: ./prompts/reviewer.md model_profile: high_reasoning tools: [file_reader, diff_viewer] memory_partition: review max_iterations: 3你可以看到每个 Agent 都标注了 model_profile——能力更强的模型给架构师和审查者执行类任务给平衡型模型。这是成本控制的第一道闸门我后面会专门讲费用问题。2.3 共享上下文层一间所有人都能看但不能乱涂乱画的白板多智能体之间怎么交换信息我采用的是黑板模式。这个名词听起来高深其实很像办公室里的那张白板任何人都能往上写内容任何人都能读取需要的部分但不允许覆盖他人写的内容而且每个区域有自己的读写权限。我的实现是四个独立的存储区域需求区、方案区、代码区、评审区。每个区有自己的键值结构比如代码区的键设计成src/模块名/文件名评审区的键是review/mr_id。各 Agent 写内容时必须带分区前缀读信息时只能通过订阅方式获取自己需要的键而不是把整个黑板 dump 给每个 Agent。为什么强调这点因为大模型的注意力资源是固定的给它塞无关内容只会稀释有效信息提高幻觉概率。Agent 之间一次典型的消息传递长这样{ message_id: msg_0042, sender: backend_dev, receiver: reviewer, msg_type: review_request, content: { file_path: src/service/task_service.py, change_summary: 新增待办事项创建与查询接口, test_status: 3 passed, 1 failed }, ref_context: blackboard://code/src/service/task_service.py }有了这个结构消息可追溯、可重放、可定位。任何一个 Agent 说我没看到上下文我都能立刻指出消息在哪个队列丢了。3. 从零落地搭建一套可运行的多智能体协作系统3.1 环境准备与基础组件选型这个系统我用 Python 3.11 作为主语言因为异步生态和 AI 工具链最成熟。消息队列选的是 Redis Stream共享状态用 SQLite 做持久化模型调用层则抽象成一个统一的model_client接口方便切换不同供应商的后端模型避免被任何单一服务商锁死。目录结构我整理如下agency_agents/ ├── agents.yaml ├── prompts/ │ ├── architect.md │ ├── backend_developer.md │ ├── tester.md │ └── reviewer.md ├── core/ │ ├── orchestrator.py │ ├── blackboard.py │ ├── message_bus.py │ └── model_client.py ├── tools/ │ ├── python_repl.py │ ├── file_editor.py │ ├── repo_index_search.py │ └── test_runner.py └── run.py我不建议一开始就把系统做得太重。第一版能把角色注册、消息传递、任务编排跑通就够了Kubernetes、监控告警、分布式部署这些都是后面的事。3.2 角色提示词怎么设计才不过时角色提示词的设计直接决定 Agent 行为质量。我的经验是提示词里必须包含四类信息身份与目标、职责边界、输出格式、禁止行为。不是写得越长越好而是要紧扣这个角色在什么约束下做什么事。以backend_developer.md为例它的核心结构是你是项目后端开发工程师。 职责根据架构师输出的设计文档实现指定的业务功能和接口。 输入任务工单、架构方案、相关代码文件引用。 输出可运行代码 修改文件清单 自测结果。 约束 - 只修改任务工单中指定的文件不擅自重构无关模块。 - 代码必须经过本地 REPL 执行验证。 - 禁止输出与任务无关的设计讨论。后面这两条约束极其重要——只修改指定文件能防止多个 Agent 改出冲突而必须执行验证能大大减少幻觉代码。第一次跑通的时候有一个 Agent 没被要求执行自测产出了一段根本跑不起来的代码。加了这条约束之后类似问题明显减少。3.3 主控循环让任务在 Agent 之间流动起来系统的运行入口是一条主控循环取出任务、判定归属、派发执行、写回黑板、检查是否还有下一步。我用一个任务结构体来描述每个工单dataclass class Task: id: str owner: str title: str description: str input_keys: list output_key: str timeout_seconds: int 600 depends_on: list field(default_factorylist)depends_on字段用来表达任务依赖比如测试 Agent 的工单必须依赖后端 Agent 的工单执行完毕。run.py里实际启动系统只需要几十行代码async def main(): config load_yaml(agents.yaml) agents { name: create_agent(name, cfg) for name, cfg in config[agents].items() } blackboard Blackboard(sqlite_path./data/blackboard.db) bus MessageBus(redis_urlredis://localhost:6379) orchestrator Orchestrator(agents, blackboard, bus) initial_task Task( idtask_0001, ownerarchitect, title解析需求并输出架构方案, description..., input_keys[raw_requirement], output_keyarchitecture_design ) await orchestrator.run_task(initial_task)第一次运行之前记得先把 Redis 和 SQLite 准备好同时在大模型账号里配置好足够的额度。我建议先用一个小需求做冒烟测试比如写一个函数把输入的列表去重并保持顺序等整个流水线走通了再上真实项目。4. 实际案例一个模拟开发任务的完整流水线4.1 任务拆解从一句话需求到可执行工单为了讲清楚整个系统怎么运转我用一个模拟项目来演示实现一个待办事项的 REST API支持创建、查询、标记完成、删除四个接口数据先放内存。我把它作为原始需求丢给架构师 Agent它产出了一份技术方案包含模块划分、数据模型和接口定义然后拆出了三个工单工单ID所属 Agent任务内容验收标准task_0002backend_dev实现 TodoItem 数据模型与四个接口代码执行通过接口返回格式符合设计task_0003tester编写 pytest 测试覆盖四个接口的常规与边界场景全部测试通过task_0004reviewer审查 task_0002 与 task_0003 的产出指出不少于 2 个问题或给出通过结论这里有个关键设计架构师 Agent 拆出来的工单里每一项都带验收标准。验收标准是后面测试 Agent 和审查 Agent 判断是否通过的依据如果没有它每个 Agent 都会按照自己的喜好定义完成结果就是没完没了的扯皮。4.2 各角色 Agent 的产出与质检后端开发 Agent 拿到 task_0002 后先读取架构方案中数据模型部分再通过文件编辑器生成代码然后立刻在 Python REPL 里执行导入和简单调用。我第一次跑的时候这个 Agent 生成的代码忽略了一个细节查询接口没做空列表边界处理但 REPL 自测没有专门跑边界场景所以自测通过了。测试 Agent 随后接管 task_0003它生成的测试用例里有一个专门测试空表查询的用例结果真实跑下来真的暴露了空列表异常。这一步非常重要——用 AI 写测试用真实的测试运行器去验收绝不依赖 Agent 自说自话。审查 Agent 的任务是复查代码和测试它的输出是一份审查意见内容大概长这样审查结论有条件通过。 问题清单 1. 查询接口在空表场景下返回结构不统一需修复。 2. 测试文件缺少对删除不存在的 ID的边界覆盖。 修改要求仅针对上述两条修复后重新运行测试。审查 Agent 的存在不仅提高了代码质量更重要的是给整个系统加了一道独立质检的闸门。没有这道闸门系统会像单 Agent 一样自产自销错误会在内部循环中被重复放大。4.3 一次迭代的成本与耗时数据为了让你心里有数我把这套系统跑一次完整迭代的实测数据整理成表格阶段耗时Token 消耗量说明架构师方案约 2 分钟约 1.2 万含一次方案重写后端开发约 4 分钟约 2.8 万含代码自测和一次修复测试开发约 3 分钟约 2.1 万含测试用例执行审查约 2 分钟约 1.5 万含一次意见回复全流程合计约 11 分钟约 7.6 万不包含人工审阅时间这个数据是我跑了多次之后取的中位数。可以看出一次小型功能迭代的 Token 成本大概在 7 到 10 万之间耗时在 10 到 15 分钟。相比一个半熟手工程师花半小时写完再让同事 review这个效率已经能打了。当然如果任务复杂度上升到整个微服务模块Token 成本和耗时都会翻好几倍但相对而言仍然可控。5. 运行中的坑与排查实录5.1 最常见的三种翻车现场翻车现场一上下文污染。有段时间我为了让审查 Agent 更了解全貌把后端 Agent 的完整执行日志都塞给了它。结果审查 Agent 被日志里大量的调试输出干扰开始纠结代码格式问题反而漏了真正的逻辑缺陷。后来改成只传代码文件的差异内容和测试结果摘要问题立刻消失。翻车现场二循环打回。审查 Agent 每次提出一两个小问题后端 Agent 改完再交审查 Agent 又提出新问题进入死循环。我踩了一次最狠的坑一个只有五六个文件的模块两个 Agent 互相 ping-pong 了超过 40 分钟。解决办法是把审查 Agent 的职责改成一次给出完整的问题清单后续只能验证清单是否修复除非出现致命安全问题否则不再追加新问题。这样从机制上杜绝了无限循环。翻车现场三幻觉引用。后端 Agent 经常在说明文档里引用一个实际不存在的文件路径审查 Agent 去核实的时候才发现文件根本不存在。这类问题不能靠提示词完全避免我加了一个专门的文件路径校验工具在消息进入队列之前自动核对引用路径不合格的直接打回有效拦截了几次特别离谱的引用。5.2 问题排查速查表我把运行中遇到的典型问题整理成一张速查表方便你照着排查现象可能原因排查与处理Agent 长时间不返回模型调用超时或队列阻塞检查 Redis 队列长度确认超时事件已触发考虑减小任务规模多个 Agent 产出互相覆盖文件写入冲突检查 tool 层是否有文件锁确认任务工单的文件范围是否重叠Agent 引用不存在的文件检索器索引过期更新代码检索索引校验 Agent 引用路径后再入队代码能跑但测试不过测试用例与实现理解不一致把架构方案的接口定义作为双方共同输入而不是各自脑补Token 消耗异常飙升上下文被无意义放大检查消息队列是否有全量日志误入确认各 Agent 记忆分区是否纯净5.3 省钱与提效的实用技巧最后分享几条我自己用下来的实在经验。第一给每个 Agent 限定输出长度。我发现默认的自由输出很容易让模型写一堆解释性文字Token 一下就上去了。在提示词里加一句只输出必要内容不解释过程同一个任务能省 20% 到 30% 的 Token。第二不要让每个 Agent 都做一轮全量上下文总结。很多流程里Agent A 的输出被原封不动塞给 Agent B导致信息重复累加。正确做法是让一个专门的管理 Agent 做摘要和汇总只把关键决策、产出物路径和待办事项传给下一个环节。第三工具数量控制在五个以内。工具列表太长模型选择工具的准确度明显下降反而额外增加重试成本。把工具打散到各 Agent 之后每个 Agent 的工具列表都短很多整体准确率反而上升。我给这套系统的代码仓库维护了一份docs/operation_guide.md每次跑完一次完整的交付就把当次的数据和问题记录追加进去。这个习惯帮我建立了系统行为的基线到现在已经积累了二十多条什么情况会翻车、怎么救回来的记录非常值得推荐。这套多智能体协作系统按部就班地搭建下来用一个周末的时间就能跑通第一版。我自己在实际操作中最大的体会是多智能体系统最难的不是让单个 Agent 变聪明而是搭建起一套让它们不抢活、不废话、不互相甩锅的协作机制。把状态管理、消息规范、验收标准这些工程细节做好远比调 prompt 对系统质量的提升来得大。如果你想把这个系统往更深处扩展可以考虑接入真正的版本管理仓库让 Agent 在分支上独立作业、在合并前统一做集成测试——这样离AI 研发团队这个目标就更近了。