轻量级 OpenAI Responses API 和 Anthropic Messages API 兼容代理。
对外暴露 POST /v1/responses、POST /v1/messages 等端点,内部将各种格式请求转换为统一的 OpenAI-compatible Chat Completions 请求,转发到上游 /chat/completions,再把上游响应转换回客户端所需的格式。
- 客户端只支持 OpenAI Responses API 或 Anthropic Messages API。
- 上游只提供或更稳定支持标准 OpenAI Chat Completions API。
- 需要将复杂的协议差异(如工具调用格式、流式事件格式、reasoning/thinking 格式)进行自动转换和兼容。
| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/v1/messages |
Anthropic Messages API 主端点,转换为 Chat Completions 转发 |
POST |
/v1/responses |
Responses API 主端点,转换为 Chat Completions 转发 |
POST |
/v1/responses/compact |
简化版 Responses 端点 |
GET |
/v1/responses |
WebSocket 端点,兼容 Codex responses_websockets_v2 |
POST |
/v1/images/generations |
图像生成透传 |
POST |
/v1/images/edits |
图像编辑透传 |
POST |
/v1/audio/speech |
语音合成透传 |
POST |
/v1/audio/transcriptions |
语音转文字透传 |
GET |
/healthz |
健康检查 |
- 非流式响应转换
- SSE 流式响应转换
instructions转 Chatsystem/developer消息input字符串、消息数组、多模态内容转换tools/tool_choice函数调用转换text.format转 Chatresponse_format- Chat 工具调用结果转 Responses
function_call - 流式
reasoning_content/reasoning转 Responses reasoning 事件 reasoning.effort/reasoning_effort/model_reasoning_effort归一化透传- 上游兼容性重试:遇到部分 400 参数不兼容错误时,移除可选字段后重试一次
- 图像/音频接口参数校验与上游错误标准化
- 请求日志开关
- Go 1.26+
- 一个兼容 Chat Completions 的上游 API
- 可选环境变量
RTC_API_KEY
export RTC_API_KEY="your-api-key"
go run main.go \
--api_base https://ark.cn-beijing.volces.com/api/coding/v3 \
--port 4000 \
--log参数说明:
| 参数 | 必填 | 默认值 | 说明 |
|---|---|---|---|
--api_base |
是 | 无 | 上游 OpenAI-compatible API base,不包含 /chat/completions |
--port |
否 | 4000 |
本地监听端口 |
--log |
否 | false |
开启请求日志 |
快捷命令:
make run-volce
make run-bailian
make run-deepseek
make run-xiaomi代理不会改写 model。客户端请求里传什么 model,就会原样转发给上游,除非代码里明确存在某个模型族的协议兼容逻辑。
因此需要按上游文档选择可用模型。例如火山方舟 Coding Plan 使用:
{
"model": "ark-code-latest"
}如果传入上游不支持的模型,例如某些套餐不支持的 gpt-5.4,代理会原样透传,上游会返回自己的错误。
DeepSeek V4 兼容后缀:
| 请求模型 | 转发模型 | 附加字段 |
|---|---|---|
deepseek-v4-xxx-none |
deepseek-v4-xxx |
thinking.type=disabled |
deepseek-v4-xxx-low |
deepseek-v4-xxx |
thinking.type=enabled, reasoning_effort=low |
deepseek-v4-xxx-max |
deepseek-v4-xxx |
thinking.type=enabled, reasoning_effort=max |
转发上游请求时:
- 客户端请求包含
Authorization时,原样透传。 - 否则使用环境变量
RTC_API_KEY,发送为Authorization: Bearer <RTC_API_KEY>。 - 两者都没有时,不发送鉴权头,上游通常会返回鉴权错误。
非流式:
curl http://127.0.0.1:4000/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"model": "ark-code-latest",
"instructions": "只输出最终答案。",
"input": "回答 OK 两个字母。",
"max_output_tokens": 64
}'流式:
curl -N http://127.0.0.1:4000/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"model": "ark-code-latest",
"input": "写一句简短问候。",
"stream": true
}'工具调用:
curl http://127.0.0.1:4000/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"model": "ark-code-latest",
"input": "调用 lookup_price 查询 AAPL。",
"tools": [
{
"type": "function",
"name": "lookup_price",
"description": "Lookup a stock price by ticker.",
"parameters": {
"type": "object",
"properties": {
"ticker": { "type": "string" }
},
"required": ["ticker"]
}
}
],
"tool_choice": { "type": "function", "name": "lookup_price" }
}'结构化输出:
curl http://127.0.0.1:4000/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"model": "ark-code-latest",
"input": "输出 AAPL 的 JSON 示例。",
"text": {
"format": {
"type": "json_schema",
"name": "quote",
"schema": {
"type": "object",
"properties": {
"ticker": { "type": "string" },
"price": { "type": "number" }
},
"required": ["ticker", "price"],
"additionalProperties": false
}
}
}
}'非流式:
curl http://127.0.0.1:4000/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: your-api-key" \
-d '{
"model": "ark-code-latest",
"max_tokens": 1024,
"system": "你是一个有用的助手。",
"messages": [
{"role": "user", "content": "回答 OK 两个字母。"}
]
}'流式:
curl -N http://127.0.0.1:4000/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: your-api-key" \
-d '{
"model": "ark-code-latest",
"max_tokens": 1024,
"stream": true,
"messages": [
{"role": "user", "content": "写一句简短问候。"}
]
}'工具调用:
curl http://127.0.0.1:4000/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: your-api-key" \
-d '{
"model": "ark-code-latest",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "查询 AAPL 股价"}
],
"tools": [
{
"name": "lookup_price",
"description": "Lookup a stock price by ticker.",
"input_schema": {
"type": "object",
"properties": {
"ticker": { "type": "string" }
},
"required": ["ticker"]
}
}
],
"tool_choice": { "type": "tool", "name": "lookup_price" }
}'POST /v1/responses/compact 是标准 Responses 端点的简化版本,适用于不需要完整 Responses 请求结构的场景。
与标准端点的差异:
| 字段 | /v1/responses |
/v1/responses/compact |
|---|---|---|
instructions |
json.RawMessage(JSON 编码的字符串) |
string(直接传入文本) |
tools / tool_choice |
✅ | ❌ |
text / truncation / include |
✅ | ❌ |
input / model / stream |
✅ | ✅ |
reasoning / reasoning_effort |
✅ | ✅ |
temperature / top_p / max_output_tokens |
✅ | ✅ |
请求示例:
curl http://127.0.0.1:4000/v1/responses/compact \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"model": "ark-code-latest",
"instructions": "只输出最终答案。",
"input": "1+1=",
"max_output_tokens": 64
}'注意:
instructions直接传文本字符串(不需要 JSON 编码),其余行为与标准端点一致。
图像和音频接口将请求透传给上游,支持适配器预处理和基本参数校验。
- 参数校验:
model为必填字段;/v1/images/generations还要求prompt必填 - 上游错误标准化:上游返回的错误响应会被解析为标准 OpenAI 错误格式
- 适配器:如果上游有特殊要求(如参数限制),可通过适配器进行预处理
加 --log 后会输出:
- 模型名
- 是否流式
- 工具数量
- 粗略输入 token 估算
- 上游错误状态码与截断后的请求摘要
- 完成耗时与 token 用量
日志会摘要化 messages、tools,避免完整输出大段正文。
测试:
go test ./...静态检查:
go vet ./...构建:
go build -ldflags="-s -w" -o responses-to-chat main.go- 只暴露
/v1/responsesHTTP / WebSocket,不暴露/v1/chat/completions。 - HTTP 不维护服务端会话状态;WebSocket 仅在单连接内维护
previous_response_id增量输入。 - 非 function 类型工具会被忽略。
- 上游必须兼容 Chat Completions 格式。
- 代理不负责判断模型是否属于套餐或账号权限范围。