Skip to content

luchen022/cf-aiapi

Repository files navigation

Cloudflare Workers - OpenAI 格式多厂商 AI 代理

完全兼容 OpenAI API 格式的多厂商 AI 代理,支持透明转发到 DeepSeek、智谱、OpenAI 等任意兼容 OpenAI 格式的 AI 服务商。

功能特性

  • ✅ 完全兼容 OpenAI API 格式
  • ✅ 支持 /v1/models/v1/chat/completions/v1/embeddings 接口
  • ✅ 支持图片输入(base64 编码或 URL 格式)
  • ✅ 支持流式响应(SSE)
  • ✅ 支持跨域(CORS)
  • ✅ 统一鉴权管理
  • ✅ 灵活的模型路由配置
  • ✅ 多账号负载均衡(基于时间轮询,一分钟内均匀分配)
  • ✅ 纯原生 JS,无依赖
  • ✅ 开箱即用

快速部署

1. 创建 Cloudflare Worker

  1. 登录 Cloudflare Dashboard
  2. 进入 Workers & Pages
  3. 点击 Create ApplicationCreate Worker
  4. worker.js 的内容复制到编辑器中
  5. 点击 Save and Deploy

2. 配置环境变量

在 Worker 设置页面,进入 SettingsVariables,添加以下环境变量:

必需的环境变量

变量名 说明 示例值
API_KEY 统一鉴权密钥 your-secret-api-key-here
PROVIDERS 厂商和模型配置(JSON 字符串) 见下方示例
WARMUP_BASE_URL Worker 对外访问地址,Cron 预热会请求 ${WARMUP_BASE_URL}/health https://your-worker.workers.dev

各厂商 API Key(按需配置)

变量名 说明
DEEPSEEK_API_KEY DeepSeek API 密钥
ZHIPU_API_KEY 智谱 API 密钥
OPENAI_API_KEY OpenAI API 密钥
MOONSHOT_API_KEY 月之暗面 API 密钥
QWEN_API_KEY 通义千问 API 密钥

3. PROVIDERS 配置示例

预热配置

如果你启用了 wrangler.toml 里的 Cron Trigger,定时预热请求会读取 WARMUP_BASE_URL,然后访问 /health

  • 自定义域名示例:https://api.example.com
  • workers.dev 示例:https://your-worker.your-subdomain.workers.dev
  • 未配置 WARMUP_BASE_URL 时,预热会自动跳过,不会再使用写死域名

wrangler.toml 中默认提供了 triggers = { crons = ["*/5 * * * *"] },你可以按需修改 Cron 表达式。

基础配置

{
  "deepseek": {
    "baseURL": "https://api.deepseek.com/v1",
    "apiKey": "DEEPSEEK_API_KEY",
    "models": ["deepseek-chat", "deepseek-coder"]
  },
  "zhipu": {
    "baseURL": "https://open.bigmodel.cn/api/paas/v4",
    "apiKey": "ZHIPU_API_KEY",
    "models": ["glm-4", "glm-4-plus", "glm-4-flash"]
  },
  "openai": {
    "baseURL": "https://api.openai.com/v1",
    "apiKey": "OPENAI_API_KEY",
    "models": ["gpt-4", "gpt-4-turbo", "gpt-3.5-turbo"]
  }
}

多账号负载均衡配置

同一个厂商有多个账号时,可以配置为数组,Worker 会自动随机选择:

{
  "deepseek": {
    "baseURL": "https://api.deepseek.com/v1",
    "apiKey": ["DEEPSEEK_API_KEY_1", "DEEPSEEK_API_KEY_2", "DEEPSEEK_API_KEY_3"],
    "models": ["deepseek-chat", "deepseek-coder"]
  },
  "zhipu": {
    "baseURL": "https://open.bigmodel.cn/api/paas/v4",
    "apiKey": ["ZHIPU_API_KEY_1", "ZHIPU_API_KEY_2"],
    "models": ["glm-4", "glm-4-plus", "glm-4-flash"]
  }
}

多 baseURL 配置(支持不同区域)

{
  "openai": {
    "baseURL": ["https://api.openai.com/v1", "https://api.openai-proxy.com/v1"],
    "apiKey": "OPENAI_API_KEY",
    "models": ["gpt-4", "gpt-3.5-turbo"]
  }
}

完整示例(混合配置)

{
  "deepseek": {
    "baseURL": "https://api.deepseek.com/v1",
    "apiKey": ["DEEPSEEK_API_KEY_1", "DEEPSEEK_API_KEY_2"],
    "models": ["deepseek-chat", "deepseek-coder"]
  },
  "zhipu": {
    "baseURL": "https://open.bigmodel.cn/api/paas/v4",
    "apiKey": "ZHIPU_API_KEY",
    "models": ["glm-4", "glm-4-plus", "glm-4-flash", "glm-4-air"]
  },
  "openai": {
    "baseURL": "https://api.openai.com/v1",
    "apiKey": "OPENAI_API_KEY",
    "models": ["gpt-4", "gpt-4-turbo", "gpt-3.5-turbo", "text-embedding-3-small"]
  },
  "moonshot": {
    "baseURL": "https://api.moonshot.cn/v1",
    "apiKey": "MOONSHOT_API_KEY",
    "models": ["moonshot-v1-8k", "moonshot-v1-32k", "moonshot-v1-128k"]
  }
}

配置说明

  • baseURL: 厂商 API 地址,支持字符串或数组(多个地址)
  • apiKey: API 密钥,支持字符串、环境变量名或数组(多个账号)
  • models: 该厂商支持的模型列表
  • apiKey 为全大写时(如 DEEPSEEK_API_KEY),Worker 会自动从环境变量读取
  • 多账号配置时,Worker 使用基于时间的轮询策略(每秒切换),确保一分钟内均匀分配
  • /v1/models 接口会返回所有配置的模型列表

使用方法

获取模型列表

curl https://your-worker.workers.dev/v1/models \
  -H "Authorization: Bearer your-secret-api-key-here"

对话补全(非流式)

curl https://your-worker.workers.dev/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret-api-key-here" \
  -d '{
    "model": "deepseek-chat",
    "messages": [
      {"role": "user", "content": "你好"}
    ]
  }'

对话补全(流式)

curl https://your-worker.workers.dev/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret-api-key-here" \
  -d '{
    "model": "glm-4",
    "messages": [
      {"role": "user", "content": "讲个笑话"}
    ],
    "stream": true
  }'

对话补全(带图片输入)

curl https://your-worker.workers.dev/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret-api-key-here" \
  -d '{
    "model": "deepseek-chat",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "image_url",
            "image_url": {
              "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
            }
          },
          {
            "type": "text",
            "text": "这张图片里有什么?"
          }
        ]
      }
    ]
  }'

文本嵌入

curl https://your-worker.workers.dev/v1/embeddings \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret-api-key-here" \
  -d '{
    "model": "text-embedding-3-small",
    "input": "Hello, world!"
  }'

客户端集成

Python (OpenAI SDK)

基础对话

from openai import OpenAI

client = OpenAI(
    api_key="your-secret-api-key-here",
    base_url="https://your-worker.workers.dev/v1"
)

response = client.chat.completions.create(
    model="deepseek-chat",
    messages=[
        {"role": "user", "content": "你好"}
    ]
)

print(response.choices[0].message.content)

带图片输入的对话

import base64
from openai import OpenAI

# 读取并编码图片
def encode_image(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode('utf-8')

# 初始化客户端
client = OpenAI(
    api_key="your-secret-api-key-here",
    base_url="https://your-worker.workers.dev/v1"
)

# 编码图片
image_base64 = encode_image("image.png")

# 发送请求
response = client.chat.completions.create(
    model="deepseek-chat",  # 确保模型支持视觉功能
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/png;base64,{image_base64}"
                    }
                },
                {
                    "type": "text",
                    "text": "这张图片里有什么?"
                }
            ]
        }
    ]
)

print(response.choices[0].message.content)

Node.js (OpenAI SDK)

import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'your-secret-api-key-here',
  baseURL: 'https://your-worker.workers.dev/v1'
});

const response = await client.chat.completions.create({
  model: 'glm-4',
  messages: [
    { role: 'user', content: '你好' }
  ]
});

console.log(response.choices[0].message.content);

Curl

curl https://your-worker.workers.dev/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret-api-key-here" \
  -d '{
    "model": "deepseek-chat",
    "messages": [{"role": "user", "content": "你好"}],
    "stream": false
  }'

支持的 AI 厂商

理论上支持所有兼容 OpenAI API 格式的厂商,包括但不限于:

环境变量配置清单

Cloudflare Workers 环境变量

基础配置示例

# 必需
API_KEY=your-secret-api-key-here
PROVIDERS={"deepseek":{"baseURL":"https://api.deepseek.com/v1","apiKey":"DEEPSEEK_API_KEY","models":["deepseek-chat","deepseek-coder"]},"zhipu":{"baseURL":"https://open.bigmodel.cn/api/paas/v4","apiKey":"ZHIPU_API_KEY","models":["glm-4","glm-4-plus"]}}

# 各厂商密钥
DEEPSEEK_API_KEY=sk-xxxxx
ZHIPU_API_KEY=xxxxx.xxxxx

多账号负载均衡配置示例

# 必需
API_KEY=your-secret-api-key-here
PROVIDERS={"deepseek":{"baseURL":"https://api.deepseek.com/v1","apiKey":["DEEPSEEK_API_KEY_1","DEEPSEEK_API_KEY_2"],"models":["deepseek-chat","deepseek-coder"]},"zhipu":{"baseURL":"https://open.bigmodel.cn/api/paas/v4","apiKey":"ZHIPU_API_KEY","models":["glm-4"]}}

# 各厂商密钥
DEEPSEEK_API_KEY_1=sk-xxxxx
DEEPSEEK_API_KEY_2=sk-yyyyy
ZHIPU_API_KEY=xxxxx.xxxxx

注意事项

  1. 所有上游厂商必须已经兼容 OpenAI API 格式
  2. Worker 只做透明转发,不做任何格式转换
  3. 确保 PROVIDERS 配置中的 baseURL 不包含尾部斜杠
  4. 流式响应需要上游厂商支持 SSE
  5. 建议使用 Cloudflare Workers 的加密环境变量存储敏感信息
  6. 多账号负载均衡使用基于时间的轮询策略,每秒自动切换账号,确保一分钟内均匀分配
  7. 一个厂商可以配置多个模型,共享同一个 baseURL 和 apiKey
  8. /v1/models 接口直接返回配置中的所有模型,不会请求上游
  9. 多账号配置适用于:
    • 提高并发能力(绕过单账号限流)
    • 增加可用性(某个账号失败时还有其他账号)
    • 分散成本(多个账号分摊费用)
  10. 图片输入功能:
    • 支持 base64 编码格式:data:image/png;base64,{base64_string}
    • 支持图片 URL 格式(如果上游支持)
    • 需要使用支持视觉功能的模型(如 GPT-4V、DeepSeek-VL 等)
    • 图片大小限制取决于上游厂商的限制

限制 Workers 运行区域(避免 IP 频繁变化)

Cloudflare Workers 默认在全球多个数据中心运行,可能导致 IP 频繁变化,被 AI 厂商风控。

方法 1:使用 wrangler.toml 配置(推荐)

wrangler.toml 中添加:

[placement]
mode = "smart"

这会让 Workers 智能选择最优区域运行,减少 IP 变化。

方法 2:在 Dashboard 中配置

  1. 进入 Worker 设置页面
  2. 找到 SettingsTriggersRoutes
  3. 配置自定义域名时,可以选择特定区域

方法 3:使用 Cloudflare for SaaS(付费)

如果需要固定 IP 或更精细的控制,可以使用:

  • Cloudflare Workers Paid Plan(支持更多区域控制)
  • Cloudflare for SaaS(可以配置固定出口 IP)

可用区域

  • WNAM - 美国西部(洛杉矶、旧金山)
  • ENAM - 美国东部(纽约、华盛顿)
  • WEUR - 西欧(伦敦、法兰克福)
  • EEUR - 东欧(华沙、布加勒斯特)
  • APAC - 亚太(新加坡、香港、东京、首尔)

推荐使用 APAC(亚太)区域,包含新加坡、香港等节点,距离中国较近,延迟低。

注意

  • 免费版 Workers 的区域控制有限
  • mode = "smart" 会自动选择最优区域,但不保证固定 IP
  • 如果需要完全固定 IP,需要使用付费方案或自建代理

故障排查

401 Unauthorized

  • 检查客户端请求头中的 Authorization: Bearer {API_KEY} 是否正确
  • 确认 Worker 环境变量 API_KEY 已正确配置

404 Model Not Found

  • 检查 PROVIDERS 环境变量是否为有效的 JSON 格式
  • 确认请求的 model 名称在 PROVIDERS 配置的 models 列表中存在
  • 确认厂商配置包含 baseURL、apiKey 和 models 字段

500 Server Error

  • 检查上游厂商的 API Key 是否有效
  • 确认上游厂商的 baseURL 是否正确
  • 查看 Worker 日志获取详细错误信息

许可证

MIT License

About

🚀 基于 Cloudflare Workers 的 OpenAI API 兼容代理,支持 DeepSeek、智谱、OpenAI 等多厂商透明转发,内置负载均衡和统一鉴权

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors