作者发现未托管的Agent把大部分预算花在生成文档级任务上,而真正复杂的bug反而被分配了同样模型;将路由规则JSON化并入Git,实现可审查、可回滚的模型选择策略。
让一个编码 Agent 无人值守地处理积压任务,两周后 provider 的账单告诉了我日志里没有的信息:Agent 把大部分预算花在了前沿模型上,做的工作不过是重新生成文档字符串、提升固定依赖版本、整理 import 顺序。而它真正接触到的唯一一个有点难度的 bug——队列消费者里的时间顺序问题——却和文档字符串用了同一个模型,同一套浅层重试策略,最终交付的补丁我在四天后 revert 了。
这种反转才是真正的问题。不是"模型太贵",而是:无人值守的 Agent 每次调用都在做消费决策,而默认决策永远是一样的。
上一篇文章论证了 Agent 权限应该纳入版本控制。把同样的思路套用到模型选择上就是:路由是策略,策略应该是文件,文件应该在 git 里可审查。以下是我现在运行的配置,用占位符代替模型标识符——catalog 变化太快,我今天写的任何名称到你读到这篇文章时都可能已经失效了。
与其把层级埋在代码里,路由规则存在于一个 JSON 文档中,它是可 diff 的、可审查的、可回滚的:
{
"tiers": [
{
"name": "gratis",
"models": ["<free-tier-model-id>"],
"accept_when": {
"any_of": ["single-file edit", "no logic change", "docs or comments", "version bump"]
}
},
{
"name": "standard",
"models": ["<mid-tier-model-id>"],
"accept_when": {
"any_of": ["multi-file edit", "new test", "isolated function change"]
}
},
{
"name": "heavy",
"models": ["<top-tier-model-id>"],
"accept_when": {
"any_of": ["concurrency", "data migration", "public API change", "touches auth or crypto"]
}
}
],
"escalation": {
"attempts_per_tier": 1,
"on_exhaustion": "open_issue_for_human"
},
"gate": {
"command": ["make", "verify"],
"timeout_seconds": 900
}
}
三个设计选择完成了安全相关的工作,它们和选什么模型完全无关:
gate 是 make verify,就这么多。一条补丁只有在该仓库真实的测试套件、linter 和类型检查器全部通过后才能推进。不存在模型去评估另一个模型输出这回事——那样的话便宜层级就会给自己的错误盖橡皮图章。
escalation 有上限。每个层级一次尝试机会,然后任务变成一个 GitHub issue,附带失败记录。没有上限的重试循环不过是更慢地抵达贵价模型的方式。
默认方向是向下,不是向上。如果分类器不确定,任务从低层级开始,通过 gate 向上失败,而不是从高层级开始然后永远发现不了任务其实很简单。
消费这个配置的 runner 就是无聊的管道代码——读策略、分类任务形状、调用 provider、跑 gate、escalate——大概 120 行。策略文件才是值得保留的 artifact,因为这是你审查、diff 和 blame 的东西。
用影子模式验证,而不是靠感觉
危险的时刻不是写策略,而是信任它。所以在任何一个任务真正经过便宜层级路由之前,我会用影子模式跑分类器:它给每个进入的任务打标签,记录它本来会怎么做,而 Agent 照常用强模型。一周的真实流量之后,回放日志然后问:
只有影子数据看起来合理之后,我才让低层级根据自己的标签行动——而且只针对影子记录干净的任务形状。无论日志看起来多好,concurrency-and-auth 类别永远不会从顶级毕业。
还有一个纪律:每当你在一个层级里换入或换出一个模型时,重新跑一遍验证。同一个模型 ID 在 provider 端更新后行为可能不同,上个月可靠的中间层级公民可能悄悄变成这个月 revert 补丁的来源。
为什么最底层免费能改变算术
如果最便宜的层级每次调用都要花钱,那么对于小规模工作负载来说路由开销可能不值。但如果它不花钱,经济账就翻转了:整个系统的期望成本收敛到真正需要强模型的那小部分任务上。
我通过 MonkeyCode 运行这个,它提供免费模型访问和免费服务器选项——所以路由过程本身和最底层执行都不挂表。披露:本文是 MonkeyCode 产品推广的一部分。无论 provider 是谁,有两个注意事项我都会坚持:我没有验证你读到这篇文章时哪些模型在免费层级——拉取实时模型列表而不是信任任何文章,包括这篇——而且任何免费层级都可能改变限额或消失。上面的设计已经能容忍这种情况:一个已死的免费模型会从它的层级报错并 escalates,这正是有界 escalation 规则的作用。
哪里会出问题
测试套件薄弱,免谈。整个方案建立在机械 gate 之上。如果 make verify 抓不住坏掉的补丁,便宜层级就会愉快地放行垃圾。先加强测试套件——这甚至在你从来不路由任何东西的情况下也值得。
分类器是脆弱的部分。任务形状启发式天然粗糙。影子模式的存在正是因为我不够信任它;如果你有足够的标注历史,对过去任务做相似性搜索比关键词匹配更好,但那是一个后续优化,不是前置条件。
交互延迟。穿越层级会增加往返。开发者盯着自动补全不应该等过一整个 escalation 链——保持交互路径单一模型。
安全关键和深度专业化的代码。如果你的领域里没有"琐碎"任务——内核工作、医疗、形式化方法——删除策略文件底部两行,所有事情从顶层开始。
如果你在真实仓库上影子测试过路由策略,我真的很想知道你的误标率是什么样的——尤其是哪些任务形状骗过了分类器。我的分类器一直被版本号更新骗到,结果发现那是 breaking change,我还没找到一个干净的信号来识别它们。