跳到主要内容

代理 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 创建另一个路由:

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 路由的每个请求中。

路由配置包含 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 格式并规划应用迁移。