Gemini CLI 本地模型路由实战:用 gemini gemma 命令与 Gemma 3 1B 自动分流请求
本篇围绕 Gemini CLI 的本地模型路由(Local Model Routing)功能展开,基于官方文档 docs/core/gemma-setup.md 并结合 packages/cli/src/commands/gemma/ 下的源码实现,完整讲解如何用一条命令在本地部署 Gemma 3 1B 分类器,实现"简单请求走 Flash、复杂请求走 Pro"的自动分流,以及各子命令、配置项、服务生命周期管理的细节与排障方法。读完后你可以独立完成安装、验证、日志观察、停用与手动降级全流程。
需要说明的是,该功能在仓库文档中被明确标注为实验性功能(experimental),仍在活跃开发中,相关配置均位于 experimental 命名空间下。
什么是本地模型路由
本地模型路由使用运行在你机器上的 Gemma 3 1B 模型对每条用户请求做分类与路由:
- 简单请求(例如读取文件、快速小修改)被路由到 Gemini Flash,以换取速度;
- 复杂请求(例如架构讨论、疑难调试)被路由到 Gemini Pro,以获得质量。
这一设计用本地推理替代云端分类器,以"几毫秒到百毫秒级的本地延迟"换取托管模型 token 用量的显著下降,从而节省云 API 成本。
注意:这是实验性功能,当前处于活跃开发阶段。
快速开始:一条命令完成全部安装
# 一条命令完成所有工作:下载运行时、拉取模型、配置设置、启动服务
gemini gemma setup
执行过程中会提示你接受 Gemma 服务条款(Gemma Terms of Use),模型下载约 1 GB。安装完成后正常使用 CLI 即可——路由在每条请求上自动发生,无需额外操作。
从源码看,setup 命令由 packages/cli/src/commands/gemma/setup.ts 实现,注册入口在 packages/cli/src/commands/gemma.ts。它实际按以下顺序执行五个阶段:
- 平台检测:通过 platform.ts 的
detectPlatform()识别darwin-arm64、linux-x64、win32-x64三种平台(其他平台直接报错退出,提示仅支持 macOS ARM64、Linux x86_64、Windows x86_64); - 下载 LiteRT-LM 运行时:从官方 release 下载对应二进制(版本与下载地址常量见 constants.ts),下载后校验 SHA-256 校验和,不匹配则删除文件并报错;在 Linux 上执行
chmod 755,在 macOS 上自动执行xattr -d com.apple.quarantine移除隔离属性; - 拉取模型:调用二进制执行
pull gemma3-1b-gpu-custom,此步骤会交互式询问是否接受 Gemma 条款,模型名gemma3-1b-gpu-custom在 constants.ts 中由GEMMA_MODEL_NAME固定; - 写入设置(注意是双作用域写入,这是文档未提及、但源码确认的关键细节):
- User 作用域(
~/.gemini/settings.json):写入autoStartServer(默认true),并保留用户已有的binaryPath配置——源码注释明确说明安全敏感项必须放在 User 作用域,防止被工作区配置覆盖而执行任意二进制; - Workspace 作用域(项目内
.gemini/settings.json):写入enabled: true与classifier(host + model),使本地模型只在该特定项目中运行,全局节省资源;
- User 作用域(
- 启动服务:除非指定
--no-start,否则调用 start.ts 的startServer()启动 LiteRT 服务并等待健康检查。
完整子命令一览
| 命令 | 作用 |
|---|---|
gemini gemma setup |
完整安装(二进制 + 模型 + 设置 + 启动服务) |
gemini gemma status |
健康检查——展示已安装与正在运行的内容 |
gemini gemma start |
启动 LiteRT 服务(默认情况下 CLI 启动时会自动拉起) |
gemini gemma stop |
停止 LiteRT 服务 |
gemini gemma logs |
跟踪服务日志,实时查看路由请求 |
/gemma |
会话内状态检查(在 CLI 内直接输入) |
各命令的补充参数(以源码 yargs 定义为准):
setup:--port <n>(默认 9379)、--skip-model(只装二进制,跳过 1GB 模型)、--start / --no-start(默认安装后启动)、--force(强制重新下载)、--consent(跳过交互式条款确认,隐含接受);start/stop/status均支持--port,未指定时从已合并的classifier.host中解析端口,解析失败回退默认端口;logs支持--lines N/-n(只显示最近 N 行后退出)与--follow/-f(默认在省略--lines时自动跟踪);Windows 上不支持实时跟踪,源码会提示改用--lines N。
status 的检查项由 status.ts 的 checkGemmaStatus() 实现,共四项,全部通过才判定 allPassing(退出码 0),任一项失败退出码为 1,方便脚本化判断:
- Binary:LiteRT 二进制是否已安装(检查默认目录或
binaryPath自定义路径); - Model:通过执行
lit list并检查输出是否包含gemma3-1b-gpu-custom判断模型是否已下载; - Server:对该端口发起探测请求,确认服务在运行(并附带 PID);
- Settings:合并后的配置中
experimental.gemmaModelRouter.enabled是否为true。
验证是否生效
- 运行
gemini gemma status——所有检查项应显示绿色✓; - 打开两个终端:
- 终端 1:
gemini gemma logs(观察进入的请求) - 终端 2:正常使用 CLI
- 终端 1:
- 随着你在 CLI 中交互,应能在日志中看到分类请求;
- 会话内输入
/gemma斜杠命令,可弹出快速状态面板。
日志与 PID 文件的物理位置(由 constants.ts 定义):
- 二进制安装目录:全局 Gemini 目录下的
bin/litert/; - 服务 PID 文件:全局临时目录下的
litert-server.pid(内容为 JSON,含pid、binaryPath、port三个字段); - 服务日志:全局临时目录下的
litert-server.log。
配置项详解:experimental.gemmaModelRouter
手动配置时,需要在 settings.json 中显式启用(完整示例见 docs/core/local-model-routing.md):
{
"experimental": {
"gemmaModelRouter": {
"enabled": true,
"classifier": {
"host": "http://localhost:9379",
"model": "gemma3-1b-gpu-custom"
}
}
}
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
enabled |
boolean | 是 | 必须为 true 才启用该功能。 |
classifier |
object | 是 | 本地模型端点配置,包含 host 与 model 两个标识符。 |
classifier.host |
string | 是 | 本地模型服务地址,应为 http://localhost:<port>。 |
classifier.model |
string | 是 | 用于路由决策的模型名,必须为 "gemma3-1b-gpu-custom"。 |
配置修改后需要重启 CLI 才能生效。
此外,从源码 packages/core/src/config/config.ts 的 GemmaModelRouterSettings 定义还可以确认两个文档未列出的默认值与额外字段:
classifier.host缺省为http://localhost:9379,classifier.model缺省为gemma3-1b-gpu-custom;autoStartServer(默认true):CLI 启动时是否自动拉起 LiteRT 服务,由gemini gemma setup写入 User 作用域;binaryPath(默认空):允许指定自定义 LiteRT 二进制的绝对路径,被 platform.ts 的getBinaryPath()优先采用;- gemmaClassifierStrategy.ts 中校验模型名必须为
gemma3-1b-gpu-custom,否则该策略不生效。
底层工作原理:路由决策链与静默降级
文档给出的核心机制:
- 本地 Gemma 将每条请求分类为 "simple" 或 "complex"(约 100ms);
- Simple → Flash,Complex → Pro;
- 若本地服务不可用,CLI 会静默回退到云端分类器——不报错、不中断。
从源码结构可以进一步印证这条链路。路由决策集中在 packages/core/src/routing/modelRouterService.ts,其内部策略注册顺序为:
- Gemma 分类器(
gemma-classifier,见 gemmaClassifierStrategy.ts)——仅当enabled为true时参与,调用本地 LiteRT 服务; - 通用云端分类器(
classifier,见 classifierStrategy.ts)——Gemma 不可用或关闭时的下一顺位; - 数值分类器(
numerical_classifier)——再下一顺位。
对"静默降级"的实现,两个策略文件都有对应注释与逻辑:"If the classifier fails for any reason (API error, parsing error, etc.)" 时返回 null 并走回退路径。而"服务是否可用"的探测由 platform.ts 的 isServerRunning() 完成:向 http://localhost:<port>/v1beta/models/gemma3-1b-gpu-custom:generateContent 发一个 POST,只要响应不是 404 即认为服务在线(400 说明路由存在、服务认识该模型端点;404 才说明端口上跑的不是这个服务),探测超时上限为 5 秒。
CLI 与本地服务之间的请求客户端是 packages/core/src/core/localLiteRtLmClient.ts,它从配置读取 classifier.host 与 classifier.model 作为访问目标。
服务如何被自动拉起
文档提到"默认情况下 CLI 启动时会自动启动 LiteRT 服务"。实现见 packages/cli/src/services/liteRtServerManager.ts 的 ensureRunning():仅当 enabled 为 true、autoStartServer 不为 false、且本地二进制存在时,才会探测端口并在服务未运行时调用 startServer() 拉起服务;任何失败只写调试日志、不影响 CLI 主流程——这与"静默降级"的设计一致。
start / stop 的生命周期管理细节
gemini gemma start(实现于 start.ts):
- 以
detached方式spawn二进制,参数为serve --port=<port> --verbose,stdout/stderr 追加写入litert-server.log; - 将
{pid, binaryPath, port}写入 PID 文件; - 等待 3 秒(
SERVER_START_WAIT_MS)后再次探测端口确认启动成功。
gemini gemma stop(实现于 stop.ts)做了多层安全保护:
- 先读 PID 文件,若进程不存在则清理陈旧 PID 文件并返回
not-running; - 杀掉之前会读取该 PID 的完整命令行(Linux 读
/proc/<pid>/cmdline,macOS 用ps,Windows 用 PowerShell 查询 CIM),确认它确实是带serve参数、匹配端口与二进制名的 LiteRT 服务,否则拒绝操作(返回unexpected-process,防止误杀无关进程); - 先
SIGTERM,1 秒后仍存活再SIGKILL,最后删除 PID 文件。
关闭路由
在设置中把 enabled 设为 false,或直接运行 gemini gemma stop 停掉服务即可:
{ "experimental": { "gemmaModelRouter": { "enabled": false } } }
也可以把 User 作用域的 autoStartServer 设为 false 阻止 CLI 启动时自动拉起服务(此时可用 gemini gemma start 手动管理)。
高级安装:手动配置(防火墙/受限环境)
如果你处于无法自动下载二进制的环境(例如严格的企業防火墙),可以完全手动完成安装,完整步骤(按平台下载 LiteRT-LM 运行时、接受条款并 pull 模型、serve 启动、用 curl/PowerShell 发请求验证、写入 settings.json)见 手动本地模型路由安装指南。要点:
- 使用的 LiteRT-LM 版本为
v0.9.0-alpha03(与 constants.ts 中LITERT_RELEASE_VERSION一致); - 三平台二进制:
lit.macos_arm64、lit.linux_x86_64、lit.windows_x86_64.exe; - 模型拉取:
<binary> pull gemma3-1b-gpu-custom(约 968.6 MB); - 手动启动:
<binary> serve --port=9379 --verbose,其中 9379 也是DEFAULT_PORT; - Windows 使用 GPU 需要 DirectXShaderCompiler 的
dxil.dll与dxcompiler.dll; - 手动安装的服务没有 PID 文件,
gemini gemma stop不会管理它,需在启动它的终端中自行停止——stop源码对此有明确的黄色警告提示。
相关文件索引
| 文件 | 作用 |
|---|---|
| docs/core/gemma-setup.md | 本文主体文档:自动化安装指南 |
| docs/core/local-model-routing.md | 手动安装与配置 schema 详解 |
| docs/cli/model-routing.md | 模型路由功能的整体说明 |
| packages/cli/src/commands/gemma/ | setup/start/stop/status/logs 五个子命令实现 |
| packages/cli/src/services/liteRtServerManager.ts | CLI 启动时的服务自动拉起逻辑 |
| packages/core/src/routing/modelRouterService.ts | 路由决策服务与策略编排 |
| packages/core/src/routing/strategies/gemmaClassifierStrategy.ts | Gemma 本地分类策略与失败回退 |
| packages/core/src/core/localLiteRtLmClient.ts | 访问本地 LiteRT 服务的客户端 |
| packages/cli/src/commands/gemma/setup.test.ts / platform.test.ts / stop.test.ts / logs.test.ts | 各子命令的单元测试,可用于核对行为预期 |
适用前提与限制:仅支持 macOS(ARM64)、Linux(x86_64)、Windows(x86_64);功能处于实验阶段,行为可能随版本演进;模型与运行时版本、校验和均以当前仓库 constants.ts 中的常量为准。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00