跳到主要内容

上游请求头

/v1/chat/completions/v1/messages/v1/responses 等标准协议端点上,AISIX 会从头构建上游请求。它选择上游凭证、重写模型名称,并且只发送服务提供方协议要求的请求头。调用方发送的请求头不会转发,因此调用方不能使用自己的凭证或 Trace 上下文访问上游服务提供方。

当上游需要更多上下文时,可以通过两个服务提供方密钥设置扩展默认行为:

  • request.default_headers 添加由 AISIX 生成的请求头,其值可以引用当前请求,例如调用方 API Key 所属团队。
  • request.forward_client_headers 将指定的入站客户端请求头(例如 anthropic-beta 或 Trace 请求头)转发到上游。

这两项设置都位于服务提供方密钥上,因此引用该密钥的每个模型都会继承它们。

本指南的主要示例使用 AISIX Cloud。对于开源 AISIX 网关,请在 resources.yamlprovider_keys 下使用相同字段。

前置条件

开始前请准备:

  • 上游服务提供方凭证和端点。示例会围绕它们创建服务提供方密钥;该资源的其他字段参见服务提供方密钥
  • 对于 AISIX Cloud,需要环境、已关联网关和具有写入权限的 Admin Token。对于 On-Premises 部署,请按照 AISIX Cloud 快速入门操作。如需申请 Hybrid Cloud 访问权限,请联系 API7
  • 对于开源 AISIX 网关,需要一个加载声明式资源文件的网关。

导出 AISIX Cloud 连接信息和示例使用的值:

# AISIX_CP 是 Admin API 基础 URL;请包含 /api,且不要以斜杠结尾。
# 本地 On-Premises 快速入门使用 http://localhost:8080/api。
export AISIX_CP="YOUR_AISIX_CLOUD_ADMIN_API_URL"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
export ENV_ID="YOUR_ENVIRONMENT_ID"
export UPSTREAM_API_KEY="YOUR_UPSTREAM_API_KEY"
# AISIX_PROXY 是网关源地址;请不要包含末尾斜杠和端点路径。
# 本地快速入门使用 http://127.0.0.1:3000。
export AISIX_PROXY="YOUR_AISIX_GATEWAY_ORIGIN"
# 第一个示例创建密钥后设置,供更新示例使用。
export PK_ID="YOUR_PROVIDER_KEY_ID"
# 允许访问引用该服务提供方密钥的模型的调用方 API Key,
# 以及该模型的别名——用于文末的验证请求。
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
export MODEL_ALIAS="YOUR_MODEL_ALIAS"

注入请求上下文请求头

当上游需要知道调用者身份时,使用 request.default_headers。内部模型服务可以据此应用租户配额、把成本归属到团队,或将自身访问日志与 AISIX 请求 ID 关联,而且无需为每个租户准备单独的上游凭证。

请求头值通常是字面字符串;如果包含 ${...} 引用,AISIX 会在认证调用方并选择模型后,按请求解析该引用:

curl -sS -X POST "$AISIX_CP/provider_keys" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "internal-vllm",
"provider": "byo",
"adapter": "openai",
"api_key": "'"${UPSTREAM_API_KEY}"'",
"api_base": "https://models.internal.example.com/v1",
"allowed_environments": ["'"${ENV_ID}"'"],
"request": {
"default_headers": {
"x-tenant-id": "${request.api_key.team_id}",
"x-cost-center": "${request.api_key.name}",
"x-correlation-id": "${request.id}",
"x-upstream-tier": "premium"
}
}
}'

❶ 调用方 API Key 所属团队,可作为上游配额或路由决策的租户标识符。

❷ 控制台中显示的调用方 API Key 名称。

❸ 当前请求的关联 ID,与 AISIX 在 x-aisix-request-id 中发送并写入自身日志的值相同。

❹ 字面值,每个请求都会原样发送。

可用变量

变量
request.id当前请求的关联 ID。
request.api_key.id调用方 API Key 的标识符。
request.api_key.name调用方 API Key 的名称。
request.api_key.team_id调用方 API Key 所属团队。
request.api_key.user_id拥有调用方 API Key 的组织成员。
model.id解析后模型的标识符。
model.name解析后模型面向调用方的名称,而不是上游模型名称。
provider_key.id当前服务提供方密钥的标识符。
provider_key.name当前服务提供方密钥的名称。

只有这些变量可以解析。保存服务提供方密钥时,如果值引用了其他名称,AISIX Cloud Admin API 会拒绝该值,使拼写错误立即失败,而不是变成一个永远无法到达上游的请求头。在资源文件中,相同形式还用于环境变量插值,参见在资源文件中配置

所有变量都不会暴露密钥。调用方 API Key、上游凭证和签名材料都不属于请求头值可以读取的请求上下文。

备注

如果请求头引用的变量在某次请求中并非都有值,AISIX 会从该请求中删除整个请求头,而不是发送空值。如果调用方 API Key 不属于任何团队,上述示例的请求会包含 x-cost-centerx-correlation-id,但不会包含 x-tenant-id。空的 x-tenant-id 会让上游误以为租户是空字符串。

转发客户端请求头

当调用方需要通过 AISIX 向服务提供方传递请求头时,使用 request.forward_client_headers。常见场景包括 Anthropic Beta 功能标记、分布式追踪请求头,以及内部模型平台读取的路由提示。

列出需要转发的请求头。每个条目可以是精确名称,也可以包含一个 * 通配符;匹配不区分大小写。两个配置块可以同时存在于同一服务提供方密钥上,下面分开展示只是为了让示例更清晰:

curl -sS -X POST "$AISIX_CP/provider_keys" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "internal-vllm-forwarding",
"provider": "byo",
"adapter": "openai",
"api_key": "'"${UPSTREAM_API_KEY}"'",
"api_base": "https://models.internal.example.com/v1",
"allowed_environments": ["'"${ENV_ID}"'"],
"request": {
"forward_client_headers": [
"anthropic-beta",
"traceparent",
"x-trace-*"
]
}
}'

❶ 精确名称。调用方发送 anthropic-beta 时,该请求头会到达服务提供方;未发送时则不会产生任何变化。

❷ W3C Trace Context 请求头,使 Trace 可以继续进入上游,而不是终止于 AISIX。

❸ 通配符条目,会匹配 x-trace-idx-trace-parent 以及具有该前缀的其他名称。使用 x-* 可以转发所有 x- 请求头,但 AISIX 绝不转发的请求头除外,任何模式都无法匹配这些请求头。

列表为空或不存在时(默认值),不会转发任何请求头。

调用方不能自行获得转发资格:该列表属于服务提供方密钥配置,没有被任何条目点名的调用方请求头仍会像以前一样被删除。

后续修改配置

在 AISIX Cloud 中,PATCH /provider_keys/{id} 接受相同的 request 配置块,变更会影响引用该密钥的每个模型。

该配置块会被整体替换,因此请发送需要保留的所有字段,而不只是发生变化的字段。先读取当前配置块——GET /provider_keys/{id} 会返回该值——然后提交编辑后的版本:

curl -sS -X PATCH "$AISIX_CP/provider_keys/$PK_ID" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"request": {
"default_headers": {"x-tenant-id": "${request.api_key.team_id}"},
"forward_client_headers": ["anthropic-beta", "x-trace-*"]
}
}'

空的 "request": {} 会清除该配置块,让密钥恢复为其服务提供方的内置默认值。完全省略该字段则会保留已存储配置块。

控制台中,相同配置块位于服务提供方密钥编辑表单的 Advanced wire-shape overrides 下,并会预填已存储值。

AISIX 绝不转发的请求头

无论如何配置,AISIX 都不会采用调用方发送的某些请求头。如果保存的服务提供方密钥在 forward_client_headers 中指定了其中任何一个,请求会失败;运行时,原本可由通配符匹配的保留请求头也会被跳过。

该限制针对调用方发送的副本。AISIX 仍会为其中一些名称发送自己的值,例如使用服务提供方密钥凭证进行身份认证、为构建的请求体设置 content-type,并添加 x-aisix-request-id

请求头组请求头原因
身份认证authorizationx-api-keyapi-keyx-goog-api-keyx-amz-datex-amz-security-tokenx-amz-content-sha256proxy-authorizationAISIX 使用服务提供方密钥自身的凭证向上游认证。转发调用方凭证会将其泄露给第三方。
会话与路由cookieset-cookiehost防止会话材料进入上游流量,并阻止通过 Host 重定向上游请求。
传输connectionkeep-alivetransfer-encodingcontent-lengthcontent-typecontent-encodingacceptaccept-encodingtetrailerupgradeexpect这些字段描述调用方连接和 AISIX 将要重写的请求体,而不是 AISIX 发出的请求。
网关所有x-aisix-*这些请求头由 AISIX 自行设置,包括 x-aisix-request-id,绝不会转发调用方副本。
客户端 SDKx-stainless-*调用方 SDK 发送的自身版本请求头。如果转发给同样使用这些请求头标识其 SDK 的服务提供方,会破坏调用。

如果请求确实需要保留原始请求头,请改用服务提供方直通。直通会按原样转发请求,只删除服务提供方密钥的 strip_headers 列表;同时会放弃标准端点提供的协议转换、统一遥测和跨服务提供方功能。

默认情况下,直通也不会转发调用方凭证:strip_headers 初始包含 authorizationcookieset-cookiex-api-key。如果从列表中删除相关条目,让调用方使用自身凭证访问上游,会把调用方密钥泄露给服务提供方。只有在你控制该上游且凭证本就用于该上游时才能这样做。

优先级

同名请求头来自多个位置时,按以下顺序确定优先级:

  1. AISIX 所有的请求头,例如上游凭证、content-typex-aisix-request-id
  2. request.default_headers
  3. request.forward_client_headers 转发的请求头。

请求头在传输时是单值;AISIX 会替换而不是追加,因此上游不会同时收到同名的运维方值和调用方值。

在资源文件中配置

开源 AISIX 网关在资源文件中支持相同字段:

provider_keys:
- display_name: internal-vllm
provider: byo
adapter: openai
api_key: ${UPSTREAM_API_KEY}
api_base: https://models.internal.example.com/v1
request:
default_headers:
x-tenant-id: ${request.api_key.team_id}
x-correlation-id: ${request.id}
forward_client_headers:
- anthropic-beta
- x-trace-*

完整字段目录参见资源文件参考

警告

在资源文件中,值中的 ${...} 也是加载时环境变量插值的语法。可用变量中列出的名称由网关按请求解析;其他 ${...} 会在文件加载时从环境中替换。命名环境变量时请注意区分两者。

验证

通过引用该服务提供方密钥的模型发送请求,并包含白名单中指定的请求头:

curl -sS -X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer $AISIX_API_KEY" \
-H "Content-Type: application/json" \
-H "x-trace-id: trace-0001" \
-d '{
"model": "'"${MODEL_ALIAS}"'",
"messages": [{"role": "user", "content": "ping"}]
}'

然后在上游确认请求携带预期请求头。可以查看你有权访问的上游服务访问日志。

如果将 api_base 指向请求检查服务,请记住 AISIX 会把服务提供方密钥凭证和请求体发送到该地址。请使用自己控制的端点、测试服务提供方密钥上的一次性凭证,以及不包含真实数据的提示词。

如果缺少预期请求头,请检查:

  • 请求头名称已列在 forward_client_headers 中,或与其中一个通配符条目匹配。
  • 请求头不属于 AISIX 绝不转发的请求头
  • 对于含变量的 default_headers 值,调用方 API Key 确实具有该属性。没有所属团队的 Key 会删除引用 request.api_key.team_id 的请求头。

后续步骤