这个适配器脚本用于解决不同上游供应商的 API 兼容性问题,无需修改 客户端应用 的核心代码。
(你的代理)
↓
客户端应用 (别人的轮子,不修改)
↓
upstream-adapter.js (适配器脚本) ← 新增
↓
上游供应商 API
编辑 adapter-config.json:
{
"upstreamUrl": "https://你的供应商API地址/v1",
"upstreamApiKey": "你的供应商API密钥",
"port": 8081,
"rules": {
"convertSystemMessages": true,
"filterErrorMessages": true,
"cleanRequestBody": true,
"ensureLastUserMessage": true
},
"debug": true
}配置说明:
upstreamUrl: 上游供应商的 API 地址(不包含/chat/completions)upstreamApiKey: 上游供应商的 API 密钥port: 适配器监听的端口(默认 8081)rules: 启用的兼容性规则(见下文)debug: 是否输出详细日志
双击运行 start-adapter.bat,或在命令行执行:
node upstream-adapter.js你会看到:
========================================
上游供应商适配器已启动
========================================
监听端口: 8081
上游 URL: https://你的供应商API地址/v1
配置文件: C:\...\adapter-config.json
========================================
使用方式:
在 客户端应用 中配置上游为: http://localhost:8081/v1
在 客户端应用 的配置中,将上游 API 地址改为:
http://localhost:8081/v1
原来的配置:
{
"upstream": "https://你的供应商API地址/v1",
"apiKey": "你的供应商API密钥"
}修改后的配置:
{
"upstream": "http://localhost:8081/v1",
"apiKey": "任意值(适配器会替换)"
}现在你的请求流程是:
VCPToolBox → 客户端应用 → 适配器(8081) → 上游供应商
适配器会自动处理兼容性问题。
问题:某些供应商不支持 system 角色消息与连续 user 消息的组合。
解决:将 system 消息合并到第一条 user 消息中。
示例:
// 转换前
{
"messages": [
{"role": "system", "content": "你是一个助手"},
{"role": "user", "content": "你好"},
{"role": "user", "content": "hi"}
]
}
// 转换后
{
"messages": [
{"role": "user", "content": "你是一个助手\n\n你好"},
{"role": "user", "content": "hi"}
]
}问题:对话历史中可能包含之前失败请求的错误消息。
解决:过滤掉以 [UPSTREAM_ERROR] 或 [ERROR] 开头的 assistant 消息。
问题:请求体中可能包含非标准字段,导致上游拒绝。
解决:只保留 OpenAI API 标准字段。
保留的字段:
- model, messages, stream, temperature, top_p, n
- stop, max_tokens, presence_penalty, frequency_penalty
- logit_bias, user, tools, tool_choice, response_format, seed
问题:某些供应商要求最后一条消息必须是 user 角色。
解决:如果最后一条消息不是 user,自动添加一条 user 消息。
启用 debug: true 后,你会看到详细的处理日志:
========== 新请求 ==========
[Request] 原始 messages 数量: 14
[Rule:FilterErrors] 已过滤 5 条错误消息
[Rule:SystemConvert] 检测到 1 条 system 消息
[Rule:SystemConvert] 已将 system 消息合并到第一条 user 消息
[Rule:CleanBody] 移除的字段: requestId
[Request] 处理后 messages 数量: 9
[Upstream] 请求 URL: https://供应商API/v1/chat/completions
[Upstream] Messages 数量: 9
[Upstream] Stream: true
[Response] 状态码: 200
[Response] Content-Type: text/event-stream
适配器支持配置文件热重载。修改 adapter-config.json 后,无需重启适配器,配置会自动生效。
[Adapter] 检测到配置文件变化,重新加载...
[Adapter] 配置加载成功: C:\...\adapter-config.json
[Adapter] 上游 URL: https://新的供应商API/v1
[Adapter] 启用的规则: convertSystemMessages, filterErrorMessages, cleanRequestBody, ensureLastUserMessage
你可以根据需要启用/禁用规则:
{
"rules": {
"convertSystemMessages": true, // 转换 system 消息
"filterErrorMessages": false, // 不过滤错误消息
"cleanRequestBody": true, // 清理请求体
"ensureLastUserMessage": false // 不强制最后是 user
}
}检查:
- 端口 8081 是否被占用?
adapter-config.json格式是否正确?
解决:
- 修改
port配置使用其他端口 - 使用 JSON 验证工具检查配置文件
检查:
- 适配器是否正在运行?
- 客户端应用 的上游配置是否正确?
解决:
- 确保适配器在运行:
node upstream-adapter.js - 确认配置:
http://localhost:8081/v1
检查:
- 查看适配器日志,确认规则是否生效
- 检查上游供应商的 API 密钥是否正确
解决:
- 启用
debug: true查看详细日志 - 验证
upstreamApiKey配置
-
适配器必须先启动:在启动
客户端应用之前,确保适配器已经运行。 -
端口冲突:如果 8081 端口被占用,修改
adapter-config.json中的port配置。 -
API 密钥安全:
adapter-config.json包含敏感信息,不要提交到版本控制系统。 -
性能影响:适配器增加了一层转发,会有轻微的延迟(通常 < 10ms)。
-
流式响应:适配器完全支持流式响应(SSE),不会影响流式传输。
不要在配置文件中硬编码 API 密钥:
// 修改 upstream-adapter.js
const config = {
upstreamUrl: process.env.UPSTREAM_URL || 'https://default-url/v1',
upstreamApiKey: process.env.UPSTREAM_API_KEY || 'default-key',
// ...
};如果需要保护适配器,添加 API 密钥验证:
// 在 server.createServer 中添加
const authKey = req.headers['authorization'];
if (authKey !== `Bearer ${config.adapterApiKey}`) {
res.writeHead(401, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Unauthorized' }));
return;
}使用 PM2 确保适配器持续运行:
npm install -g pm2
pm2 start upstream-adapter.js --name "api-adapter"
pm2 save
pm2 startup在 upstream-adapter.js 中添加新的处理函数:
function yourCustomRule(requestBody) {
// 你的处理逻辑
return requestBody;
}
// 在 applyRules 函数中调用
function applyRules(requestBody) {
let body = { ...requestBody };
if (config.rules.yourCustomRule) {
body = yourCustomRule(body);
}
return body;
}修改配置支持多个上游:
{
"upstreams": {
"claude": {
"url": "https://claude-provider/v1",
"apiKey": "key1",
"rules": { "convertSystemMessages": true }
},
"gpt": {
"url": "https://gpt-provider/v1",
"apiKey": "key2",
"rules": { "convertSystemMessages": false }
}
}
}如果遇到问题:
- 查看适配器日志(启用
debug: true) - 检查 客户端应用 的日志
- 使用
test-api-request.js直接测试上游供应商
MIT License