⚡ Grok API Pool MIT 开源 最后实测 2026-08-06 自部署 · 免费
负载均衡 · Key 轮询 · 容错降级

Grok API Pool 部署指南

一个 Key 不够用?把 N 个 Grok API Key 组成一个 Pool,统一入口、自动轮询、自动熔断、统一监控。
实战踩坑笔记,LiteLLM / Nginx+Lua / 自建网关三套方案任你选。

⚡ 本指南以 2026-08-06 实测为准。所有 API Key / Token / 域名 / IP 一律用占位符,部署前请自行替换。
0 为什么要建 1 原理拆解 2 方案比较 3 LiteLLM 4 Nginx+Lua 5 自建网关 6 安全规范 7 限制注意 8 监控维护 9 踩坑合集 10 指令速查 11 附录

0 为什么要建 API Pool(目的 + 架构概览)

直接拿一个 Key 怼生产环境,迟早出事。单 Key 有三大硬伤:

🐌

速率限制

官方按 tier 限 RPM / TPM / 每日配额,一个 Key 很快触顶,报 429 限流

💥

单点故障

Key 失效、被风控、余额耗尽 → 全线停摆,连个备胎都没有

📊

用量盲区

哪个调用方花了多少钱、何时打满配额,完全看不到

🚫

被封风险

高并发打一个 Key,很容易触发官方滥用检测,直接封号

Pool 的核心价值:

用户请求 反向代理 / Pool 管理器 [Key A] [Key B] [Key C] xAI Grok API 响应

客户端只认一个入口地址;轮询、熔断、重试全部在 Pool 层完成。

适用场景:

⚠️ 老实话:Pool 是「分散」不是「突破」——总配额 = N 个 Key 配额相加,官方的单 Key 限速依然存在。想绕过单账号总配额?那是与官方 ToS 对着干,下文第 7 节有讲。

1 原理拆解(How It Works)

不管你选哪套方案,底层都是这几个机制。理解了它,出问题才知道怎么查。

Round-Robin 轮询

请求按顺序轮流分派:1→Key A、2→Key B、3→Key C、4→Key A…… 最简单,所有 Key 用量平均。LiteLLM 叫 simple-shuffle,Nginx 默认 upstream 就是轮询。

加权轮询(Weighted)

不同 Key 配额不同(例如一个 100 RPM、一个 60 RPM),按权重分配,配额大的多接一些。LiteLLM 用 weighted 策略,在 model_inforpm 即可。

健康检查(Health Check)

定时或按请求探测每个 Key 状态:429(限流)、401(Key 失效)、503(上游挂)→ 即刻标记为「冷却」,不再分派请求给它,直至冷却期结束。

熔断机制(Circuit Breaker)

连续失败 N 次才触发熔断,暂停该 Key M 分钟;成功一次就重置计数。这个机制防「抖」——不会因为一次 429 就废了一个好 Key。LiteLLM 参数:allowed_fails + cooldown_time

缓存层(可选)

相同请求(相同 prompt)直接回缓存,完全不经过上游,节省配额省钱。适合固定 prompt 的场景(例如翻译、摘要模板)。注意:对话类请求缓存命中率低,要小心缓存了不该缓存的内容。

日志与监控

每个 Key 独立记录:请求数、token 用量、延迟、状态码、失败原因。这些是第 8 节做告警的数据基础——没有日志就如同盲目开车。

机制作用关键配置建议
轮询请求均匀分发simple-shuffle / upstream 默认✅ 必开
加权按配额比例分配rpm / weight🟡 Key 配额不一致才需要
健康检查剔除失效 Keyenable_pre_call_checks✅ 必开
熔断防抖动 + 自动恢复allowed_fails: 3 / cooldown_time: 60✅ 必开
缓存节省配额省钱Redis / 内存缓存❌ 按场景选
日志监控用量 / 告警数据源Prometheus / 日志轮替✅ 必开

2 方案比较(选哪种 Pool 方案)

四套方案都是开源 / 免费,功能与维护成本相差很远。直接看表:

方案优点缺点适合谁部署难度建议
A. LiteLLM Proxy
推荐 ⭐
轮询/加权/熔断/重试/fallback 全部内置,改 YAML 即可;OpenAI 兼容,客户端零改动;自带 /metrics 监控 Python 进程食 ~200-400MB 内存;概念略多,新手要看文档 认真部署、团队共用、要监控告警 ✅ 首选
B. Nginx + Lua / OpenResty 极轻量、零额外进程;与现有 Nginx 架构融合;性能天花板最高 轮询/熔断/健康检查全部要自己写 Lua;无自带监控面板;Debug 靠日志 已有 Nginx 基础、只想要简单轮询、机器资源紧张 🟡 轻量备选
C. 自订 Python FastAPI 网关 逻辑 100% 可控;想加什么功能都可以(缓存/计费/审计);代码就是文档 全部自己写自己维护;健壮性靠你;出 bug 没有人救 想完全掌控、学习用途、有特殊业务逻辑 🟡 进阶向
D. One API / New API Web 管理界面友好,鼠标点几下加 Key;中文社区活跃;多模型聚合(Grok/OpenAI/Claude 通食) 功能重,带用户体系/计费/额度一堆东西;Grok 要按 OpenAI 兼容手动配;更新频繁有兼容风险 中文团队、要图形界面管理、顺便接多个模型厂商 低-中 🟡 团队向备选
✅ 结论:没有特殊理由就 LiteLLM。它内置的 router 逻辑(轮询 + 熔断 + 重试 + fallback)就是我们想要的东西,无需自己写。Nginx+Lua 适合「机器配置低、只要轮询」;FastAPI 适合想练手/要私有逻辑;One API 适合要管理界面的团队。

3 实战部署:LiteLLM Proxy(主推方案)

以下步骤在 Ubuntu 22.04 / Debian 12 上亲测可行。用 Docker 或 venv 都可以,venv 适合机器资源紧张。

3.1 环境准备

bash
# Ubuntu 22.04+ / Python 3.10+
sudo apt update && sudo apt install -y python3.11 python3.11-venv curl jq
python3.11 -m venv /opt/litellm/venv
source /opt/litellm/venv/bin/activate
pip install -U "litellm[proxy]"
💡 想用 Docker?docker run -d --name litellm -p 4000:4000 -v $(pwd):/app ghcr.io/berriai/litellm:main-latest --config /app/config.yaml,之后的 config.yaml 一样适用。

3.2 配置 config.yaml(多 Key 轮询 + 健康检查 + 熔断)

/opt/litellm/config.yaml
# ── 模型路由表:同一个对外名 grok-main 挂多个 Key ──
model_list:
  - model_name: grok-main          # 对外暴露名,客户端请求用这个
    litellm_params:
      model: grok/grok-3           # 真实上游模型(xAI 命名,看官方 docs)
      api_key: os.environ/GROK_API_KEY_1
      rpm: 60                      # 这个 Key 每分钟上限,加权轮询依据
    model_info:
      tier: primary
  - model_name: grok-main
    litellm_params:
      model: grok/grok-3
      api_key: os.environ/GROK_API_KEY_2
      rpm: 60
    model_info:
      tier: primary
  - model_name: grok-main
    litellm_params:
      model: grok/grok-3
      api_key: os.environ/GROK_API_KEY_3
      rpm: 30
    model_info:
      tier: primary
  - model_name: grok-fallback      # 兜底模型:主模型全挂时用
    litellm_params:
      model: grok/grok-3-mini
      api_key: os.environ/GROK_API_KEY_1

# ── Router 核心:轮询 + 熔断 + 重试 + fallback ──
router_settings:
  routing_strategy: simple-shuffle # 轮询分派(或 least-busy / weighted)
  enable_pre_call_checks: true     # 发送前先查配额,减少无效请求
  cooldown_time: 60                # 熔断后冷却秒数(M 分钟恢复)
  allowed_fails: 3                 # 连续失败 N 次触发熔断
  num_retries: 2                   # 失败自动换 Key 重试次数
  request_timeout: 60              # 单请求超时(秒)
  fallbacks: [{"grok-main": ["grok-fallback"]}]   # 全部 Key 挂晒→兜底模型

litellm_settings:
  drop_params: true
  set_verbose: true
  telemetry: false                 # 关闭遥测,隐私友好

3.3 环境变量 .env(全部占位符)

/opt/litellm/.env
# 三个独立账号的 Grok API Key(不要用同一个账号开的多个 Key!原因见第 7 节)
GROK_API_KEY_1=YOUR_GROK_API_KEY_1
GROK_API_KEY_2=YOUR_GROK_API_KEY_2
GROK_API_KEY_3=YOUR_GROK_API_KEY_3

# 保护 Pool 入口的 Master Key(客户端请求时要带)
LITELLM_MASTER_KEY=YOUR_MASTER_KEY
⚠️ 权限:chmod 600 /opt/litellm/.env,不要给其他用户读到。详见第 6 节。

3.4 systemd 服务(24/7 运行 + 自动重启)

/etc/systemd/system/litellm.service
[Unit]
Description=LiteLLM Proxy (Grok API Pool)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/litellm
EnvironmentFile=/opt/litellm/.env
ExecStart=/opt/litellm/venv/bin/litellm --config /opt/litellm/config.yaml --port 4000
Restart=always
RestartSec=5
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target
bash
sudo chown -R www-data:www-data /opt/litellm
sudo systemctl daemon-reload
sudo systemctl enable --now litellm
sudo systemctl status litellm --no-pager

3.5 验证:轮询 + 熔断实测

bash
# 1) 健康检查
curl -s http://127.0.0.1:4000/health/liveliness

# 2) 连续发 5 次请求,看日志确认 Key 有轮换
for i in 1 2 3 4 5; do
  curl -s http://127.0.0.1:4000/v1/chat/completions \
    -H "Authorization: Bearer YOUR_MASTER_KEY" \
    -H "Content-Type: application/json" \
    -d '{"model":"grok-main","messages":[{"role":"user","content":"hi"}],"max_tokens":10}'
  echo
done

# 3) 看日志:留意每个请求用了哪个 Key(provider/API Key 尾几位)
journalctl -u litellm -f --no-pager
✅ 熔断测试(强烈建议做):临时把一个 Key 改成错误值,重启后连续请求,日志应见到它失败 3 次 → 进入冷却 → 其他 Key 顶上;改回正确值后 60 秒自动恢复。这一步做过才算真正部署完成。
💡 Agent 类客户端接入:客户端请求前会用 /v1/models 校验模型名,务必让对外模型名(model_name)与列表一致;若客户端工具集包含 web_search 而上游 console 通道会注入同名原生工具,需要在网关层去重,否则整个请求会被 400 拒绝(详见第 9 节)。

4 实战部署:Nginx + Lua 轻量版(备选方案)

机器只有 512MB RAM 又不想装 Python?用 OpenResty(Nginx + LuaJIT)做轻量网关。轮询、Key 注入、熔断全部用 Lua 写,食内存几乎为零。

4.1 安装 OpenResty

bash
# Ubuntu / Debian 官方源
sudo apt install -y openresty   # 或者按 openresty.org 加官方源

# 检查 Lua 模块
openresty -V 2>&1 | grep -o 'lua-nginx-module'

4.2 nginx.conf 完整模板(Key 池 + 轮询 + 熔断 + 入口鉴权)

/etc/openresty/conf.d/grok-pool.conf
# Grok API Pool —— Nginx + Lua 轻量网关
# 部署前替换: YOUR_GROK_API_KEY_1..3 / YOUR_POOL_ENTRY_KEY / your-domain.com

lua_shared_dict grok_pool 1m;   # 跨 worker 共享熔断状态

init_by_lua_block {
    -- Key 池(占位符,部署前替换)
    KEYS = { "YOUR_GROK_API_KEY_1", "YOUR_GROK_API_KEY_2", "YOUR_GROK_API_KEY_3" }
    RR = 0              -- round-robin 游标
    MAX_FAILS = 3       -- 连续失败熔断阈值
    COOLDOWN_SEC = 60   -- 冷却秒数
}

upstream grok_backend {
    server api.x.ai:443;
    keepalive 16;       -- 连接复用,降低握手开销
}

server {
    listen 443 ssl;
    server_name your-domain.com;

    ssl_certificate     /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    location /v1/ {
        rewrite_by_lua_block {
            -- 1) 校验调用方 Key(保护 Pool 入口)
            if ngx.var.http_authorization ~= "Bearer YOUR_POOL_ENTRY_KEY" then
                return ngx.exit(ngx.HTTP_UNAUTHORIZED)
            end

            -- 2) 轮询选 Key,跳过冷却中的;全部冷却则取第一个硬试
            local d = ngx.shared.grok_pool
            local now = os.time()
            local chosen = KEYS[1]
            ngx.ctx.key_idx = 1
            for i = 1, #KEYS do
                local idx = (RR % #KEYS) + 1
                RR = RR + 1
                local cooldown = d:get("cd:" .. idx) or 0
                if cooldown <= now then
                    chosen = KEYS[idx]
                    ngx.ctx.key_idx = idx
                    break
                end
            end

            -- 3) 注入上游要用的 Key(覆盖调用方传的)
            ngx.req.set_header("Authorization", "Bearer " .. chosen)
        }

        proxy_pass https://grok_backend/v1/;
        proxy_set_header Host api.x.ai;
        proxy_ssl_name api.x.ai;
        proxy_ssl_server_name on;
        proxy_buffering off;        -- 流式响应必须关缓冲
        proxy_read_timeout 300s;
        proxy_connect_timeout 10s;

        header_filter_by_lua_block {
            -- 4) 429/401/503 → 记失败;连续 MAX_FAILS 次 → 冷却 COOLDOWN_SEC
            local status = ngx.status
            if status == 429 or status == 401 or status == 503 then
                local idx = ngx.ctx.key_idx
                if idx then
                    local d = ngx.shared.grok_pool
                    local fails = (d:get("f:" .. idx) or 0) + 1
                    if fails >= MAX_FAILS then
                        d:set("cd:" .. idx, os.time() + COOLDOWN_SEC)
                        d:set("f:" .. idx, 0)
                    else
                        d:set("f:" .. idx, fails)
                    end
                end
            end
        }
    }
}
bash
# 语法检查 + 重载
openresty -t
sudo systemctl reload openresty

# 测试:带入口 Key 请求
curl -s https://your-domain.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_POOL_ENTRY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"grok-3","messages":[{"role":"user","content":"hi"}],"max_tokens":10}'
⚠️ 这套方案的局限(亲测):Lua 版没有自带监控面板,日志只能靠 error_log;SSE 流式要记得 proxy_buffering off;Key 数量变化要改配置重载。想要熔断/健康检查/监控全套,老老实实返去 LiteLLM。

5 实战部署:自订 Python Gateway(进阶)

想完全掌控逻辑?用 FastAPI + httpx 写一个 ~120 行的轮询池网关,核心流程:Key 池初始化 → 请求分发 → 响应处理 → 失败重试 → 冷却恢复。以下代码亲测可跑,填占位符即用。

5.1 主程序 gateway.py

gateway.py
# gateway.py —— Grok API Pool 网关(FastAPI + httpx 异步)
# 启动: uvicorn gateway:app --host 0.0.0.0 --port 8000
# 部署前替换: 环境变量 GROK_KEYS 填真实 Key,逗号分隔
import asyncio
import os
import time

import httpx
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse, StreamingResponse

# ── 配置(全部走环境变量,不要硬编码)──
API_KEYS = os.getenv("GROK_KEYS", "").split(",")     # 多个 Key 逗号分隔
GROK_BASE = os.getenv("GROK_BASE", "https://api.x.ai/v1")
MODEL = os.getenv("GROK_MODEL", "grok-3")
MAX_FAILS = int(os.getenv("MAX_FAILS", "3"))         # 熔断阈值
COOLDOWN = int(os.getenv("COOLDOWN_SEC", "60"))      # 冷却秒数
TIMEOUT = float(os.getenv("TIMEOUT_SEC", "60"))
ENTRY_KEY = os.getenv("POOL_ENTRY_KEY", "YOUR_POOL_ENTRY_KEY")

# ── Key 池状态:失败次数 + 冷却截止时间 ──
state = {k: {"fails": 0, "cooldown_until": 0.0} for k in API_KEYS}
lock = asyncio.Lock()
rr = 0                                    # round-robin 游标

app = FastAPI(title="Grok API Pool Gateway")


def _healthy(key):
    return state[key]["cooldown_until"] < time.time()


async def _pick_key():
    # 轮询 + 跳过冷却中的 Key;全部冷却就全部重试(最坏情况)
    global rr
    async with lock:
        now = time.time()
        keys = [k for k in API_KEYS if _healthy(k)]
        if not keys:
            keys = API_KEYS
        k = keys[rr % len(keys)]
        rr += 1
        return k


def _on_fail(key, reset=False):
    # 失败计数;连续 MAX_FAILS 次 → 熔断冷却
    s = state[key]
    if reset:
        s["fails"] = 0
        s["cooldown_until"] = 0.0
    else:
        s["fails"] += 1
        if s["fails"] >= MAX_FAILS:
            s["cooldown_until"] = time.time() + COOLDOWN
            s["fails"] = 0


@app.get("/v1/models")
async def models():
    return {"object": "list", "data": [{"id": MODEL, "object": "model"}]}


@app.post("/v1/chat/completions")
async def chat(request: Request):
    # 入口鉴权:调用方要带自己的 Key
    if request.headers.get("Authorization") != "Bearer " + ENTRY_KEY:
        return JSONResponse({"error": {"message": "unauthorized"}}, status_code=401)

    body = await request.json()
    headers = {"Content-Type": "application/json"}

    # 流式请求:单次直通(重试会破坏 SSE 顺序,不做)
    if body.get("stream"):
        async def gen():
            async with httpx.AsyncClient(timeout=TIMEOUT) as client:
                async with client.stream(
                    "POST", f"{GROK_BASE}/chat/completions",
                    json=body, headers=headers,
                ) as resp:
                    async for chunk in resp.aiter_bytes():
                        yield chunk

        key = await _pick_key()
        headers["Authorization"] = f"Bearer {key}"
        return StreamingResponse(gen(), media_type="text/event-stream")

    # 非流式:失败换 Key 重试,直到全部 Key 试完
    for _ in range(len(API_KEYS) + 1):
        key = await _pick_key()
        headers["Authorization"] = f"Bearer {key}"
        try:
            async with httpx.AsyncClient(timeout=TIMEOUT) as client:
                resp = await client.post(
                    f"{GROK_BASE}/chat/completions", json=body, headers=headers
                )
            if resp.status_code in (429, 401, 503):
                _on_fail(key)          # 限流/凭证错/上游挂 → 换 Key
                continue
            if resp.status_code >= 500:
                _on_fail(key)
                continue
            _on_fail(key, reset=True)  # 成功 → 重置计数
            return JSONResponse(content=resp.json(), status_code=resp.status_code)
        except httpx.TimeoutException:
            _on_fail(key)
        except Exception:
            _on_fail(key)

    return JSONResponse(
        {"error": {"message": "all keys unavailable"}}, status_code=503
    )
requirements.txt
fastapi
uvicorn[standard]
httpx

5.2 Docker 部署(可选)

Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY gateway.py .
EXPOSE 8000
CMD ["uvicorn", "gateway:app", "--host", "0.0.0.0", "--port", "8000"]
docker-compose.yml
services:
  grok-gateway:
    build: .
    ports:
      - "127.0.0.1:8000:8000"          # 只绑本机,外面经反向代理入
    environment:
      GROK_KEYS: "YOUR_GROK_API_KEY_1,YOUR_GROK_API_KEY_2,YOUR_GROK_API_KEY_3"
      GROK_BASE: "https://api.x.ai/v1"
      GROK_MODEL: "grok-3"
      POOL_ENTRY_KEY: "YOUR_POOL_ENTRY_KEY"
      MAX_FAILS: "3"
      COOLDOWN_SEC: "60"
    restart: unless-stopped
bash
docker compose up -d --build
# 测试
curl -s http://127.0.0.1:8000/v1/chat/completions \
  -H "Authorization: Bearer YOUR_POOL_ENTRY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"grok-3","messages":[{"role":"user","content":"hi"}],"max_tokens":10}'
⚠️ 自己写的网关要自己负责:单进程状态只在本机有效,多实例要换 Redis;进程挂了要 systemd/Docker 拉起;还要自己写日志轮替和监控。这套适合学习和私有逻辑,生产环境首选还是 LiteLLM。

6 安全与屏蔽敏感数据规范

这一节是红线——真 Key 流出一次,轻则被盗刷,重则连累成个账号。以下规范逐条执行。

6.1 占位符命名规则(全文统一)

敏感数据占位符说明
Grok API KeyYOUR_GROK_API_KEY_1 / _2 / _3每个独立账号一个 Key,编号区分
Pool 入口 KeyYOUR_POOL_ENTRY_KEY客户端调用时要带的共享密钥
LiteLLM Master KeyYOUR_MASTER_KEY保护 /chat/completions 入口
Bot TokenYOUR_BOT_TOKEN接 Telegram Bot 时用
域名your-domain.com证书、server_name 一律用这个
服务器 IP<YOUR_SERVER_IP>防火墙 / 白名单场景用

6.2 硬性要求

6.3 入口加一层 HTTPS + 鉴权(Nginx 示例)

/etc/nginx/conf.d/grok-entry.conf
server {
    listen 80;
    server_name your-domain.com;
    # 强制跳 HTTPS(certbot 会帮你写好,这里示意)
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name your-domain.com;
    ssl_certificate     /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    # LiteLLM 自带 Master Key 鉴权,这里再加一层 IP 白名单(可选)
    allow <YOUR_SERVER_IP>/32;
    deny all;

    location / {
        proxy_pass http://127.0.0.1:4000;      # 指去 LiteLLM
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_buffering off;                    # 流式响应
        proxy_read_timeout 300s;
    }
}
✅ 证书一条龙:sudo certbot --nginx -d your-domain.com,免费自动续期,无需自己处理证书。

7 限制与注意事项(Limitations)

实话实说:Pool 不是万能的,以下限制部署前就要想清楚。

限制说明应对
只能分散,不能突破总吞吐 = N 个 Key 配额之和,单 Key 限速依然存在按需加 Key,不要指望一个 Pool 变无限
同账号多 Key 可能共享配额xAI 政策以官方为准——部分 tier 下同一账号开的多个 Key 可能共用同一配额池,那 Pool 就等于白建❌ 部署前用不同账号各开一个 Key(实测最稳)
高并发触发滥用检测多 Key 同时高频打,可能触发官方风控,成批账号被审查/封禁控制总 QPS,观察配额消耗曲线,不要一次拉满
额外单点延迟经 Pool 多一跳,通常 +5~20ms,可接受但不是 0Pool 与调用方尽量同区域部署
流式/长连接要特殊处理SSE 流式要关缓冲、调大超时;长连接会话要会话保持Nginx 开 proxy_buffering off;LiteLLM 配 request_timeout
法律与 ToS 风险Key 共享、转售、多 Key 聚合是否违反 xAI 服务条款,要自己确认🟡 自用共享注意合规,商用转售掂量清楚
⚠️ 最容易被忽略的一条:「同账号多 Key 共享配额」——如果你发现 Pool 加了 Key 但总配额没有变,九成是这个原因。解法只有一句:用不同账号的 Key

8 监控与维护

部署完成只是开始。Key 会失效、配额会打满、账号会被风控——所以要有监控与维护流程。

8.1 日志轮替(logrotate)

/etc/logrotate.d/litellm
/var/log/litellm/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}
💡 systemd 服务直接看 journalctl -u litellm,配 journald.confSystemMaxUse=500M 防日志撑爆磁盘。

8.2 Prometheus 指标(LiteLLM 自带 /metrics)

指标名含义建议告警阈值
litellm_total_requests总请求数-
litellm_token_usage_totaltoken 用量(按模型分 label)日用量对比基线
litellm_remaining_quota各 Key 剩余配额🟡 低于 20% 告警
litellm_deployment_failures各 Key 失败次数❌ > 0 持续 5 分钟告警
litellm_deployment_latency延迟直方图P95 > 5s 告警
prometheus.yml 片段
scrape_configs:
  - job_name: litellm
    metrics_path: /metrics
    static_configs:
      - targets: ["127.0.0.1:4000"]

8.3 Key 轮换策略

quota-watch.sh(80% 用量告警示例)
#!/usr/bin/env bash
# 用 curl 查 Prometheus,剩低 <20% 就推告警(占位符自行替换)
THRESHOLD=20
QUOTA=$(curl -s "http://127.0.0.1:9090/api/v1/query" \
  --data-urlencode 'query=litellm_remaining_quota' | jq -r '.data.result[0].value[1]' 2>/dev/null)
[ -z "$QUOTA" ] && exit 0
if [ "$QUOTA" -lt "$THRESHOLD" ]; then
  curl -s "https://api.telegram.org/botYOUR_BOT_TOKEN/sendMessage" \
    -d "chat_id=YOUR_CHAT_ID" \
    -d "text=⚠️ Grok Key 剩余配额得 $QUOTA%"
fi

8.4 每分鐘狀態頁(探測節流)

💡 实操参考:本页配套的健康监控即按此模式实现——每 30 分钟一次真实探测 + 每分钟刷新状态数据,配额消耗可忽略。

9 踩坑合集(亲测经验)

这些都是从实战中捡回来的教训,直接照抄即可。

QLiteLLM 启动后报 "model not found"?

🔍 原因:请求入面的 model 名与 model_listmodel_name 不一致,或者 litellm_params.model 写错了上游模型名。

✅ 解决:① 用 curl http://127.0.0.1:4000/v1/models 看实际暴露的模型名;② 确认 litellm_params.model 用官方命名(例如 grok/grok-3);③ 改完 config 要重启:sudo systemctl restart litellm。还不行就开 set_verbose: true 看完整报错。

QNginx 轮询但所有请求都打到同一个 Key?

🔍 原因:① keepalive 连接复用,同一连接上的请求都走同一条路;② 没有真正做「按请求选 Key」,只是 upstream 层面的多 server(这个与 Key 轮换无关);③ Lua 游标 RR 在每个 worker 各自计数,请求少时好像「只是用同一个」。

✅ 解决:确认轮询逻辑在 rewrite_by_lua / balancer_by_lua 按请求执行;用 lua_shared_dict 存游标做跨 worker 计数;测试时并发 10 以上先看得出轮换(curl 单发很容易连续命中同一 worker)。

Q某个 Key 报 429,但 Pool 继续分派请求给它?

🔍 原因:① 未启用 enable_pre_call_checks(发送前不查配额);② allowed_fails 阈值太高,未到熔断线;③ 429 之后没有将失败记录下去(Nginx/Lua 版常见——没有写 header_filter_by_lua)。

✅ 解决:LiteLLM 开 enable_pre_call_checks: true,配 allowed_fails: 3 + cooldown_time: 60;自建/Nginx 版确保 429/401/503 都有计数逻辑。改完看日志确认该 Key 进入冷却。

QDocker 部署后无法连接 Grok API(DNS/网络问题)?

🔍 原因:① 容器 DNS 解析不到 api.x.ai(公司/机房 DNS 污染);② 容器出不到网(无外网路由);③ 全局代理环境变量 HTTP_PROXY 令容器走去不存在的代理。

✅ 解决:① 加 DNS:compose 入面 dns: ["1.1.1.1", "8.8.8.8"];② 测试 docker exec litellm curl -v https://api.x.ai 看卡在哪步;③ 检查 env | grep -i proxy,不要继承宿主代理;④ 公司网络封锁就经自己服务器代理出去。

Q流式回应(streaming)在 Pool 中断断续续?

🔍 原因:① 中间代理缓冲了 SSE 数据(Nginx 默认 proxy_buffering on);② 读超时太短,SSE 长连接被掐断;③ 网关把流式请求当普通请求处理,等成个 body 先返回。

✅ 解决:Nginx 加 proxy_buffering off + proxy_read_timeout 300s;LiteLLM 调大 request_timeout;自建网关确保 stream: true 走 StreamingResponse 直通,不要做重试(重试会打乱 SSE 顺序)。

Q客户端(AI Agent / 集成工具)请求报 "Duplicate tool names: web_search"?

🔍 原因:部分上游(例如 Grok console 通道)会自动注入原生 web_search 工具;如果客户端工具集自带同名 function 工具(Agent 类客户端几乎必然携带),上游会拒绝整个请求——400 invalid-argument。典型症状:普通 curl 测试正常,但接上 Agent 后所有请求 400 并静默降级到备用模型。

✅ 解决:① 在网关层过滤——把客户端发送的 function 版 web_search 转换为原生类型并去重(chenyme/grok2api 可修改 convertChatTools 后重新构建镜像,改完用独立 tag 部署以免被自动更新覆盖);② 或让客户端对该模型禁用 web_search 工具;③ 自建网关则在转发前对工具列表去重。改完记得重启网关进程(长驻进程会缓存旧配置,见下一题)。

Q改完配置后请求仍然打到旧地址 / 旧模型?

🔍 原因:① 长驻网关 / 代理进程在启动时缓存配置,修改 config 后未重启所以不生效;② 部分客户端的命令行参数(如 -m / --model不做别名解析,直接把参数名当作模型名发送;③ 配置的模型名不在 /v1/models 列表内,客户端校验直接拒绝。

✅ 解决:① 修改配置后重启网关进程(systemctl restartdocker compose up -d);② 别名用交互式命令切换(如 /model 别名),不要依赖 -m 参数;③ 先用 curl /v1/models 确认模型名真实存在,切换后核对日志中的 base_url 与模型名是否与预期一致。

Qcron 定时任务中浏览器启动失败("browser executable file path cannot be found")?

🔍 原因:cron 环境 PATH 极简(通常只有 /usr/bin:/bin),浏览器自动化库(如 DrissionPage)的自动探测找不到可执行文件。手动执行正常、定时执行失败,九成是这个原因。

✅ 解决:① 在脚本内显式扫描常见浏览器路径并调用 set_browser_path 指定;② 创建符号链接 /usr/bin/chromium → /usr/bin/chromium-browser;③ 脚本内全部使用绝对路径,并用 flock 防止任务重叠。

Q健康监控每分钟探测一次,配额很快就打光?

🔍 原因:真实 chat 探测会消耗配额;每分钟一次意味着每天 1440 次调用,会把 Pool 的总配额吃掉大半。

✅ 解决:探测节流——真实探测每 30~60 分钟一次即可;日常监控改读 admin API / 网关日志(请求数、错误数、配额窗口),页面只展示最近一次探测结果。页面每分钟刷新的是「状态数据」,不是「探测请求」。

10 常用指令速查表

指令作用
pip install -U "litellm[proxy]"安装 LiteLLM Proxy
litellm --config config.yaml --port 4000启动 LiteLLM(手动测试用)
sudo systemctl enable --now litellm注册 systemd 服务并启动
journalctl -u litellm -f实时看 LiteLLM 日志
curl http://127.0.0.1:4000/health/livelinessLiteLLM 健康检查
curl http://127.0.0.1:4000/v1/models列出对外模型名
curl -X POST http://127.0.0.1:4000/v1/chat/completions -H "Authorization: Bearer YOUR_MASTER_KEY" ...发测试请求
openresty -t && sudo systemctl reload openrestyNginx 语法检查 + 重载
docker compose up -d --build起 Docker 版网关
docker exec litellm curl -v https://api.x.ai容器内测上游连通性
openssl rand -hex 16生成随机密钥(Master Key 用)
chmod 600 .env收紧 .env 权限
logrotate -f /etc/logrotate.d/litellm手动触发日志轮替
grep -rn "sk-" . --include="*.py" --include="*.yaml"提交前自查有无泄漏真 Key
sudo certbot --nginx -d your-domain.com免费 HTTPS 证书一条龙
curl http://127.0.0.1:PORT/v1/models确认对外模型名(客户端校验依据)
/model 别名(客户端内交互命令)切换模型别名(部分 CLI 的 -m 参数不做别名解析)
systemctl restart 网关 / docker compose up -d修改配置后重启长驻网关进程使其生效

11 附录

11.1 文件路径总览(LiteLLM 方案)

目录结构
/opt/litellm/
├── config.yaml          # 路由配置(多 Key / 熔断 / fallback)
├── .env                 # 密钥(chmod 600,不入 Git)
├── venv/                # Python 虚拟环境
└── (Docker 方案则用 compose 管理)

/etc/systemd/system/litellm.service   # systemd 单元
/etc/logrotate.d/litellm              # 日志轮替
/etc/nginx/conf.d/grok-entry.conf     # 对外入口(HTTPS + 反代)

11.2 Grok API 相关限制(以官方 docs 为准)

项目参考值备注
模型grok-3 / grok-3-mini官方命名随时变,以 /v1/models 与 docs 为准
Context Windowgrok-3 约 128K token(参考)以官方 docs 最新值为准
Rate Limit视 tier 而定(RPM / TPM)在 console.x.ai 控制台看自己账号实际配额
定价按 token 计费以官方 pricing 页为准,Pool 层统一记录用量方便对账
配额刷新通常按 UTC 日重置监控脚本留意时区,不要在重置前一刻误报

11.3 部署完成清单(逐项打勾)

11.4 参考链接

💬 最后一句:Pool 部署好之后,记得定时看监控——Key 会失效、配额会打满,但只要你个告警在度,就永远不会「死得无声无色」。祝部署顺利,少踩坑!

附錄 B:帳戶自動化註冊實戰

本附錄補充「如何有效自動創建 Grok 帳戶」及建議頻率。所有指令與腳本均以實測為準。完整 16 步驟流程 + 智能工具鏈已收錄於獨立頁面:📄 完整註冊與系統工作流(本頁只保留精華摘要,避免雙線維護)。

B.1 每日兩批註冊機制

~/.hermes/scripts/grok-pool-batch.sh
#!/bin/bash
# 由 Hermes cron 呼叫,預設每批 5 個
exec ~/grok-pool/cron-batch.sh "${@:-5}"

B.2 重要修復與踩坑

tr -d '\r\n' 會把多個 token 連成一行
✅ 只去 \r(保留 \n 分隔):
sed -i 's/\r$//' accounts_*.txt
❌ cron 環境找不到 Chromium
browser_runtime.py 加入常見路徑掃描(同 cpa_xai/browser_session.py 做法)。

B.3 保養與重啟流程

B.4 配額觀察與暫停機制

當 console 配額接近 80% 時,建議暫停新增批次 48 小時,觀察現有帳戶的實際消耗。健康監察頁會在配額 gauge 顯示警戒線。

B.5 完整自動化指令速查(含 placeholder)

設定每日兩批 cron(04:00 / 16:00)
(crontab -l 2>/dev/null; echo ""; echo "# Grok 帳戶自動註冊批次"; \
echo "0 4 * * * /home/YOUR_USERNAME/.hermes/scripts/grok-pool-batch.sh 5"; \
echo "0 16 * * * /home/YOUR_USERNAME/.hermes/scripts/grok-pool-batch.sh 5") | crontab -
手動執行一批(例如 5 個帳戶)
cd /home/YOUR_USERNAME/grok-pool && ./cron-batch.sh 5
檢查最新一批 log
ls -t ~/grok-pool/logs/batch_*.log | head -1 | xargs tail -30
hermes 更新後重裝 picker patch
python3 /home/YOUR_USERNAME/grok-pool/reapply-picker-patch.py
重啟 gateway(systemd-run)
systemd-run --user --on-active=90s --unit=grok-restart \
bash /home/YOUR_USERNAME/grok-pool/restart-gateway.sh
⚠️ 注意:xAI 服務條款是否允許 Key 共享/轉售,請自行確認法律風險。本附錄僅描述技術實現。

B.6 完整系統工作流(2026-08-07 更新)

完整端到端流程(Cron → 註冊 → 匯入 → 監控 → 智能調度)請見獨立頁面:

2026-08-07 實測更新
① 已停止匯入 web 帳戶(DC IP 被 anti-bot 擋死,僅保留 console)——grok-pool-register.sh 只呼叫 /accounts/console/import
② 確認 grok-4.3Team Fingerprint RPM 硬鎖(~60/min,log 關鍵字 upstream_team_model_rate_limited)——加帳戶無法突破,需靠隊列整形 + 降級鏈。
③ 確認 grok2api 原生支援 tool-calling(OpenAI tools 透傳)——Hermes 可直接驅動池做真 agent。
④ 新增智能工具鏈:smart_gateway.py(熔斷 + 速率整形 + 降級鏈)、poc_agent.py(端到端 ReAct)、gateway_monitor.py(429 監控)、verify_phase1.py(驗收測試)。

附錄 C:将 Grok API Key 接入 Telegram 的注意事项

把 Grok API Key 接入 Telegram bot(或通过任何 Telegram 渠道传递 Key)之前,先读完这一节。核心原则只有一条:Key 一旦出现在任何 Telegram 聊天记录里,就按已泄露处理。以下为 2026-08-06 实测整理。

C.1 Key 永远不要出现在聊天记录中

C.2 用文件/环境变量保存,不硬编码

C.3 推荐做法:Key 收在网关后面,bot 只连网关

C.4 接入前检查清单

C.5 泄露处置

一句话总结:Key 收在网关、bot 只认网关地址;任何出现在聊天记录里的 Key 一律按泄露处理,立即吊销轮换。

附錄 D:监控与告警实战(零 API 成本)

本附錄记录本指南配套的监控与告警方案:全部数据来自被动来源(网关自带审计账本 + 管理 API + 本地 SQLite),不消耗任何上游配额。仪表板:system-monitor。2026-08-06 实测。

D.1 监控架构

D.2 被动审计统计(核心)

grok2api 自带审计账本 request_audits 表(SQLite,docker volume 内),每一条请求都记录 status_code / error_code / duration_ms / first_token_ms / total_tokens / client_key_name / account_name。collector 直接读表聚合,零上游成本:

D.3 防 spike / RPM 设置

通过管理 API 改运行参数(无需重启,restartRequired: [])。先 GET 拿全量配置与 revision,改完再 PUT:

PUT /api/admin/v1/settings
# 1) 登录拿 token
curl -X POST http://127.0.0.1:8001/api/admin/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"YOUR_ADMIN_PASSWORD"}'

# 2) GET 全量配置(拿到 revision)
# 3) 修改以下字段后再 PUT {"config": {...}, "revision": "0"}

routing:
  maxAttempts: 10        # 默认 999 —— 降级时 retry 风暴会打爆上游(429 雪崩)
  capacityWait: 1.5s     # 默认 500ms —— 账号全忙时排队代替硬撞
accounts:
  autoCleanReauthEnabled: true   # 自动清理需要重新登录的死账号

D.4 告警阈值(watchdog)

条件阈值说明
网关挂api_ok=false 或 status.json 超过 180 秒立即报警
1h 错误率爆升错误率 > 50% 且请求 ≥ 8上游故障 / 风控
429 风暴1h 内 429 ≥ 15RPM 被限,检查账号与 maxAttempts
配额用尽used_pct ≥ 80%Console 配额预警
reauth 突增reauth 账号 ≥ 8批量掉登录,需重新导入
probe 失败端到端探针返回失败推理链路异常

防噪音设计:同一条件需连续 2 次检查成立才报警;同类报警 30 分钟内不重复;条件消失即重置计数。cron:*/5 * * * * flock -n /tmp/grok-pool-watch.lock /usr/bin/python3 /home/YOUR_USERNAME/grok-pool/pool-watch.py

⚠️ 安全提醒:collector / watchdog 脚本内含管理密码与本地路径,切勿原样发布到公开仓库;本文档所有示例均已使用占位符。仪表板数据经 nginx 公开,status.json 不包含任何密钥。

附錄 E:免費生成圖像與影片(Console Route 實戰)

Grok 免費帳戶除聊天外,還附帶 Imagine 圖像(5/日)與影片(2/日)配額,經 Console 帳戶池(79 帳戶)可達每日 ~395 張圖 / ~158 段片,全部 $0。2026-08-08 實測。關鍵在於路由必須走 Console/ 前綴——默認的 grok-imagine-image 會路由到 Web 帳戶(datacenter IP 被 anti-bot 擋 → 502 upstream_unavailable)。

1. 免費配額總覽

能力Model(必須 Console/ 前綴)每帳戶/日79 帳戶池
ChatConsole/grok-4.310 請求790 請求
ImageConsole/grok-imagine-image5 張395 張
Image→VideoConsole/grok-imagine-video2 段158 段

2. 生圖(OpenAI 兼容)

POST /v1/images/generations
curl -X POST https://your-domain/v1/images/generations \
  -H "Authorization: Bearer YOUR_GROK_API_KEY" -H "Content-Type: application/json" -d '{
    "model": "Console/grok-imagine-image",   ← 必须 Console/ 前缀
    "prompt": "Tokyo alley, film look, 8k",
    "size": "1024x1536",                     ← 2:3 直向; 1:1=1024x1024
    "n": 1
  }'

3. 生片(Image-to-Video)

POST /v1/videos/generations
curl -X POST https://your-domain/v1/videos/generations \
  -H "Authorization: Bearer YOUR_GROK_API_KEY" -H "Content-Type: application/json" -d '{
    "model": "Console/grok-imagine-video",
    "prompt": "woman walks then jumps, slow motion",
    "image": {"url": "data:image/jpeg;base64,"},   ← 必须 HTTPS 或 data URL
    "aspect_ratio": "2:3"                                  ← 关键! 否则固定 16:9 会压扁直向图
  }'
# 返回 {"request_id":"video_xxx"} → 轮询状态
curl "https://your-domain/v1/videos/video_xxx" -H "Authorization: Bearer YOUR_GROK_API_KEY"
# {"status":"done","video":{"url":".../v1/videos/video_xxx/content"}} → 下载
curl "https://your-domain/v1/videos/video_xxx/content" -H "Authorization: Bearer YOUR_GROK_API_KEY" -o out.mp4

4. 踩坑清單(全部實測驗證)

5. 一鍵腳本 grok_gen.py(生圖/生片)

grok_gen.py(片段,完整版見本指南源倉)
用法:
  python3 grok_gen.py image "prompt" [-ar 2:3|16:9|1:1|9:16] [-o out.png]
  python3 grok_gen.py video "動作描述" [-i input.png] [-ar 2:3] [-o out.mp4]

核心邏輯(關鍵三行):
  body = {"model": "Console/grok-imagine-image", "prompt": prompt, "size": sizes.get(ar)}
  body = {"model": "Console/grok-imagine-video", "prompt": prompt,
          "image": {"url": "data:...;base64,..."}, "aspect_ratio": ar}
  # video 下载: urllib Request 带 Authorization header → /videos/{id}/content
💡 提示:所有請求走 OpenAI 兼容端點(/v1/images/generations/v1/videos/generations),可直接接入現有 OpenAI SDK;配額每日 UTC 窗口重置,79 帳戶 staggered 輪換。腳本已整合入 ~/grok-pool/tools/grok_gen.py