模型列表拉不出来怎么排查:自动拉取型与手写型工具的两条不同路径

2026-08-07

接好自定义 API 之后选不到模型,第一步不该是换密钥,而是先判断你手上这个工具的模型列表到底是它自己去服务端拉的,还是要你一行行写进配置文件的。 这两类工具的排查动作从第一步就分叉:前者是网络与端点的问题,后者根本不是”出错”,而是你还没写。判断错了方向,密钥换三遍也没用。

本文只谈”模型选不到”这一段。相关但不同的问题各有专文:路由到了某个上游却调用失败,看 OpenRouter 路由失败排查;模型能选到、请求也发出去了,但返回的 JSON 结构对不上导致解析炸掉,看 API 返回结构变了怎么办;模型正常但工具读不懂你的代码库,那是索引层的事,看 Cursor 索引失败排查。这篇的边界很窄:卡在”还没能选中一个模型”之前。

一、先分清两类:列表是拉来的,还是你写上去的

先把一个容易混的概念说清楚。OpenAI 兼容端点指的是:服务商把自家的接口做成和 OpenAI 那套 HTTP 协议一样的形状,路径、请求体、返回体都对齐,于是任何按 OpenAI 协议写的客户端都能直接接上去。绝大多数编程工具的”自定义模型”功能,走的就是这条路。

但”协议一样”不等于”取模型列表的方式一样”。截至 2026-08-07 各家官方文档,可以看出两种明显不同的设计取向:

第一类,客户端主动去拉。 Kilo Code 官方文档写明:凭据有效时,它会从 /v1/models 端点自动拉取模型列表;自动检测失败可以手动填模型 ID。按这段文档描述的机制去推,这类工具的”没有可选模型”就有一条可追的因果链 —— 有一次取列表的网络请求应该发出去过,结果不合预期。链条可追,排查才有顺序可言。

第二类,你写多少它就有多少。 Zed 的 settings.json 里,模型写在 available_models 数组中,每一项自己带 namedisplay_namemax_tokens。Continue 的 config.yaml 里,模型写在 models 块下,每一项必填 nameprovidermodel 三项。这两家的文档记录都是手写形态。对这类工具来说,你没写,就没有 —— 这不是故障,是设计。

判断方法很直接:看这个工具的官方文档里,配置模型时给的是”一个表单/一条命令”,还是”一段 YAML/JSON 数组”。给数组的,八成属于第二类。

顺带说一句界面:本文不描述任何一家的界面长什么样,配置项在哪一屏、有没有提示文字,以你实际看到的界面为准。这里只谈配置层,因为配置层是你能在文件里、在终端里自己复核的部分。

二、自动拉取型:排查顺序跟着那次请求走

如果你的工具属于第一类,排查就沿着”客户端 → 端点 → 凭据 → 返回”这条链走,而不是漫无目的地换东西。

第一步核 Base URL 的形态。 这一项各家写法不统一,也最容易照着别家的示例填错。Kilo Code 官方文档明确说它接受两种形态:标准形态 https://api.provider.com/v1,以及完整端点 https://api.provider.com/v1/chat/completions;文档说明第二种是为”端点结构非标准”的服务商与自建网关准备的。注意这是 Kilo Code 这一家文档的写法,别把它套到别家 —— 各家这一项连字段名都不一样,详见下一节的表。

至于”少写或多写一段路径会怎样”,这属于 HTTP 路由的一般机制:客户端会把配置的前缀和它自己要访问的路径拼起来发出去,拼出来的地址在服务端不存在,就拿不到列表。这是协议层的推理,不是哪家文档写的结论。要自己验一次很简单:打开终端,用 curl 带上你的密钥去请求你填进配置的那个地址后面接 /models(例如前缀写的是 .../v1,就请求 .../v1/models),命令形如 curl -H "Authorization: Bearer 你的密钥" 地址算通过的标准:HTTP 状态码 200,返回体里能看到一个模型对象的数组。若返回 404,说明地址拼错或该服务端不提供这个接口;返回 401/403,问题在密钥不在地址;连接直接失败或超时,问题在网络层,往下看第五节的边界说明。

第二步核凭据。 密钥无效时拉不到列表,这在逻辑上是显然的 —— Kilo Code 文档的措辞就是”凭据有效时”才会自动拉取。所以别急着怀疑端点,先确认这把密钥在别处能用。具体动作:拿上一步那条 curl 命令,把地址换成服务商文档首页给的示例地址,密钥不变再跑一次。算通过的标准:换了地址就能拿到 200,说明密钥没问题,锅在你填的那个前缀;两个地址都是 401/403,说明密钥本身失效或复制时带了空格与换行 —— 后者极常见,重新复制一遍再试。

第三步看是不是这条链根本不适用。 Kilo Code 文档里有一条很具体的提醒:接 Azure 上的 GPT-5 时,不要用通用的 OpenAI 兼容 provider,要用 Kilo 原生的 azure provider,因为 Azure 会拒绝 max_tokens 参数。这条提醒的价值在于提醒你一个更普遍的判断 —— 你以为的”兼容端点”,可能在某个参数上并不兼容。这时候换密钥、改 URL 都是徒劳。

第四步再回到手填。 Kilo Code 文档说得很清楚,自动检测失败可以手动填模型 ID。所以自动拉取型工具最终也能退化成手写型来用。这一步不丢人:并非所有 OpenAI 兼容端点都实现了列模型的那个接口,上一步的 curl 若稳定返回 404,基本就该走手填这条路了。手填时模型 ID 从哪儿抄?从服务商文档里调用示例的请求体上抄,别自己拼。

三、手写型:列表是空的,因为你还没写完那段配置

第二类工具的排查,本质上是”对照文档补字段”。

Continue 的模型配置在 config.yamlmodels 块下,必填三项:name(唯一标识)、provider(如 openai、ollama、mistral)、model(具体模型名)。可选项里有 apiBase,用于覆盖默认 API 端点。官方文档给的示例可以原样抄:

models:
  - name: GPT-4o
    provider: openai
    model: gpt-4o
    roles:
      - chat
      - edit
    defaultCompletionOptions:
      temperature: 0.7
      maxTokens: 1500

这里有个很容易忽略的机制:Continue 的 roles 取值有 chatautocompleteembedrerankeditapplysummarize默认值是 [chat, edit, apply, summarize]embed 指把文本转成向量用于检索,rerank 指对检索回来的结果重新排序 —— 这两件事和聊天是不同的角色。文档记录到”取值有哪些、默认是哪几个”为止,客户端拿这份取值具体怎么分派功能,文档没有逐条说明;按字段语义推,默认值里不含 embed/rerank,要用到它们大概率得显式写出来,实际行为以官方文档为准。这不是”列表空”,但和”某个功能选不到模型”是同一类误会。

Zed 这边,官方文档给的 settings.json 结构如下:

{
  "language_models": {
    "openai_compatible": {
      "my-provider": {
        "api_url": "https://example.com/v1",
        "available_models": [
          {
            "name": "my-model",
            "display_name": "My Model",
            "max_tokens": 128000
          }
        ]
      }
    }
  }
}

api_url 是自定义 base URL;available_models 是模型数组,每项含 name(模型标识)、display_name(界面显示名)、max_tokens(上下文窗口上限)。上下文窗口指模型一次请求能容纳的 token 总量,超出就装不下 —— 这一项在 Zed 这里要你自己填。另外 Zed 还有 capabilities 对象控制能力开关,含 tools、images、parallel_tool_calls 等。

密钥这一项 Zed 的文档态度很明确,原话是 “Do not put API keys in settings.json.”,另一页写的是 “Provider keys saved through Zed are stored in the system keychain, not in settings.json.”(keychain 是操作系统提供的凭据保管服务,密码由系统加密保存,不落在明文文件里)。凭据的两条路是:provider 设置界面,或环境变量,命名规则为 <PROVIDER_NAME>_API_KEY —— provider 名为 my-provider 时对应 MY_PROVIDER_API_KEY。以上是官方文档的说法,不是本文的建议。

顺带对照一下:Gemini CLI 的 settings.json 支持环境变量插值,写成 $VAR_NAME${VAR_NAME},加载时自动解析。所谓插值就是配置文件里只写变量名,实际值运行时从环境里取 —— 这样配置文件能进版本库,密钥不进。三家在”密钥怎么和配置文件共处”上给的答案不同,但都是可复核的文档事实。

四、字段对照表:同一件事,五个名字

下表的字段名逐字来自各家官方文档,核对日期 2026-08-07。

配置项(逐字)属于哪家它是什么这一项不对时的后果(按协议与字段语义推断,非厂商说法)出处
Base URLKilo Code服务端 API 的地址前缀,文档说接受 /v1/v1/chat/completions 两种形态拼出的地址在服务端不存在,请求拿不到有效返回kilo.ai 文档
ModelsKilo Code模型来源,可手动添加或自动检测自动检测走不通时需退回手填模型 ID同上
HeadersKilo Code可选,自定义 HTTP 头,键值对形式网关要求的鉴权头缺失时,请求会被上游拒绝同上
apiBaseContinue覆盖默认 API 端点不写则走该 provider 的默认端点,自建服务不会被访问到docs.continue.dev
rolesContinue模型承担的角色,默认 [chat, edit, apply, summarize]需要 embed/rerank 却没写,对应功能选不到这个模型同上
api_urlZed自定义 base URL同 Base URL 的路由后果zed.dev 文档
available_modelsZed手写的模型数组,每项含 name/display_name/max_tokens数组为空则没有可选项,这是配置结果不是故障同上
<PROVIDER_NAME>_API_KEYZed环境变量形式的密钥命名规则变量名拼错等同于没配密钥同上

再补一条跨家对照,同样来自各家文档:Cline、Roo Code、Kilo Code 在配置里叫 Base URL;Continue 叫 apiBase;Zed 叫 api_url;goose 用 OPENAI_HOST(另有 OPENAI_BASE_PATH,是拆成两段的设计);Crush 用命令行参数 --base-url这五个不是同一个东西,照搬别家的填法就是自己给自己造 bug。

还有一条硬门槛值得单列。Roo Code 官方文档原话是:

“Roo Code uses native tool calling exclusively. This is the only supported tool protocol — there is no XML-based fallback.”

原生工具调用(function calling)指模型按结构化协议返回”要调用哪个工具、传什么参数”,而不是把意图写在自然语言里让客户端猜。按 Roo Code 文档的说法,它只认这一种协议、没有 XML 回退,文档建议先查服务商文档确认该模型是否支持工具调用。这意味着在 Roo Code 上,“模型能选到”和”模型能干活”是两道关。Continue 有 capabilities.tool_use,Zed 的 capabilities 含 tools 与 parallel_tool_calls,说明这件事在几家都被当成需要显式声明的能力。

五、边界与代价:这条排查路径不管什么

先说这套方法放弃了什么。

它只覆盖配置层,不覆盖网络层。 公司代理、证书拦截、DNS 解析异常,都会让”端点填对了也拉不到”,而这套排查完全看不见这类原因。遇到怎么改配置都不通的情况,请把排查交给网络侧,别在配置文件里继续试。

它不判断模型好不好用。 能选中一个模型,和这个模型能不能撑住你的活,是两件事。工具调用支持与否、上下文窗口够不够,属于模型能力范畴,本文只讲到”配置项在哪一栏”为止。接入方式的整体对比可以看 编辑器接入自定义 API 的做法,兼容端点本身的协议差异看 OpenAI 兼容端点是什么

它不给你任何数字。 价格、免费额度、限速、各家支持的完整模型清单,本文一律不写,这类内容变化太快,写下来就是给你埋雷。

它不能替代官方文档的完整性。 本文依据的是各家官方文档在 2026-08-07 那一天的记录。某个字段没在本文出现,只说明本文依据的那一页记录里没有它,不等于该产品没有这项能力。要下结论请翻文末列出的原始 URL。

还有一件明确不管的事:本文不排各家座次。几家在设计取向上确实不同 —— 有的把模型列表交给服务端接口,有的要你写死在配置里 —— 但这是取向差异,不是优劣。自动拉取省事,代价是多一层依赖;手写麻烦,代价换来的是配置完全可预期。

六、避坑清单:为什么会踩,怎么避

坑一:把别家的字段名搬过来用。 为什么会踩:这些工具在你眼里都是”填个地址和密钥”,字段名的差异在脑子里被抹平了。怎么避:配置前先打开你正在用的那一家的文档页,字段名逐字对照,尤其是 apiBaseapi_urlBase URLOPENAI_HOST--base-url 这五个 —— 长得像,位置也像,但不通用。

坑二:在手写型工具上等着列表自己出现。 为什么会踩:用惯了自动拉取型工具,会默认”配完就该有”。怎么避:先确认工具类型。看到文档给的是 available_models 数组或 models 块,就说明模型得你写;写完之前不存在”列表为空”这个故障。

坑三:/v1 加不加全靠猜。 为什么会踩:各家示例形态不一致,Kilo Code 文档接受两种写法,别家未必。怎么避:以你正在配的这一家的文档示例为准,别用另一家的示例反推。真拿不准就用命令行直接请求一次那个地址,看服务端怎么回。

坑四:把密钥写进会进版本库的文件。 为什么会踩:JSON/YAML 配置文件里正好有个像密钥的位置,顺手就填了。怎么避:Zed 文档直接写了 “Do not put API keys in settings.json.”,凭据走设置界面或 <PROVIDER_NAME>_API_KEY 环境变量;Gemini CLI 那种支持 $VAR_NAME 插值的,也可以让配置进库、密钥留在环境里。

坑五:只顾着接上,忘了工具调用这道关。 为什么会踩:模型能出现在可选项里,看起来就”成了”。怎么避:如果你用的工具对工具调用有硬要求(Roo Code 文档写明只认原生 tool calling、无 XML 回退),配之前先去服务商文档确认这个模型支持不支持 —— 这是 Roo Code 文档自己给的建议。

坑六:把”兼容”当成全参数兼容。 为什么会踩:兼容端点这个词太让人放心了。怎么避:记住 Kilo Code 文档那条 Azure 提醒的形状 —— 某个上游可能拒绝某个具体参数,这时候通用兼容通道就是走不通的,得换专用接入方式。遇到怎么调都不对的情况,早点怀疑参数层。

坑七:把 roles 的默认值当成”全都有”。 为什么会踩:写完 models 三项必填就以为配完了。怎么避:打开文档的 roles 一节,逐字对一遍默认值 —— Continue 文档记的默认是 [chat, edit, apply, summarize]embedrerank 不在其中。要用嵌入或重排,先试着把这两个值显式写进 roles 再看功能里能不能选到这个模型;这一步是按字段语义推的做法,文档没有逐条说明其效果,以官方文档为准。

最后提醒时效:上面提到的所有字段与行为,都是截至 2026-08-07 各家官方文档的情况,请以官方文档最新版为准。

数据来源与核对日期

本文全部产品事实来自以下官方文档页面,核对日期均为 2026-08-07

本文明确没有写的内容:任何产品的价格、免费额度、订阅档位、限速数字、版本号,以及各家支持的完整模型清单。这些要么会随时变动,要么本次未做核实,写进来只会误导你;请一律以各产品官方文档为准。同样没有写的还有各家的界面长相与菜单层级 —— 本文依据的是配置层记录,界面以你实际看到的为准。表格中”后果”一列,以及正文里关于 roles 取值如何影响功能可选性的说法,都是按 HTTP 协议通用行为与字段名语义推出的判断,不是任何一家官方文档的原文表述;同样地,正文给出的 curl 验证步骤是通用协议层做法,不是哪一家文档记载的官方排查流程。

延伸阅读:同一组里的 编辑器里报 401 但 curl 正常聊天能用补全不工作;接完之后照 接完自定义模型别急着干活 逐项过一遍,才算真接通。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。