Agent 子代理编排与模型路由
Agent 子代理编排与模型路由
学习目标
本章要解决什么问题:理解 ECC 如何通过 61 个专业子代理和模型级路由实现高效的 Agent 编排。
读完本章后,你将了解:
- ECC 的子代理分类体系及其设计原则
- 每个代理如何绑定到不同的底层模型(opus / sonnet / haiku)
- 并行委托的执行策略
- 代理主动调用的触发条件
前置知识
本章涉及 Agent 核心循环和多 Agent 路由的通用原理,建议先阅读:
下文假设你已理解上述概念,直接聚焦 ECC 的具体实现。
项目实践
61 个专业子代理的分类体系
ECC 的 agents/ 目录包含 61 个 Markdown 格式的子代理定义,每个文件使用 YAML frontmatter 声明元数据:
---name: code-reviewerdescription: Expert code review specialist...tools: ["Read", "Grep", "Glob", "Bash"]model: sonnet---这些代理可以按功能分为四大类:
模型级路由:每个代理绑定不同模型
ECC 的核心创新之一是在代理定义层面直接声明模型,而非在主 Agent 调用时动态选择:
| 代理类型 | 绑定模型 | 典型代理 | 设计理由 |
|---|---|---|---|
| 规划/架构 | opus | planner, architect | 复杂推理、多步骤规划需要最强模型 |
| 代码审查 | sonnet | code-reviewer, security-reviewer | 模式识别任务 sonnet 足够,且调用频率高 |
| 测试/E2E | sonnet | tdd-guide, e2e-runner | 测试生成是结构化任务 |
| 后台观察 | sonnet | silent-failure-hunter | 需要分析但不需要深度推理 |
| 文档查找 | sonnet | docs-lookup | 信息检索任务 |
这种代理级模型路由实现了成本与能力的精细匹配:高频调用的审查代理使用中等成本模型,低频调用的规划代理使用高成本模型。
并行委托策略
ECC 在 AGENTS.md 中明确指示:
Use parallel execution for independent operations — launch multiple agents simultaneously.
适用并行场景:
- 多语言项目同时调用各语言 reviewer
- 代码修改后同时触发 code-reviewer + security-reviewer
- 多个独立文件的构建修复
不适用并行场景:
- 需要前一代理输出作为输入的依赖链(如 planner → implement → review)
主动调用触发条件
ECC 定义了明确的代理调用触发规则:
复杂功能请求 → planner代码已编写/修改 → code-reviewer(自动触发)Bug 修复或新功能 → tdd-guide架构决策 → architect安全敏感代码 → security-reviewer自主循环/监控 → loop-operatorHarness 配置优化 → harness-optimizer关键设计:不需要用户手动调用。主 Agent 根据上述条件自动判断并委托。
问题与规避
代理过多导致上下文膨胀
问题:61 个代理的列表本身就占用大量上下文窗口。
ECC 的规避方案:
- AGENTS.md 中只列出 12 个常用代理及其触发条件
- 完整代理列表放在独立的表格中,供查阅但不总是加载
- 按语言分组的 reviewer 只在对应语言项目上下文中提及
模型切换时状态丢失
问题:不同代理运行在不同模型上,委托时需要传递完整上下文。
规避方案:
- 每个代理的定义是自包含的(prompt + 示例 + 检查清单)
- 委托时由主 Agent 传递相关的 git diff 和上下文文件
- 不依赖代理间的持久状态共享
并行代理结果合并冲突
问题:多个 reviewer 同时审查同一代码,可能给出矛盾建议。
规避方案:
- 每个代理有明确的责任边界(如 security-reviewer 只管安全,code-reviewer 管质量)
- 输出格式统一(severity 分级),由主 Agent 汇总
- 当发现矛盾时,以更高严重级别为准
设计取舍
为什么用 Markdown 文件定义代理?
代理定义为 .md 文件(带 YAML frontmatter)而非 JSON/YAML 配置或代码:
- 可读性:人类可直接阅读和编辑
- 自包含:一个文件包含身份、指令、示例、检查清单
- 版本控制友好:diff 清晰,git blame 可追踪
- 模型直接消费:LLM 天然理解 Markdown 文本
代价:无法表达复杂的条件逻辑。ECC 的选择是将条件逻辑放在指令文本中(“如果 X,则做 Y”),而非编程语言的 if-else。
为什么代理数量高达 61 个?
61 个代理看起来很多,但 ECC 的设计哲学是专业化而非通用化:
- 每种主流语言有专属 reviewer + build-resolver(TypeScript/Python/Go/Rust/Java/Kotlin/C++/F#/Swift/Dart)
- 每个代理专注单一职责,指令精确
- 相比一个”万能 agent”,专业代理在特定任务上表现更稳定
替代方案:少数通用代理 + 语言特定规则。ECC 选择全量专业化,因为实测发现通用代理在语言特定任务上的表现不如专属代理。
模型绑定的硬编码 vs 动态路由
ECC 在代理定义中硬编码模型(model: sonnet),而非运行时动态选择:
- 优势:简单、可预测、每个代理的成本可知
- 代价:新模型发布时需要手动更新代理定义
- 替代方案:基于任务复杂度动态路由(如 chain-of-strategies)。ECC 认为对于已知的、重复性强的任务,硬编码路由更可靠
参考来源
- 源码验证:
agents/目录下 61 个.md文件 - 源码验证:
AGENTS.md中的 Agent Orchestration 规则 - 多 Agent 路由与隔离 — 通用多 Agent 设计模式