Skip to content

awei807-wei/adapter

Repository files navigation

上游供应商适配器使用说明

📋 概述

这个适配器脚本用于解决不同上游供应商的 API 兼容性问题,无需修改 客户端应用 的核心代码。

🏗️ 架构

 (你的代理)
    ↓
客户端应用 (别人的轮子,不修改)
    ↓
upstream-adapter.js (适配器脚本) ← 新增
    ↓
上游供应商 API

🚀 快速开始

1. 配置适配器

编辑 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: 是否输出详细日志

2. 启动适配器

双击运行 start-adapter.bat,或在命令行执行:

node upstream-adapter.js

你会看到:

========================================
  上游供应商适配器已启动
========================================
  监听端口: 8081
  上游 URL: https://你的供应商API地址/v1
  配置文件: C:\...\adapter-config.json
========================================

使用方式:
  在 客户端应用 中配置上游为: http://localhost:8081/v1

3. 配置 客户端应用

客户端应用 的配置中,将上游 API 地址改为:

http://localhost:8081/v1

原来的配置

{
  "upstream": "https://你的供应商API地址/v1",
  "apiKey": "你的供应商API密钥"
}

修改后的配置

{
  "upstream": "http://localhost:8081/v1",
  "apiKey": "任意值(适配器会替换)"
}

4. 测试

现在你的请求流程是:

VCPToolBox → 客户端应用 → 适配器(8081) → 上游供应商

适配器会自动处理兼容性问题。

🔧 兼容性规则

规则 1: convertSystemMessages

问题:某些供应商不支持 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"}
  ]
}

规则 2: filterErrorMessages

问题:对话历史中可能包含之前失败请求的错误消息。

解决:过滤掉以 [UPSTREAM_ERROR][ERROR] 开头的 assistant 消息。

规则 3: cleanRequestBody

问题:请求体中可能包含非标准字段,导致上游拒绝。

解决:只保留 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

规则 4: ensureLastUserMessage

问题:某些供应商要求最后一条消息必须是 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
  }
}

🐛 故障排查

问题 1: 适配器启动失败

检查

  • 端口 8081 是否被占用?
  • adapter-config.json 格式是否正确?

解决

  • 修改 port 配置使用其他端口
  • 使用 JSON 验证工具检查配置文件

问题 2: 客户端应用 无法连接适配器

检查

  • 适配器是否正在运行?
  • 客户端应用 的上游配置是否正确?

解决

  • 确保适配器在运行:node upstream-adapter.js
  • 确认配置:http://localhost:8081/v1

问题 3: 仍然返回 400 错误

检查

  • 查看适配器日志,确认规则是否生效
  • 检查上游供应商的 API 密钥是否正确

解决

  • 启用 debug: true 查看详细日志
  • 验证 upstreamApiKey 配置

📝 注意事项

  1. 适配器必须先启动:在启动 客户端应用 之前,确保适配器已经运行。

  2. 端口冲突:如果 8081 端口被占用,修改 adapter-config.json 中的 port 配置。

  3. API 密钥安全adapter-config.json 包含敏感信息,不要提交到版本控制系统。

  4. 性能影响:适配器增加了一层转发,会有轻微的延迟(通常 < 10ms)。

  5. 流式响应:适配器完全支持流式响应(SSE),不会影响流式传输。

🔐 生产环境建议

1. 使用环境变量

不要在配置文件中硬编码 API 密钥:

// 修改 upstream-adapter.js
const config = {
  upstreamUrl: process.env.UPSTREAM_URL || 'https://default-url/v1',
  upstreamApiKey: process.env.UPSTREAM_API_KEY || 'default-key',
  // ...
};

2. 添加认证

如果需要保护适配器,添加 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;
}

3. 使用 PM2 管理

使用 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 }
    }
  }
}

🆘 获取帮助

如果遇到问题:

  1. 查看适配器日志(启用 debug: true
  2. 检查 客户端应用 的日志
  3. 使用 test-api-request.js 直接测试上游供应商

📄 许可

MIT License

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors