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

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_URLLLM_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 网关

  1. 进入目录:cd workspace/infrastructure/oneapi(或从任意路径执行 ./infrastructure/oneapi/deploy_gateway.sh,脚本会自行切换到所在目录)。
  2. 若首次部署且无 .env,脚本会从 .env.example 复制;务必编辑 .envTAILSCALE_IP 改为本机真实 Tailscale IP,否则端口可能绑定失败或无法访问。
  3. 执行:./deploy_gateway.sh
  4. 访问管理后台: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(如 temperaturemax_tokens)。

6. 错误处理与日志

  • HTTP 非 200:客户端会尝试解析响应体中的 error.messagemessage(兼容 OneAPI/OpenAI 格式),将摘要写入抛出 Error 的 messagecause,并在控制台打印 [LLM_Client] Error calling <modelName>: <摘要>,便于在 OpenClaw Gateway 日志中直接看到失败原因。
  • 超时:抛出 Errorcode: 'ETIMEDOUT',并打印 [LLM_Client] Error calling <modelName>: timeout (<timeoutMs>ms)
  • 配置错误:未设置 LLM_BASE_URL/LLM_API_KEYmessages 非数组、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_URLLLM_API_KEYLLM_MODEL_IDEMBEDDING_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 与维护人员查阅。