From a35ce7cc93e8d439a9eb97776c5f0bc51386ae63 Mon Sep 17 00:00:00 2001 From: bigemon Date: Fri, 10 Apr 2026 09:43:33 +0800 Subject: [PATCH] =?UTF-8?q?Initial:=20LiteLLM=20Gateway=20=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E9=AA=A8=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - config.yaml: MiniMax M2.7/M2.5/Lightning 三层路由 + fallback - run.sh: 启动脚本 - .env.example: 环境变量模板 - TODO.md: 完整项目规划与待办 - docs/: 部署指南、配置说明、Skill 接入文档 --- .env.example | 21 +++++ README.md | 47 ++++++++++ TODO.md | 168 +++++++++++++++++++++++++++++++++++ config.yaml | 71 +++++++++++++++ docs/DEPLOYMENT.md | 163 ++++++++++++++++++++++++++++++++++ docs/SKILL_INTEGRATION.md | 180 ++++++++++++++++++++++++++++++++++++++ run.sh | 34 +++++++ 7 files changed, 684 insertions(+) create mode 100644 .env.example create mode 100644 README.md create mode 100644 TODO.md create mode 100644 config.yaml create mode 100644 docs/DEPLOYMENT.md create mode 100644 docs/SKILL_INTEGRATION.md create mode 100644 run.sh diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..93c5c79 --- /dev/null +++ b/.env.example @@ -0,0 +1,21 @@ +# ============================ +# LiteLLM Gateway — 环境变量 +# ============================ +# 复制本文件为 .env,然后填入真实值 + +# MiniMax API Key(真实 key,仅保存在网关侧,不暴露给 agent) +MINIMAX_API_KEY=sk-your-minimax-api-key + +# LiteLLM Master Key(管理员 key,用于管理接口) +# 必须以 sk- 开头 +LITELLM_MASTER_KEY=sk-litellm-admin-key-change-this + +# 数据库(可选,默认 SQLite) +# DATABASE_URL=postgresql://user:password@host:5432/litellm + +# 日志级别 +# LITELLM_LOG_LEVEL=INFO + +# 其他可选 +# LITELLM_DROP_PARAMS=true +# LITELLM_MAX_PARALLEL_REQUESTS=100 diff --git a/README.md b/README.md new file mode 100644 index 0000000..8ccbde0 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# LiteLLM Gateway + +## 定位 + +MiniMax 模型 API 网关,为整个 agent 集群提供: +- 🔐 **安全代理** — 真实 API Key 不暴露给 agent +- 🛡️ **额度管控** — per-key RPM/TPM 限制,防止滥用 +- 🔄 **智能回落** — M2.7 → M2.5 → M2.5-Lightning 自动切换 +- 📊 **用量追踪** — 实时 API 调用日志与消费统计 +- 🔥 **热更新** — key 管理/模型添加完全热生效,Sileya 的 key 配置不受影响 + +## 架构 + +``` +OpenClaw Agent (Sileya / 李狗蛋 / 妮可 ...) + → sk-agent-key (LiteLLM Virtual Key) + → LiteLLM Proxy (:4000) + ├── 额度检查 / 用量记录 + ├── 智能路由 + fallback + └── MINIMAX_API_KEY (仅此处持有) + → api.minimax.io +``` + +## 部署 + +### 环境要求 +- Python 3.9+ +- 独立服务器或轻量容器(不强制 Docker) +- 推荐:OMV (Nas) / Proxmox 容器 / 任意 VPS + +### 快速启动 +```bash +pip install litellm + +# 配置环境变量 +export MINIMAX_API_KEY="sk-xxx" +export LITELLM_MASTER_KEY="sk-litellm-admin-key" + +# 启动 +uvicorn litellm_proxy:app --host 0.0.0.0 --port 4000 +``` + +## 文档 +- [TODO](./TODO.md) — 项目规划与待办 +- [CONFIG_GUIDE](./docs/CONFIG_GUIDE.md) — 配置说明 +- [DEPLOYMENT](./docs/DEPLOYMENT.md) — 部署指南 +- [SKILL_INTEGRATION](./docs/SKILL_INTEGRATION.md) — Sileya Skill 接入 diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..ff3a4ac --- /dev/null +++ b/TODO.md @@ -0,0 +1,168 @@ +# TODO — LiteLLM Gateway + +> 建立时间:2026-04-10 +> 负责人:西莉雅 (Sileya) + +--- + +## 背景 + +### 问题 +- MiniMax M2.7 频繁返回 529(服务过载),导致 session 被 terminate +- Agent 的 API Key 存在泄漏风险(直接写在配置里) +- 没有额度管控,agent 滥用无法控制 +- 缺少统一日志,无法追踪用量 + +### 目标 +在 OMV(Nas/Proxmox)节点上部署 LiteLLM Gateway,实现: +1. MiniMax API 安全代理(key 集中管理) +2. 模型自动回落(M2.7 → M2.5 → M2.5-Lightning) +3. per-key 额度管控 +4. 完整 API 管理接口(用量查询、key 生成/封禁) +5. Sileya Skill 化(通过 API 动态管理) + +--- + +## 部署规划 + +### 部署节点 +- **OMV (Open Media Vault)** — 运行在 NAS 上的 Proxmox 容器 +- 或者直接跑在 Nas 本身(推荐,更简单) + +### 模型路由策略 +``` +优先: MiniMax-M2.7 + ↓ 529 / 超时 / 500 +备用: MiniMax-M2.5 + ↓ 529 / 超时 / 500 +兜底: MiniMax-M2.5-Lightning +``` + +### 双 Key 隔离 +- `sk-sileya-fixed` — 西莉雅的专属 key,指向固定 model group,**不动 config.yaml 就永远不受影响** +- `sk-admin-*` — 管理员 key,可动态管理其他 key + +### 热更新策略 +| 操作 | 是否需要重启 | +|------|------------| +| `/key/generate` 生成新 key | ❌ 不需要 | +| `/key/block` 封禁 key | ❌ 不需要 | +| `/model/new` 动态加模型 | ❌ 不需要 | +| 改 fallback 策略 / 模型顺序 | ⚠️ 需要(但不频繁,重启 < 5s)| + +--- + +## 待办事项 + +### P0 — 必须完成(网关可用) +- [ ] **DEPLOY-01**: 在 OMV/Nas 上安装 Python 环境 + pip install litellm +- [ ] **DEPLOY-02**: 配置 `config.yaml`(MiniMax provider + fallback 路由 + virtual key) +- [ ] **DEPLOY-03**: 配置 `.env`(MINIMAX_API_KEY + LITELLM_MASTER_KEY) +- [ ] **DEPLOY-04**: 启动验证 — curl 测试 `/health` +- [ ] **DEPLOY-05**: OpenClaw 接入 — 修改 `openclaw.json` 的 model provider 指向 LiteLLM + +### P1 — 管控能力 +- [ ] **MGMT-01**: 生成各 agent 的专属 key(`sk-sileya-fixed`、`sk-ligoudan`、`sk-nico`) +- [ ] **MGMT-02**: 配置 per-key RPM 限制(各 agent 独立额度) +- [ ] **MGMT-03**: Sileya Skill — `lite-llm-admin`(用量查询、key 管理接口) +- [ ] **MGMT-04**: 验证 hot reload — 测试 `/key/generate` 不影响 Sileya session + +### P2 — 安全加固 +- [ ] **SEC-01**: 网络隔离 — LiteLLM 仅内网可访问,Tailscale/ZeroTier 组网 +- [ ] **SEC-02**: 确认 Sileya 的 key 配置在 `config.yaml` 固定区域,不参与动态更新 +- [ ] **SEC-03**: 审计日志 — 确认所有请求记录到数据库 + +### P3 — 可选优化 +- [ ] **OPT-01**: LiteLLM Dashboard(`:4000/ui`)启用,Web UI 管理 +- [ ] **OPT-02**: Prometheus metrics 接入(Grafana 监控) +- [ ] **OPT-03**: 多 provider 预留 — 对接其他 LLM(Claude/GPT)时网关层无需修改 + +--- + +## 关键配置 + +### config.yaml 核心结构 +```yaml +model_list: + - model_name: MiniMax-M2.7 + litellm_params: + model: minimax/MiniMax-M2.7 + api_key: os.environ/MINIMAX_API_KEY + api_base: https://api.minimax.io/v1 + rpm: 60 + + - model_name: MiniMax-M2.5 + litellm_params: + model: minimax/MiniMax-M2.5 + api_key: os.environ/MINIMAX_API_KEY + api_base: https://api.minimax.io/v1 + rpm: 60 + + - model_name: MiniMax-M2.5-Lightning + litellm_params: + model: minimax/MiniMax-M2.5-Lightning + api_key: os.environ/MINIMAX_API_KEY + api_base: https://api.minimax.io/v1 + rpm: 120 + +router_settings: + fallback_params: [{"model": ["MiniMax-M2.7", "MiniMax-M2.5", "MiniMax-M2.5-Lightning"]}] + num_retries: 3 + retry_after: 5 + timeout: 30 + +general_settings: + master_key: os.environ/LITELLM_MASTER_KEY +``` + +### Sileya Key 专属配置(不参与动态更新) +```yaml +# config.yaml 中的 sileya 专属区 +# 此区域修改需要重启,但这种情况极低频 +``` + +--- + +## API 接口 + +### 管理 API(admin key) +``` +POST /key/generate — 生成新 key +GET /key/info?key=sk-xxx — 查询 key 用量 +GET /spend — 查询总用量 +POST /key/block — 封禁 key +POST /key/unblock — 解封 key +POST /model/new — 动态添加模型(热生效) +``` + +### 对外 API(agent 使用) +``` +POST /v1/chat/completions — 标准 OpenAI 兼容接口 +GET /health — 健康检查 +``` + +--- + +## 目录结构 +``` +litellm-gateway/ +├── README.md +├── TODO.md +├── config.yaml # 主配置 +├── .env.example # 环境变量模板 +├── requirements.txt # Python 依赖 +├── run.sh # 启动脚本 +└── docs/ + ├── CONFIG_GUIDE.md + ├── DEPLOYMENT.md + └── SKILL_INTEGRATION.md +``` + +--- + +## 里程碑 + +- [ ] **M1**: LiteLLM 在 OMV 上跑通,health check 通过 +- [ ] **M2**: Sileya 通过 LiteLLM 代理访问 MiniMax,fallback 验证通过 +- [ ] **M3**: 所有 agent 迁移到独立 key 体系 +- [ ] **M4**: Sileya Skill `lite-llm-admin` 可用,日常管理无需手动操作 diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..91d5425 --- /dev/null +++ b/config.yaml @@ -0,0 +1,71 @@ +# ============================================ +# LiteLLM Gateway — config.yaml +# ============================================ +# MiniMax 模型路由配置 +# 完整文档: https://docs.litellm.ai/docs/proxy/configs + +model_list: + # ── MiniMax M2.7 (优先) ────────────────────── + - model_name: MiniMax-M2.7 + litellm_params: + model: minimax/MiniMax-M2.7 + api_key: os.environ/MINIMAX_API_KEY + api_base: https://api.minimax.io/v1 + rpm: 60 + model_info: + mode: chat + supports_function_calling: true + + # ── MiniMax M2.5 (备用) ────────────────────── + - model_name: MiniMax-M2.5 + litellm_params: + model: minimax/MiniMax-M2.5 + api_key: os.environ/MINIMAX_API_KEY + api_base: https://api.minimax.io/v1 + rpm: 60 + model_info: + mode: chat + supports_function_calling: true + + # ── MiniMax M2.5-Lightning (兜底) ─────────── + - model_name: MiniMax-M2.5-Lightning + litellm_params: + model: minimax/MiniMax-M2.5-Lightning + api_key: os.environ/MINIMAX_API_KEY + api_base: https://api.minimax.io/v1 + rpm: 120 + model_info: + mode: chat + +# ── 路由设置 ─────────────────────────────────── +router_settings: + # 失败后按顺序回落 + fallback_params: + - model: + - MiniMax-M2.7 + - MiniMax-M2.5 + - MiniMax-M2.5-Lightning + # 每个模型重试次数 + num_retries: 3 + # 重试前等待秒数 + retry_after: 5 + # 单次请求超时(秒) + timeout: 30 + # 路由策略:优先用最好的模型 + routing_strategy: latency-based-routing + +# ── 全局设置 ─────────────────────────────────── +litellm_settings: + drop_params: true + set_verbose: false + # 每次请求记录到数据库 + success_callback: ["database"] + +# ── 服务器设置 ───────────────────────────────── +general_settings: + # 管理员 master key(必须以 sk- 开头) + master_key: os.environ/LITELLM_MASTER_KEY + # 数据库(SQLite 轻量版,生产推荐 PostgreSQL) + database_url: "sqlite:///./litellm.db" + # UI 管理界面 + ui_access_mode: "admin" diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md new file mode 100644 index 0000000..f21fdb6 --- /dev/null +++ b/docs/DEPLOYMENT.md @@ -0,0 +1,163 @@ +# 部署指南 + +## 目标节点 + +**OMV (Open Media Vault) on NAS / Proxmox** + +推荐直接跑在 Nas 上,不强制 Docker,直接 Python 运行。 + +--- + +## 步骤 1 — 环境准备 + +### 检查 Python 版本 +```bash +python3 --version # 需要 >= 3.9 +``` + +### 创建用户(可选,推荐) +```bash +useradd -m -s /bin/bash litellm +su - litellm +mkdir -p ~/litellm-gateway +``` + +--- + +## 步骤 2 — 安装依赖 + +```bash +pip install litellm +``` + +可选: +```bash +pip install uvicorn[standard] # ASGI 服务器(生产推荐) +``` + +--- + +## 步骤 3 — 配置 + +```bash +cd ~/litellm-gateway + +# 复制环境变量模板 +cp .env.example .env + +# 编辑 .env,填入真实值 +nano .env +``` + +**必须设置的值:** +- `MINIMAX_API_KEY` — MiniMax 真实 API Key +- `LITELLM_MASTER_KEY` — 管理员 key(以 `sk-` 开头) + +--- + +## 步骤 4 — 启动 + +```bash +chmod +x run.sh +./run.sh +``` + +**后台运行(生产):** +```bash +# nohup +nohup ./run.sh > logs/litellm.log 2>&1 & + +# 或用 systemd(见下方) +``` + +--- + +## 步骤 5 — 验证 + +```bash +# 健康检查 +curl http://localhost:4000/health + +# 测试 chat completions +curl -X POST http://localhost:4000/v1/chat/completions \ + -H "Authorization: Bearer sk-your-master-key" \ + -H "Content-Type: application/json" \ + -d '{ + "model": "MiniMax-M2.7", + "messages": [{"role": "user", "content": "Hello"}] + }' +``` + +--- + +## 步骤 6 — OpenClaw 接入 + +在 `~/.openclaw/openclaw.json` 中修改 MiniMax provider: + +```json +{ + "providers": { + "minimax": { + "apiKey": "sk-your-minimax-api-key" + }, + "minimax-portal": { + "apiKey": "sk-your-litellm-key", + "baseURL": "http://:4000/v1" + } + } +} +``` + +> ⚠️ 注意:LiteLLM 使用 OpenAI 兼容接口,所以 OpenClaw 的 `minimax-portal` provider 可以直接指向 LiteLLM 的 `/v1` 端点。 + +--- + +## systemd 服务(OMV 持久化) + +```ini +# /etc/systemd/system/litellm.service +[Unit] +Description=LiteLLM Gateway +After=network.target + +[Service] +Type=simple +User=litellm +WorkingDirectory=/home/litellm/litellm-gateway +ExecStart=/home/litellm/litellm-gateway/run.sh +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +``` + +```bash +sudo systemctl daemon-reload +sudo systemctl enable litellm +sudo systemctl start litellm +``` + +--- + +## 网络访问控制 + +### 仅内网访问(推荐) +确保 LiteLLM 的端口 `:4000` 不暴露到公网。 + +### Tailscale / ZeroTier 组网(推荐) +```bash +# 在服务器上安装 Tailscale +curl -fsSL https://tailscale.com/install.sh | sh +tailscale up --accept-routes + +# OpenClaw 节点也加入同一网络 +# 然后 LiteLLM 只监听 Tailscale IP(如 100.64.x.x:4000) +``` + +### 防火墙规则(OMV) +```bash +# 只允许内网段访问 4000 +iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 4000 -j ACCEPT +iptables -A INPUT -p tcp --dport 4000 -j DROP +``` diff --git a/docs/SKILL_INTEGRATION.md b/docs/SKILL_INTEGRATION.md new file mode 100644 index 0000000..704a6c0 --- /dev/null +++ b/docs/SKILL_INTEGRATION.md @@ -0,0 +1,180 @@ +# Sileya Skill 接入 — lite-llm-admin + +## 目标 + +Sileya 持有 admin key,可以通过 API 管理 LiteLLM Gateway: +- 查询各 agent 用量 +- 生成/封禁 key +- 动态调整 fallback 策略 +- 监控网关健康状态 + +--- + +## Skill 核心接口 + +### 基础信息 +``` +Base URL: http://:4000 +Admin Key: sk-litellm-admin-key(西莉雅持有) +Header: Authorization: Bearer +``` + +### API 列表 + +#### 1. 生成新 agent key +```http +POST /key/generate +Content-Type: application/json +Authorization: Bearer + +{ + "models": ["MiniMax-M2.7", "MiniMax-M2.5", "MiniMax-M2.5-Lightning"], + "metadata": { + "agent": "李狗蛋", + "owner": "sileya" + } +} + +Response: +{ + "key": "sk-litellm-xxxxx", + "expires": null, + "models": ["MiniMax-M2.7", "MiniMax-M2.5", "MiniMax-M2.5-Lightning"] +} +``` + +#### 2. 查询 key 用量 +```http +GET /key/info?key=sk-litellm-xxxxx +Authorization: Bearer + +Response: +{ + "key": "sk-litellm-xxxxx", + "spend": 0.0001065, + "models": [...], + "expires": null +} +``` + +#### 3. 查询总用量 +```http +GET /spend +Authorization: Bearer + +Response: +{ + "total_spend": 12.345, + "key_spends": [ + {"key": "sk-litellm-xxxxx", "spend": 5.123, "agent": "李狗蛋"}, + {"key": "sk-litellm-yyyyy", "spend": 7.222, "agent": "妮可"} + ] +} +``` + +#### 4. 封禁 key +```http +POST /key/block +Content-Type: application/json +Authorization: Bearer + +{ + "key": "sk-litellm-xxxxx" +} +``` + +#### 5. 解封 key +```http +POST /key/unblock +Content-Type: application/json +Authorization: Bearer + +{ + "key": "sk-litellm-xxxxx" +} +``` + +#### 6. 动态添加模型(热生效) +```http +POST /model/new +Content-Type: application/json +Authorization: Bearer + +{ + "model_name": "gpt-4o", + "litellm_params": { + "model": "openai/gpt-4o", + "api_key": "sk-openai-xxx", + "rpm": 60 + } +} +``` + +--- + +## Sileya Skill 实现 + +```python +# SKILL.md 核心逻辑 + +import requests +import os + +LITELLM_BASE = os.environ["LITELLM_BASE_URL"] # http://:4000 +ADMIN_KEY = os.environ["LITELLM_ADMIN_KEY"] + +def _headers(): + return {"Authorization": f"Bearer {ADMIN_KEY}", "Content-Type": "application/json"} + +def generate_agent_key(agent_name: str, models: list[str]): + """给新 agent 分配独立 key""" + resp = requests.post( + f"{LITELLM_BASE}/key/generate", + headers=_headers(), + json={"models": models, "metadata": {"agent": agent_name}} + ) + resp.raise_for_status() + return resp.json()["key"] + +def get_all_spend(): + """查询总用量""" + resp = requests.get(f"{LITELLM_BASE}/spend", headers=_headers()) + resp.raise_for_status() + return resp.json() + +def block_agent_key(key: str): + """封禁某 agent 的 key""" + resp = requests.post( + f"{LITELLM_BASE}/key/block", + headers=_headers(), + json={"key": key} + ) + resp.raise_for_status() + +def get_key_info(key: str): + """查询单个 key 详情""" + resp = requests.get( + f"{LITELLM_BASE}/key/info", + headers=_headers(), + params={"key": key} + ) + resp.raise_for_status() + return resp.json() +``` + +--- + +## 热更新保障 + +Sileya 的 key 配置(`sk-sileya-fixed`)在 `config.yaml` 中固定。管理员通过 API 修改其他 key 时,Sileya 的 key 完全不受影响。 + +只有修改 `config.yaml` 本身的模型路由策略时需要重启网关,但这种情况极低频(可能一个月一次),且重启 < 5 秒。 + +--- + +## 使用场景 + +1. **新 agent 上线** → Sileya 调用 `/key/generate` 生成专属 key +2. **发现异常用量** → Sileya 调用 `/key/info` 查询,必要时 `/key/block` +3. **月初对账** → Sileya 调用 `/spend` 汇总所有 agent 消费 +4. **529 高峰期** → Sileya 监控 fallback 情况,确认回落正常 diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..5da7f18 --- /dev/null +++ b/run.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# LiteLLM Gateway 启动脚本 + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# 加载环境变量 +if [ -f ".env" ]; then + export $(grep -v '^#' .env | xargs) +else + echo "ERROR: .env 文件不存在,请复制 .env.example 为 .env 并填写" + exit 1 +fi + +# 检查必要变量 +if [ -z "$MINIMAX_API_KEY" ]; then + echo "ERROR: MINIMAX_API_KEY 未设置" + exit 1 +fi + +if [ -z "$LITELLM_MASTER_KEY" ]; then + echo "ERROR: LITELLM_MASTER_KEY 未设置" + exit 1 +fi + +echo "=== LiteLLM Gateway 启动中 ===" +echo "端口: 4000" +echo "模型: MiniMax-M2.7 / M2.5 / M2.5-Lightning" +echo "" + +# 启动 +uvicorn litellm_proxy:app --host 0.0.0.0 --port 4000 --log-level info