跳到主要内容

Route(路由)

当前版本的 route 运行时数据直接来自 PostgreSQL routes 主表。

关键字段

  • id
  • tenant_id
  • name
  • path_prefix
  • disabled_at
  • disable_auth
  • protocol_transformation_type
  • legacy_bearer_auth_tokens
  • passthrough_auth_token
  • groups
  • labels
  • plugin_config(运行时由 plugin_configs 表聚合得到)
  • metadata

注意:

  • 上面的 plugin_config 是运行时字段
  • Management API 的 Route 资源已不再包含这个字段
  • 管理面需要通过独立的 RoutePluginConfigService 管理 route 级插件配置

当前运行时语义

一条请求命中 route 后,会继续执行:

  1. path_prefix 最长前缀匹配
  2. 按 route 认证优先级决定是否鉴权
  3. 进入 groups 约束与 upstream 选择
  4. 取 route / consumer / api key 的分组交集
  5. upstream_models 中解析候选 upstream,并按 key 展开成候选集
  6. 先按候选的 priority 从高到低排序;仅在同优先级内按权重随机无放回排序
  7. 把候选列表交给 forwarder,在内部做 fallback 编排

补充:

  • GET /v1/models 不再透传某个上游的 /models
  • gateway 会先按现有认证 / groups / 协议过滤逻辑解析“完整可用 upstream 集合”
  • 当前本地 /models 聚合不会读取 provider / upstream capabilities
  • 然后聚合这些 upstream 的 upstream_models.model,去重后按字母序返回 OpenAI 兼容的 models list
  • 因此 /v1/models 的结果不会受 route.max_attempts 重试上限影响

Forwarder Capabilities

  • forwarder capability 已从 route 移到 provider.capabilities / upstream.capabilities
  • 这组能力只描述“请求已经进入 forwarder 且已选到某个 upstream 后,是否允许继续处理该接口”
  • upstream.capabilities 非空时会完整覆盖 provider 默认值;为空时继承 provider
  • 当 provider 与 upstream 都未显式配置时,运行时会按 provider.protocol 推导默认能力集

协议转换

  • chat 入站协议按裁剪后的请求路径判断:/chat/completions/responses/messages
  • 上游协议按 upstream -> provider -> protocol 判断
  • 默认 protocol_transformation_type = if-different-protocol
  • 当前 chat 主线已固定走统一 IR 模型:
    • 按入站协议解析 RequestIR
    • 按候选 upstream 的 provider.protocol 组装请求
    • 成功候选返回后,再按原始入站协议回组装响应
  • 因此当前运行时不会按 protocol_transformation_type 的不同取值切换“透传 / 转换 / 报错”行为
  • 该字段目前仍保留在 route 配置与管理面模型里,后续若重新接入运行时开关语义,会再单独说明
  • chat 路径当前支持三种入站协议:
    • /chat/completions -> chat-completions
    • /responses -> open-responses
    • /messages -> claude-messages
  • 成功候选返回后,gateway 会始终按原始入站协议回组装响应

Chat 请求体解析

当前 chat 请求在进入 forward_chat middleware 前,会先由 gateway 解析为内部 IR。

这意味着当请求体无法通过对应入站协议的解析或校验时,gateway 会直接返回本地 400 invalid chat request body: <reason>,而不会继续透传给上游做校验。

多 Upstream 与 Fallback

  • 一个 upstream 配置多个 API key 时,会被展开成多个独立候选
  • 候选排序先按 upstream.priority 从高到低分层;同优先级内再做加权随机无放回
  • upstream_api_key 继承所属 upstream 的优先级
  • upstream_api_key.lb_weight 优先;未设置或 <= 0 时回退到 upstream.lb_weight
  • 单次请求最多尝试 route.max_attempts 个候选,默认 2
  • 任意非 2xx、transport error、assemble/parse error 都会触发 fallback
  • 对于流式 chat,请求一旦成功向客户端写出首个 event,就锁定当前候选,不再 fallback

认证优先级

当前 route 的认证优先级固定为:

  1. disable_auth = true
  2. passthrough_auth_token = true
  3. legacy_bearer_auth_tokens 非空
  4. 默认走 consumer_api_keys

分组语义

  • routes.groups = [] 表示 route 不限制组
  • consumers.groups = [] 表示 consumer 不限制组
  • consumer_api_keys.groups = [] 表示 api key 不限制组
  • upstreams.group 仍然是单值,默认 default

如果最终没有任何显式分组约束,运行时会回落到 upstream 的 default 组。