CodeBuddy 学习(9):多 Agent 协调架构
·
CodeBuddy 学习(9):多 Agent 协调架构
一、概述:为什么需要多 Agent
1.1 单 Agent 的两个天花板
| 天花板 | 具体表现 | 多 Agent 如何突破 |
|---|---|---|
| 并行瓶颈 | 前端和后端必须串行排队 | 不同 Agent 同时开工,时间压缩 |
| 审查盲区 | 写完没人检查,质量靠自觉 | Test Agent / Review Agent 独立把关 |
1.2 核心思想
一个人干活靠自律,一个团队干活靠制度。多 Agent 就是把"制度"固化到流程里——每个 Agent 有自己的明确职责边界,出问题时能快速定位到具体角色,而不是在"一个 AI 做了什么"的迷雾中排查。
二、四个角色与越界红线
2.1 角色定义
| 角色 | 职责范围 | 输入来源 | 这条线不能越 |
|---|---|---|---|
| Frontend Agent | 页面、组件、交互、状态管理 | UI Speckit + 接口契约 | 禁止私改后端契约 |
| Backend Agent | API、数据模型、业务规则 | Feature Speckit | 禁止跳过验收宣称完成 |
| Test Agent | 回归用例、边界测试、失败复现 | 验收项 + 运行日志 | 禁止顺手修代码 |
| Review Agent | 规则一致性检查、风险审查 | 所有角色的产出 | 禁止直接大改代码 |
2.2 边界设计原则
- FE 只做 UI + 交互,不碰接口定义。如果需要改接口,必须通过 Backend Agent。
- BE 只做 API + 数据,不碰前端组件。如果需要调整数据结构,更新接口契约后通知 FE。
- Test 只写测试、跑测试、报告结果。发现 Bug 后交给对应的开发 Agent 修复,自己不修。
- Review 只做审查。发现问题后标注风险等级,不直接修改代码。
三、完整实战:用户管理模块
3.1 阶段一:建队与规划
操作一:一条命令建队
确保 /config teamcreate 为 true,然后输入:
我正在开发一个用户管理模块,需要以下功能:
- 用户列表展示(分页)
- 多条件筛选(按角色、状态筛选,按姓名/邮箱模糊搜索)
- CSV 导出
请创建一个开发团队:
- Frontend Agent:负责页面和交互
- Backend Agent:负责 API 接口
- Test Agent:负责测试验证
先给出职责分工与首轮任务。
操作二:启动前六项检查
在 Agent 开始工作前,完成以下检查:
| 序号 | 检查项 | 示例 | 为什么重要 |
|---|---|---|---|
| 1 | 锁定工作目录 | 所有 Agent 确认 cwd: ./user-management | 避免 Agent 在错误的项目中操作 |
| 2 | 锁定 Speckit 版本 | 确认规约文档版本(如 v1.0) | 需求不能在执行中随意变 |
| 3 | 明确权限边界 | FE 禁写 API、BE 禁写组件 | 每个角色只操作自己的范围 |
| 4 | 设定最大轮次 | 每个 Agent 6-10 轮 | 防止单个 Agent 陷入无限循环 |
| 5 | 设定降级策略 | 同类错误 2 轮未收敛 → 降级串行 | 提前约定"什么时候放弃并行" |
| 6 | 建立证据目录 | artifacts/round-logs/ | 每一步可追溯 |
操作三:接口契约(最关键一步)
在多 Agent 开始分工之前,必须先对齐接口契约。契约是 FE 和 BE 之间的唯一通信标准。
接口契约 v1.0:
GET /api/users 返回格式:
{
code: 200,
data: {
total: number, // 总记录数
page: number, // 当前页码
pageSize: number, // 每页条数
list: [{
id: number,
name: string,
email: string,
role: 'admin' | 'user',
status: 'active' | 'inactive',
createdAt: string // ISO 8601 格式
}]
}
}
查询参数:
- page: number(默认 1)
- pageSize: number(默认 10,最大 100)
- keyword: string(模糊搜索 name 和 email)
- role: 'admin' | 'user'
- status: 'active' | 'inactive'
GET /api/users/export 返回:
- Content-Type: text/csv
- Content-Disposition: attachment; filename="users.csv"
- 列名与 list 字段一致(驼峰形式)
3.2 阶段二:并行执行
任务指令的四段式格式
| 段 | 含义 | 示例 |
|---|---|---|
| 目标 | 要完成什么 | “实现用户列表页,含条件筛选和空数据态” |
| 边界 | 不做什么 | “不修改后端 API 接口定义” |
| 验收标准 | 怎样算完成 | “列表正确渲染、筛选器可交互、数据与 API 返回值一致” |
| 禁止项 | 绝对不可做的事 | “禁止引入新 UI 框架;禁止修改约好的字段名” |
Round 1:并行开工
你的指令:
@Backend @Frontend 开始执行各自的首轮任务。
@Backend:
目标:创建 GET /api/users 接口
边界:仅做查询,不做创建/修改/删除
验收:返回字段 {total, page, pageSize, list: [{id, name, email, role, status, createdAt}]}
禁止:不引入 ORM 之外的数据库依赖
@Frontend:
目标:创建用户列表页面骨架 + 筛选器 UI
边界:先用 mock 数据,不连真实 API
验收:筛选器(关键字输入框、角色下拉、状态下拉)可交互
禁止:不修改接口契约中的字段名
Round 1 汇总:
BE-1: GET /api/users 接口已创建 ✓
状态:已完成
产出:src/app/api/users/route.ts
FE-1: 列表页骨架 + 筛选器 UI 完成 ✓
状态:已完成
产出:src/components/UserList.tsx, src/components/UserFilter.tsx
⚠️ 冲突发现:
BE 侧返回 total 字段,但 FE 侧在组件中用了 totalCount。
两边不一致,需要对齐。
→ 建议统一为 total。
Round 2:纠偏 + 推进
你的指令:
统一字段名为 total。
@Backend:确认导出接口返回字段名全部使用驼峰。
@Frontend:
1. 将 totalCount 改为 total,连接真实 API
2. 筛选器支持 keyword 模糊搜索、role 和 status 下拉联动
3. 空数据态:显示"暂无用户数据"提示
@Backend @Frontend 完成后通知 @Test 介入。
Round 2 汇总:
BE-2: CSV 导出接口实现 ✓
GET /api/users/export 返回 CSV 文件,列名驼峰
FE-2: 筛选器全功能完成 ✓
keyword 搜索 / role 下拉 / status 下拉 / 空数据态
阻塞:无(total vs totalCount 已在 Round 1 纠偏后解决)
新增风险:CSV 导出时如果数据量过大,可能超时
→ 建议后续加入分页导出或异步任务
Round 3:测试 + 审查 + 交付
你的指令:
@Test:
执行完整回归测试,覆盖以下场景:
1. 正常列表(10 条数据,验证分页)
2. 筛选 4 场景(keyword/role/status/组合筛选)
3. CSV 导出(内容与列表数据一致)
4. 空数据态(后端返回空列表时的前端展示)
5. 接口异常(模拟 500 错误时的前端降级展示)
@Review:
审查 FE/BE 产出,重点检查:
1. 接口契约一致性(字段名、数据类型、错误码)
2. 边界覆盖(空数据、大数据量、网络异常)
3. 安全(XSS 防护、SQL 注入防护)
最终交付摘要:
FE-1: completed ✓ BE-1: completed ✓
FE-2: completed ✓ BE-2: completed ✓
TEST: completed ✓ REVIEW: completed ✓
测试结果:7 条用例,0 失败
遗留项(后续优化,不在本期范围):
- CSV 导出 loading 动画
- 大数据量分页导出
- 移动端适配
整体评估:可以交付 ✅
3.3 调试过程
场景一:两个 Agent 的字段名不一致
现象:在 Round 1 中发现 total vs totalCount 不一致。
原因:
- 接口契约中写的是 total,但 FE Agent 在实现时遵循了
某个内部命名规范("计数类字段用 xxxCount")。
- 契约虽然写了,但 Agent 可能没有严格按契约执行。
排查:
1. 检查接口契约文档中该字段的定义。
2. 检查 FE Agent 的系统指令中是否有与契约冲突的规则。
修复:
1. 明确指令:"以接口契约为准,任何偏离契约的命名都需要先提出讨论"。
2. 在四段式指令的"禁止项"中加入"禁止修改契约中已定义的字段名"。
场景二:Test Agent 顺手修了 Bug
现象:Test Agent 在测试时发现一个 Bug,直接写了代码修复。
原因:Test Agent 的指令中缺少了"禁止修代码"的明确约束。
排查:检查 Test Agent 的系统指令和本轮任务指令。
修复:
1. 在 Test Agent 的"禁止项"中强制加入:"禁止直接修改任何源码文件"。
2. 测试发现 Bug → 记录到测试报告 → 通知对应开发 Agent 修复。
场景三:并行执行中同类错误反复出现
现象:FE Agent 在第 2 轮和第 3 轮都重复了相同的 API 调用错误。
原因:排查不够彻底,上次修复只改了表面。
触发降级:
如果同类错误 2 轮未收敛 → 停止并行 → 串行排查。
降级策略:
1. 暂停所有 Agent。
2. 针对该问题单独排查(单 Agent 串行模式)。
3. 问题解决后重新并行。
四、冲突处理与降级机制
4.1 日常纠偏流程
先看契约 → 再看规则 → 最后看实现
三种指令速查:
| 指令类型 | 写法 | 用途 |
|---|---|---|
| 点名分派 | @Agent名 任务描述 | 将任务指定给特定 Agent |
| 点名纠偏 | @Agent名 问题 + 范围 + 禁止 | 发现偏差时精准纠正 |
| 全员广播 | @all 约束内容 | 发布所有 Agent 都需要遵守的规则变更 |
4.2 降级触发条件
| 触发条件 | 降级策略 |
|---|---|
| 同类错误 2 轮未收敛 | 停止并行 → 单 Agent 串行排查(避免批量犯错) |
| 跨模块不可控 | 修订 Speckit → 串行执行(先稳后快) |
| 证据与结论冲突 | 回到规划阶段重新对齐(避免在错误方向上越走越远) |
五、安全与质量红线
| 红线 | 后果 |
|---|---|
| 暴露 API Key / Token 到日志或代码中 | App 瞬间失守 |
| 跳过验收步骤直接标 completed | 未验证代码进入主干 |
| 危险操作未经审查(rm -rf / 生产配置变更) | 不可逆的线上事故 |
证据链要求
每个 Agent 的每轮完成汇报必须包含:
- 输入指令(我收到了什么任务)
- 关键改动(我改了什么文件、什么逻辑)
- 验证输出(测试/ESLint/TypeScript 编译的结果)
- 结论(已完成 / 部分完成 / 遇到阻塞)
缺一项不能标 completed。
六、小结
| 阶段 | 你要做的 |
|---|---|
| 建队 | 一句话建队 → 六项检查 → 先对齐接口契约再开工 |
| 分任务 | 四段式指令(目标/边界/验收/禁止) |
| 并行跑 | FE/BE 同时开工 → 每轮 Round 汇总 → 发现问题开纠偏 |
| 出问题 | 先看契约 → 点名纠偏 → 2 轮不收敛就降级串行 |
| 交付 | 四件套:功能 + 测试 + 风险 + 复盘 |
更多推荐



所有评论(0)