智能模型路由
Gemini CLI — 智能模型路由
学习目标
- 理解 CompositeStrategy 链式模型路由的执行流程
- 掌握各类策略的触发条件和决策依据
- 分析本地 Gemma 分类器和数值分类器的应用场景
前置知识
本章涉及多模型适配的通用原理,建议先阅读:
下文假设你已理解多 Provider 抽象和认证策略,直接聚焦 Gemini CLI 在单一 Provider(Google)内的模型路由实现。
项目实践
链式策略路由
ModelRouterService 使用 CompositeStrategy 串联多个路由策略,按顺序评估,首个做出决策的策略短路返回:
策略链(按优先级): 1. FallbackStrategy — 当前模型不可用时切换 2. OverrideStrategy — 用户显式指定的模型 3. ApprovalModeStrategy — 根据审批模式选模型 4. GemmaClassifierStrategy — 本地 Gemma 轻量分类器(可选启用) 5. ClassifierStrategy — 基于任务特征分类 6. NumericalClassifierStrategy — 基于 token 阈值决策(可选启用) 7. DefaultStrategy — 使用配置的默认模型CompositeStrategy 的执行模型:
- 按顺序调用每个策略的
route()方法 - 任何策略返回非 null 决策后立即返回
- 全部策略返回 null 时,使用终端策略(DefaultStrategy)的决策
- 记录元数据:选中策略名称、延迟(ms)、推理理由
各策略详解
1. FallbackStrategy
检查当前配置的模型是否可用(通过 ModelAvailabilityService)。如果不可用,切换到预定义的 fallback 模型。
适用场景:模型下线、配额耗尽、区域不可用。
2. OverrideStrategy
检测用户是否通过 -m 参数或 /model 命令显式指定了模型。如果是,直接使用该模型。
优先级高:用户显式指定应覆盖所有自动路由。
3. ApprovalModeStrategy
根据审批模式选择模型:
| 审批模式 | 典型模型选择 |
|---|---|
| yolo(免确认模式) | 更快的模型(如 Flash) |
| default | 配置的默认模型 |
| verbose(详细确认模式) | 更强的模型(如 Pro) |
逻辑:免确认模式通常执行大量简单任务,用快速模型更经济;详细确认模式涉及复杂决策,用强模型更安全。
4. GemmaClassifierStrategy
在本地运行 Gemma 轻量模型进行任务复杂度分类:
GemmaClassifierStrategy: ├── 输入:任务描述 + 上下文 ├── 本地推理(无需 API 调用) └── 输出:任务复杂度等级 → 映射到具体模型优势:分类决策完全在本地执行,不消耗 API 配额。
启用条件:需要本地 Gemma 模型可用,且 getGemmaModelRouterSettings().enabled 为 true。
5. ClassifierStrategy
基于任务特征(代码规模、工具需求、任务类型等)使用通用分类器进行决策。
6. NumericalClassifierStrategy
基于预估的 token 数量阈值做决策:
if estimatedTokens > threshold: return strong_modelelse: return default_model阈值通过 getResolvedClassifierThreshold() 解析,支持配置。
适用场景:大文件或长对话场景,预估 token 消耗超过阈值时使用更强模型。
7. DefaultStrategy
返回配置的默认模型。作为保底策略,始终返回有效决策。
路由触发时机
模型路由在 client.ts 的 processTurn() 中触发:
// 每次 turn 开始前if (this.currentSequenceModel) { // 保持粘滞性,不重新路由 modelToUse = this.currentSequenceModel;} else { // 首次 turn,调用 Router const router = this.config.getModelRouterService(); const decision = await router.route(routingContext); modelToUse = decision.model;}路由上下文(RoutingContext)包含:
history:当前对话历史(curated,去除已压缩部分)request:当前用户请求requestedModel:用户请求的模型(如果有)
路由遥测
每次路由决策都记录遥测数据(logModelRouting):
| 字段 | 说明 |
|---|---|
model | 选中的模型 |
source | 做出决策的策略名称 |
latencyMs | 路由耗时 |
reasoning | 决策理由 |
failed | 路由是否失败 |
error_message | 失败时的错误信息 |
这使得用户和开发者可以追踪路由决策的质量,诊断模型选择不当的问题。
问题与规避
路由策略的调试
问题:CompositeStrategy 链中哪个策略做出的决策不易直观看到。
对策:
- 路由元数据通过
debugLogger输出日志 - 遥测记录每个决策的策略名称和理由
GeminiEventType.ModelInfo事件在 UI 中显示实际使用的模型
Gemma 分类器的本地资源占用
问题:本地 Gemma 模型需要一定的内存和计算资源,可能在低端设备上影响性能。
对策:Gemma 分类器默认不启用,需要显式配置 enabled: true 才会加载。用户可根据设备能力决定是否启用。
路由决策与模型粘滞性的冲突
问题:路由可能每次选择不同模型,但粘滞性要求保持同一模型。
对策:粘滞性优先。路由仅在 currentSequenceModel == null 时执行,一旦选定,后续 turn 不再重新路由,直到粘滞性被解除。
设计取舍
链式策略 vs 单一决策函数
| 方案 | 优势 | 代价 |
|---|---|---|
| 链式策略 | 每个策略独立开发和测试、可按需启用/禁用、优先级清晰 | 策略数量增多后总延迟增加、策略间优先级可能不直观 |
| 单一决策函数 | 逻辑集中、延迟低 | 难以扩展、修改一个条件可能影响其他条件 |
Gemini CLI 的选择:链式策略。模型路由涉及多维度(可用性、用户指定、审批模式、任务复杂度等),链式结构允许每维度独立为一个策略,新增策略时不影响已有策略。