Skip to content

Latest commit

 

History

History
235 lines (179 loc) · 7.21 KB

File metadata and controls

235 lines (179 loc) · 7.21 KB

OpenAI Compatible Client

最小可用的 OpenAI 兼容 API 客户端 + API 网关,使用 Node.js 内置 http/https 实现,零外部依赖。

文件结构

E:\OpenAPI
├── index.js              # CLI 入口(chat / stream / serve)
├── package.json
├── config.example.json   # 配置文件模板
├── config.json           # 实际配置(需自行创建)
├── README.md
└── lib
    ├── ai.js             # OpenAICompatibleClient 核心
    ├── config.js         # 配置加载
    └── server.js         # API 网关 HTTP 服务

快速开始

1. 创建配置文件

Copy-Item .\config.example.json .\config.json

2. 编辑 config.json

{
  "baseURL": "https://your-openai-compatible-endpoint.example.com/v1",
  "apiKey": "sk-your-api-key",
  "model": "gpt-4o-mini",
  "port": 3000
}
字段 说明
baseURL 任何兼容 OpenAI /chat/completions 接口的 API 地址
apiKey API 密钥
model 默认模型名称
port 网关模式监听端口(默认 3000,仅 serve 命令使用)

三种运行模式

模式一:单次对话 chat

node index.js chat "你好,请用中文解释什么是事件循环。"

工作流程:

CLI 参数  →  index.js 拼装 messages  →  OpenAICompatibleClient.chat()
                                                │
                                     POST {baseURL}/chat/completions
                                                │
                                         等待完整响应返回
                                                │
                                         打印到控制台

模式二:流式对话 stream

node index.js stream "请写一段关于编程的短文。"

字符会逐个打印到终端,体验类似 ChatGPT 的打字效果。

工作流程:

CLI 参数  →  index.js 拼装 messages  →  OpenAICompatibleClient.streamChat()
                                                │
                                     POST {baseURL}/chat/completions
                                     (stream: true)
                                                │
                                     SSE 逐块到达 → onDelta → process.stdout.write()
                                                │
                                     [DONE] → onComplete → 换行结束

模式三:API 网关 serve

node index.js serve

启动后会显示:

API gateway listening on http://localhost:3000

网关架构

┌─────────────────┐       ┌─────────────────┐       ┌─────────────────────┐
│   外部客户端      │       │   本网关 (3000)   │       │   真实 AI 后端       │
│                   │       │                   │       │                     │
│  无需知道真实     │ POST  │  隐藏 API Key     │ POST  │  真实的 API 验证     │
│  API Key          │──────>│  转发请求         │──────>│                     │
│                   │       │                   │       │                     │
│  用户只需指向     │<──────│  返回响应         │<──────│                     │
│  localhost:3000   │  JSON │                   │  SSE  │                     │
└─────────────────┘       └─────────────────┘       └─────────────────────┘

非流式请求

Invoke-RestMethod -Method Post `
  -Uri "http://localhost:3000/v1/chat/completions" `
  -Headers @{"Content-Type" = "application/json"} `
  -Body '{"messages":[{"role":"user","content":"Hello"}]}'

返回完整的 OpenAI 格式响应 JSON:

{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "created": 1779417002,
  "model": "doubao-seed-2-0-lite-260428",
  "choices": [{
    "index": 0,
    "message": { "role": "assistant", "content": "..." },
    "finish_reason": "stop"
  }],
  "usage": { "prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0 }
}

流式请求

# PowerShell
$body = '{"messages":[{"role":"user","content":"Hello"}],"stream":true}'
$response = Invoke-WebRequest -Method Post `
  -Uri "http://localhost:3000/v1/chat/completions" `
  -Headers @{"Content-Type" = "application/json"} `
  -Body $body
$response.Content

返回 SSE(Server-Sent Events)格式,data: [DONE] 表示流结束:

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":...,"model":"...","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":...,"model":"...","choices":[{"index":0,"delta":{"content":" world"},"finish_reason":null}]}

data: [DONE]

请求参数说明

网关接口 POST /v1/chat/completions 接受以下 JSON 字段:

字段 类型 必需 说明
messages array 对话消息数组,格式同 OpenAI API
stream boolean 是否流式输出,默认 false
model string 覆盖配置文件中的默认模型
temperature number 温度参数 (0-2)
max_tokens number 最大输出 token 数

注意:客户端不需要发送 apiKey,网关使用配置文件中的密钥。如果客户端发送了 apiKey 字段,会被静默忽略。

错误状态码

状态码 场景
200 成功
400 JSON 解析失败 / messages 字段缺失或格式错误
404 访问了 /v1/chat/completions 以外的路径
405 使用了 POST 以外的方法
413 请求体超过 1MB
502 上游 API 调用失败
500 服务器内部错误

集成到其他系统

作为桌面客户端的后端

任何支持自定义 API 地址的客户端都可以指向这个网关:

API 地址: http://localhost:3000/v1
API Key:  (留空或随意填写,网关不使用它)

支持的客户端示例:ChatBox、OpenCat、Cherry Studio、NextChat 等。

在 Node.js 项目中嵌入网关

const { startServer } = require('./lib/server');
const { loadConfig } = require('./lib/config');

const config = loadConfig();
config.port = 8080;  // 可覆盖端口
startServer(config);

在 Node.js 项目中嵌入客户端

const { OpenAICompatibleClient } = require('./lib/ai');

const client = new OpenAICompatibleClient({
  baseURL: 'https://api.openai.com/v1',
  apiKey: 'sk-xxx',
  model: 'gpt-4o'
});

const reply = await client.chat([{ role: 'user', content: 'Hello' }]);

实现说明

  • 零外部依赖:仅使用 Node.js 内置 httphttpscryptofspathurl 模块
  • 请求地址:{baseURL}/chat/completions
  • 认证方式:Authorization: Bearer <apiKey>
  • 兼容普通 chat completions
  • 兼容 SSE 流式输出
  • 默认超时 60 秒
  • 网关请求体最大 1MB