API 报 model not found / 模型不存在 / invalid model?按这个顺序排查,十分钟找到是哪一步写错了

这个错 90% 不是模型下线了

model_not_found 时,多数人的第一反应是「模型被下架了」,跑去问客服,或者干脆换个更贵的模型试。这个方向九成是错的。真实原因几乎都是同一件事:你代码里写的那串模型名字,和网关认识的那串字符串对不上。模型没下线,通道也活着,只是它不认识你说的这个名字。

网关收到请求,第一步就是拿 model 字段去自己的清单里查表。查不到就立刻退回,顺手给你一句「不存在,或者你没权限」。这是模板文案,同时盖住了三种完全不同的情况:名字拼错了、名字属于别的平台前缀、你真的没开通这个模型。所以它读起来永远像在甩锅。

报错说的是「网关不认识这个字符串」

model not found 翻译成人话:网关拿着你给的字符串,在模型清单里没查到。清单里很可能有个长得几乎一样、只差一个字符的名字,但字符串比对是精确匹配,差一个连字符就是不认识,「差不多」不算数。

三步排查路径,顺序不能乱

  1. 先拉清单对名字:把网关当前支持的模型 ID 全量拉下来,拿你写的那个字符串去清单里找,找得到才往下走。
  2. 再查客户端有没有偷偷加料:不少客户端和 SDK 会在你填的名字外面套前缀、加后缀,你以为发出去的是原来那个名字,实际发出去的是另一个字符串。
  3. 第三步才怀疑模型下线或权限:清单里确实没有,而且你确定以前能用,那才是换名、停用,或者账号没开通。

顺序反了会浪费整晚。先花三十秒拉清单,九成情况在这一步就结束了。

先把完整报错原文挖出来

四种真实报错原文,长什么样

不同网关、不同客户端吐出来的文案差别很大,先认全,后面一眼看到就知道该往哪查。

OpenAI 风格的 404,文案最长,也最容易被误读成权限问题:

{"error":{"message":"The model 'gpt-5.2' does not exist or you do not have access to it.","type":"invalid_request_error","code":"model_not_found"}}

Python SDK 抛异常时,会把状态码和错误体拼成一条字符串甩给你:

Error code: 404 - {'error': {'message': 'The model `gpt-4o` does not exist', 'type': 'invalid_request_error', 'code': 'model_not_found'}}

DeepSeek 那边的文案更短:

{"error":{"message":"Model Not Exist","type":"invalid_request_error"}}

自己搭过中转的人对这句更熟,这是通道层给的报错:

No available channel for model xxx

再往下还有客户端自己的中文兜底,界面上直接显示「模型不存在」或者 unknown model。这些说法背后是同一个错误码,处理动作也一样。

400 的 invalid model 和 404 的 model_not_found 不是一回事

invalid model 大多出现在 400,意思是「你这个字段值我不接受」,通常是字段位置或类型不对,请求根本没走到查表那一步。model_not_found 出现在 404,说明表已经查过了,确实没这个名字。拿到 400 就把完整请求体打出来看结构,拿到 404 就直接拉清单对名字。分不清这两个,会在字段格式上白找半天。

客户端那些模糊文案对应的真实错误

Chatbox、Cherry Studio、Cline 这类客户端会把上游报错吞掉,换成自己的一句中文提示。看到「模型不存在」,先别信客户端,去日志里翻原始响应体;看到「请求失败」,那多半是超时或限流,跟模型名没关系。能开日志的都开上,翻请求体直接看实际发出去的 model 字段。

第一条该敲的命令:拉模型清单对名字

一条 curl 把清单拉下来

别猜,直接问网关自己支持什么。

curl -s https://xyuapi.top/v1/models -H "Authorization: Bearer $KEY" | python -m json.tool | grep '"id"'

这条命令做了三件事:拉回清单、格式化成一行一个字段、只留模型 ID 那一行。输出就是一串模型 ID,把自己代码里那串字符在上面扫一遍。

用 grep 精确匹配,确认名字在不在

清单长的时候肉眼扫容易看漏,用命令判:

curl -s https://xyuapi.top/v1/models -H "Authorization: Bearer $KEY" \
  | python -m json.tool | grep -F '"claude-sonnet-4-5-thinking"'

-F 是纯字符串匹配,不把名字里的点号和连字符当正则元字符,避免假命中。有输出就是有,没输出就是没有。

想宽松一点,看看是不是只错了一点点,就把匹配改成大小写不敏感:

curl -s https://xyuapi.top/v1/models -H "Authorization: Bearer $KEY" \
  | python -m json.tool | grep -i 'sonnet'

这会把清单里所有带 sonnet 的模型列出来,一般在里面就能找到你要填的那个名字,复制走人。

拉不到清单怎么判断是 Key 的问题还是路径的问题

回 401 是 Key 的问题:鉴权头拼错、Bearer 后面少个空格、Key 前后粘进引号或换行符。把 Key 单独打印出来看长度和首尾就抓到了。

回 404 是路径的问题,多半 base_url 写错。把 https://xyuapi.top/v1 换成 https://xyuai.cc/v1 再敲一次,两个都能拉通,才说明网络和 Key 都没问题。

最常见的 8 个坑,每个都有改法

坑 1:客户端写死的模型名和平台正式 ID 不一致

老教程里写什么名字你照着填,可平台上的正式 ID 是带版本号或思考后缀的那个。改法:拉清单,模糊搜到正式 ID,覆盖掉客户端配置里那一行,不要自己造名字。

坑 2:大小写和连接符写错

写成 claude-sonnet-4.5 或者 Claude-Sonnet-4-5,都会直接 404。清单里的小写加连字符才是规范写法,点号、下划线、大写全属于另一个字符串。改法:从清单输出里复制粘贴,手打就有出错的机会。

坑 3:多平台前缀加错了地方

有些客户端会自动加 openai/anthropic/ 这类路由前缀,名字本身没错,加上前缀就查不到了。改法:把实际发出去的请求体打印出来看一眼,前缀是被自动加的就去设置里关掉它。

坑 4:base_url 填错,漏 /v1 或多填路径

填成 https://xyuapi.top 会打到站点根路径;填成 https://xyuapi.top/v1/chat/completions 则是客户端又拼了一次路径,两段叠在一起。改法:base_url 只填到 https://xyuapi.top/v1 为止,后面的路径交给客户端拼。

坑 5:端点和模型名规则不匹配

OpenAI 兼容的对话走 /v1/chat/completions,Claude 原生走 /v1/messages,Gemini 原生走 /v1beta。同一个模型名在原生端点下可能有额外要求。改法:先用对话接口跑通,确认名字没问题,再去折腾原生端点。

坑 6:model 字段放错层级

model 塞进 messages 里,或者写成 "model": {"id": "..."} 这种对象。两种都会被判成字段不合法,报错有时还会伪装成模型不存在,把人带偏。改法:model 是顶层字段,值必须是纯字符串。

坑 7:模型确实换名或下线

老 ID 停用很正常,清单里只保留新的。改法:在模糊搜的结果里挑一个当前在用的替代模型,把配置、缓存、客户端预设里的老名字一起换掉,只改一处等于没改。

坑 8:带了模型不支持的能力参数

请求里加了函数调用、图片理解、思考开关,但选的模型不支持。有些网关不给「能力不支持」,而是回一句模型不存在。改法:额外参数全去掉,只留 modelmessagesmax_tokens 发一次;通了再一个个加回来,加到哪个报错,问题就在那个参数上。

排查对照表:报错原文 → 真实含义 → 该敲哪条命令

报错原文真实含义你现在该做的事
codemodel_not_found,状态 404清单里没有这个字符串/v1/models,精确匹配一次
The model 'xxx' does not exist or you do not have access to it.名字不存在,或者账号没开这个模型清单里有就查账号权限,没有就改名
Model Not Exist同样是清单里查不到检查大小写和连字符,错一个字符也算不存在
No available channel for model xxx名字可能没错,但当前没有可用通道等几十秒重试,持续出现就换同系列另一个 ID
状态 400,文案是 invalid model字段值或者字段位置不合法打印完整请求体,确认 model 在顶层且是字符串
状态 401Key 或者鉴权头的问题检查 Bearer 格式和 Key 本身,跟模型名无关
/v1/models 上回 404路径或者 base_url 写错base_url 只写到 /v1,不要多写路径
客户端显示「模型不存在」但日志里是别的错客户端把上游报错吞了打开客户端日志,找原始响应体

模型 ID 的命名规律与对照表

小鱼API 上真实的模型 ID 长什么样

认准几条书写规律,手写名字的出错率能降一大截。

常见「以为要写」的名字 vs 平台正式 ID

容易写错的名字平台正式 ID单价
claude-sonnet-4.5claude-sonnet-4-5-thinking0.09 元/次
claude-opus-4.6claude-opus-4-6-thinking0.25 元/次
gpt-5.5-thinkinggpt-5.50.2 元/次
deepseek-v3deepseek-v3.2-thinking0.049 元/次
deepseek-r1deepseek-r1-thinking0.049 元/次
gemini-3-progemini-3-pro-preview0.05 元/次
gemini-2.5-pro-thinkinggemini-2.5-pro0.031 元/次
grok-4grok-4.10.05 元/次
kimi-k2kimi-k2.50.09 元/次
nanobananaNanoBanana-Pro0.27 元/次

生图和推理模型的命名差异

生图模型按次算一整张图,调用方式和对话接口不一样。拿对话接口去调生图模型,报错往往也是找不到模型,容易被误导成名字写错了。

别把价格表里的写法当模型 ID

价格表为排版好看,会把两个 ID 挤在一格里用斜杠隔开。斜杠只是分隔符,不是模型名的一部分,把带斜杠的一整串粘进配置,必然查不到。

上线前用 Python 校验模型名

思路:启动时对一遍白名单

程序启动时先拉一次清单,把配置里的模型名逐个比对,不在清单里就打印最接近的候选,直接告诉你该改成什么,别等线上跑出 404 才发现。

完整代码

import difflib
import os
import requests

BASE = "https://xyuapi.top/v1"
KEY = os.environ["XYU_KEY"]
CONFIGURED = [
    "claude-sonnet-4-5-thinking",
    "gemini-2.5-pro",
    "gpt-5.5",
    "deepseek-v3-thinking",
]

def fetch_ids():
    resp = requests.get(
        f"{BASE}/models",
        headers={"Authorization": f"Bearer {KEY}"},
        timeout=30,
    )
    resp.raise_for_status()
    return [m["id"] for m in resp.json()["data"]]

def main():
    ids = fetch_ids()
    print(f"gateway models: {len(ids)}")
    for name in CONFIGURED:
        if name in ids:
            print(f"OK   {name}")
            continue
        near = difflib.get_close_matches(name, ids, n=3, cutoff=0.5)
        print(f"BAD  {name} -> 候选: {near or '无相近模型'}")

if __name__ == "__main__":
    main()

跑一次就知道配置里哪几个名字是错的。difflib 是标准库,不用装东西,候选按相似度排序,第一条一般就是你要改成的那个名字。

相似度候选怎么算

get_close_matches 的第三个参数是候选个数,第四个是相似度下限。名字带版本号的时候,把下限调到 0.4 到 0.5,报出来的候选更全;只想看最接近的那一个,就把个数设成 1、下限提到 0.7。

把模型清单存到本地,随时 grep

存成 models.json

只在联网的时候对名字不够用,本地留一份,写配置时随手就能查。

mkdir -p ~/.cache/xyu
curl -s https://xyuapi.top/v1/models -H "Authorization: Bearer $KEY" \
  -o ~/.cache/xyu/models.json
wc -c ~/.cache/xyu/models.json

文件存好以后,写配置之前先在本地查一遍,比每次重新发请求快得多,离线也能用。

用 grep -i 模糊搜

想找 Claude 全系列:

grep -o '"id": *"[^"]*"' ~/.cache/xyu/models.json | grep -i claude

只想看有哪些生图模型:

grep -o '"id": *"[^"]*"' ~/.cache/xyu/models.json | grep -i -E 'image|banana|draw'

想一次找好几个关键词,把 -E 里的词用竖线连起来,想加几个加几个。搜出来的每一行都是能直接复制进客户端的正式 ID。

定期刷新这份缓存

模型清单会变,加新模型、停老模型都会动到它。写个定时任务每天拉一次,或者在部署脚本里加一行都行。这条命令本来就幂等,多跑几次不会有副作用。

落地建议与计费说明

接入方式很直接

小鱼API(xyuai.cc)是 AI API 接入平台,协议按 OpenAI 兼容来做,任何支持自定义 OpenAI 地址的客户端都能接。

项目
主入口https://xyuapi.top/v1
备用入口https://xyuai.cc/v1
对话接口/v1/chat/completions
模型清单/v1/models
计费方式按次计费为主,输入长度不影响价格
最低充值7 元,支付宝或微信付款

Chatbox、Cherry Studio、NextChat、Cline、RooCode、KiloCode、LobeChat 这些客户端都行,只要填三样东西:接口地址、Key、模型 ID。模型 ID 从上面那条清单命令里复制,别手打。

计费按次,输入长度不影响价格

一次请求固定价,输入长度不影响价格。几个实际会用到的手感数字:gemini-2.5-pro 每次 0.031 元,deepseek-v3.2-thinking 每次 0.049 元,claude-sonnet-4-5-thinking 每次 0.09 元,gpt-5.5 每次 0.2 元,claude-opus-4-6-thinking 每次 0.25 元。最低充值 7 元,支付宝和微信都能付,不需要海外信用卡。另有按量计费与无限卡套餐可选。

出错时优先核对的三件事

  1. 模型名字符串和清单里的正式 ID 是否逐字符一致,大小写和连字符都算数。
  2. 请求里实际发出去的 model 值是什么,用客户端日志或者抓包确认,不要信界面上显示的那一行。
  3. base_url 有没有多写或者少写路径,正确写法是只到 /v1 为止。

这三件事按顺序核对一遍,model not found 这类报错基本都能当场收口。

相关阅读

🚀 想要立即使用?来小鱼API体验全系列AI模型

查看全部产品

支持Gemini / Claude / GPT / Grok / DeepSeek · 国内直连 · 支付宝/微信