You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
10 KiB
10 KiB
LLM API 网关 (OneAPI) 与 Skill 模型路由客户端
文档版本: 2026-03-16 用途: 供 AI 与后续维护人员理解 OneAPI 网关部署与 Skills 共享 LLM 客户端的架构、功能与使用方式。
1. 架构概览
- OneAPI 网关:独立于 OpenClaw 进程的 Docker 服务,对外提供 OpenAI 兼容的 Chat Completions API,实现多模型统一管理、按需路由与跨服迁移(迁移时打包
infrastructure/oneapi/data即可无损恢复)。 - Skill 共享客户端:
skills/shared/llm_client.js供视觉、Coding、金融等 Skill 按「模型名」调用网关,通过环境变量LLM_BASE_URL、LLM_API_KEY配置,与现有 remote-blueprints 的 Agent 配置命名一致。
┌─────────────────────────────────────────────────────────────────┐
│ Skills (daily-horoscope, tavily, 视觉/Coding/金融 等) │
│ require('../shared/llm_client').callSpecificModel(model, msgs) │
└─────────────────────────────┬─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ skills/shared/llm_client.js │
│ - 读取 LLM_BASE_URL, LLM_API_KEY │
│ - URL 智能拼接、超时(默认 60s)、错误解析与 [LLM_Client] 日志 │
└─────────────────────────────┬─────────────────────────────────────┘
│ HTTP POST /v1/chat/completions
▼
┌─────────────────────────────────────────────────────────────────┐
│ OneAPI (openclaw-llm-gateway) │
│ - 绑定 TAILSCALE_IP:3000,仅内网访问 │
│ - 数据持久化: ./data → SQLite │
└─────────────────────────────────────────────────────────────────┘
2. 文件与目录结构
2.1 OneAPI 基础设施(独立于 OpenClaw)
| 路径 | 说明 |
|---|---|
workspace/infrastructure/oneapi/docker-compose.yml |
服务定义:镜像 justsong/one-api:latest,容器名 openclaw-llm-gateway,端口 ${TAILSCALE_IP}:3000:3000,数据卷 ./data:/data,时区 TZ=Asia/Shanghai。 |
workspace/infrastructure/oneapi/.env.example |
环境变量模板,仅 TAILSCALE_IP=xxx.xxx.xxx.xxx,需改为本机 Tailscale IP。 |
workspace/infrastructure/oneapi/deploy_gateway.sh |
部署脚本:先切换到脚本所在目录(CWD 无关),若无 .env 则从 .env.example 复制,再执行 docker compose up -d,并打印管理后台 URL 与默认账密(root/123456)。需 chmod +x。 |
workspace/infrastructure/oneapi/data/ |
运行时由 Docker 创建,持久化 OneAPI 的 SQLite;迁移时打包此目录即可恢复。 |
2.2 Skill 共享客户端
| 路径 | 说明 |
|---|---|
workspace/skills/shared/llm_client.js |
共享模块:导出 callSpecificModel(modelName, messages, options),无 npm 依赖,仅依赖 Node 内置 fetch(Node 18+)。 |
3. 环境变量(与 Agent 配置对齐)
| 变量 | 说明 | 使用处 |
|---|---|---|
LLM_BASE_URL |
网关基础 URL,如 http://100.x.x.x:3000;可带或不带 /v1,客户端会智能拼接。 |
llm_client.js、remote-blueprints 的 Agent 模型配置 |
LLM_API_KEY |
OneAPI 分配的 API Key(在 OneAPI 管理后台创建)。 | llm_client.js、Agent 模型配置 |
TAILSCALE_IP |
本机 Tailscale IP,用于 OneAPI 端口绑定与访问地址。 | infrastructure/oneapi/.env、deploy_gateway.sh |
4. 部署 OneAPI 网关
- 进入目录:
cd workspace/infrastructure/oneapi(或从任意路径执行./infrastructure/oneapi/deploy_gateway.sh,脚本会自行切换到所在目录)。 - 若首次部署且无
.env,脚本会从.env.example复制;务必编辑.env将TAILSCALE_IP改为本机真实 Tailscale IP,否则端口可能绑定失败或无法访问。 - 执行:
./deploy_gateway.sh。 - 访问管理后台:
http://<TAILSCALE_IP>:3000,默认登录 root / 123456;在后台添加渠道与模型并创建 API Key,将 Key 填入使用方的LLM_API_KEY。
5. Skill 侧使用 llm_client
5.1 基本用法
const { callSpecificModel } = require('../shared/llm_client'); // 路径按实际 Skill 位置调整
const messages = [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Hello' },
];
const response = await callSpecificModel('qwen3.5-plus', messages, {
temperature: 0.7,
max_tokens: 2048,
timeoutMs: 120000, // 可选,默认 60000
});
// response 为 OpenAI 兼容的 JSON,如 { choices: [...], usage: {...} }
const text = response.choices?.[0]?.message?.content ?? '';
5.2 行为与约束
- URL 智能拼接:若
LLM_BASE_URL已以/v1结尾(如http://100.x:3000/v1),则只拼接/chat/completions;否则拼接/v1/chat/completions,避免出现/v1/v1/chat/completions导致 404。 - 超时:默认 60 秒,可通过
options.timeoutMs覆盖;超时后抛出带code: 'ETIMEDOUT'的 Error,便于 Skill 降级。 - 仅支持非流式:当前实现不支持
stream: true,传入stream: true会抛出配置错误;流式需后续扩展或由 Skill 自行请求网关。 - 参数:
messages必须为数组;options中除timeoutMs外(仅客户端使用)会原样传给 API(如temperature、max_tokens)。
6. 错误处理与日志
- HTTP 非 200:客户端会尝试解析响应体中的
error.message或message(兼容 OneAPI/OpenAI 格式),将摘要写入抛出 Error 的message与cause,并在控制台打印[LLM_Client] Error calling <modelName>: <摘要>,便于在 OpenClaw Gateway 日志中直接看到失败原因。 - 超时:抛出
Error,code: 'ETIMEDOUT',并打印[LLM_Client] Error calling <modelName>: timeout (<timeoutMs>ms)。 - 配置错误:未设置
LLM_BASE_URL/LLM_API_KEY、messages非数组、stream: true等,抛出带code: 'LLM_CLIENT_CONFIG'的 Error。
7. 与现有系统关系
- Agent 的
models.providers.default_llm.baseUrl已指向同一 OneAPI 实例(http://100.115.94.1:3000/v1),Chat 请求统一由 OneAPI 路由。 - 与
workspace/remote-blueprints/template/.env.tpl中的LLM_BASE_URL、LLM_API_KEY、LLM_MODEL_ID、EMBEDDING_MODEL_ID命名一致;Skill 侧通过callSpecificModel按模型名路由,Agent 侧使用LLM_MODEL_ID作为默认模型。
8. mem0 记忆系统与 OneAPI 的集成(2026-03-16)
mem0-integration Skill 的 LLM 和 Embedder 也全面切换到 OneAPI 网关,不再直连 DashScope。
8.1 完整请求路径
用户消息
│
├─→ OpenClaw Agent 对话 ──→ default_llm/MiniMax-M2.5 ──→ OneAPI :3000
│ │
│ 路由到渠道
│
└─→ mem0-integration plugin (Python 子进程)
│
├─ Pre-Hook: Embedder (text-embedding-v4) ──→ OneAPI :3000
│ 向量化查询 → Qdrant 检索
│
└─ Post-Hook: LLM (MiniMax-M2.5) ──→ OneAPI :3000
提取/合并记忆 → Embedder → Qdrant 写入
8.2 LLM 与 Embedder 的分工
| 模型 | 分工 | 调用时机 |
|---|---|---|
LLM (MiniMax-M2.5) |
从对话中提取有价值的记忆;去重/合并已有记忆;生成结构化记忆摘要 | Post-Hook 写入时(后台异步) |
Embedder (text-embedding-v4) |
将文本向量化(1024 维);写入 Qdrant + Pre-Hook 检索时均需调用 | 读写均需 |
mem0 中 LLM 和 Embedder 相互独立,可以使用不同模型。当前两者都走 OneAPI,但 OneAPI 内部可为 Chat 和 Embedding 配置不同渠道。
8.3 环境变量传递路径
/.openclaw/.env
LLM_BASE_URL=http://100.115.94.1:3000/v1
LLM_API_KEY=sk-...
LLM_MODEL_ID=MiniMax-M2.5
EMBEDDING_MODEL_ID=text-embedding-v4
│
▼ OpenClaw Gateway 加载 .env → process.env
│
▼ index.js: spawn(python, args, { env: process.env })
│
▼ mem0_client.py 模块加载时
OPENAI_BASE_URL ← LLM_BASE_URL
OPENAI_API_KEY ← LLM_API_KEY
LLM model ← LLM_MODEL_ID
Embedder model ← EMBEDDING_MODEL_ID
8.4 systemd 服务配置说明
/etc/systemd/system/openclaw-gateway.service 已移除原来的三行硬编码 DashScope 环境变量:
# 已移除(不再需要):
# Environment=MEM0_DASHSCOPE_API_KEY=sk-...
# Environment=OPENAI_API_BASE=https://dashscope.aliyuncs.com/...
# Environment=OPENAI_BASE_URL=https://dashscope.aliyuncs.com/...
API 端点和密钥现在完全由 .env 文件管理,通过 OpenClaw→Python 子进程链传递,与 Agent 配置保持单一来源。
9. 修复与审查记录
- llm_client.js:增加
messages数组校验;明确拒绝stream: true并抛出配置错误,避免对流式响应调用response.json()导致异常;parseErrorBody支持error为字符串的网关格式;对LLM_BASE_URL/LLM_API_KEY做.trim()避免 .env 尾随空格。 - deploy_gateway.sh:逻辑与目录穿透已按计划实现,无需修改;文档中强调首次部署后须编辑
.env设置真实TAILSCALE_IP。 - 文档:本文件汇总架构、文件结构、环境变量、部署步骤、Skill 使用方式、错误与日志、与现有系统关系,便于 AI 与维护人员查阅。