报 model_not_found 时,多数人的第一反应是「模型被下架了」,跑去问客服,或者干脆换个更贵的模型试。这个方向九成是错的。真实原因几乎都是同一件事:你代码里写的那串模型名字,和网关认识的那串字符串对不上。模型没下线,通道也活着,只是它不认识你说的这个名字。
网关收到请求,第一步就是拿 model 字段去自己的清单里查表。查不到就立刻退回,顺手给你一句「不存在,或者你没权限」。这是模板文案,同时盖住了三种完全不同的情况:名字拼错了、名字属于别的平台前缀、你真的没开通这个模型。所以它读起来永远像在甩锅。
把 model not found 翻译成人话:网关拿着你给的字符串,在模型清单里没查到。清单里很可能有个长得几乎一样、只差一个字符的名字,但字符串比对是精确匹配,差一个连字符就是不认识,「差不多」不算数。
顺序反了会浪费整晚。先花三十秒拉清单,九成情况在这一步就结束了。
不同网关、不同客户端吐出来的文案差别很大,先认全,后面一眼看到就知道该往哪查。
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。这些说法背后是同一个错误码,处理动作也一样。
invalid model 大多出现在 400,意思是「你这个字段值我不接受」,通常是字段位置或类型不对,请求根本没走到查表那一步。model_not_found 出现在 404,说明表已经查过了,确实没这个名字。拿到 400 就把完整请求体打出来看结构,拿到 404 就直接拉清单对名字。分不清这两个,会在字段格式上白找半天。
Chatbox、Cherry Studio、Cline 这类客户端会把上游报错吞掉,换成自己的一句中文提示。看到「模型不存在」,先别信客户端,去日志里翻原始响应体;看到「请求失败」,那多半是超时或限流,跟模型名没关系。能开日志的都开上,翻请求体直接看实际发出去的 model 字段。
别猜,直接问网关自己支持什么。
curl -s https://xyuapi.top/v1/models -H "Authorization: Bearer $KEY" | python -m json.tool | grep '"id"'
这条命令做了三件事:拉回清单、格式化成一行一个字段、只留模型 ID 那一行。输出就是一串模型 ID,把自己代码里那串字符在上面扫一遍。
清单长的时候肉眼扫容易看漏,用命令判:
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 的模型列出来,一般在里面就能找到你要填的那个名字,复制走人。
回 401 是 Key 的问题:鉴权头拼错、Bearer 后面少个空格、Key 前后粘进引号或换行符。把 Key 单独打印出来看长度和首尾就抓到了。
回 404 是路径的问题,多半 base_url 写错。把 https://xyuapi.top/v1 换成 https://xyuai.cc/v1 再敲一次,两个都能拉通,才说明网络和 Key 都没问题。
老教程里写什么名字你照着填,可平台上的正式 ID 是带版本号或思考后缀的那个。改法:拉清单,模糊搜到正式 ID,覆盖掉客户端配置里那一行,不要自己造名字。
写成 claude-sonnet-4.5 或者 Claude-Sonnet-4-5,都会直接 404。清单里的小写加连字符才是规范写法,点号、下划线、大写全属于另一个字符串。改法:从清单输出里复制粘贴,手打就有出错的机会。
有些客户端会自动加 openai/、anthropic/ 这类路由前缀,名字本身没错,加上前缀就查不到了。改法:把实际发出去的请求体打印出来看一眼,前缀是被自动加的就去设置里关掉它。
填成 https://xyuapi.top 会打到站点根路径;填成 https://xyuapi.top/v1/chat/completions 则是客户端又拼了一次路径,两段叠在一起。改法:base_url 只填到 https://xyuapi.top/v1 为止,后面的路径交给客户端拼。
OpenAI 兼容的对话走 /v1/chat/completions,Claude 原生走 /v1/messages,Gemini 原生走 /v1beta。同一个模型名在原生端点下可能有额外要求。改法:先用对话接口跑通,确认名字没问题,再去折腾原生端点。
把 model 塞进 messages 里,或者写成 "model": {"id": "..."} 这种对象。两种都会被判成字段不合法,报错有时还会伪装成模型不存在,把人带偏。改法:model 是顶层字段,值必须是纯字符串。
老 ID 停用很正常,清单里只保留新的。改法:在模糊搜的结果里挑一个当前在用的替代模型,把配置、缓存、客户端预设里的老名字一起换掉,只改一处等于没改。
请求里加了函数调用、图片理解、思考开关,但选的模型不支持。有些网关不给「能力不支持」,而是回一句模型不存在。改法:额外参数全去掉,只留 model、messages、max_tokens 发一次;通了再一个个加回来,加到哪个报错,问题就在那个参数上。
| 报错原文 | 真实含义 | 你现在该做的事 |
|---|---|---|
code 是 model_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 在顶层且是字符串 |
| 状态 401 | Key 或者鉴权头的问题 | 检查 Bearer 格式和 Key 本身,跟模型名无关 |
在 /v1/models 上回 404 | 路径或者 base_url 写错 | base_url 只写到 /v1,不要多写路径 |
| 客户端显示「模型不存在」但日志里是别的错 | 客户端把上游报错吞了 | 打开客户端日志,找原始响应体 |
认准几条书写规律,手写名字的出错率能降一大截。
claude-sonnet-4-5-thinking。-thinking 后缀,同一个家族的思考版和不思考版是两个 ID,不能互相顶替。-preview,比如 gemini-3-pro-preview,它和正式版同样算两个 ID。gpt-image-2-pro、NanoBanana-Pro。| 容易写错的名字 | 平台正式 ID | 单价 |
|---|---|---|
| claude-sonnet-4.5 | claude-sonnet-4-5-thinking | 0.09 元/次 |
| claude-opus-4.6 | claude-opus-4-6-thinking | 0.25 元/次 |
| gpt-5.5-thinking | gpt-5.5 | 0.2 元/次 |
| deepseek-v3 | deepseek-v3.2-thinking | 0.049 元/次 |
| deepseek-r1 | deepseek-r1-thinking | 0.049 元/次 |
| gemini-3-pro | gemini-3-pro-preview | 0.05 元/次 |
| gemini-2.5-pro-thinking | gemini-2.5-pro | 0.031 元/次 |
| grok-4 | grok-4.1 | 0.05 元/次 |
| kimi-k2 | kimi-k2.5 | 0.09 元/次 |
| nanobanana | NanoBanana-Pro | 0.27 元/次 |
生图模型按次算一整张图,调用方式和对话接口不一样。拿对话接口去调生图模型,报错往往也是找不到模型,容易被误导成名字写错了。
价格表为排版好看,会把两个 ID 挤在一格里用斜杠隔开。斜杠只是分隔符,不是模型名的一部分,把带斜杠的一整串粘进配置,必然查不到。
程序启动时先拉一次清单,把配置里的模型名逐个比对,不在清单里就打印最接近的候选,直接告诉你该改成什么,别等线上跑出 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。
只在联网的时候对名字不够用,本地留一份,写配置时随手就能查。
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
文件存好以后,写配置之前先在本地查一遍,比每次重新发请求快得多,离线也能用。
想找 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 元,支付宝和微信都能付,不需要海外信用卡。另有按量计费与无限卡套餐可选。
model 值是什么,用客户端日志或者抓包确认,不要信界面上显示的那一行。/v1 为止。这三件事按顺序核对一遍,model not found 这类报错基本都能当场收口。