当 LLM CLI 不是 API:一次真实的 Gemini Adapter 调试复盘
很多人在讨论多模型路由时,默认前提是「所有模型都是 HTTP API」。
但现实中,总会遇到 CLI-only、半官方、行为不稳定 的模型接入方式。这是一篇关于 Google Gemini CLI 的真实适配与调试复盘。
背景:为什么要接入 Gemini CLI
在我的模型路由系统中,已经存在多个 Adapter:
- ✅ Qwen(HTTP API)
- ✅ CodeBuddy(CLI)
- ✅ Google Gemini(CLI)
设计目标很简单:
Router 负责“选谁”,Adapter 负责“怎么用”
Gemini 之所以选择 CLI 而不是 SDK,是因为:
- CLI 是 Google 官方支持路径
- 能快速覆盖多个模型
- 本地调试与自动化测试方便
于是我写了一个 GoogleAdapter,通过 child_process 调用 gemini。
第一次失败:看起来一切都对,但就是不工作
表象
在 Adapter 中执行:
gemini --prompt "hi" --model gemini-2.5-flash --output-format json
返回结果却是:
- exit code ≠ 0
- Adapter 判定 健康检查失败
- Router 认为 Gemini 不可用
但奇怪的是:
gemini --version✅gemini list-models✅- API Key 已配置 ✅
误区:以为是自己代码写错了
一开始我怀疑的是:
- JSON 解析逻辑
- stdout / stderr 混用
- Node.js spawn 参数问题
- Adapter 抽象设计有缺陷
但这些方向全部走不通。
关键转折点:直接跑 CLI,而不是“想当然”
我开始完全抛开代码,只做一件事:
像普通用户一样,用终端跑 gemini
gemini --prompt "hi" --model gemini-2.5-flash
这时,终端给出了一个非常“温柔”的提示:
The --prompt (-p) flag has been deprecated and will be removed in a future version.
⚠️ 重点在于:
- 这是 stderr
- CLI 仍然输出了一些内容
- 但 exit code = 1
也就是说:
CLI 行为已经变了,但并没有以“硬错误”的形式提醒你。
真正的原因:Gemini CLI 的接口语义变更
Gemini CLI 已经从:
gemini --prompt "hi"
切换为:
gemini "hi"
也就是:
- prompt 变成了 位置参数
--prompt进入废弃阶段- 但并未立即兼容旧行为
✅ 当我把 Adapter 改为:
gemini "hi" --model gemini-2.5-flash --output-format json
一切立刻恢复正常。
第二个现实问题:CLI 冷启动非常慢
即便修复参数问题后,我又遇到了第二个“非代码错误”:
- 首次调用 Gemini CLI:20–25 秒
- 默认 timeout:30 秒
- 在网络波动时,极易超时
解决方式很朴素:
timeout: 60_000
这不是“性能优化”,而是尊重现实。
最终结果:Gemini Adapter 稳定可用
测试命令:
yuangs router test google-gemini --prompt "hi"
结果:
- ✅ 健康检查通过
- ✅ 模型响应正常
- ✅ JSON 解析正确
- ⏱️ 执行时间 ~23.8s(在安全范围内)
当前默认模型策略:
gemini-2.5-flash:通用 / 对话gemini-2.5-pro:代码 / 高复杂度任务
这次调试带来的架构启示
1️⃣ CLI ≠ API
CLI 的问题在于:
- 参数语义可能悄悄改变
- stderr / stdout / exit code 不一致
- 文档更新滞后
✅ 正确做法是:
把 CLI 当作“不稳定外部系统”
2️⃣ Adapter 层必须是“变化缓冲区”
这次问题如果发生在:
- Router 层 → 架构设计失败
- 调用方 → 使用体验灾难
而现在:
- 变化被完全限制在 Adapter 内
- Router / 上层 零修改
这正是 Adapter 模式存在的意义。
3️⃣ 健康检查 ≠ 功能正确
gemini --version成功- 不代表
gemini "hi"可用
CLI Adapter 的健康检查必须是:
最小真实调用
结语
这次 Gemini Adapter 的问题,不是“踩坑”,而是一次很好的提醒:
真实世界的 LLM 接入,从来不是一条干净的 API 路径。
当你开始接入:
- CLI
- 本地模型
- 半官方工具
你面对的不是“调用问题”,而是系统演化问题。
而一个好的模型路由系统,
应该 天然允许这些变化发生,而不被拖垮。
如果你正在做:
- 多模型路由
- LLM Infra
- CLI / SDK 混合接入
希望这次 Gemini 的真实复盘,能帮你少走一点弯路。