cj2api:将 ChatJimmy 转换为 OpenAI 兼容 API 的零成本方案

被困在封闭生态里的 API

很多开发者都遇到过这种尴尬:发现一个不错的 AI 服务,但它只提供专有 API 格式。而你现有的项目、工具链都是围绕 OpenAI API 设计的,改造成本让人望而却步。

ChatJimmy 就是这样一个服务。它的模型能力不错,但接口格式与主流生态不兼容。想在 Cursor、Continue 这些 AI 编程工具里用它?不行。想用 langchain、semantic-kernel 这些框架集成它?需要额外开发适配层。

协议转换的 reverse proxy

cj2api 的设计非常直接——它是一个 reverse proxy,运行在 Cloudflare Worker 上,拦截 OpenAI 格式的请求,将其转换为 ChatJimmy 的接口格式,再把响应转回 OpenAI 格式返回。

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    
    // 仅处理 /v1/chat/completions 路径
    if (url.pathname !== '/v1/chat/completions') {
      return new Response('Not Found', { status: 404 });
    }
    
    const body = await request.json();
    
    // 构建 ChatJimmy 请求
    const cjRequest = {
      messages: body.messages,
      stream: body.stream || false,
      temperature: body.temperature || 0.7,
      max_tokens: body.max_tokens || 2048
    };
    
    // 发送到 ChatJimmy API
    const response = await fetch(env.CHAT_JIMMY_ENDPOINT, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${env.CHAT_JIMMY_API_KEY}`
      },
      body: JSON.stringify(cjRequest)
    });
    
    // 流式响应直接透传,非流式响应转换格式
    if (cjRequest.stream) {
      return new Response(response.body, {
        headers: { 'Content-Type': 'text/event-stream' }
      });
    }
    
    const data = await response.json();
    return Response.json({
      id: `chatcmpl-${Date.now()}`,
      object: 'chat.completion',
      created: Math.floor(Date.now() / 1000),
      model: body.model || 'chatjimmy',
      choices: [{
        index: 0,
        message: { role: 'assistant', content: data.content },
        finish_reason: 'stop'
      }]
    });
  }
};

这种架构的优势在于:请求方完全无需知道背后是哪个 AI 服务,它只认 OpenAI 格式。

轻量、边缘化、零成本

部署在 Cloudflare Worker

Cloudflare Worker 是一个边缘计算平台,部署在这里意味着:

  • 全球低延迟:请求会被路由到最近的边缘节点,亚太地区的响应时间通常在 50ms 以内
  • 免费额度充足:每天 10 万次请求,个人项目绰绰有余
  • 无需运维:没有服务器要管理,没有容器要维护

对于个人项目或小规模使用,这基本上等于零成本。

原生支持流式输出

OpenAI API 的流式响应使用 Server-Sent Events(SSE)格式。cj2api 正确处理了 stream 参数,能够将 ChatJimmy 的流式输出转换为标准 SSE 格式。

这意味着所有支持 OpenAI 流式 API 的客户端都能开箱即用:

// 客户端示例:使用 fetch 订阅流式响应
const response = await fetch('https://cj2api.example.workers.dev/v1/chat/completions', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: 'gpt-3.5-turbo',
    messages: [{ role: 'user', content: '写一个 hello world' }],
    stream: true
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  console.log(decoder.decode(value));
  // 输出: data: {"choices":[{"delta":{"content":"Hello"}}]}\n\n
}

自带测试页面

项目内置了一个简单的 Web 测试界面,部署后可以直接在浏览器里测试 API 是否正常工作。不需要额外准备 Postman 或 curl 命令。

与同类工具的对比

特性 cj2api 其他通用 API 桥接工具
部署方式 一键部署到 Cloudflare Worker 通常需要自建服务器
成本 零成本(免费额度内) 需要云服务器费用
流式支持 原生支持 SSE 格式 部分支持
测试工具 内置测试页 需要额外准备
配置复杂度 仅需 2 个环境变量 通常需要配置文件

cj2api 的定位更垂直——专门针对 ChatJimmy,配置简单,开箱即用。

5 分钟完成部署

前提条件

  • 一个 Cloudflare 账号(免费即可)
  • ChatJimmy 的 API 访问凭证(Endpoint 和 API Key)

部署方法一:Wrangler CLI

# 安装 Wrangler
npm install -g wrangler

# 登录 Cloudflare
wrangler login

# 克隆项目
git clone https://github.com/你的fork/cj2api.git
cd cj2api

# 安装依赖
npm install

# 设置环境变量
wrangler secret put CHAT_JIMMY_ENDPOINT
# 输入你的 ChatJimmy API 地址,如 https://api.chatjimmy.com/v1/chat

wrangler secret put CHAT_JIMMY_API_KEY
# 输入你的 API Key

# 部署
wrangler deploy

部署方法二:Cloudflare Dashboard

  1. 登录 Cloudflare Dashboard,进入 Workers & Pages
  2. 创建新的 Worker,将上面的代码粘贴进去
  3. 在 Worker 设置中添加环境变量 CHAT_JIMMY_ENDPOINTCHAT_JIMMY_API_KEY
  4. 点击 Deploy

部署完成后,你会得到一个类似 cj2api.your-subdomain.workers.dev 的域名,这就是你的 OpenAI 兼容 API 端点。

验证部署

curl https://cj2api.your-subdomain.workers.dev/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer dummy-key" \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": false
  }'

注意:Authorization 头里的 key 是占位符,cj2api 目前不强制验证。生产环境使用建议自行添加验证逻辑,例如在 reverse proxy 层检查请求头中的真实 API Key。

适用场景

快速验证:想测试 ChatJimmy 的能力,但不想改代码。直接在 Cursor 的设置里换一个 endpoint,几秒钟就能切过来。

临时项目:hackathon 或原型开发,需要快速接入 AI 能力。不用折腾环境配置,直接调用现成的兼容接口。

工具链集成:让 ChatJimmy 成为 OpenAI 生态工具的后端选项。比如在 Continue 插件里配置自定义 endpoint,或者在 langchain 的 ChatOpenAI 类里指定 openai_api_base

# langchain 示例
from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI(
    model_name="chatjimmy",
    openai_api_base="https://cj2api.your-subdomain.workers.dev/v1"
)

如果你恰好有 ChatJimmy 的访问渠道,又想利用现成的 OpenAI 工具链,cj2api 是一个值得一试的轻量方案。