9Router 通用工具集成指南:通过 OpenAI 兼容 API 连接任意 LLM 应用
9Router 对外提供标准的 OpenAI 兼容 API 端点(/v1),任何支持 OpenAI API 格式的工具、脚本与开发框架都可以零改造接入,从而统一使用 9Router 背后聚合的 Claude、DeepSeek、GLM 等数十家提供商能力。本文以官方集成文档(gitbook/content/es/integration/other-tools.md)为主线,结合仓库源码讲解通用配置模式、各语言 SDK 接入示例、自定义脚本编写、故障排查与最佳实践,读完后你可以在自己的项目或工具链中直接落地一套可用的 9Router 接入方案。
概述:一个端点,兼容万物
9Router 将"模型网关 + 多账户路由 + 自动回退"能力封装为一个与 OpenAI API 兼容的服务端点。文档明确指出:凡是支持 OpenAI API 格式的工具都能连接 9Router,典型场景包括:
- 自研脚本与自定义应用
- API 客户端与接口测试工具
- CLI 工具与命令行实用程序
- 第三方集成
- 开发框架(如 LangChain、LlamaIndex)
从源码层面看,9Router 的 OpenAI 兼容层是真实存在的独立路由集合:src/app/api/v1/ 下提供了 chat/completions、models、responses、embeddings、images/generations、audio/speech 等标准端点。默认运行时端口为 20128(见 .env.example 中的 PORT=20128 与 CLAUDE.md 中"Default runtime port is 20128"的说明),dashboard 与 API 分别位于 /dashboard 与 /v1。
通用配置模式
任何 OpenAI 兼容工具只需三个配置项即可接入 9Router:
9Router 本地运行:
Base URL: http://localhost:20128/v1
API Key: your-api-key-from-dashboard
Model: cualquier modelo de 9Router (cc/*, cx/*, glm/*, etc.)
9Router 云端部署:
Base URL: https://9router.com/v1
API Key: your-api-key-from-dashboard
Model: cualquier modelo de 9Router (cc/*, cx/*, glm/*, etc.)
要点说明:
- Base URL 必须以
/v1结尾。这是 OpenAI 兼容协议的标准路径前缀,9Router 的所有兼容端点都挂载在该前缀之下(src/app/api/v1/)。 - API Key 从 dashboard 获取。需要说明的是,本地模式下 API Key 是否强制校验取决于设置项
requireApiKey:在 src/sse/handlers/chat.js 中可以看到,只有该设置为true时才校验Authorization头中的 Key,否则请求会以"本地模式"放行(日志输出No API key provided (local mode))。 - 模型名采用
供应商前缀/模型名格式,如cc/*(Claude)、cx/*(Codex/DeepSeek 通道)、glm/*(智谱 GLM)等。
可用模型一览
文档列出的核心模型如下,均采用 前缀/模型ID 命名:
Claude 系列(Anthropic,前缀 cc)
| 模型 ID | 定位 |
|---|---|
cc/claude-opus-4-5-20251101 |
旗舰能力 |
cc/claude-sonnet-4-20250514 |
均衡性价比 |
cc/claude-haiku-4-20250514 |
轻量快速 |
从 CLI 源码 cli/src/cli/menus/cliTools.js 可以看到,cc/claude-opus-4-5-20251101 正是 9Router 生态中的默认 Opus 模型值(ANTHROPIC_DEFAULT_OPUS_MODEL),说明该 ID 是经过实际验证的可用模型标识。
DeepSeek 系列(前缀 cx)
| 模型 ID | 定位 |
|---|---|
cx/deepseek-chat |
通用对话 |
cx/deepseek-reasoner |
深度推理 |
在提供商注册表 open-sse/providers/registry/deepseek.js 中确认了 deepseek-chat 与 deepseek-reasoner 两个模型 ID 的存在,且该供应商支持多端点传输(multi-endpoint transport),可根据客户端请求格式跳过转换直连。
GLM 系列(智谱 AI,前缀 glm)
| 模型 ID | 定位 |
|---|---|
glm/glm-4-plus |
高能力通用 |
glm/glm-4-flash |
高性价比 |
重要提示:以上模型列表为文档给出的参考示例。实际可用的模型集合以运行时 GET /v1/models 的返回为准——该端点会动态合并静态模型目录、已启用连接、Combo 组合、自定义模型与模型别名(实现见 src/app/api/v1/models/route.js 的 buildModelsList),因此你 dashboard 中启用的账户会直接影响返回列表。
集成示例:主流 SDK 与协议客户端
Python + OpenAI SDK
from openai import OpenAI
client = OpenAI(
api_key="your-api-key-from-dashboard",
base_url="http://localhost:20128/v1"
)
response = client.chat.completions.create(
model="cc/claude-sonnet-4-20250514",
messages=[
{"role": "user", "content": "Hello, how are you?"}
]
)
print(response.choices[0].message.content)
Node.js + OpenAI SDK
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "your-api-key-from-dashboard",
baseURL: "http://localhost:20128/v1"
});
const response = await client.chat.completions.create({
model: "cc/claude-sonnet-4-20250514",
messages: [
{ role: "user", content: "Hello, how are you?" }
]
});
console.log(response.choices[0].message.content);
原生 cURL
curl http://localhost:20128/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key-from-dashboard" \
-d '{
"model": "cc/claude-sonnet-4-20250514",
"messages": [
{"role": "user", "content": "Hello, how are you?"}
]
}'
该请求最终由 src/app/api/v1/chat/completions/route.js 接收,先做 JSON 解析校验与模型存在性检查,再进入 src/sse/handlers/chat.js 的 handleChat 核心流程。
HTTP 客户端(Postman、Insomnia)
Request:
POST http://localhost:20128/v1/chat/completions
Headers:
Content-Type: application/json
Authorization: Bearer your-api-key-from-dashboard
Body:
{
"model": "cc/claude-sonnet-4-20250514",
"messages": [
{"role": "user", "content": "Hello, how are you?"}
],
"temperature": 0.7,
"max_tokens": 1000
}
请求体中 temperature、max_tokens 等标准 OpenAI 采样参数会被透传并作用于后端真实模型调用。
LangChain 集成
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage
llm = ChatOpenAI(
model_name="cc/claude-sonnet-4-20250514",
openai_api_key="your-api-key-from-dashboard",
openai_api_base="http://localhost:20128/v1",
temperature=0.7
)
messages = [HumanMessage(content="Explain quantum computing")]
response = llm(messages)
print(response.content)
LlamaIndex 集成
from llama_index.llms import OpenAI
llm = OpenAI(
model="cc/claude-sonnet-4-20250514",
api_key="your-api-key-from-dashboard",
api_base="http://localhost:20128/v1"
)
response = llm.complete("What is machine learning?")
print(response.text)
自定义脚本示例
批量处理脚本
import openai
import json
openai.api_key = "your-api-key-from-dashboard"
openai.api_base = "http://localhost:20128/v1"
def process_batch(prompts, model="cx/deepseek-chat"):
results = []
for prompt in prompts:
response = openai.ChatCompletion.create(
model=model,
messages=[{"role": "user", "content": prompt}]
)
results.append({
"prompt": prompt,
"response": response.choices[0].message.content
})
return results
prompts = [
"Explain AI in one sentence",
"What is machine learning?",
"Define neural networks"
]
results = process_batch(prompts)
print(json.dumps(results, indent=2))
流式响应处理
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "your-api-key-from-dashboard",
baseURL: "http://localhost:20128/v1"
});
async function streamResponse(prompt) {
const stream = await client.chat.completions.create({
model: "cc/claude-sonnet-4-20250514",
messages: [{ role: "user", content: prompt }],
stream: true
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || "";
process.stdout.write(content);
}
}
streamResponse("Write a short story about AI");
流式请求(stream: true)在 9Router 内部走 SSE 流式处理链路,后端提供商返回的增量内容会被逐段转发给客户端;对长回答场景,流式能显著降低首字延迟感知。
多模型对比脚本
from openai import OpenAI
client = OpenAI(
api_key="your-api-key-from-dashboard",
base_url="http://localhost:20128/v1"
)
models = [
"cc/claude-sonnet-4-20250514",
"cx/deepseek-chat",
"glm/glm-4-plus"
]
prompt = "Explain quantum computing in simple terms"
for model in models:
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}]
)
print(f"\n=== {model} ===")
print(response.choices[0].message.content)
这类脚本的实用价值在于:同一个请求体在不同前缀的模型间切换即可横向对比模型输出质量,无需改动任何其他代码。
通用集成模式
用环境变量管理凭据
# .env file
ROUTER_API_KEY=your-api-key-from-dashboard
ROUTER_BASE_URL=http://localhost:20128/v1
ROUTER_MODEL=cc/claude-sonnet-4-20250514
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("ROUTER_API_KEY"),
base_url=os.getenv("ROUTER_BASE_URL")
)
将 Base URL 与模型名也放入环境变量,可以在本地/云端环境之间无缝切换,无需改动代码。
错误处理
from openai import OpenAI, OpenAIError
client = OpenAI(
api_key="your-api-key",
base_url="http://localhost:20128/v1"
)
try:
response = client.chat.completions.create(
model="cc/claude-sonnet-4-20250514",
messages=[{"role": "user", "content": "Hello"}]
)
print(response.choices[0].message.content)
except OpenAIError as e:
print(f"Error: {e}")
指数退避重试
import time
from openai import OpenAI, RateLimitError
client = OpenAI(
api_key="your-api-key",
base_url="http://localhost:20128/v1"
)
def chat_with_retry(prompt, max_retries=3):
for attempt in range(max_retries):
try:
response = client.chat.completions.create(
model="cc/claude-sonnet-4-20250514",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
except RateLimitError:
if attempt < max_retries - 1:
time.sleep(2 ** attempt) # Exponential backoff
else:
raise
值得注意的是,9Router 网关自身已内置多账户自动回退:在 src/sse/handlers/chat.js 中可以看到,当某个账户调用失败时,markAccountUnavailable 会将该账户标记为不可用并自动切换下一个账户重试(FALLBACK → NEXT ACCOUNT),直到所有账户耗尽。因此客户端侧的重试逻辑主要面向网络层抖动与客户端限流,属于防御性补充。
故障排查指南
连接问题
症状: 无法连接 9Router。
# 检查 9Router 是否在运行
curl http://localhost:20128/health
注意:当前仓库源码中健康检查端点 src/app/api/health/route.js 实际返回 {"ok": true}(而非早期文档示例中的 {"status": "ok"}),因此排查时以实际返回的 {"ok": true} 为准。
解决方案:
- 确认 9Router 进程正在运行
- 确认端口 20128 未被防火墙或占用进程阻塞
- 确认 Base URL 完整且以
/v1结尾
认证错误(401 Unauthorized)
症状:
Error: Invalid API key
解决方案:
- 从 dashboard 重新核对 API Key
- 检查
Authorization头格式是否为Bearer your-api-key - 确保 API Key 前后没有多余空格或换行符
补充说明:只有当设置项 requireApiKey 开启时网关才会拒绝无效 Key(返回 401 Invalid API key);关闭状态下本地请求可匿名通过,但生产/云端部署建议始终开启。
模型不存在(404 Model not found)
症状:
Error: Model 'cc/claude-opus' not found
解决方案:
- 使用精确的模型名(模型 ID 区分大小写)
- 通过
curl http://localhost:20128/v1/models查看当前实际可用的模型列表 - 确认该模型已在你的计划/已启用账户中
超时问题
症状:
Error: Request timed out after 30s
解决方案:
- 在客户端配置中调大超时阈值
- 对时间敏感任务改用更快的小模型(如
cc/claude-haiku-*) - 检查到 9Router 的网络连通性
限流(429 Too Many Requests)
症状:
Error: Rate limit exceeded
解决方案:
- 客户端实现指数退避重试
- 降低请求频率
- 在 dashboard 检查速率限制
- 考虑升级计划
最佳实践
安全
- 将 API Key 存放在环境变量中,不要硬编码
- 切勿将 API Key 提交到版本控制系统
- 云端部署一律使用 HTTPS
- 定期轮换 API Key
性能
- 按任务复杂度选择匹配的模型
- 对重复查询实现缓存
- 长回答使用流式输出
- 尽可能合并请求
错误处理
- 始终编写 try-catch 块
- 配合指数退避的重试逻辑
- 记录错误日志以便调试
- 提供降级/回退机制(9Router 网关层的多账户回退是天然的兜底,客户端侧可再叠加一层模型级回退)
成本优化
- 简单任务选用高性价比模型(如
glm/glm-4-flash、cx/deepseek-chat) - 在合适场景缓存响应
- 在 dashboard 持续监控用量
- 在代码中设置请求上限
后续学习路径
总结:9Router 的 OpenAI 兼容端点让"任意 OpenAI 兼容工具 + 多提供商聚合"成为一条低成本接入路径。只要记住三个关键点——Base URL 指向 http://localhost:20128/v1、模型名使用 前缀/模型ID 格式、实际模型清单以 /v1/models 返回为准,你就能在几分钟内把任何脚本、框架或第三方工具接入 9Router,并自动获得多账户回退与统一模型调度的能力。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.2 K634
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown300
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java101
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java50
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript60
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python280