LiteLLM 本地统一网关 —— 零基础配置攻略

写于 2026-10-15

面向:不写代码也能照着做的人 本机项目位置:D:\Code\20261015_litellm-proxy 网关地址:http://127.0.0.1:4000/v1(只在自己电脑上开放,外网访问不到) 最近更新:2026-10-15 晚 配套技术备忘录:同目录 20261015 LiteLLM本地统一网关配置.md


一、这份攻略要解决什么问题

你手上现在有一大堆"AI 账号":谷歌的 Gemini、智谱的 GLM、深度求索的 DeepSeek、火山方舟、OpenRouter……

麻烦在哪?

  1. 每个平台都有自己的网址、自己的钥匙(API Key),换个软件就得重新填一遍。
  2. 某个平台今天额度用完了、或者突然抽风,软件就直接报错,你得手动去改配置换一个。
  3. 想知道"我这个月到底在 AI 上花了多少钱",得挨个平台登录去看。

LiteLLM 网关就是来解决这三件事的。 你可以把它理解成——

一个"总机接线员"。 所有软件都只记住总机的电话号码(127.0.0.1:4000),只填总机的分机号(比如 auto)。 至于这个电话最后是由 Gemini 接、还是由 GLM 接,由总机按你写好的顺序自动去试。 打不通第一家,它自己立刻拨第二家,你什么都不用管。

一句大白话:装一个"AI 电话总机",只填一个地址,坏了自己换,花钱有账本。


二、先搞懂 4 个词(后面全靠它们)

词 大白话解释 在本机对应什么
网关(Proxy) 那个"总机"。一个转接用的中间程序 D:\Code\20261015_litellm-proxy 这个程序,跑起来后占着 127.0.0.1:4000 这个门牌号
上游(Provider) 真正干活的 AI 公司服务器 Google、智谱、DeepSeek、OpenRouter、火山方舟
模型组名(别名) 你给总机起的"分机号" auto、auto-cn、glm-4-flash 这些名字
降级链(Fallback) 打不通就换下一家的顺序表 写死在配置里的一串名单,如 A → B → C

关键理解:软件里填的是"分机号",不是"真实模型名"。 分机号 auto 的样子是固定的,但它背后今天可能由 Gemini 接、明天由 GLM 接。 所以配置里换模型,你的软件一个字都不用改——这正是网关最大的好处。


三、这套网关给你带来的 5 个好处

  1. 一个地址接所有 AI。 任何支持 OpenAI 格式的软件(Cherry Studio、Chatbox、Hermes、各种插件), 网址填 http://127.0.0.1:4000/v1,钥匙填总机钥匙,模型填 auto,就通了。
  2. 自动降级,不中断。 主模型报错(额度用完、网络不通、限流),毫秒级自动换下一家,你几乎无感。
  3. 钥匙集中管理。 五家平台的钥匙只存在一个地方(~/AppData/Local/hermes/.env),软件里只有总机钥匙。
  4. 有账本。 每条请求花了多少 token、多少钱,都记进 spend.db,可出报表。
  5. 完全私有。 只在 127.0.0.1(本机)监听,没有对外端口,别人连不上,也不会把你的对话内容上传到第三方。

四、动手之前:先认清这台机器上的 5 个文件

都在 D:\Code\20261015_litellm-proxy\ 目录里:

文件 作用 能不能手改?
build_config.py 配置的"唯一源头"。所有模型、降级顺序都写在这里 ✅ 要改配置就改它
config.yaml 程序真正读的配置。由上面那个脚本自动生成 ❌ 千万别手改,下次重建会被覆盖
client.env 存"总机钥匙"(网关自己的密码)和总机网址 一般不用动
spend.db 账本(SQLite 数据库文件) 不用动,用报表工具看
proxy.log 网关的运行日志,出问题先看它 只看不改

⚠️ 第一条铁律:只改 build_config.py,不要手改 config.yaml。 这条规则最容易犯。config.yaml 第一行就写着"自动生成,勿手改"。 手改一时爽,下次一重建(重启前必做的动作)就全没了,然后你会怀疑人生。

上游那五家的钥匙存在另一个地方:C:\Users\<你的用户名>\AppData\Local\hermes\.env。 build_config.py 会自动去那里读,所以钥匙不会出现在 config.yaml 之外的地方被人看到。


五、日常操作:只要记住 3 条命令

打开终端(本机用的是 Git-Bash 风格的命令行),先进入项目目录:

cd /d/Code/20261015_litellm-proxy

1. 启动网关

双击 start_proxy.bat 也可以,命令行方式如下:

.venv/Scripts/litellm.exe --config config.yaml --host 127.0.0.1 --port 4000 > proxy.log 2>&1

注意:这条命令会一直占住窗口不返回,这是正常的(网关是个常驻程序)。 所以要么用双击 start_proxy.bat,要么在终端里让它在后台跑。

2. 看它活了没有(最常用)

curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:4000/health/liveliness
  • 显示 200 = 活着,正常。
  • 显示 000 或者报错 = 没起来,去看 proxy.log 最后 20 行。

3. 关掉它

PID=$(netstat -ano | grep -E ':4000\s+.*LISTENING' | head -1 | awk '{print $NF}'); taskkill //F //PID $PID

为什么要写得这么绕?因为直接找"litellm"这个程序名去杀杀不干净—— 它启动后会变成两个进程(一个包装进程 + 一个真正干活的),只杀一个会留下 "僵尸网关":端口不占了,但进程还在,于是你重启了配置却像没生效。 所以按端口占用者去杀才准。

改配置之后的完整流程(三步,缺一不可)

cd /d/Code/20261015_litellm-proxy

# ① 重建配置(从 .env 读钥匙,重新生成 config.yaml)
.venv/Scripts/python.exe build_config.py

# ② 结构体检(有没有写错的模型名、有没有绕成死循环)
.venv/Scripts/python.exe validate_config.py

# ③ 杀掉旧的 + 启动新的
PID=$(netstat -ano | grep -E ':4000\s+.*LISTENING' | head -1 | awk '{print $NF}'); taskkill //F //PID $PID
# 然后双击 start_proxy.bat

六、这台机器现在的"路由表"(谁优先、谁接替)

6.1 分机号(你在软件里填的名字)

分机号 第一跳(起步模型) 用完了自动往哪走 什么时候用它
auto OpenCode Go 订阅的 deepseek-v4.1-flash 订阅内免费模型 → 官方免费 Gemini → GLM-4.7-flash → glm-4-flash → glm-4.5-flash → DeepSeek → 本地模型 默认就用这个
auto-fast 官方 gemini-3.1-flash-lite(最快) GLM 系 想要"秒回"、不太在意质量
auto-strong 订阅的 deepseek-v4.1-flash(超时放宽到 5 分钟) glm-z1-flash(推理)→ DeepSeek-Pro 难题、长文分析
auto-cn GLM-4.7-flash glm-4-flash → 本地模型 外网整个断了时手动换它,全程国内直连
ds41-flash 订阅的 deepseek-v4.1-flash 订阅内免费模型 → 官方 Gemini → GLM 只想用订阅额度、不想绕路
ocf-catjam 订阅内的免费模型 cat-jam 官方 Gemini → GLM 最快(实测 0.8 秒)、免费
glm-4-flash GLM-4-flash glm-4.5-flash → DeepSeek 图便宜、图稳定
local-qwen 本机 llama.cpp (终点) 断网、断钱,纯离线

一句话记法:平时填 auto,外网断了改 auto-cn。

6.2 真正的降级顺序(auto 的完整链路)

① OpenCode Go 订阅 deepseek-v4.1-flash   ← 订阅主力(月额度 $80,实测 1.6~3.7 秒)
        ↓ 额度用尽 / 429 / 超时 / 连不上
② 订阅内免费模型 longcat-2.5-preview-free ← 免费、不限量(实测 3.3~6.4 秒)
        ↓
③ 订阅内免费模型 cat-jam-free            ← 免费、不限量(实测 0.8~2.0 秒)
        ↓
④ 官方 gemini-3-flash-preview            ← 免费层:20 次/天
        ↓
⑤ 官方 gemini-3.6-flash                  ← 免费层:20 次/天
        ↓
⑥ 官方 gemini-3.5-flash                  ← 免费层:20 次/天
        ↓
⑦ 官方 gemini-3.1-flash-lite             ← 免费层:20 次/天
        ↓
⑧ GLM-4.7-flash(国内直连)               ← 免费,偶发"访问量过大"
        ↓
⑨ glm-4-flash → glm-4.5-flash(国内直连)  ← 免费
        ↓
⑩ ds-flash(DeepSeek 官方)
        ↓
⑪ local-qwen(本机模型,完全离线)          ← 终点

关于"优先 Gemini"的实话(这一条已经过时,但原理仍值得知道): 官方 Gemini 免费层是 每款模型每天 20 次(不是每分钟 20 次!)。 API 报错原文写得很清楚:Quota exceeded ... limit: 20 ... Please retry in 11h9m。 所以它只能当"第四顺位之后的免费补位",不适合当主力。

关于"订阅额度用尽后走免费版"的实话(重要): 订阅里确实有一个 deepseek-v4.1-flash-free,但它用不了。实测请求它会被拒绝:

403 FreeTierError:OpenCode's free tier can only be used from within OpenCode.

翻译:免费层只允许在 OpenCode 自己的客户端里用,别的程序(包括本网关)一律拒绝。 我们试过把身份伪装成 OpenCode 也没用(服务端不是看这个),而且它压根不在订阅端点的模型清单里。 所以第二顺位改成了同在订阅内、实测可用的免费模型(第②③跳那两个), 效果一样:主力额度用完后自动落到不花钱的模型,你不需要做任何事。

6.3 已停用的"花钱模型"

OpenRouter 上那些按量计费的模型(Claude、GPT、以及同款 Gemini 的付费通道), 2026-10-15 已全部从网关里摘掉,理由是你要求的"只走免费链路"。 它们在 build_config.py 里以注释形式留着(搜 or-claude 就能看到), 哪天想重新启用,把注释去掉、填上 OpenRouter 钥匙、把名字加回降级链即可。


七、怎么查"刚才那条请求到底是谁回答的"

这是最实用的技能。网关有个账本 spend.db。看最近 20 条:

cd /d/Code/20261015_litellm-proxy
.venv/Scripts/python.exe -c "
import sqlite3
c = sqlite3.connect('spend.db')
for r in c.execute('select id,ts,model,prompt_tokens,completion_tokens,status from spend_log order by id desc limit 20'):
    print(r)
"

怎么看:

  • status = failure 的行,就是"第一优先尝试失败"的那一跳。
  • 紧跟在它后面的 status = success 行,就是实际回答你的模型。
  • 典型样子长这样(这就是"降级成功"的铁证):
(263, '2026-10-15T21:04:58', 'gemini-3.1-flash-lite', 23284, 4, 'success')   ← 实际是它答的
(261, '2026-10-15T21:04:10', 'gemini-3-flash-preview', 0, 0, 'failure')        ← 首选的官方 preview 429 了

看花费报表:

.venv/Scripts/python.exe spend_report.py --days 7            # 按模型汇总
.venv/Scripts/python.exe spend_report.py --days 7 --detail   # 明细

⚠️ 一个容易误会的点:免费模型也会显示"花了多少钱"。 账本里的金额是 LiteLLM 按"官方标价"估算的参考值,不是真实扣款。 官方免费层被计成 $0.0058 这种数字,实际 Google 一分钱没扣。 判断真花钱要看有没有走 OpenRouter 付费通道——现在那些通道已经全关了,所以真实花费是 0。


八、常见问题急救手册

Q1. 软件报"连接被拒绝 / Connection refused"

网关没起来。三步排查: 1. curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:4000/health/liveliness → 不是 200 就是没起来。 2. tail -20 proxy.log 看最后的报错。 3. 最常见原因是端口 4000 被另一个进程占着(比如上一轮的僵尸进程)。 用第五章"关掉它"的命令杀干净,再启动。

Q2. 明明是 35 个模型,怎么现在只有 29 个?

不是坏了。2026-10-15 把 OpenRouter 的 7 个付费模型停用了(or-*), 所以从 35 变 29。这是故意的,为了只走免费链路。

Q3. 为什么我明明配了 Gemini 优先,实际全走 GLM?

先查额度,不要先怀疑配置。 顺序: 1. 查账本(第七章),看 failure 行的错误。 2. 直接给 Google 发一个最小请求看原始报错: - HTTP 400 模型不存在 → 名字写错了 - HTTP 429 limit: 20 ... retry in 11h → 每天 20 次的额度用完了(当前最常见) - HTTP 429 该模型当前访问量过大 → 瞬时过载,等一下就好 3. 结论话术要诚实:"降级链工作正常" ≠ "首选模型在工作"。 免费额度下首选经常不是主力,这是额度的限制,不是配置的错。

Q4. 有时候一条回复要等 14 秒、甚至 45 秒?

降级链只在"报错"时触发,它感知不到"慢但成功"。 一个模型排队 20 秒才回 200,网关只能原样把结果交给你。 这类尖峰是某个上游(尤其 GLM-4.7-flash 高峰期)在排队,不是网关的开销。 实测基线:auto 中位 1.1 秒、auto-cn 中位 1.3 秒;偶发 14~45 秒是上游排队。 想避免就改用 glm-4-flash(实测 0.4 秒)或 auto-fast。

Q5. 报错里出现 429,是什么意思?

429 = "请求太多了 / 额度用完了",不是"你配置写错了"。 网关的处理方式是:立刻换下一家(不做无谓重试,因为重试只会让你多等一遍退避时间)。 实测这个决定把最坏等待从 60.9 秒压到了 3.1 秒。

Q6. 改了配置,重启了,但感觉没生效?

99% 是僵尸进程。litellm.exe 启动后会派生出两个 python 进程, 只杀父进程会留下不占端口但仍在运行的"幽灵",它还在用旧配置。 按第五章的命令(按端口占用者杀 + 复查)处理。

Q7. 网关重启后,软件里的钥匙全失效了?

不该发生。总机钥匙存在 client.env 里,首次生成后会一直复用。 如果真失效了,看 client.env 里的 OPENAI_API_KEY 是否被清空。

Q8. 重启电脑之后还要手动启动吗?

不用。已经配了"登录自启": - D:\Code\20261015_litellm-proxy\autostart.vbs 是启动逻辑(已在运行就跳过,不会起两个)。 - …\Start Menu\Programs\Startup\litellm-gateway.vbs 是自启入口。 - autostart.log 是启动记录,出现 already running, skip 就是幂等护栏生效。

想撤销自启:把启动目录里那个 litellm-gateway.vbs 删掉即可(纯用户级,不用管理员)。

Q9. 报错说 Request is missing x-opencode-session 是什么意思?

这是 OpenCode Go 的硬性要求:请求必须带一个"会话标识"头,不带就拒绝。 不是你的钥匙或配置错了。

  • 从网关发出:已经在 build_config.py 里加好了 extra_headers,正常不会有这个问题。
  • 从 Hermes 直接发出:本机 Hermes 版本旧、不会自动带, 已在 config.yaml 的 model.default_headers 里补上(见第十章)。
  • 症状就是"被后备链接管、订阅额度没用上",看到这条报错就照第十章检查。

Q10. 订阅的免费模型(longcat / cat-jam)回复很慢或者返回空内容?

两个已知点: 1. 这几个免费模型先"思考"再回答。如果你把「最大输出长度」设得很小 (比如 32),额度会被思考过程吃光,正文就是空的。把上限调到 300 以上就正常了。 2. 它们是"限时免费/预览"模型,延迟会波动(实测 cat-jam 0.8 秒,longcat 3~6 秒)。 嫌慢就手动把模型改成 ocf-catjam。


九、把这台总机接给别的软件

任何支持"OpenAI 兼容接口"的软件都一样,三个填空:

填空项 填什么
接口地址 / Base URL http://127.0.0.1:4000/v1
API Key / 密钥 打开 D:\Code\20261015_litellm-proxy\client.env,抄里面 OPENAI_API_KEY= 后面那串
模型 / Model auto(或第六章表格里任意一个分机号)

举例(Cherry Studio):设置 → 模型服务 → 添加"OpenAI",按上表填三格,点测试连接,能通就够了。


十、接给 Hermes(本机 AI 助手)—— 已经配好了

Hermes 这边现在是"三层保险":

层 设置 作用
主力 模型 = OpenCode Go 订阅的 deepseek-v4.1-flash 直连吃订阅额度(月 $80)
后备① 本地网关 litellm-local 的 auto 订阅额度用尽 / 报错时立刻切进来,走订阅内免费模型 → 官方 Gemini → GLM
后备② DeepSeek deepseek-v4-flash 连网关进程都挂了的最后兜底

真机验证日志(关键那一行):

22:19:30 OpenAI client created provider=opencode-go base_url=https://opencode.ai/zen/go/v1 model=deepseek-v4.1-flash
22:19:47 API call #1: model=deepseek-v4.1-flash provider=opencode-go in=22789 out=4 latency=17.6s

没有任何 400、没有触发降级 → 订阅的模型真正被用上了。

⚠ 一个必须知道的技术细节:x-opencode-session

OpenCode Go 有个硬性要求:每个请求必须带一个叫 x-opencode-session 的"会话标识"头, 不带就直接拒绝(报错原文:Request is missing x-opencode-session and cannot be routed efficiently)。

本机 Hermes 版本较旧(0.17.0),不会自动带这个头,结果就是:每次请求都被拒 → 后备链接管 → 订阅额度一点都没用上。表现为"明明配好了却走了别的模型"。

已在 config.yaml 的 model: 下补上(这是 Hermes 官方支持的配置项):

model:
  provider: opencode-go
  default: deepseek-v4.1-flash
  default_headers:
    x-opencode-session: hermes-cli-opencode-go   # 补上必需的头
    User-Agent: hermes-agent/0.17.0              # 官方也要求用自有 UA 而非 SDK 默认名

副作用:这个 ID 是固定值,而官方建议"每个会话一个"。功能完全正常, 只是提示词缓存的优化效果会略打折扣。想彻底解决需要升级 Hermes(官方新版本已内建发送)。

还有一条细节值得知道:遇到 429 之后,Hermes 会把主力模型冷冻 60 秒, 这段时间内不会再去敲那扇已经关上的门,避免每条消息都白等一次。

配置存在 C:\Users\<你的用户名>\AppData\Local\hermes\config.yaml。 ⚠️ 这份文件有 700 多行、注释很多,不要用记事本直接改、也不要用"读进来再整体写回"的脚本改 (会把注释和钥匙一起弄坏)。要改请让 Hermes 用"文本锚点替换"的方式改。


十一、名词小词典

名词 大白话
LiteLLM 一个开源程序,作用就是当"AI 总机"。它自己不是 AI,只是转接员
Proxy / 代理 站在你和 AI 公司中间帮忙转发的程序
API Key 就是各家的"钥匙",泄露了别人就能用你的额度
token AI 眼里的"字数单位"。中文大约 1 个字 ≈ 1 个 token 上下,英文约 4 个字母 1 个 token
429 服务端说"你请求太多 / 额度没了"
fallback / 降级 第一家不行就换第二家
cooldown / 冷却 某家刚失败,先冷冻一小段时间不再去试它,免得每次请求都白等
health / liveliness 网关的"我在活着吗"检查接口,返回 200 就是活着
.env 专门存钥匙的文件,和其他配置分开放
SQLite / spend.db 一个"单文件小数据库",这里是账本

十二、一页速查卡

# 进入项目
cd /d/Code/20261015_litellm-proxy

# 启动(或直接双击 start_proxy.bat)
.venv/Scripts/litellm.exe --config config.yaml --host 127.0.0.1 --port 4000 > proxy.log 2>&1

# 健康检查(200 = 活着)
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:4000/health/liveliness

# 停止(按端口占用者杀,避免僵尸)
PID=$(netstat -ano | grep -E ':4000\s+.*LISTENING' | head -1 | awk '{print $NF}'); taskkill //F //PID $PID

# 改配置三步:重建 → 体检 → 重启
.venv/Scripts/python.exe build_config.py
.venv/Scripts/python.exe validate_config.py
# 然后重新启动

# 全量测试 / 模拟断网测试 / 计费验证
.venv/Scripts/python.exe test_all.py
.venv/Scripts/python.exe test_fallback.py
.venv/Scripts/python.exe verify_spend.py

# 花费报表
.venv/Scripts/python.exe spend_report.py --days 7
.venv/Scripts/python.exe spend_report.py --days 7 --detail

软件里的三个填空: 地址 http://127.0.0.1:4000/v1 | 钥匙看 client.env | 模型写 auto


十三、三条最容易踩的坑(血泪总结)

  1. 不要手改 config.yaml。 它是自动生成物,下次重建直接覆盖你的修改。 要改就改 build_config.py,然后跑重建。
  2. 启动必须用 .venv\Scripts\litellm.exe,不要用 python -m litellm。 后者会报 No module named litellm.__main__ —— 这是包装机制决定的,不是环境坏了。
  3. 别用"重启了却没生效"来怀疑人生。 先查有没有僵尸进程(按端口杀,不要按名字杀)。 这个坑解释过至少三次"配置明明改了却没用"的假象。

本攻略由 Hermes 于 2026-10-15 依据本机实测写成,所有命令均在 D:\Code\20261015_litellm-proxy 上真机验证通过。