前一篇把骨架立起来之后,项目停更了一段时间。原因很简单:跑通 Demo 只是第一步,真正让我卡住的是“单 Agent 能干活,但一堆 Agent 在一起反而互相捣乱”这个尴尬局面。这篇主要记录我从单 Agent 原型切到 Paseo 做编排、用 Beads 管理状态和复用之后,整个软件开发 Agent Team 才真正像一支团队的过程。
如果你也在搭类似的软件开发 Agent Team,正卡在“Agent 之间有对话但没协作”“上下文乱成一锅粥”“改一个地方崩三个环节”这类问题上,这篇应该能给你省不少时间。我会把角色拆解、消息流设计、状态落地方式和真实跑出来的性能数据都摊开讲,尽量讲透“为什么这么做”,而不只是贴代码。
1. 为什么从“单 Agent 原型”切到 Paseo 编排,这个跨步值不值
1.1 前篇遗留的问题:单 Agent 根本撑不起“团队”这个说法
前一篇里我用单个 Agent 接了代码库索引和命令行工具,看起来能完成不少任务,但用了一周就发现天花板很明显:单个 Agent 的上下文窗口有限,需求一复杂,前半段的设计文档和后半段的代码修改就会互相挤占上下文空间;更麻烦的是,它没有真正的任务边界——让一个 Agent 既当架构师又当测试工程师,结果往往是它在设计阶段就开始写代码,在测试阶段又开始改需求。
单独跑几个 Demo 看不出问题,一旦接真实需求,所有缺陷都会放大。我遇到最典型的一个场景:让单 Agent 实现一个带分页的列表页,它在生成接口代码时“记着”要用某个分页参数,等生成前端组件时又把这个参数的名字改了,导致最后联调完全对不上。这本质上不是模型的智力问题,而是职责边界和状态传递出了问题。
所以那段时间我基本得出一个结论:软件开发 Agent Team如果没有清晰的编排层和状态管理层,充其量是一个“会聊天的代码生成器”。要做成“团队”,必须引入两样东西——负责调度的编排运行时,和负责让 Agent 之间共享、沉淀数据的统一载体。这就是 Paseo 和 Beads 进场的直接原因。
1.2 Paseo 在团队模型里到底承担什么
Paseo 在我这套系统里的定位非常纯粹:它是一个多 Agent 编排运行时,负责定义“谁在什么条件下做什么事,结果怎么流转”。它不直接写代码,也不直接做测试,它只干三件事:路由、调度、生命周期管理。
路由的意思是,某条消息进来之后,Paseo 根据话题(topic)和上下文状态,决定把消息投递给哪个 Agent。比如需求描述一旦出现“实现XX功能”这类结构化的输入,它就路由到架构师 Agent;架构师产出的设计文档被确认后,产生的一组任务又会被路由到开发 Agent 的工作队列里。
调度解决的是“多个 Agent 同时想干活,谁先谁后”的问题。Paseo 里每个 Agent 的入参和出参都有明确的 schema,调度器可以判断任务之间的依赖关系。比如测试执行必须等开发 Agent 的补丁合并到工作区之后才能跑,这种依赖关系在 Paseo 里用 edge 来表达,比我之前用 if-else 手工维护状态机要清晰得多。
生命周期管理则解决“Agent 挂了怎么处理”的问题。真实开发中,模型调用超时、返回格式非法、中间节点抛异常都是常态。Paseo 允许我为每个节点定义超时、重试和降级策略。比如架构师 Agent 调用超时两次之后,系统不会直接把整个 pipeline 废掉,而是走一个降级分支——使用上一次成功的设计草稿继续往下走,并把异常记录到监控面板里。
不选 LangGraph 或 CrewAI 而选 Paseo,原因也算简单:LangGraph 的图模型很强大,但在这个场景里我需要的路由是“基于角色和话题”的,而不是纯粹的 state machine;CrewAI 上手快,但它的角色协作比较偏“对话流”,不适合需要精确控制产物格式和写入路径的开发场景。Paseo 刚好处在两者中间——有足够的自由度,又不逼我把所有流程都建模成状态机。
1.3 Beads 的角色:不是框架,是粘合剂
如果说 Paseo 是团队的“项目经理”,那 Beads 就是团队共用的“共享白板”——所有 Agent 的输入、输出、中间产物、测试结果都落到 Beads 上,谁需要谁去取,而不是靠 Agent 之间互相传话。
我最早踩的坑就是把数据直接塞在消息里,A Agent 生成的完整设计文档直接拼到 B Agent 的 prompt 里。一开始看着挺直接,但很快就发现两个问题:一是 prompt 长度爆炸,设计文档动辄几千 token,再加上上下文窗口里已有的内容,平均一次请求要烧掉两三万 token,成本翻了好几倍;二是无法溯源,某个文件改动是谁做的、基于哪份设计文档做的,全都查不到。
Beads 解决了这两个问题。它的核心抽象就是“一个带类型的、可寻址的、可持久化的数据单元”。每个 Bead 有唯一的 id、类型类型、元信息和正文。Agent A 产出的设计文档是一个 Bead,Agent B 读取需求时只需要按 id 或类型去查对应的 Bead,读完把结论再写成新的 Bead。这样所有中间产物都有记录、有版本、可按需取用,而不是全部堆进上下文里。
所以我说 Beads 是“粘合剂”,它粘合的不仅是数据,还有团队协作的时间轴——谁在什么时候产出了什么,全都留在里面,这不仅方便调试,也为后面做经验复用打下了基础。
2. Agent Team 的角色拆解:架构师、开发者、测试者、审阅者的协作关系
2.1 四个角色的职责边界
现在的 Agent Team 一共有四个角色,职责边界非常明确。这个边界不是我自己拍脑袋定的,而是跑了两三轮真实需求之后一点点收敛出来的。一开始我也试过搞“全能 Agent”“超级 Agent”,但协作效果很差,最后才明白一个道理:智能体协作里,边界清晰比单个角色能力强更重要。
| 角色 | 输入 | 输出 | 核心关注点 |
|---|---|---|---|
| 架构师 Agent | 需求描述、现有代码索引 | 技术方案、任务拆解清单 | 技术选型、模块拆分、风险识别 |
| 开发 Agent | 任务清单、技术方案、相关代码上下文 | 代码补丁、文件变更集 | 代码可编译、风格一致、接口对接正确 |
| 测试 Agent | 变更文件列表、需求验收条件 | 测试用例、测试执行结果 | 覆盖关键路径、定位回归问题 |
| 审阅 Agent | 代码补丁、测试结果 | 审查意见、合并/修复建议 | 代码质量、安全隐患、是否有明显坏味道 |
架构师 Agent 不需要了解具体某个函数的实现细节,它只负责把需求翻译成技术方案,并把大任务拆成可以独立执行的小任务。开发 Agent 拿到任务之后,只关心自己这一个 slice 的实现,不关心全局设计。测试 Agent 是独立的,它不能使用开发 Agent 写出来的那套逻辑来验证自己,必须从验收条件出发重新生成用例。审阅 Agent 作为最后一道闸门,检查代码变更是否真的满足需求,有冲突就打回,通过则进入交付流程。
一开始我也担心这种“流水线式”的分工会不会太死板,但实际跑下来效果出奇的好。因为每个 Agent 的 prompt 都只需要专注于自己那一小块专业知识,上下文消耗大幅下降,输出质量也稳定了很多。
2.2 角色之间的消息流设计
消息流的设计是整个系统里最值得抠细节的地方。我的做法是用 Paseo 的 topic 机制定义了一套流转协议,每个角色只监听自己关心的 topic。这样新增一个角色时不需要改动其他角色的代码,只需要定义它订阅哪些 topic、产出哪些 topic 就行。
默认的流转链路是这样的:需求进入requirements话题,架构师 Agent 监听这个话题,产出design和task.breakdown两类 Beads;开发 Agent 监听task.assigned话题,把拿到的任务拆成具体的文件变更;变更落到patch.produced话题上,测试 Agent 收到之后开始跑测试;测试结果进入test.completed,审阅 Agent 读取补丁和测试结果后产出review.approved或review.rejected;最终所有被批准的变更汇总成一次交付。
这里有个很关键的设计:消息流里传的不是内容本身,而是 Beads 的引用。也就是说,开发 Agent 产出补丁之后,往patch.produced话题发的是一个 patch Bead 的 id,而不是补丁全文。拿到这个 id 的 Agent 如果需要看细节,再去取内容。这样每个 Agent 的输入消息都很轻量,只有到了真正需要内容的时候才加载,上下文压力小了很多。
2.3 为什么没有直接上 AutoGen 式的“自由对话”
有不少朋友问我,为什么不直接用 AutoGen 那一套 multi-agent conversation?让 Agent 们自己对话、自己协商,不是更接近“团队”吗?
我试过,但很快就放弃了。最大的问题是不确定性。自由对话模式下,A 和 B 可能围绕一个很小的技术点来回吵十几个回合,消耗大量 token 不说,最后还不一定收敛。更麻烦的是排错困难——对话流不固定,同一个输入跑两次可能走上完全不同的路径,出了问题你很难复现。
软件开发这个场景本质上需要的是确定性交付:需求进来,必须有明确的产物落盘,必须有明确的测试结果,必须有明确的交付或打回结论。自由对话适合头脑风暴、方案探索,不适合把它作为默认的工程化执行路径。所以我的设计是:常规流程走确定性 Pipeline,只在架构师做技术方案评估时允许有限度的多轮讨论。这个折中方案在灵活性和可控性之间找到了比较好的平衡点。
3. Beads 在状态与上下文管理上的实战落地
3.1 把 Agent 之间传递的数据封装成 Beads
真正动手落 Beads 的时候,第一步是先定义清楚有哪些 Bead 类型,每个类型长什么样。我把软件开发流程中的核心产物都建模成了 Bead,初期只建了五类:需求、技术方案、任务、补丁、测试报告。
type Bead = | { kind: 'requirement'; id: string; payload: Requirement } | { kind: 'design'; id: string; payload: DesignDoc } | { kind: 'task'; id: string; payload: TaskItem } | { kind: 'patch'; id: string; payload: PatchSet } | { kind: 'test.report'; id: string; payload: TestReport };每个 Bead 除了 payload 之外,还必须带几个元信息字段:创建者 Agent 的 id、上游 Bead 的引用链、创建时间、版本号。有了引用链,就可以在任何一个环节回溯前因后果,这比打印日志好用得多。我后面排查一个 bug 时,就是靠这条引用链找到了“测试报告引用了过期的开发补丁”这个根因。
这里必须强约束一件事:Agent 只能通过 Beads 写入数据,不能直接改工作区文件。哪怕是开发 Agent 要改文件,也必须先产出 patch Bead,由专门的 executor 组件去应用补丁。这个约束看起来绕了一圈,但它保证了所有的变更都可追踪、可回滚,也为后面的并发控制留出了空间。
3.2 跨 Agent 的上下文持久化:为什么不直接把内容塞给下一个 Agent
前面提到过,我早期是把设计文档全文拼到下一个 Agent 的 prompt 里。为什么后来坚决不这么干了?除了成本问题,还有一个更隐蔽的坑:模型在上下文很长的时候,对中间部分的注意力会明显下降,也就是说你把 8000 字设计文档塞进去,模型可能只认真读了开头和结尾,中间的技术细节全被忽略了。
Beads 的解决方式是把 Bead 当“可寻址的知识片段”。下游 Agent 收到的是 Bead 引用和内容摘要,它如果判断某个细节需要用到一个字段,再去完整加载这个 Bead。这种按需加载的方式有两个好处。一是上下文占用稳定可控,不会随着项目规模线性增长;二是“摘要触发加载”的机制天然引导 Agent 抓重点,而不是被海量细节淹没。
为了让 Agent 能“按需”找到 Beads,我给每个 Bead 建了一个轻量的索引。索引包含类型、标签(tag)、创建时间和摘要关键词。比如开发 Agent 要查“用户模块的分页参数”,索引会返回所有包含“分页”标签的 Beads 摘要,开发 Agent 再从中挑出它真正需要的那一两个完整加载。
3.3 共享工作区的并发控制与版本对齐
几个 Agent 同时要改同一个工程的代码时,最容易出现的问题就是文件互相覆盖。比如开发 Agent A 正在改userService.ts,开发 Agent B 同时也要改这个文件里的一个函数,两个人基于不同的旧版本修改,最后 A 先提交,B 的补丁一应用就把 A 的改动覆盖了。
这个问题的本质是“共享工作区”没有并发控制。我给 Beads 加了一层简单的文件级锁机制。任何 Agent 在下发变更到工作区之前,必须声明它将要修改哪些文件路径,executor 检查这些路径上有没有未释放的锁。如果已经被锁住,后到的任务会进入 waiting 队列,等锁释放之后重新尝试。这个机制实现起来不难,但对防止互相踩踏非常有效。
除了锁,还有一个版本对齐的问题。每个 Agent 拿到任务时,我都会在 prompt 里附带一个workspace revision字段,告诉它当前工作区的基线版本。它的补丁必须基于这个基线生成。如果它生成补丁期间工作区已经被别的 Agent 推进了几个版本,这条补丁会被标记为“过期”而打回重做。这个设计和 Git 的 rebase 逻辑有些类似,但实现上要轻量得多。
从实际体验看,这层并发控制大概减少了 80% 以上的文件冲突问题,剩下的 20% 靠审阅 Agent 处理,成本已经非常可控了。
4. 第一阶段 Pipeline:从需求到可运行代码的完整流程
4.1 需求解析与任务拆解阶段的设计逻辑
先看整个 Pipeline 的入口。用户提交的需求描述先进 Paseo 的一个前置节点做规范化——不是让架构师直接动手,而是先用一个轻量的预处理节点把需求里模糊的部分标准化:明确用户角色、明确输入输出、明确验收标准。预处理节点产出的是一份“需求规格 Bead”,架构师 Agent 拿到的已经是相对清晰的材料,不用再花时间反复理解原始需求。
架构师 Agent 拿到规格之后,做两件事。第一件事是技术方案设计:确定模块怎么划分、接口怎么定义、数据模型怎么设计。第二件事是把整个实现拆成若干个可独立执行的任务,每个任务标注了涉及的文件路径、依赖任务和验收条件。这一步是最耗时的,但也是最关键的——任务拆得越清晰,后面开发 Agent 的效率和质量就越高。
拆完之后,这些任务会按照依赖关系被 Paseo 调度成一张执行 DAG。没有依赖的任务可以并行跑,有依赖的任务必须等待上游完成后才能启动。比如“新增用户表结构”和“设计前端表单校验”两个任务没有依赖关系,就可以并行;而“实现列表查询接口”依赖“新增表结构”,就必须排队。
4.2 编码阶段:并行和串行的取舍
开发 Agent 的执行方式是整个 Pipeline 里最容易出问题的环节,也是我调整最多的部分。一开始我贪图效率,把十几个任务全部并行丢给开发 Agent 跑,结果惨不忍睹。表面上看起来每个任务都在独立完成,但拼到一起的时候问题全出来了:一个 Agent 假设了某个工具函数不存在,另一个 Agent 恰恰在写这个工具函数但因为并行没有完成,于是一堆“资源暂时不可用”的报错。
后来我把调度策略改成了“有限并行”:同一时刻最多允许 3 个开发 Agent 并行执行,并且它们在文件路径上不能重叠。没有文件依赖的任务可以并行,共享文件的必须串行。这个调整直接让我的有效交付率(提交的补丁能被成功应用的比率)从 35% 提到了 78%,代价只是总时长多了几分钟,非常划算。
每个开发 Agent 执行时,Paseo 还会注入一套必要的上下文:相关的 Beads 摘要、接口定义、已存在的代码结构说明。这些内容都是从 Beads 索引里即时查出来的,不是静态写死在 prompt 里的,所以能保证上下文和当前任务匹配。
4.3 测试执行和结果回填:让测试 Agent 独立生成用例
开发 Agent 提交补丁之后,测试 Agent 就要登场了。这个环节的设计原则是“不信开发的话”。开发 Agent 说“我测过了”,我们不听,测试 Agent 必须从需求规格和验收条件出发,独立生成测试用例并执行。
测试 Agent 的输入是需求规格 Bead、变更文件列表和测试脚手架信息。它生成测试用例之后,会实际在工程目录里跑起来,把结果汇总成测试报告 Bead。测试报告不仅包含通过/失败的结论,还会列出它认为覆盖不够的路径,作为审阅阶段的重要参考。
执行测试这一步我用的是容器化环境,每次跑都基于最新的工作区快照重新构建,避免脏环境干扰结果。一个独立小工具的测试大概需要 20-40 秒,一个包含前后端的模块可能需要 2-3 分钟。这个开销可以接受,因为如果让有问题的代码流入下一阶段,返工成本会高得多。
4.4 失败分支的处理机制:重试到底该不该自动执行
Pipeline 跑失败时最忌讳的就是“无脑自动重试”。我踩过一个很经典的坑:测试 Agent 跑某个测试一直失败,我设置了 3 次自动重试,结果它每次失败后都“换个姿势”重新生成测试用例,但被测代码本身就有问题。它折腾了 3 次,浪费了一堆 token,最后测试报告显示“失败”,开发 Agent 看一眼就知道是代码问题,气得要死。
后来我把重试逻辑改成了分级处理:如果失败原因是“测试环境没起来”“依赖没装好”这类基础设施问题,自动重试 2 次;如果失败原因是“测试断言不过”“编译报错”这类业务代码问题,不重试,直接进入“修复循环”。修复循环会由开发 Agent 读取失败报告、修改补丁、重新提交,但整个循环最多执行 2 轮,超过之后系统会把问题升级到人工处理。
现在回头看,这个分级处理机制救了不少次项目。没有它,自动重试会浪费大量资源;有了它,系统在自己该解决的问题上自动修复,在自己不该解决的问题上及时止损。
5. Agent 的“记忆”与经验复用:把 Beads 变成团队的长期资产
5.1 Token 是成本,记忆是资产
随着项目推进,我发现一个很微妙的变化:同样的技术风险,Agent Team 处理得越来越顺手。比如项目的代码风格约定、某些模块的历史决策原因、已知的技术债位置,这些信息第二次遇到时系统处理得明显更精准。
原因不是模型变聪明了,而是 Beads 库里积累了越来越多“历史记忆”。每一个 Bead 都记录了之前的决策和结果,新的任务被执行时,Agent 可以通过索引查到类似的历史记录,参考之前的做法。这让 Agent Team 的每一轮执行都不再是“从零开始”,而有了一种积累感。
我特意把 Beads 库和 Git 历史放在一起:每次交付完成之后,系统会把本次交付对应的 Beads 快照和 Git commit 绑定。之后任何时候需要回溯“某个功能是怎么一步步做成现在这个样子的”,只要看 commit 关联的 Beads 时间线就行。
5.2 沉淀一次成功修 bug 的路径,让它变得可复用
举一个真实的例子。某次测试发现了一个典型的“竞态条件” bug,开发 Agent 花了三个来回才修好。修完之后,我没有让这次经验白白流失,而是把排查路径和修复方案做成了一类新的模板 Bead,存进了 Beads 库。
这个模板记录了竞态条件 bug 的典型特征、排查步骤、常用修复模式。下次再出现类似的并发问题时,测试 Agent 的失败报告会自动带上“这可能属于竞态条件类 bug”的提示,开发 Agent 拿到提示后会先按模板里记录的路径快速排查,再决定是否采用模板中的修复模式。实测下来,同一类问题的修复轮次平均从 3.1 轮降到了 1.2 轮,效果显著。
这里的关键是模板不能是静态文本,而是可被 Agent 查询的结构化 Beads。我会把模板拆成“特征描述”“排查步骤”“修复示例”三个字段,分别写入不同类型的 Beads。这样模型能按自己当前遇到的问题去匹配最相关的那部分内容,而不是把整篇模板塞进上下文。
5.3 团队 Wiki:Beads 索引的另一种打开方式
后来我干脆做了一个小的可视化面板,把 Beads 库里的数据按类型和标签聚合展示。看起来就像团队的 Wiki,但它是自动生成的——每个 Agent 的关键产出都会实时反映在面板上,不用任何人手工维护。
面板上能看到三类信息:当前进行中的任务和负责人、已经完成的任务和产出摘要、最新的技术决策和理由。这些信息对调试系统非常有帮助,平时跑完一条 pipeline,我不用去翻日志,在面板上扫一眼就知道发生了什么。对团队协作来说,这个面板也让 Agent 的工作变得更可解释——不是黑盒,每一步都有据可查。
6. 真实跑下来的性能数据与调优笔记
6.1 实测数据:两个不同类型的任务跑出来的结果
技术方案说得再多,不如拿真实数据说话。我这里整理了两个代表性的实测结果,一个是很简单的静态页面项目,另一个是一个带数据库操作的小工具模块。
第一个项目需求是“实现一个包含登录页和首页的个人中心静态页面,登录后展示用户信息”。整个 Pipeline 从输入需求到交付代码,总共耗时 4 分 12 秒,产生 7 个 Beads,经历 2 次任务并行,最终交付代码 12 个文件 860 行。一次通过,没有走修复循环。
第二个项目需求是“实现一个用户管理模块,支持增删改查和分页,数据存 SQLite,提供 REST API”。这个任务明显复杂,总共耗时 13 分 48 秒,产生 23 个 Beads,经历 3 轮开发-测试-审阅循环。前两轮都因为测试没通过打回,第三轮通过。一看时间分布,光“测试失败-修复-重新测试”就占了将近一半的时间。
值得说明的是,这两个数据都是在模型质量和上下文策略比较稳定的情况下跑的。如果模型服务本身波动很大,数值会涨得很夸张,这一点后面会提到。
6.2 对比调优前后的关键指标变化
我在整个迭代过程中记录了两次比较完整的基线,可以作为参考。
| 性能指标 | 初版(自由对话版) | 调优后(Paseo+Beads) | 变化幅度 |
|---|---|---|---|
| 单轮耗时(复杂任务) | ~28 min | ~14 min | 降低 50% |
| 有效交付率(补丁可应用率) | 35% | 78% | 提升 2.2 倍 |
| 上下文峰值消耗 | 128k tokens | 42k tokens | 降低 67% |
| 修复循环平均轮次 | 4.6 轮 | 1.8 轮 | 降低 61% |
| 可追溯性(出问题能否定位根因) | 基本靠猜 | 通过 Beads 链可回溯 | 质的提升 |
初版的数据是自由对话模式跑出来的,每个 Agent 都在“聊”,看似很热闹,但实际交付效率很低。调优后最大的变化不是单个 Agent 变强了,而是整个系统的“浪费”变少了——不重复沟通、不重复生成、不互相覆盖。这也印证了我一直坚持的原则:Agent 团队的瓶颈从来不是模型的智商,而是前后端的衔接和组织方式。
6.3 调优过程中踩到的三个坑,逐一说明
第一个坑是prompt 里同时塞了太多 Beads 摘要,导致 Agent 抓不住重点。我本来是想“让 Agent 视野更广”,把相关 Beads 的摘要都放进上下文,结果模型把摘要里最显眼的内容当成最重要的,真正关键的验收条件反而被忽略。解决办法是控制摘要数量,只放与当前任务直接相关的 Beads,并且把验收条件单独用一个结构化字段写清楚。
第二个坑是重试导致的“环路风暴”。某个 Agent 在某次调用中因为输出格式不符合 schema 被重试,重试时它生成的代码和第一次完全不同,但两个版本都写进了 Beads。后面其他 Agent 读到这两个版本就凌乱了,都不知道该信哪个。后来我在每次重试前先把上一次的产出 Bead 标记为superseded,并且在下游查询时默认排除这个状态的数据,问题立刻消失。
第三个坑是测试环境和真实运行环境不一致。有一阵子测试报告显示全绿,但交付的代码一到用户手里就崩。排查了半天发现是容器的 Node 版本和线上版本不一样,某些新语法在线上不支持。修法很简单,把容器基础镜像锁定到和线上完全一致的版本。这个坑和 Agent 本身一点关系都没有,纯粹是工程环境的细节,但恰恰是这类细节决定了 Agent Team 能不能真正交付可用的东西。
6.4 模型成本:跑一个复杂任务大概烧多少钱
最后说一下大家最关心的成本问题。以我用的模型 API 均价来算,一个复杂模块(类似上面用户管理模块)的 token 消耗大约是 65 万 token 左右,折合人民币大概 8-12 元。其中大头是开发 Agent 生成代码和测试 Agent 跑测试时反复读取 context 的部分,大约占了 60% 以上。
如果想省成本,最有效的手段是减少无效重试和控制 Bead 全文加载次数。比如给每个 Agent 设置“最多完整加载 N 个 Bead”的配额,或者对特别长的 Beads 先让它读摘要,确认需要再全文加载。这套机制配合起来,单任务的 token 消耗大概还能再降 30% 左右,代价是偶尔会漏读一些细节,需要靠审阅 Agent 补位。
7. 如果你也准备照抄这套方案,我的建议
7.1 别一上来就搞六七个角色,先跑通三个
我见过很多人一上来就设计什么“CEO Agent”“CTO Agent”“架构师 Agent”“产品经理 Agent”一大堆,结果每个角色的 prompt 都是抄来抄去的空话,跑起来根本没法用,因为任务边界非常模糊。我的建议是起步阶段只留三个角色:架构师、开发、测试。这三个角色刚好覆盖“设计-实现-验证”的最小闭环。跑通之后再根据实际需要增加角色,比如你觉得交付质量不够,再加审阅 Agent;觉得需求解析太弱,再加预处理节点。
角色设计和建模一样,最忌讳一次性想得太全。多余的抽象不只是代码量的问题,它会分散上下文、增加消息流转的复杂度,还会让调试变得特别痛苦。
7.2 Bead 类型的定义要“先粗后细”,别一上来就搞绝对的规范化
一开始我把 Bead 设计得特别细,什么“用户接口定义 Bead”“数据库表结构 Bead”“前端路由 Bead”全部分开。看起来很有条理,但用起来非常痛苦——Agent 产出的数据经常跨类型,分类不清晰的时候它就会硬塞进一个不合适的类型,后面查询时反而找不着。
后来我把类型收敛到前面说的五个大类,每个大类里用标签(tag)做细分。比如“技术方案 Bead”下面可以有“后端架构”“数据库设计”“接口规范”等不同的标签。这样 Agent 的分类负担小了很多,系统查询的灵活性却更高了。等到某个标签的数据量大到需要单独拉出来管理时,再把它升级成独立的 Bead 类型,这个时机才比较合适。
7.3 一定要给 Beads 库做个概览面板
这一点可能很多人会忽略。Beads 库用起来很爽,但如果只有一个 API 没有可视化界面,你会经常处于“不知道现在系统里到底有哪些东西”的焦虑状态。尤其是 Debug 的时候,一份概览面板能帮你快速定位问题出在哪个环节、哪个 Bead 的状态不对。
我的面板逻辑很简单:按 Pipeline 阶段分组展示 Beads,每个 Bead 显示类型、创建时间、上游引用、状态。接入实现也就两三百行代码,但这东西的投入产出比高得惊人。它不只是调试工具,也是 Agent Team 的“仪表盘”,每次跑完一条 Pipeline 扫一眼就知道哪里好哪里坏,省去了大量人工审查时间。
这篇文章写到这里,基本上把我从单 Agent 到多 Agent 团队的关键决策、落地方式、真实数据和值得注意的坑都盘了一遍。最后再分享一个我自己坚持了很久的原则:Agent Team 这个方向,不要迷信某个框架或某个模型能解决所有问题,真正决定上限的永远是“职责边界是否清晰、数据流转是否可控、经验能否沉淀复用”这三件事。围绕这三件事持续做工程化打磨,哪怕模型换了一代又一代,这套架构的收益都不会消失。