模型下线生效日的两条坑:单查假阴性退出码 0,列表计数恒差 9
最近在整一份模型依赖清单,顺手赶上 2026-10-10 这天六条百炼模型下线公告共同生效。我上午 10:4x 拿自己关心的二十个模型 ID 对了一遍账,下午 13:4x 又对了一遍,本来只想确认名单上的 ID 有没有开始报错,结果先撞上两条跟下线没直接关系的坑。记下来,都是能复现的读数。
坑一:单查返回 not found,退出码却是 0
先看命令。查一个模型 ID 在不在架,最顺手的写法是单查:
bl model list --model wan-video
echo $?
上午 10:41 的输出是 Model "wan-video" not found.,退出码 0。
我一开始以为自己敲错了 ID。回分页全量列表翻了一遍,wan-video 明明在列。再逐个试,同一批里 cosyvoice、embedding、qwen-rerank、deepseek、Kimi-K2、happyhorse-1.1 也是同样的结果:单查说 not found,分页列表里在列,退出码 0。加起来七个家族。
同一条单查对另一部分 ID 又完全正常。qwen3-max、qwen3-vl-flash、qwen3-coder-plus 单查成功,qwen3-max-2026-01-23、deepseek-v3、kimi-k2-thinking 这些带日期后缀的快照 ID 单查也成功。
下午 13:47 我原样复测了一遍,七个仍然 not found,退出码仍然是 0。假阴性是稳定的,不是网络抖动。成因我从外部查不到,也没有文档说明这一批为什么进不了单查,所以只记现象,不猜原因。
坑在退出码上。任何按 returncode == 0 判断"查询成功"的脚本,会把"查无此模型"当成功处理,然后一路走进"模型在架"的分支。我自己那份预检脚本是靠匹配输出文本判断的,所以它这天报了警;要是当初图省事只看退出码,它到今天还会是绿的。
bl finetune capability --base-model 对同族 ID 给的是同样的假阴性,一起记上。

坑二:total 与实际返回恒差 9,而且矩阵在缩
分页拉全量:
bl model list --page-size 50 --output json
翻完四页,两次读数如下。
| 读数 | 上午 10:4x | 下午 13:4x |
|---|---|---|
| 四页实际返回的模型族数 | 179 | 178 |
返回体 total 字段 |
188 | 187 |
total 减实际返回 |
9 | 9 |
两条独立的事实。一是矩阵在一天之内缩了一个族;二是 total 两次都比实际返回多 9,差值稳定。差 9 的原因我查不到,所以两个数都留着,不做换算。
实践上的结论很简单:写盘点脚本时,遍历以翻页拿到的实际记录数为准,total 只当参考值,别拿它当基数去算完成率或者校验分页是否拉全。
顺带一条相关的盲区。分页列表的浏览态里,每个家族的 items 是空数组,带日期后缀的快照 ID 在这一层根本看不见,只有单查成功之后从家族详情的 items[] 里才读得到。13:4x 查 qwen3-max 家族,items 是四个:qwen3-max、qwen3-max-2026-01-23、qwen3-max-preview、qwen3-max-2025-09-23,名单上的那几个此刻仍作为家族成员列在详情里。资产盘点只跑分页列表的话,快照 ID 一个都扫不到。
还有一条负结论:列表返回的 JSON 里,offline、deprecate、retire、sunset、expire 这些词我全搜了一遍,没有任何下线标记字段。在架状态没法从字段推断,只能拿名单做集合差。

那名单上的 ID 今天到底能不能调
这条不是坑,是必须写清楚的边界。
官方错误码页写的是:调用已下线模型返回 403 Endpoint.AccessDenied,原文举例是 qwen-max-2025-01-25 这类历史快照。
上午 10:44 我拿名单上的三个 ID 各发了一次一个 token 的最小调用,加一个对照的在架 ID:
qwen3-max → ok,exit 0
qwen3-coder-plus → ok,exit 0
qwen3-max-2026-01-23 → ok,exit 0
qwen3.7-max(对照) → ok,exit 0
下午 13:46 用对账脚本再跑一批快照 ID,单查层面同样全部返回在架。两次都没复现到 403。
我能写的只有一句:生效日上午与下午两次实测,名单上的 ID 仍可调用成功,与错误码页的预期报错不一致;公告自带【以实际变更时间为准】,灰度还是延迟,从外部判定不了。我不写"下线没生效",那超出了我手里的证据。
对写脚本的人,含义是两条:probe 通过不等于不在名单上,这两个判断口径不同;报错开始的那天不会提前打招呼,所以门禁得建在名单对账上,不能建在报错监控上。
把两条坑绕过去:一个对账脚本
三条路径各有盲区,让它们互相补就行。我把对账写成 check_model_ids.py:分页拉全量拿家族集合;逐个单查,成功就读 items 拿快照;单查说 not found 的,回分页集合里看家族在不在,在就标 ⚠ 假阴性;带日期后缀的 ID 再按前缀回退找家族核对。
npm install -g bailian-cli
python3 check_model_ids.py qwen3-max wan-video cosyvoice deepseek-v3 qwen3.7-max
13:48 的输出:
# 分页全量:4 页 / 178 个家族(bl 2.1.0,No Auth)
模型 ID 单查 分页家族 家族详情 items 结论
qwen3-max ok 在列 含 在架(单查与详情一致)
wan-video not-found(exit0) 在列 - ⚠ 列表在列但单查假阴性
cosyvoice not-found(exit0) 在列 - ⚠ 列表在列但单查假阴性
deepseek-v3 ok - - 在架(单查与详情一致)
qwen3.7-max ok 在列 含 在架(单查与详情一致)
七个假阴性家族全部落在 ⚠ 那一列,没有一个被写成"不存在"。脚本不要鉴权、只读、不耗额度,四页列表约十秒拉完,挂在发布流程里成本可以忽略。
它不解决名单从哪来。名单要自己去官方机制页 help.aliyun.com/zh/model-studio/model-depreciation 找,那页正文可读,10-10 这批挂了六条公告(118177、118434、118344、118345、118331、118332),往下还有八个历史批次,其中两批注明"未发布专项公告"。ID 级清单不在机制页上,也不在国内公告页里(那六页是 SPA 壳,正文只到"影响时间"),只在国际站同主题公告页上,正文可读、清单表是一张图,读图转出来是主线 5 条加快照 40 条与推荐替换模型名。表里同时印着单价,价格我不抄,能进代码的只有名字:主线替换集中在 qwen3.7-max、qwen3.6-flash、qwen3.7-plus 三个上。公告还写明推荐替换指引不再随新模型上线而频繁更新,抄下来得标日期。
另一半对账在控制台侧。机制页的操作建议第一条是去模型监控页看账号实际在调哪些模型,路径为控制台 > 模型监控。命令行答"这个 ID 在不在矩阵里",监控页答"我有没有在用",两问答完才轮到迁移。

适用场景与我留下的习惯
这套做法适合三类情况:依赖里写死了带日期后缀快照 ID 的项目;发布前想确认模型 ID 还认不认的流程;做资产盘点又发现列表数对不上的时候。不适合的也很明确:判断几点几分开始报错,只能给两个时刻的快照;做全自动门禁,ID 级名单只存在于公告表格图里,机器可读的文本名单今天不存在;预测下一批,历史上有两批没发专项公告。
三条习惯记在这儿。模型 ID 进代码之前过一遍对账脚本,进代码之后每次发布前再过一遍。快照 ID 与主线 ID 分开登记,登记时就把"它一定会下线"写进去。迁移建议人工核,官方明说替换指引不频繁更新,社区那篇迁移实录里(作者自述,我没复现)模型自给的建议凭空造出 8 个带 -latest 后缀的别名,还推荐了 23 个本身就在退役名单上的模型。
装对账能力是一条命令的事(CLI 安装页,API Key 签发页),列表这一步不要鉴权,先跑起来看看矩阵长什么样。百炼控制台首页在这里。
本文所有在架与可调通的读数都带时刻,2026-10-10 上午 10:4x 与下午 13:4x 各一遍。矩阵在动,total 与实际返回的差值也可能变,发布或排障前请重跑对账脚本,别拿本文的快照当现状。

浙公网安备 33010602011771号