路由

JoyToken 的路由发生在 api-gateway 内部。网关先校验 API Key 和策略,再把 OpenAI 兼容请求整理成 router-service 的 Route 输入。路由器返回 selected_model 后,网关才会执行钱包预冻结、提供方调用、用量计算和账单记录。

POST /openai/v1/chat/completions
-> ValidateApiKey
-> build policy
-> Route
-> wallet freeze
-> provider invoke
-> usage / billing

路由输入

Chat 请求会被转换成路由输入:

输入来源
request_id当前实现中路由输入使用网关内部生成的 req-<timestamp>;外部 X-Request-ID 主要用于网关日志、账单和提供方链路
session_id请求里的 user;没有时使用 chat: 加最后一条 user message
user_idAPI Key 校验结果里的 owner_id
system_prompt第一条 role = system 的 message
messagesOpenAI messages 转换后的 role / content
latest_prompt最后一条 user message;没有 user message 时使用最后一条 message
client_ipX-Forwarded-ForX-Real-IP 或远端地址
tools请求里的 OpenAI 兼容 tools

如果 message content 是数组或对象,网关会先序列化为 JSON 字符串再交给路由器。视觉输入会被识别为 vision 能力标签。

模型选择

model 字段决定网关是否让路由器自动选型,或者把请求约束成固定模型。

请求模型当前行为
未传或空字符串使用网关默认模型;如果没有默认值,等同 auto
autorouter-service 在策略允许范围内自动选择模型
固定模型 ID网关会把它放进路由策略的 fixed_model,仍然经过路由器校验和解析
API Key 绑定 fixed_model如果请求模型不是 auto 且不同于绑定模型,网关直接拒绝
Auto routing request
1{
2 "model": "auto",
3 "tier": "standard",
4 "messages": [
5 { "role": "user", "content": "Summarize this support ticket." }
6 ]
7}
Pinned model request
1{
2 "model": "GLM-5",
3 "messages": [
4 { "role": "user", "content": "Write a concise release note." }
5 ]
6}

Tier 选择

JoyToken 当前把 tier 归一化为三档:

标准 tier常见别名
economye, low, basic, free
standards, m, mid, middle, medium, normal
premiump, h, high, l, large, pro

实际可用 tier 来自几层约束的交集:

  1. API Key 创建时绑定的策略快照。
  2. API Key 自己绑定的 tier
  3. 请求体里的 tier
  4. 钱包余额和预算预检查。

如果请求体传了不合法的 tier,网关返回 403 policy_rejected。如果请求 tier 不在策略允许范围内,也会被拒绝。

策略约束

网关会从 policy_snapshot_json 和 API Key 绑定字段中组装策略,再传给路由器:

约束来源和用途
routing_strategy策略快照;支持 BALANCECOST_FIRSTQUALITY_FIRSTSPEED_FIRST
allowed_tiers策略里的 tiers / allowed_tiers、API Key tier、请求 tier 的交集
model_blacklist禁止命中的模型列表;固定模型也会检查黑名单
fixed_modelAPI Key 固定模型或请求固定模型
ip_whitelist / ip_blacklist网关在调用 router 前先检查客户端 IP
tag策略绑定的场景标签,会被小写归一化
industry_packs策略绑定的行业场景包
required_feature_tags网关根据请求内容补充,例如图片输入会要求 vision
quota_remaining来自 API Key limit_daily,作为路由输入之一

钱包感知回退

如果请求是 model: "auto",并且第一次路由选中的 tier 在钱包预冻结时余额不足,网关会在策略允许范围内尝试重新路由到其他 tier。

当前 tier回退顺序
premiumstandard -> economy
standardpremium -> economy
economystandard -> premium

这个回退只在 model: "auto" 时触发。固定模型请求如果预冻结失败,会直接返回 402 insufficient_quota

响应元数据

非流式响应会把路由信息合并进 JSON body 的 metadata。流式响应会在 [DONE] 之前追加一条元数据事件。

Response metadata
1{
2 "metadata": {
3 "model": "GLM-5",
4 "tier": "standard",
5 "score": 7.57,
6 "task_score": {
7 "system_score": 0.1,
8 "tool_score": 0.2,
9 "history_score": 0.4,
10 "latest_conversation_score": 0.8,
11 "total_score": 0.86,
12 "tier": "standard"
13 },
14 "latency": {
15 "routing_ms": 6,
16 "first_token_ms": 875,
17 "stream_ms": 9878
18 },
19 "billing": {
20 "credits_used": "0.2288",
21 "input_tokens": 54,
22 "output_tokens": 545,
23 "cached_input_tokens": 0,
24 "cached_output_tokens": 0
25 }
26 }
27}

成功响应还会带响应头:

响应头含义
X-DAOE-Used-Model提供方实际使用的模型
X-DAOE-Used-Providerprovider-adapter 返回的提供方
X-DAOE-Failover流式提供方故障切换时为 1

常见排查

现象优先检查
requested tier is invalid请求体 tier 是否能归一化为 economy / standard / premium
requested tier is not allowedAPI Key 策略是否允许该 tier
requested model is not allowedAPI Key 是否绑定了固定模型
client ip is not allowed策略快照的 IP 白名单
wallet balance is insufficient钱包余额、预算、所选 tier 的预冻结额度
router response missing selected_modelrouter-service 是否返回了合法的 selected_model