中文 | English
一个自托管的、OpenAI 兼容的 API 代理服务。它把上游模型服务封装为标准的 OpenAI Chat Completions 接口,并额外保留一个透传上游原始事件流的调试接口。
GET /healthGET /v1/modelsGET /v1/models/{model}POST /v1/chat/completionsPOST /api/chat:透传上游原始 NDJSON 事件流,便于调试
不同模型会按内部规则路由到对应的上游接口。
npm start默认服务地址:
http://localhost:8787
如需固定本地配置,可参考 .env.example;不配置 .env 也能直接运行。
先生成本地环境配置,并按需修改 API_KEY:
Copy-Item .env.example .env推荐使用 Compose 部署:
docker compose up -d --build默认会把宿主机 8787 端口映射到容器内服务。需要改宿主机端口时,修改 .env 中的 HOST_PORT:
HOST_PORT=18787
首次启动会在项目目录下创建 browser-profile/,用于持久化浏览器上下文(已在 .gitignore 中忽略)。
查看运行状态与日志:
docker compose ps
docker compose logs -f更新并重启:
docker compose up -d --build停止服务:
docker compose down也可以直接构建并运行镜像:
docker build -t app .
docker run -d --name app --restart unless-stopped `
-p 8787:8787 `
--env-file .env `
app健康检查:
Invoke-RestMethod http://localhost:8787/health主要环境变量(完整项见 .env.example):
| 变量 | 说明 |
|---|---|
PORT |
服务监听端口,默认 8787 |
API_KEY |
客户端访问密钥,留空则不校验 |
MACARON_ORIGIN |
上游服务 Origin(默认指向官方上游) |
MACARON_DEFAULT_MODEL |
默认模型 |
MACARON_UPSTREAM_TRANSPORT |
上游传输方式:auto / browser / direct |
MACARON_TIMEOUT_MS |
上游请求超时(毫秒) |
MACARON_BROWSER_EXECUTABLE |
浏览器可执行文件路径 |
MACARON_BROWSER_USER_AGENT |
浏览器上下文使用的 User-Agent(可选) |
CORS_ALLOW_ORIGIN |
CORS 允许来源,默认 * |
如果设置了 API_KEY,客户端请求需携带任意一种认证:
Authorization: Bearer <your-key>
或:
x-api-key: <your-key>
部分上游模型支持按请求传入独立的上游密钥与 base URL:
{
"upstream_api_key": "...",
"upstream_base_url": "..."
}也可使用请求头 x-macaron-upstream-api-key 与 x-macaron-upstream-base-url。
部分上游对纯服务端发起的请求会返回限流或安全质询,而来自真实浏览器的请求可以正常完成。MACARON_UPSTREAM_TRANSPORT 用于控制这一行为:
auto:先尝试直接的服务端请求,仅当上游返回质询时,自动回退到真实浏览器上下文。browser:始终通过浏览器上下文发送上游请求。direct:只用服务端请求,遇到质询会直接以错误返回。
浏览器上下文会以接近真实桌面浏览器的环境发起请求——统一的 User-Agent、客户端提示(Client Hints)与基础环境特征——以提升在严格风控下的成功率。可通过 MACARON_BROWSER_USER_AGENT 覆盖默认 UA;浏览器配置持久化在 browser-profile/,可跨重启复用。
本地运行若提示找不到浏览器,请安装 Chrome 或 Edge,或显式指定:
# Windows
$env:MACARON_BROWSER_EXECUTABLE = "C:\Program Files\Google\Chrome\Application\chrome.exe"# Linux
export MACARON_BROWSER_EXECUTABLE=/usr/bin/chromiumDocker 镜像内置 Chromium,默认 MACARON_BROWSER_EXECUTABLE=/usr/bin/chromium-browser。
上游通常按出口 IP 限流,短时间内请求过多会返回 429(部分上游同时启用安全质询,见上文)。这类 IP 限流无法靠切换浏览器绕过——浏览器与服务端共用同一出口 IP——因此代理在客户端侧主动限速并退避重试,尽量不把 429 透传给调用方:
MACARON_MAX_CONCURRENCY(默认 3):同时在途的上游请求数上限。MACARON_RATE_MAX/MACARON_RATE_MIN/MACARON_RATE_WINDOW_MS(默认 7 / 2 / 15000):滚动窗口内的最大/最小请求数与窗口长度。速率上限在RATE_MIN~RATE_MAX间自适应(AIMD):撞到限流就乘性减半、持续成功则缓慢提速,自动收敛到当前出口 IP 的真实上限,换平台 / 换 IP 一般无需手工调参;令RATE_MIN == RATE_MAX退回固定速率。MACARON_MAX_RETRIES/MACARON_RETRY_BASE_MS/MACARON_RETRY_MAX_MS(默认 4 / 2000 / 20000):退避重试次数与基准/上限延迟(优先采用上游返回的retry-after)。GET /health返回限流器实时状态(effectiveLimit/inWindow/active/queued),便于观测节流与收敛。
以下 OpenAI 采样参数会原样转发给上游(是否生效取决于上游,未知字段预期会被忽略):
temperature、top_p、max_tokens、stop、frequency_penalty、presence_penalty、seed
tools 与 tool_choice 也会一并转发,但工具调用能否端到端工作取决于上游是否支持;当前代理只做请求侧透传,尚未解析上游的工具调用返回。
客户端 base_url 配置为:
http://localhost:8787/v1
非流式请求示例:
Invoke-RestMethod http://localhost:8787/v1/chat/completions `
-Method Post `
-ContentType "application/json" `
-Body '{
"model": "<model-id>",
"messages": [
{ "role": "user", "content": "Say hi in one short sentence." }
]
}'流式请求示例:
Invoke-WebRequest http://localhost:8787/v1/chat/completions `
-Method Post `
-ContentType "application/json" `
-Body '{
"model": "<model-id>",
"stream": true,
"messages": [
{ "role": "user", "content": "Say hi." }
]
}' | Select-Object -ExpandProperty Content通过 GET /v1/models 获取当前可用模型列表;默认模型由 MACARON_DEFAULT_MODEL 指定,并提供若干别名解析到默认模型。
npm run check
npm test测试套件使用本地 mock 上游,不会请求真实的上游服务。
本服务依赖上游接口的当前形态。若上游调整接口或事件格式,本代理需同步更新。
当前实现的是 OpenAI Chat Completions 兼容层,而非完整的 Responses API。流式响应在上游报错时会在 chunk 中附带 error 字段,并以合法的 finish_reason(stop)结束,以兼容严格校验的客户端。