智能路由
按任务难度给请求挑模型:判定模型读一眼问题,再交给对应档位的模型
智能路由让网关替你判断这条请求有多难,再把它交给合适的模型:简单的问题走便宜的模型,复杂的任务走强力的模型。做法是给客户端一个虚拟模型(默认 astra-auto):客户端把模型选成它,Astra 就先让一个小的判定模型看一眼问题,选出档位,再把请求发给那个档位的模型。
功能默认关闭。要打开,先配好判定模型和每个档位的模型;配不全时开关会被拒绝,并告诉你缺哪一项。客户端选其他(真实)模型时完全不受影响。
它怎么工作
- 客户端请求的模型是虚拟模型(
astra-auto)。 - Astra 取出最近一条用户消息(已经过隐私护栏),问判定模型:这条请求该用哪个档位?
- 判定模型回答档位和把握有多大。它不生成文字,只回答这一道选择题。
- 请求发往该档位的模型。请求日志里「请求模型」仍是
astra-auto,「上游模型」是实际用的那个。
和直接用 OpenRouter 的 jev-router 有什么不同
OpenRouter 上的 typesafe/jev-router 是「判定 + 生成」一体的聊天模型,决策在 OpenRouter 一侧,选不到你自己的提供商和账号。
Astra 的智能路由把判定和生成拆开:判定交给判定模型,生成仍走你配置的提供商、账号、故障转移和计费。
三步配置
① 判定模型
| 项目 | 说明 |
|---|---|
| 接口协议 | TypeSafe Jev(默认):TypeSafe 的 System One 接口,POST {地址}/v1/systemone。OpenRouter、Vercel AI Gateway 等托管的 Jev 用的是同一个协议,只是地址和模型名不同。OpenAI Decisions:OpenAI 的 Decisions 接口,POST {地址}/v1/decisions |
| 服务 | 预设:TypeSafe 官方、OpenRouter、Vercel AI Gateway(OpenAI 协议下是 OpenAI 官方),也可以填自定义地址。选预设会同时填好地址和模型名 |
| API 密钥 | 判定服务自己的密钥。加密保存,界面只显示掩码 |
| 判定模型 | TypeSafe 默认 jev-latest(一个别名,指向当前的稳定版)。调好阈值之后建议固定版本号,例如 jev-1.13.0 |
| 超时 | 默认 2000 毫秒。超时按失败处理,这条请求改用回退档位。需要先建立连接时(服务启动后的第一次判定、连接断开之后)多等 3 秒:经代理建立连接常常要好几秒 |
| 判定指令 | 留空使用内置问题:「哪个档位是能把这条请求做好的最便宜的一档?」。需要时可以改 |
更改服务地址会清除已保存的密钥
一把密钥只属于签发它的服务。把判定模型指到另一个地址(或换了接口协议)时,如果没有同时填入新服务的密钥,已保存的密钥会被清除,不会被发到新地址。
Jev 是什么:TypeSafe 的 System One「决策模型」,不生成文字,只对你给的问题返回选择和概率,官方标价输入每百万 token 0.042 美元、输出免费,官方称一次判定的端到端响应在 70 到 500 毫秒(厂商自己的数字,以你的网络实测为准)。官方说明不会用客户的请求训练模型;数据保留期限以 TypeSafe 的数据处理协议为准。
OpenAI Decisions 目前是草案
OpenAI 这一路是按第三方文档对 OpenAI 格式的描述实现的,没能用 OpenAI 官方文档核对。启用前请先用下面的「试一试」确认它能正常工作。
试一试:输入一段话,点「判定」,用页面上现在的设置(不用先保存)问一次判定模型,看它选哪个档位、有多大把握、花了多久。它会调用一次判定服务,按量计费。「试一试」比真实请求等得久:回答比真实请求允许的时间慢时,结果里会写明真实请求会改用回退档位。第一次判定通常要先建立连接,再试一次才是平时的速度。
连接:Astra 和判定服务之间的连接建立后,只要空闲不超过一小时就一直保留(能用 HTTP/2 时用 HTTP/2,并定时发心跳),之后的判定不用再握手,经代理时一次判定通常只要几百毫秒。
② 档位与模型
档位是一把从省钱到强力的梯子,默认三个:light、standard、heavy,可以改成 2 到 6 个。每个档位有:
- 名称,只用于显示;
- 描述:判定模型读的就是这段话,所以要写清楚这一档的任务长什么样。建议用英文写:TypeSafe 官方说明非英文文本的判定准确率较低;
- 模型:从已启用的提供商模型里选,选的是「某个提供商的某个模型」。判定出这个档位,请求就发给这个提供商的这个模型——不是调用方自己绑定的提供商里碰巧也有同名模型的那一个。同一个模型有几个提供商都提供时,列表里每个提供商各占一项。
档位的顺序就是从便宜到强力的顺序,可以用上移 / 下移调整。
谁能用到档位的提供商
允许「所有客户端」的令牌(默认令牌就是)可以用到任何档位的提供商,客户端不用另外绑定它。 限制了客户端的令牌只用它本来就能用到的提供商(客户端绑定的、令牌直连的), 这样虚拟模型不会把一个受限的令牌带到别处。档位的提供商它用不到——或者那个提供商停用了、不再提供这个模型、只允许 Claude Code 使用——时, 请求会改用离它最近、用得到的档位(先往更强的找,没有再往弱的找),不会发给一个会回「模型不存在」的提供商; 智能路由页面会列出是谁用不到哪个档位、为什么、该怎么改。
用不到一个档位的原因(页面、请求日志和链路的 astra.route.adjusted_reason 用的是同一套):
| 原因 | 记录的值 | 怎么办 |
|---|---|---|
| 令牌限制了客户端,档位的提供商不在它能用的范围里 | token_limited | 在「令牌」页让它允许所有客户端,或在「客户端」页给调用方绑定这个提供商 |
| 档位的提供商已被删除 | provider_missing | 给档位重新选一个模型 |
| 档位的提供商已停用或没有接口地址 | provider_off | 启用它(或补上接口地址),或给档位换一个模型 |
| 档位的提供商是只允许 Claude Code 的订阅,调用方不是 Claude Code | claude_code_only | 给档位换一个模型,或在订阅设置里允许其他客户端 |
| 档位的提供商现在不提供这个模型(没有,或已停用) | model_not_served | 到「提供商」页检查这个模型,或给档位换一个 |
旧版本保存的档位只记了模型名:Astra 会补上当时显示在模型旁边的那个提供商(按提供商列表的顺序,第一个提供这个模型的),下次保存时一并存下。
③ 路由规则
什么时候判定:
| 规则 | 行为 | 取舍 |
|---|---|---|
| 按会话(默认) | 一个会话判定一次,之后一直用同一个档位。判成最低档时不钉住:问候、「1+1」这类简单问题之后,下一条消息再判定,直到某一条判成更高的档位 | 少调用判定服务,也不会中途换模型(换模型会让提示缓存失效)。代价:会话后来的任务变难了也不会升档 |
| 每次提问 | 每条新的用户消息判定一次;同一条消息里因工具结果产生的后续请求沿用它的档位 | 能跟着任务难度变化。代价:多调用判定服务,换模型会让提示缓存失效 |
会话靠请求里的会话标识识别(Claude Code 的会话 id、Codex 的 session-id 或 prompt_cache_key,没有的时候用「系统提示 + 第一条用户消息」的指纹)。**拿不到会话标识时,按会话规则会退化成每次提问。**带 previous_response_id 的 Responses 请求依赖上一个响应所在的提供商,所以从不换模型。
其余几项:
| 项目 | 说明 |
|---|---|
| 会话保持时间 | 默认 60 分钟,会话空闲超过它,下一次请求重新判定(每次用到都会续期) |
| 回退档位 | 判定失败、把握不够或读不到内容时使用,默认取中间一档 |
| 最低把握 | 0 到 1,默认 0.3。把握是判定概率的集中程度,不是答对的概率。TypeSafe 没有推荐值,可以先用默认值,再用「试一试」调 |
| 带上之前几条用户消息 | 默认 2。给判定模型一点上下文(「继续」这类很短的消息需要它);0 表示只发当前这一条 |
| 发送字数上限 | 默认 6000。一次判定最多发出去多少个字符 |
| 虚拟模型名(高级) | 默认 astra-auto。不能和某个提供商的真实模型重名 |
启用与使用
页面顶部的开关会连同页面上还没保存的修改一起保存。启用需要:判定服务的密钥和模型已填,每个档位都选了一个当前有提供商提供的模型。
启用后:
- 客户端页给客户端选模型时,列表里会出现虚拟模型;
GET /v1/models(以及 Gemini 的模型列表)会列出「Astra Auto」;- 直接调用时把请求里的
model写成astra-auto。
关闭智能路由后,仍请求虚拟模型的客户端会收到明确的提示「智能路由未启用」,而不是上游的「模型不存在」。已经写进客户端配置里的虚拟模型名不会被自动清除。
部分客户端按模型名推断能力
有的客户端会按模型名判断上下文窗口、思考设置等能力,虚拟模型名对它们是陌生的。如果遇到这种情况,可以在「高级」里把虚拟模型名改成客户端更认得的样子。
判定失败时
判定出任何问题都不会让这条请求失败:请求改用回退档位,并且不会被钉住,会话的下一次请求会重新判定。
| 情况 | 记录的原因 |
|---|---|
| 超时、连不上、密钥被拒绝、被限流、服务繁忙、请求被拒绝、返回的内容无法识别 | timeout network auth rate_limited overloaded bad_request bad_response |
| 判定的把握低于最低把握 | low_confidence |
| 请求里没有可读的用户文字(例如只有工具结果) | no_text |
| 密钥没有保存,或者保存的密钥读不出来 | not_configured |
| 判定服务连续失败 3 次后,30 秒内不再调用它 | breaker |
回退不会让请求失败,所以光看回答看不出来。智能路由页面的「最近的判定」列出最近 50 次新的判定(沿用会话或同一条消息的不算):几次按判定分配、几次因为什么改用了回退档位、判定服务回答的中位耗时。大多数判定都没用上时,页面会提示该检查什么;保存设置后从头统计。有客户端用不到某个档位的模型时,页面也会列出来。
隐私与成本
- 发出去什么:只发送最近一条用户消息,以及之前最多 N 条用户消息(合计不超过字数上限),不发送助手回复、工具结果、图片和系统提示。去掉了 Claude Code 注入的
<system-reminder>块。 - 隐私护栏:发给判定模型的文字取自隐私护栏处理之后的请求,所以脱敏模式下发出去的是占位符。在「只检测不处理」(试运行)模式下,请求本身不被改写,判定模型收到的和上游收到的一样是原文。
- 判定服务是第三方,请按你对它的信任程度选择。
- 成本:判定调用不是网关请求,不计入令牌的额度和限流,费用记在判定服务的账上,请求日志里也没有它自己的一行。每次判定的 token 数记在这条请求的链路里。
- 中文准确率:TypeSafe 官方只说非英文文本的准确率较低,没有给出数据。用中文提问的话,请先用「试一试」验证,必要时换成 OpenAI 协议对照。
查看判定结果
在请求日志里,请求模型是虚拟模型名,上游模型是实际用的模型,模型名旁边的「智能路由」标记写着这条请求怎么分的:绿色是按判定分配(刚判定的,或沿用会话 / 本轮的判定),橙色是没按判定走——「回退 standard(超时)」表示没用上判定、走了回退档位,「light → standard(用不到)」表示判定的档位这个调用方用不到、改用了别的档位。鼠标停在标记上能看到发往哪个模型,打开请求详情的「智能路由」一节有档位、决定来自、把握、回退原因和判定耗时。在链路追踪里,走了虚拟模型的请求会在隐私护栏和解析之间多一个「智能路由」节点,点开可以看到档位、决定从哪来、把握和判定耗时。展开节点底部的「记录的全部属性与事件」,字段是:
| 属性 | 含义 |
|---|---|
astra.route.mode | session 或 turn |
astra.route.source | 决定从哪来:judge(刚判定的)、pin(会话钉住的)、turn(同一条消息里沿用的)、fallback、breaker |
astra.route.grade / astra.route.model | 选中的档位编号和它的模型 |
astra.route.confidence | 判定的把握(0–1) |
astra.route.fallback_reason | 用回退档位的原因,见上表 |
astra.route.adjusted_from | 原本判定的档位:这个调用方用不到它,请求改用了 astra.route.grade |
astra.route.adjusted_reason | 用不到的原因,见「谁能用到档位的提供商」下面的表 |
astra.route.judge.protocol / .model / .ms / .input_tokens / .output_tokens | 这次判定调用的协议、判定服务报告的模型、耗时和 token 数(沿用的决定没有这几项) |
astra.route.judge.new_connection | 这次判定要先和判定服务建立连接 |
常见问题
选了 astra-auto 报「智能路由未启用」。 打开智能路由页面的开关;开关打不开时,页面会列出还缺哪些配置。
报「模型不存在」。 看链路里 astra.route.model 是哪个模型,再确认这个客户端能用到的提供商里有它。
同一个会话里模型变了。 「按会话」不会中途换模型。会换的情况有:会话标识不稳定(系统提示里带时间戳,会让指纹变化)、改了智能路由的设置(旧的钉全部作废)、会话空闲超过保持时间、Astra 重启(钉只存在内存里)。
很简单的问题(比如「1+1」)也被分到了中档。 先看请求日志里这条请求的「智能路由」标记(橙色表示没按判定走),或者链路图上的「智能路由」节点(提醒色表示没用上判定,或改过档)。决定来自「回退」或「熔断」时,判定根本没用上,请求走的是回退档位(默认中间一档),原因在「回退原因」里;最常见的是超时,见下一条。决定来自「判定」但写着原判定档位时,判定选的是更便宜的档位,但调用方用不到那个档位的提供商(见「谁能用到档位的提供商」)。只有「判定」且没有原判定档位时,才是判定模型自己的选择:用「试一试」看它的把握,必要时改写档位描述。
判定经常超时。 智能路由页面「最近的判定」会显示超时的次数。再看超时那几条请求的「智能路由」节点:写着「先建立了连接」,说明慢在建立连接,经代理时常见。判定服务的地址能直连时,可以让它绕过代理:在「设置」→「网络代理」里选「自定义」,填上原来的代理地址,再把判定服务的域名填进「不走代理的地址」。连接建好以后,只要空闲不超过一小时,之后的判定都不用再握手。判定本身就慢时,把超时调大一些。
判定很慢。 把超时调短,超时和连续失败都会自动改用回退档位。判定服务连续失败时,Astra 会在 30 秒内不再调用它。
第一句很短,整个会话被钉在便宜的档位。 判成最低档时不会钉住会话,下一条消息会重新判定;判定把握低于最低把握时也不会钉住。仍然不合适的话,改用「每次提问」。
Astra Gate