代理 OpenAI 请求
OpenAI 提供用于文本生成、推理、多模态输入和工具使用的模型。
使用 APISIX 可以在网关集中处理服务提供方身份认证和模型选择,因此客户端应用不需要持有 OpenAI 凭证。
集中管理 OpenAI 流量还让运维人员能够在一个位置为多个应用统一应用限流、日志记录、提示词控制和其他网关策略。
本指南介绍如何使用 ai-proxy 插件代理 Chat Completions、Responses API 和 Embeddings 请求。Chat Completions 仍受支持,而 OpenAI 建议新的文本生成项目使用 Responses API。APISIX 会将配置的 API Key 和模型附加到每个请求。
前置条件
- 安装 Docker。
- 安装 cURL 以发送验证请求。
- 按照快速入门教程在 Docker 或 Kubernetes 中启动 APISIX 实例。
- 拥有 OpenAI 账户,并能通过 API 访问同时支持 Chat Completions 和 Responses API 的模型以及一个向量嵌入模型。
获取 OpenAI API Key
创建 OpenAI API Key,然后导出 API Key 和模型:
export OPENAI_API_KEY="<your-api-key>"
export OPENAI_MODEL="<your-model-name>"
export OPENAI_EMBEDDING_MODEL="<your-embedding-model-name>"
创建 OpenAI 路由
APISIX 会先检测每个 OpenAI 请求所用的协议,再选择对应的上游端点:
| 客户端协议 | 检测方式 | OpenAI 上游路径 |
|---|---|---|
| Responses API | 请求体包含 input,且请求 URI 以 /v1/responses 结尾。 | /v1/responses |
| Chat Completions | 请求体包含 messages 数组。 | /v1/chat/completions |
| Embeddings | 请求体包含 input,且未匹配 Responses API 或 Chat Completions 规则。 | /v1/embeddings |
APISIX 按表中顺序检查规则。Responses 和 Embeddings 请求都使用 input,因此包含 input 但不包含 messages 的请求,除非其 URI 以 /v1/responses 结尾,否则会被识别为 Embeddings。Responses 路由 URI 可以有自定义前缀,但必须保留该后缀。
为 Chat Completions 和 Responses API 请求创建一个路由,并为使用独立向量嵌入模型的 Embeddings 创建另一个路由:
- Admin API
- ADC
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
--data-binary @- <<EOF
{
"id": "openai-apis",
"uris": [
"/openai/chat",
"/openai/v1/responses"
],
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer $OPENAI_API_KEY"
}
},
"options": {
"model": "$OPENAI_MODEL"
}
}
}
}
EOF
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
--data-binary @- <<EOF
{
"id": "openai-embeddings",
"uri": "/openai/embeddings",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer $OPENAI_API_KEY"
}
},
"options": {
"model": "$OPENAI_EMBEDDING_MODEL"
}
}
}
}
EOF
❶ 配置任意面向客户端的 Chat Completions 路径。APISIX 仅根据 messages 字段识别该格式。
❷ 配置面向客户端的 Responses 请求路径。APISIX 根据 /v1/responses 后缀和 input 字段共同识别该格式。
❸ 选择 OpenAI 服务提供方。APISIX 会将检测到的各种请求格式分别发送到对应的 OpenAI 上游路径。
❹ 将配置的文本生成模型添加到此路由的每个请求中。客户端提供的模型不会覆盖该值。
❺ 配置任意面向客户端的 Embeddings 路径。当 Responses API 和 Chat Completions 规则均未匹配时,APISIX 根据 input 识别该格式。
❻ 将配置的向量嵌入模型添加到 Embeddings 路由的每个请求中。
services:
- name: OpenAI Service
routes:
- uris:
- /openai/chat
- /openai/v1/responses
methods:
- POST
name: openai-apis
plugins:
ai-proxy:
provider: openai
auth:
header:
Authorization: "Bearer ${OPENAI_API_KEY}"
options:
model: ${OPENAI_MODEL}
- uris:
- /openai/embeddings
methods:
- POST
name: openai-embeddings
plugins:
ai-proxy:
provider: openai
auth:
header:
Authorization: "Bearer ${OPENAI_API_KEY}"
options:
model: ${OPENAI_EMBEDDING_MODEL}
❶ 配置任意面向客户端的 Chat Completions 路径。APISIX 仅根据 messages 字段识别该格式。
❷ 配置面向客户端的 Responses 请求路径。APISIX 根据 /v1/responses 后缀和 input 字段共同识别该格式。
❸ 选择 OpenAI 服务提供方。APISIX 会将检测到的各种请求格式分别发送到对应的 OpenAI 上游路径。
❹ 将配置的文本生成模型添加到此路由的每个请求中。客户端提供的模型不会覆盖该值。
❺ 配置任意面向客户端的 Embeddings 路径。当 Responses API 和 Chat Completions 规则均未匹配时,APISIX 根据 input 识别该格式。
❻ 将配置的向量嵌入模型添加到 Embeddings 路由的每个请求中。
将配置同步到 APISIX:
adc sync -f adc.yaml
路由配置包含 OpenAI API Key。启用密钥环数据加密后,APISIX 会在将路由保存到 etcd 之前加密该 Key。生产环境中请配置自定义密钥环。
验证
使用三种受支持的 API 格式分别发送请求,以验证协议检测和上游路由。
发送 Chat Completions 请求
发送包含消息列表的请求:
curl -i "http://127.0.0.1:9080/openai/chat" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "system",
"content": "You explain technical concepts concisely."
},
{
"role": "user",
"content": "Explain what an API gateway does in one sentence."
}
]
}'
你应该收到 HTTP 200 响应。Chat Completions 在 choices[].message.content 中返回生成的文本:
{
"choices": [
{
"message": {
"role": "assistant",
"content": "An API gateway routes, secures, and manages requests between clients and backend services."
}
}
]
}
发送 Responses API 请求
发送包含独立指令和输入的请求:
curl -i "http://127.0.0.1:9080/openai/v1/responses" -X POST \
-H "Content-Type: application/json" \
-d '{
"instructions": "You explain technical concepts concisely.",
"input": "Explain what an API gateway does in one sentence."
}'
你应该收到 HTTP 200 响应。Responses API 在 output 中返回带类型的条目:
{
"status": "completed",
"output": [
{
"type": "message",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "An API gateway routes, secures, and manages requests between clients and backend services."
}
]
}
]
}
以流式方式发送 Responses API 请求
发送流式请求:
curl "http://127.0.0.1:9080/openai/v1/responses" -X POST \
--no-buffer \
-H "Content-Type: application/json" \
-d '{
"stream": true,
"input": "Count from one to five."
}'
❶ 禁用 cURL 输出缓冲,使其在每个事件到达时立即显示。
❷ 请求 OpenAI 返回流式响应。
该 数据流使用带类型的服务器发送事件,包括携带生成文本的 response.output_text.delta 事件,以及最后的 response.completed 事件。
ai-proxy 流式传输不需要 proxy-buffering 插件。该插件控制标准 NGINX 上游路径,而 ai-proxy 不使用这条路径发送服务提供方请求。如需更改 ai-proxy 刷新流式输出的频率,请配置 streaming_flush_interval_ms。将其设为 0 可同步刷新每个上游数据块。
发送 Embeddings 请求
向 Embeddings 路由发送输入字符串:
curl -i "http://127.0.0.1:9080/openai/embeddings" -X POST \
-H "Content-Type: application/json" \
-d '{
"input": "APISIX is an API gateway."
}'
你应该收到 HTTP 200 响应,其中 data[].embedding 包含一个向量:
{
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [
-0.0067,
-0.0392
]
}
]
}
清理
不再需要这些 APISIX 路由时,请将其删除:
curl "http://127.0.0.1:9180/apisix/admin/routes/openai-apis" -X DELETE \
-H "X-API-KEY: ${ADMIN_API_KEY}"
curl "http://127.0.0.1:9180/apisix/admin/routes/openai-embeddings" -X DELETE \
-H "X-API-KEY: ${ADMIN_API_KEY}"
从 Shell 中删除 OpenAI 相关值:
unset OPENAI_API_KEY OPENAI_MODEL OPENAI_EMBEDDING_MODEL
如果使用了 ADC,请从 adc.yaml 中删除 API Key,或按照组织的密钥处理策略保护该文件。
下一步
现在,你已将 APISIX 配置为可向 OpenAI 代理 Chat Completions、Responses API 和 Embeddings 请求。
参阅 OpenAI 的迁移指南,比较两种 API 格式并规划应用迁移。