子 agent 别为省钱降级
子 agent 降到小模型,单次看不出问题,累积下来跨字段不变量频繁被破坏,审查也兜不住
有工程不变量的任务,子 agent 默认用最强模型;纯机械任务例外
发生了什么
为了省钱,我曾经把不少子 agent 配成小模型。单看每一次的输出都过得去:代码能跑,测试也过。
累积一段时间后,问题浮出来了:跨字段的不变量频繁被破坏。比如两个字段必须同时改,某个状态只能在另一个条件成立时出现,小模型改了这边、漏了那边。审查也兜不住,因为这类问题分散在不同的 PR 里,每个 diff 单看都合理。
为什么会这样
子 agent 只拿到截取的一段上下文,没写明的约束得靠它自己从代码里推断。这恰恰是强模型和小模型差距最大的地方:小模型能把眼前的指令执行对,却更容易漏掉要从代码里推出来的约束。
还有一个容易忽略的机制:在 Claude Code 里,主会话派子 agent 时可以按次传 model 参数,它的优先级高于子 agent 定义里的 model 字段。就算定义里写了强模型,主会话为了“省成本”也可能临时降级。
怎么做
有不变量的子 agent 写死模型。实现、重构、迁移、审查这类任务,在 .claude/agents/<name>.md 里写 model: inherit(跟主会话一致)或 model: opus:
---
name: implementer
description: 按 plan 实现改动,遵守仓库里的不变量
model: inherit
---拦住按次降级。在权限规则里给小模型加 ask,主会话想降级时你要确认:
{
"permissions": {
"ask": ["Agent(model:*haiku*)"]
}
}想一刀切,可以设环境变量 CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1(v2.1.257 起),除内置的 Explore 外,所有子 agent 都跑主会话的模型。
纯机械任务单独开口子。批量重命名、移动文件、格式化这类不需要判断的活,单独定义一个 model: haiku 的子 agent,提示词里写清楚“只做机械操作,遇到需要判断的就停下来报告”。
注意它和上一步的 FORCE 互斥:开了 FORCE,Claude Code 会忽略子 agent 定义里的 model 字段,这个例外不会生效。要么统一强制,要么只在需要强制的会话里用 CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1 claude 启动,机械任务放在没开 FORCE 的会话里跑。
这是保守默认,用评测来调。这是我在当前工作负载下的选择:跨字段不变量多、返工贵,宁可多花 token。预算有限时,非交互运行可以用 claude -p --max-budget-usd <金额> 封顶,子 agent 的花费也计入。哪些子 agent 能降级,拿几个有代表性的历史任务,强模型和小模型各跑一遍,比较一次通过审查的比例和返工次数再定。运行中用 /tasks 核对实际模型。