Route(路由)
当前版本的 route 运行时数据直接来自 PostgreSQL routes 主表。
关键字段
idtenant_idnamepath_prefixdisabled_atdisable_authprotocol_transformation_typelegacy_bearer_auth_tokenspassthrough_auth_tokenallow_missing_model_pricingupstreamsupstream_selectormodel_selectorplugin_config(运行时由plugin_configs表聚合得到)
注意:
- 上面的
plugin_config是运行时字段 - Management API 的 Route 资源已不再包含这个字段
- 管理面需要通过独立的 RoutePluginConfigService 管理 route 级插件配置
当前运行时语义
一条请求命中 route 后,会继续执行:
- 按
path_prefix最长前缀匹配 - 按 route 认证优先级决定是否鉴权
- 进入 route 绑定 upstream 与 selector 选择
- 以
route.upstreams[]为基础集合,再叠加 route / consumer / api key selector - 在
upstream_models中解析候选 upstream,并按 key 展开成候选集 - 先按
route.upstreams[].priority从小到大排序;仅在同优先级内按route.upstreams[].lb_weight做加权随机无放回排序 - 把候选列表交给 forwarder,在内部做 fallback 编排
补充:
GET /v1/models不再透传某个上游的/models- gateway 会先按现有认证 / route 绑定 / selector / 协议过滤逻辑解析“完整可用 upstream 集合”
- 当前本地
/models聚合不会读取 provider / upstreamcapabilities - 然后聚合这些 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 - 当
protocol_transformation_type = disabled时,运行时会追加一个内部 upstream selector:aidy/protocol = 入站协议,因此候选阶段只会保留同协议 upstream - 当前 chat 主线已固定走统一 IR 模型:
- 按入站协议解析
RequestIR - 按候选 upstream 的
provider.protocol组装请求 - 成功候选返回后,再按原始入站协议回组装响应
- 注:即使同协议,当前 chat 主线仍采用先解析 IR 再重组的路径;
protocol_transformation_type在这里的影响是,forced会忽略未知的字段,而if-different-protocol则保留(更类似透传);但无论是哪种,如果请求体无法通过协议的校验将返回错误
- 按入站协议解析
- 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 时,会被展开成多个独立候选
- 候选排序先按
route.upstreams[].priority从小到大分层;仅在同优先级内再按route.upstreams[].lb_weight做加权随机无放回 - 多 API key 当前只是展开成多个
id/key凭证候选,等价于多条相同 route-upstream priority 和 lbWeight 的候选 route.upstreams[].priority的语义是“数值越小优先级越高”- 单次请求最多尝试
route.max_attempts个候选,默认2 - 任意非
2xx、transport error、assemble/parse error 都会触发 fallback - 对于流式 chat,请求一旦成功向客户端写出首个 event,就锁定当前候选,不再 fallback
认证优先级
当前 route 的认证优先级固定为:
disable_auth = truepassthrough_auth_token = truelegacy_bearer_auth_tokens非空- 默认走
consumer_api_keys
Selector 语义
route.upstreams[]决定这条 route 允许使用哪些 upstreamroute.upstream_selector/consumer.upstream_selector/consumer_api_key.upstream_selector会继续收紧 upstream 候选route.model_selector/consumer.model_selector/consumer_api_key.model_selector会继续收紧upstream_models候选- 空 selector 表示不额外限制
- 具体语义见 Label & Selector
如果 route.upstreams[] 为空,则这条 route 当前没有任何可用 upstream。
缺失模型价格策略
- 默认情况下,alias 映射后的真实上游模型必须存在对应 provider pricing,否则请求会在转发前被拒绝。
- Tenant 或 Route 任意一个设置
allow_missing_model_pricing = true时,允许缺失价格的请求继续。 - 价格检查使用实际请求到上游的模型名;例如客户端请求 alias
gpt-4o-mini-latest,映射到上游gpt-4o-mini后,会检查gpt-4o-mini的价格。