a6-plugin-ai-proxy
概览
ai-proxy 插件将 Apache APISIX 变为 AI 网关。客户端可以将受支持协议的请求发送到 APISIX,而无需自行处理服务提供方身份认证和端点选择。插件会检测客户端协议、选择兼容的服务提供方端点,在适配器可用时转发原生格式或进行格式转换,并处理响应流式传输。
适用场景
- 将 Chat Completions、Responses API、Embeddings、Anthropic Messages 或 Bedrock Converse 请求代理到兼容的服务提供方
- 在网关集中管理 API Key,而不是将其分发给客户端
- 为 LLM 调用增加可观测性,包括 Token 数和延迟
- 与
ai-prompt-template、ai-prompt-decorator或内容审核插件组合,构建完整的 AI 网关处理链
协议检测
APISIX 会结合请求 URI 检测协议。Anthropic Messages 请求必须使用以 /v1/messages 结尾的 URI,Bedrock Converse 请求必须使用以 /converse 结尾的 URI。如果没有这些后缀,请求体可能会被识别为其他协议,例如 OpenAI Chat。
包含 input 字段的 OpenAI Responses 请求必须使用以 /v1/responses 结尾的 URI,否则 APISIX 会将请求体识别为 OpenAI Embeddings。Embedding 路由则应使用以 /v1/embeddings 结尾的 URI。
使用 Bedrock 流式传输时,面向客户端的 URI 仍须以 /converse 结尾,并在请求体中设置 stream: true。APISIX 随后会选择上游 /model/{modelId}/converse-stream 端点。
支持的服务提供方
| 服务提供方 | 值 | 端点行为 |
|---|---|---|
| OpenAI | openai | 在 https://api.openai.com 上自动选择 /v1/chat/completions、/v1/responses 或 /v1/embeddings |
| DeepSeek | deepseek | https://api.deepseek.com/chat/completions |
| Azure OpenAI | azure-openai | 通过 override.endpoint 自定义 |
| Anthropic | anthropic | 在 https://api.anthropic.com 上自动选择 /v1/chat/completions 或 /v1/messages |
| AIMLAPI | aimlapi | https://api.aimlapi.com/v1/chat/completions |
| OpenRouter | openrouter | https://openrouter.ai/api/v1/chat/completions |
| Gemini | gemini | https://generativelanguage.googleapis.com/v1beta/openai/chat/completions |
| Vertex AI | vertex-ai | https://aiplatform.googleapis.com |
| Amazon Bedrock | bedrock | Bedrock Runtime 的区域和模型专属端点;自 APISIX 3.17.0 起可用 |
| OpenAI 兼容 | openai-compatible | 通过 override.endpoint 自定义 |
插件配置参考
| 字段 | 类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
provider | string | 是 | — | 10 个受支持服务提供方之一 |
auth | object | 是 | — | 认证配置(见下文) |
options | object | 否 | — | 模型和生成参数 |
options.model | string | 否 | — | 模型名称(提供方相关) |
options.temperature | number | 否 | — | 采样温度 |
options.top_p | number | 否 | — | 核采样 |
options.max_tokens | integer | 否 | — | 生成的最大 Token 数 |
options.stream | boolean | 否 | — | 覆盖传出请求的 stream 字段。对于 Bedrock Converse,在发往 /converse 的请求中设置 stream: true 会选择 /model/{modelId}/converse-stream,并返回未经修改的 AWS EventStream 二进制帧,响应头为 Content-Type: application/vnd.amazon.eventstream,而不是 SSE;客户端必须解析 EventStream 响应。 |
override | object | 否 | — | 服务提供方端点和请求体覆盖设置 |
override.endpoint | string | 否 | — | 服务提供方的协议和主机,或包含 路径及查询参数的完整 URL |
provider_conf | object | 否 | — | Vertex AI 或 Amazon Bedrock 的服务提供方专属配置 |
provider_conf.project_id | string | 否 | — | Vertex AI 的 GCP 项目 ID;除非已配置 override.endpoint,否则必须与 region 一起提供 |
provider_conf.region | string | 否 | — | Vertex AI 的 GCP 区域;Amazon Bedrock 的必填 AWS 区域 |
logging | object | 否 | — | 日志选项 |
logging.summaries | boolean | 否 | false | 记录模型、耗时和 Token |
logging.payloads | boolean | 否 | false | 记录请求/响应体 |
timeout | integer | 否 | 30000 | 请求超时时间(毫秒) |
keepalive | boolean | 否 | true | 保持连接 |
keepalive_timeout | integer | 否 | 60000 | Keepalive 超时时间(毫秒) |
keepalive_pool | integer | 否 | 30 | Keepalive 连接池大小 |
ssl_verify | boolean | 否 | true | 校验 SSL 证书 |
按服务提供方配置身份认证
OpenAI / DeepSeek / AIMLAPI / OpenRouter
{
"auth": {
"header": {
"Authorization": "Bearer sk-your-api-key"
}
}
}
Anthropic
{
"auth": {
"header": {
"x-api-key": "your-anthropic-api-key",
"anthropic-version": "2023-06-01"
}
}
}
原生 Anthropic Messages 请求需要 anthropic-version 请求头。请按上例在 auth.header 中配置该请求头,或要求客户端发送它。
Azure OpenAI
{
"auth": {
"header": {
"api-key": "your-azure-key"
}
},
"override": {
"endpoint": "https://YOUR-RESOURCE.openai.azure.com/openai/deployments/gpt-4/chat/completions?api-version=2024-02-15-preview"
}
}
Gemini
{
"auth": {
"header": {
"Authorization": "Bearer your-gemini-key"
}
}
}
Vertex AI (GCP 服务账户)
{
"auth": {
"gcp": {
"service_account_json": "{ ... }",
"max_ttl": 3600,
"expire_early_secs": 60
}
},
"provider_conf": {
"project_id": "your-project-id",
"region": "us-central1"
}
}
service_account_json 也可以通过 GCP_SERVICE_ACCOUNT 环境变量设置。
Amazon Bedrock
{
"auth": {
"aws": {
"access_key_id": "your-access-key-id",
"secret_access_key": "your-secret-access-key",
"session_token": "your-session-token"
}
},
"provider_conf": {
"region": "us-east-1"
},
"options": {
"model": "your-model-id"
}
}
使用临时 AWS 凭证时必须提供会话令牌。
自定义 OpenAI 兼容 API
{
"auth": {
"header": {
"Authorization": "Bearer your-token"
}
},
"override": {
"endpoint": "https://your-custom-llm.com/v1/chat/completions"
}
}
分步操作:路由到 OpenAI
1. 创建启用 ai-proxy 的路由
a6 route create -f - <<'EOF'
{
"id": "openai-chat",
"uri": "/v1/chat/completions",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer sk-your-openai-key"
}
},
"options": {
"model": "gpt-4",
"temperature": 0.7,
"max_tokens": 1024
}
}
}
}
EOF
2. 发出请求
curl http://127.0.0.1:9080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is 1+1?"}
]
}'
网关添加身份认证信息并将请求转发到 OpenAI,客户端无需接触提供商 API Key。
常见模式
流式响应
{
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer sk-your-key"
}
},
"options": {
"model": "gpt-4",
"stream": true
}
}
}
}
客户端会收到服务器发送事件(SSE)。如需在流式模式下获取 Token 数,客户端应在请求体中加入 stream_options.include_usage: true。
Azure OpenAI
{
"plugins": {
"ai-proxy": {
"provider": "azure-openai",
"auth": {
"header": {
"api-key": "your-azure-key"
}
},
"options": {
"model": "gpt-4"
},
"override": {
"endpoint": "https://myresource.openai.azure.com/openai/deployments/gpt-4/chat/completions?api-version=2024-02-15-preview"
},
"timeout": 60000
}
}
}
Embeddings 端点
a6 route create -f - <<'EOF'
{
"id": "embeddings",
"uri": "/v1/embeddings",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer sk-your-key"
}
},
"options": {
"model": "text-embedding-3-small"
},
"override": {
"endpoint": "https://api.openai.com/v1/embeddings"
}
}
}
}
EOF
启用日志
{
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer sk-your-key"
}
},
"options": {
"model": "gpt-4"
},
"logging": {
"summaries": true,
"payloads": false
}
}
}
}
具有多条路由的模型路由
插件本身不会按模型路由。请创建多条路由,并使用 vars 匹配请求正文中的模型字段:
# Route requests for gpt-4 to OpenAI
a6 route create -f - <<'EOF'
{
"id": "openai-gpt4",
"uri": "/v1/chat/completions",
"methods": ["POST"],
"vars": [["post_arg.model", "==", "gpt-4"]],
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": { "header": { "Authorization": "Bearer sk-openai-key" } },
"options": { "model": "gpt-4" }
}
}
}
EOF
# Route requests for deepseek-chat to DeepSeek
a6 route create -f - <<'EOF'
{
"id": "deepseek-chat",
"uri": "/v1/chat/completions",
"methods": ["POST"],
"vars": [["post_arg.model", "==", "deepseek-chat"]],
"plugins": {
"ai-proxy": {
"provider": "deepseek",
"auth": { "header": { "Authorization": "Bearer sk-deepseek-key" } },
"options": { "model": "deepseek-chat" }
}
}
}
EOF
使用ai-proxy-multi进行负载平衡
对于跨提供商的负载平衡、故障转移和基于优先级的路由,
改用ai-proxy-multi:
{
"plugins": {
"ai-proxy-multi": {
"balancer": {
"algorithm": "roundrobin"
},
"fallback_strategy": ["rate_limiting", "http_429", "http_5xx"],
"instances": [
{
"name": "openai-primary",
"provider": "openai",
"priority": 1,
"weight": 8,
"auth": {
"header": { "Authorization": "Bearer sk-openai-key" }
},
"options": { "model": "gpt-4" }
},
{
"name": "deepseek-backup",
"provider": "deepseek",
"priority": 0,
"weight": 2,
"auth": {
"header": { "Authorization": "Bearer sk-deepseek-key" }
},
"options": { "model": "deepseek-chat" }
}
]
}
}
}