用TypeScript构建迷你模型路由器:Gemini Agent带来的架构启示

Google 发布 Gemini agent,模型选择与 agent 编排解耦,路由成为需要可解释策略的独立基础设施层。
Google 在 Gemini at Work 大会上发布的 Gemini agent 将模型选择变成独立于 agent 编排的决策:它跨 Gemini 与 Claude 模型进行编排,并按任务挑选最合适的模型。文章据此指出,路由是一种策略而非感觉,必须回答三个固定顺序的问题——哪些模型有能力完成任务、合格的模型里哪个最便宜、项目预算是否还有余额。作者用 TypeScript 实现了一个迷你路由器:能力过滤、价格排序、预算检查,每一步都输出 why 字符串。演示中,标注为 small 的任务因 40000 token 超出窗口被升级到 mid,超预算任务进入暂停状态,等待人工提额后恢复,未知模型名被直接拒绝。文章最后强调,教学模型与生产系统的差距在于任务分级需分类器、成本需包含工具与重试、缺少质量回馈,但整体架构形状不变。
Google Cloud在Gemini at Work大会上发布了Gemini agent,号称"面向工作的通用智能体"。它能规划任务、调用技能和工具、连接业务系统。但发布中一句话引起了我的注意:
它为每个任务选择最合适的模型,内置成本控制,并且具备企业客户所需的安全性、管理和治理能力。
Thomas Kurian在主题演讲中补充说,该agent能跨Google的Gemini模型和Anthropic的Claude模型进行编排,并强调"最适合任务的模型不一定是最大的那个"。
这意味着agent和模型现在是两个独立的选择。每次任务都需要有人——或者说有代码——来做这个选择。
路由是一种策略,不是感觉。如果你无法解释为什么选了某个模型,那你根本就没有路由器。

问题本质:三个问题决定一切
路由器必须为每个任务回答三个问题。
哪些模型有能力完成这个任务?这些合格的模型中哪个最便宜?运行它的预算还有剩余吗?
大多数代码只回答了第一个问题——硬编码一个模型名字,然后就不管了。账单到达时,第三个问题替你回答了。
顺序本身就是设计:能力优先,价格其次,预算最后。这个顺序不能颠倒,因为一个"便宜但不能胜任"的模型,本质上是一次带有额外步骤的重试。它表面省钱,实际在制造返工。
模型路由(Model Routing) 这一概念并非 Google 首创,它在大模型工程化领域有一条清晰的技术脉络。早期的实践出现在多模型 API 网关(如 OpenRouter、LiteLLM)中,核心动机是成本与延迟——同一任务用不同模型可能相差百倍费用。2024 年后,随着 Claude、Gemini、GPT 系列在能力上逐渐分化,路由从"省钱技巧"升级为"架构决策":不同模型在代码、推理、长上下文、工具调用上各有短板,单一模型难以覆盖全部工作负载。学术界的 RouteLLM、FrugalGPT 等工作则从另一个方向切入,用训练好的分类器预测"任务难度",在弱模型与强模型之间动态切换,在保证质量的前提下压降成本。企业侧的路由还叠加了合规维度:数据驻留、审计日志、供应商锁定都要求编排层与模型解耦。因此文中强调的"agent 与模型是两个独立选择",本质上是在架构上把"做什么"和"用谁做"分成两层,让模型可以像后端服务一样被替换、被度量、被治理。
第一步:描述模型
模型在路由器眼里就是一组可比较的事实。每个模型有一个层级(small/medium/large)、一个价格(每千token的美分)、一个上下文窗口上限、以及是否支持工具调用。
每个任务则声明它需要什么层级、有多大(token数)、是否需要工具,以及是否有人工指定的模型覆盖(override)。
这里保留override是有原因的——Google在发布中明确说用户可以自己选模型。这个设计细节值得保留在迷你实现里,因为它反映了一个真实需求:人类有时比策略更清楚当前场景的特殊性。
type Tier = "small" | "medium" | "large";
type Model = { name: string; tier: Tier; usdPer1kTokens: number; maxContext: number; tools: boolean };
type Task = { id: string; project: string; need: Tier; tokens: number; tools?: boolean; override?: string };
第二步:判断适配性
适配是一个硬性过滤器,不做打分。模型层级低于任务要求的不适配。上下文窗口装不下任务token数的不适配。任务需要工具但模型不支持的不适配。
const RANK: Record<Tier, number> = { small: 0, medium: 1, large: 2 };
function fits(m: Model, t: Task): boolean {
if (RANK[m.tier] < RANK[t.need]) return false;
if (t.tokens > m.maxContext) return false;
if (t.tools && !m.tools) return false;
return true;
}
这里的关键洞察是:适配判断必须发生在价格排序之前。先排除不能干活的模型,再从能干活的中选最便宜的。反过来做只会浪费时间——你可能先选中一个便宜模型,发现它上下文不够,再换,再发现它不支持工具,再换。
上下文窗口(Context Window) 是路由决策中最容易被低估的约束。它指模型单次推理能接收的最大 token 数量,包含输入提示与输出。不同模型的窗口差异巨大,从早期的 4K、8K,到如今的 128K、200K 乃至百万级。窗口不是"越大越好"这么简单:窗口越大,注意力机制的二次复杂度导致推理成本与延迟显著上升,且"中间遗忘"(lost in the middle)现象会让超长上下文里的关键信息被稀释。工程上通常把任务 token 数与模型窗口做硬比较——超出即淘汰,这是不可协商的物理限制。文中 summarize-thread 的例子很典型:任务被标注为 small 级别,但 40000 token 的输入直接排除了窗口较小的 mini 模型,触发了向 mid 的升级。这类"能力标签与实际输入规模不匹配"的情况在生产中极为常见,也是为什么适配过滤必须在价格排序之前执行——先看能不能装下,再谈贵不贵。
第三步:选最便宜的合格模型
通过适配过滤后的候选模型按预估成本排序,取第一名。
const candidates = MODELS.filter((m) => fits(m, t))
.sort((a, b) => cost(a, t) - cost(b, t));
if (candidates.length === 0) return { why: "no model fits" };
return { model: candidates[0], why: `cheapest model that fits (${candidates.length} fit)` };
注意几个设计决策。override仍然需要通过适配检查——如果有人强行把一个小模型指定给超大任务,路由器应该拒绝而不是执行。未知模型名被拒绝,而不是猜测。每个结果都带有一个why字符串,这个字符串就是整个路由器的价值所在。
第四步:执行预算上限
每个项目有一个预算上限,账本(Ledger)追踪已花费金额。检查发生在任务运行之前,不是之后。
class Ledger {
spent = new Map<string, number>();
constructor(private caps: Record<string, number>) {}
route(t: Task): Route {
const { model, why } = pick(t);
if (!model) return { kind: "rejected", task: t.id, why };
const c = cost(model, t);
const spent = this.spent.get(t.project) ?? 0;
const cap = this.caps[t.project] ?? 0;
if (spent + c > cap) {
return { kind: "paused", task: t.id, model: model.name, cost: c,
why: `cap $${cap} would be hit (spent $${spent.toFixed(4)})` };
}
this.spent.set(t.project, Math.round((spent + c) * 10_000) / 10_000);
return { kind: "run", task: t.id, model: model.name, cost: c, why };
}
raise(project: string, cap: number) { this.caps[project] = cap; }
}
暂停不等于失败。被暂停的任务等待人类提高上限后恢复。Google说它的agent内置了成本控制,而这是这个概念的迷你版本。
当人类决定提高某个项目的预算上限时,被暂停的任务自动恢复执行。但路由器不会自己给自己加预算——这个约束是刻意的。
成本控制中的"暂停而非失败"(pause vs. fail) 是一种刻意的设计模式,在分布式系统与云计费中都有先例。传统做法是任务超预算直接报错,让调用方重试或放弃;但 agent 场景下,一个长链路任务的前半段可能已经产生了有效产出,直接丢弃意味着前序 token 全部浪费。暂停语义保留任务状态,等待外部条件(人工提额)改变后原地恢复,更接近工作流引擎里的"等待信号"(wait for signal)而非"补偿事务"。与之配套的是预扣与对账:文中用预估成本在运行前检查并记账,属于乐观预留;生产中更严谨的做法是两步提交——运行前冻结额度,运行后按实际用量结算并释放差额,否则预估偏差会累积成账实不符。此外,单进程 Map 账本在多副本部署下会产生竞态,真实系统需要 Redis 或数据库的原子自增或分布式锁来保证上限不被同时穿透。
实际运行效果
用七个示例任务演示整个流程,输入输出如下:
tiny-model-router demo
[RUN] tag-email mini $0.0008 cheapest model that fits (3 fit)
[RUN] draft-reply mid $0.0180 cheapest model that fits (2 fit)
[RUN] contract-review big $2.7000 cheapest model that fits (1 fit)
[PAUSED] summarize-thread mid $0.1200 cap $0.1 would be hit (spent $0.0188)
[RUN] quick-fix big $0.0150 user override
[REJECT] translate override "gpt-x" is not a known model
[PAUSED] second-review big $2.7000 cap $3 would be hit (spent $2.7000)
raise legal cap to $6, resume paused work
[PAUSED] summarize-thread mid $0.1200 cap $0.1 would be hit (spent $0.0338)
[RUN] second-review big $2.7000 cheapest model that fits (1 fit)
spent: { support: 0.0338, legal: 5.4 }
几个值得注意的路由决策:标记邮件(tag-email)三个模型都能做,所以分给了最便宜的mini。草拟回复(draft-reply)需要工具调用,mini不支持,mid胜出。合同审查(contract-review)需要large层级,只有big符合。总结线程(summarize-thread)虽然标注为small级别任务,但40000个token超过了mini的上下文窗口,所以路由到了mid——而这一步会超出support项目的预算上限,因此暂停。翻译(translate)要求了一个不存在的模型名,被拒绝。第二轮法律审查(second-review)会超过legal项目的$3上限,暂停等待人工提额。
人类提高legal上限后,second-review恢复执行。summarize-thread保持暂停,因为没有人提高support的上限。这是正确的——路由器没有给自己加预算的权限。
这个模型的局限
这是一个教学模型,真实路由要难得多。
层级是猜的。 真实任务不会自己标注"我是small级别"。你需要一个分类器或者廉价的预判来做出这个判断。
价格是按token计算的。 实际成本还包括工具调用、沙箱环境、重试和缓存token。
没有质量检查。 真正的路由器应该监控便宜模型的回答是否站得住脚,如果不行就路由到更贵的模型。
预估值先于运行。 Token数在运行后才能确切知道,但预算检查用的是预估值。
单一账本、单进程。 真实的支出追踪是共享的,两个任务可能同时越过上限。
这些局限不改变整体架构的形状:按能力过滤,按价格排序,检查预算,打印原因。
更大的图景
整个路由逻辑可以用一棵决策树概括:
task → filter: tier, context, tools → sort: cheapest fit (or override) → ledger: under the cap? → run / pause / reject,每一步都附带原因。
任务提供需求,模型提供选项,过滤器提供底线,价格提供排序,预算提供天花板,人类提供提额。
我认为"你用的是什么模型?"这个问题对agent来说正在变成错误的问题。模型每隔几个月就会更换。Google在发布中几乎也是这么说的。
更好的问题是:你的路由策略是什么,你能读懂它吗?
选择模型现在是工作的一部分。所以它也应该成为日志的一部分。
相关推荐

恒星究竟能有多大?最大恒星的物理极限
红超巨星是宇宙中体积最大的恒星,半径可达太阳的2000倍,吞没内太阳系。但恒星尺寸没有精确上限,模型预测可达15000倍太阳半径。质量最大的蓝色恒星体积远小于红超巨星——最大和最重是两回事。

苹果HomeView智能屏全功能解析:墙挂桌面两用,299美元
苹果发布299美元智能显示屏HomeView,支持壁挂和桌面两种安装方式,配备1200万像素摄像头实现面部识别,可控制智能家居、播放音乐、发送食谱到屏幕逐步跟做。本文全面解析HomeView的表盘、应用扩展、隐私保护和烹饪集成等核心功能。

承诺的新工作室去哪了?Craft Computing用五年时间给出答案
Craft Computing主理人回应观众质疑:承诺五年的新工作室因建设成本从3万暴涨至7.5万美元而搁浅,最终改为168平方英尺车库改造空间。频道收入因算法变化下滑,内容方向也将转向更务实的项目制作。