子代理分配器 は何をしますか?
把一份 plan.md 变成一份可执行的分工表:谁做什么、用哪个模型、开多大思考强度、失败了怎么升级。
省额度的原理很简单:计划里大部分工作量其实是读文件、搜代码、跑测试、按规格改代码,这些不需要最贵的模型。贵模型只应该花在少数真正需要判断力的地方。本技能的工作就是把这两类分开。
输入
- plan.md 的路径。没给就找当前目录下的
plan.md/PLAN.md/PLANS.md,找不到再问。 - 目标平台:
claude(Claude Code)、codex(OpenAI Codex)或both。没说明时按当前运行环境判断;判断不了就问一次。 - 取向(可选):
省、均衡(默认)、稳。只影响下面第 4 步里拿不准时往哪边靠。
确定平台后,读对应的参考文件,里面有该平台的具体模型名、价格比例和 effort 档位:
- Claude →
references/claude.md - Codex →
references/codex.md - both → 两个都读,输出里并排给两套配置
模型名和价格会过时。参考文件是唯一的事实来源,不要凭记忆填模型名。
流程
1. 读计划,拆成任务单元
沿用 plan.md 自己的步骤划分,只在两种情况下调整:
- 拆开:一个步骤里同时有"大量读取/搜索"和"做判断/改代码"。把读取部分拆出去给便宜的子代理,它只返回摘要。
- 合并:几个连续的小步骤改的是同一批文件、需要同一份上下文。合成一个任务,避免重复加载上下文。
不要过度拆分。每个子代理都有启动开销(重新读上下文、写交接说明),几分钟就能做完的小事让主代理顺手做掉,在文档里标"主代理直接执行"。
2. 给每个任务打五个标记
| 标记 | 问的问题 | 取值 |
|---|---|---|
| 明确度 | 规格是否已经写死,照做即可? | 明确 / 部分 / 开放 |
| 出错代价 | 做错了容易发现、容易回滚吗? | 低 / 中 / 高 |
| 可验证 | 有没有测试、构建、lint、脚本能自动判对错? | 有 / 可补 / 无 |
| 读取量 | 需要读多少材料才能动手? | 少 / 多 |
| 影响面 | 改动是局部的,还是跨模块、影响架构? | 局部 / 跨模块 / 架构 |
plan.md 里没写清楚的,按最可能的情况判断,并在输出的"假设"一栏写出来,不要停下来逐条问。
3. 映射到四个档位
各平台的具体模型见参考文件,这里只定档位:
| 档位 | 用于 | 典型任务 |
|---|---|---|
| T0 轻量 | 明确 + 低代价 + 结果一眼能验 | 搜文件、读日志、跑测试并汇报、分类、抽取、摘要 |
| T1 标准 | 明确 + 局部 + 可验证 | 按规格实现功能、修定位好的 bug、写测试、写文档、UI 还原 |
| T2 主力 | 部分明确,或跨模块,或需要调试判断 | 多文件功能、排查原因不明的 bug、代码审查、整合子代理结果 |
| T3 旗舰 | 开放 + 架构级,或出错代价高且无法自动验证 | 架构决策、大型重构的方案、多约束冲突的取舍、指挥多个子代理 |
判断顺序:先假设是 T1,然后看有没有理由往下或往上。
- 往下到 T0 的理由:任务本质是"找到并报告",不产出要合并的代码。
- 往上到 T2 的理由:明确度不是"明确",或影响面不是"局部"。
- 往上到 T3 的理由:必须同时满足"开放或架构级"和"错了代价高"。只满足一个用 T2 加高 effort。
一份正常的计划里 T3 任务通常只有 0 到 2 个。如果分出来一半都是 T3,回去重新检查拆分,多半是把"读取"和"判断"捆在一起了。
4. 定思考强度
effort 是比换模型更细的旋钮,先调它。
- 起步一律用参考文件里该档位的默认起步值。
- 可验证 = 有:保持起步值,甚至降一档。模型能跑测试自检时,高 effort 的收益很小。
- 可验证 = 无 且 出错代价 ≥ 中:升一档。
- 有人在实时等结果:降一档,速度优先。
- 取向为
省时拿不准就取低的,稳时取高的。
超过 high 之后,再升 effort 的花费往往接近直接换上一档模型的低 effort。所以升级阶梯写成这样:
- 先补验证手段(给它一条能跑的测试或检查命令)
- effort 升一档,最多到
high - 换上一档模型,effort 从该档的最低起步值开始
Codex 的 T0 是例外,它在高 effort 下性价比依然很好,详见 references/codex.md。
5. 质量保护
省额度不能以返工为代价,返工比一开始用对模型更贵。下面几条是保证"质量变化不明显"的手段:
- 每个任务都要有完成标准。能写成命令的写成命令(
pytest tests/x、npm run build)。写不出完成标准的任务,档位升一级。 - 改代码和关键判断留在 T1 以上。T0 只读不写,或只写不进主分支的东西(报告、清单)。
- 便宜模型做完后,由高一档的模型审 diff。审 diff 只读变更部分,token 很少,却能拦住大部分问题。在分配表里把它列成一个独立的审查任务,放在每个阶段末尾。
- 子代理只返回结论。在角色说明里规定返回格式和长度上限(如"不超过 200 字的摘要 + 相关文件路径列表"),避免长输出灌满主代理的上下文。
6. 排执行顺序
- 互不依赖的任务标成可并行。
- 尽量把同一模型的任务排在一起,在阶段之间的自然断点换模型。中途频繁换模型会丢缓存,等于重付一遍上下文的钱。
- 平台特有的注意事项(缓存归属、长上下文加价阈值等)见参考文件,命中时写进输出的"注意事项"。
输出
在 plan.md 同目录写 plan.dispatch.md,用下面的结构。任务很多时表格保留全部任务,角色卡只给子代理任务写。
# 子代理分配:<计划名>
来源:<plan.md 路径> 平台:<claude / codex / both> 取向:<省 / 均衡 / 稳>
## 总览
| # | 任务 | 执行者 | 档位 | 模型 | effort | 依赖 | 可并行 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | … | 探查员 | T0 | … | … | 无 | 与 2 |
档位分布:T0 ×n,T1 ×n,T2 ×n,T3 ×n
主代理:<模型> / <effort>,负责 <协调、整合、最终验收等>
## 执行阶段
### 阶段 1:<名称>(模型:…)
- 任务 1、2 并行
- 阶段末审查:<谁审、审什么>
## 角色卡
### 任务 1:<名称>
- **角色**:<一句话定位,如"只读探查员:定位所有调用旧接口的位置">
- **模型 / effort**:… / …
- **目标**:…
- **输入**:<要读的文件、目录、报错信息>
- **约束**:<不许改什么、遵循什么规范>
- **完成标准**:<命令或可检查的状态>
- **返回格式**:<内容与长度上限>
- **升级阶梯**:补验证 → effort 升到 … → 换 … / …
- **选型理由**:<一句话,对应五个标记>
## 假设与注意事项
- <plan.md 没写清、由本技能推断的地方>
- <平台相关的成本陷阱>
## 预计节省
相对"全部用主力档默认配置"的粗略估计:<如"约一半任务降到 T0/T1,这部分单价降到 1/2 至 1/20">
角色卡的"目标、输入、约束、完成标准"四项就是可以直接粘贴给子代理的提示词,写的时候按能独立看懂来写,子代理看不到 plan.md 的其余部分。
"预计节省"只给量级和依据,不要编造精确百分比。实际消耗取决于任务本身,建议用户跑完后对照用量统计回头调整。
示例
plan.md 里有一步:
- 把 utils/ 下所有用
oldLogger的地方换成newLogger,注意有些地方传了自定义 formatter
处理:这一步混了"找出所有调用点"(读取量多、只读)和"替换并处理 formatter 特例"(要改代码、有特例需要判断)。拆成两个任务:
| # | 任务 | 执行者 | 档位 | effort | 理由 |
|---|---|---|---|---|---|
| 3a | 列出所有 oldLogger 调用点,标出带自定义 formatter 的 | 探查员 | T0 | 起步值 | 只读,漏了会被 3b 的 grep 检查发现 |
| 3b | 按清单替换,formatter 特例逐个适配 | 实现者 | T1 | 起步值 | 规格明确,完成标准是 grep -r oldLogger utils/ 为空且测试通过 |
如果没有测试覆盖 formatter 行为,3b 的 effort 升一档,并在"假设与注意事项"里写明。