接自定义模型前先确认工具调用:三家 Agent 工具的不同处理方式
给编辑器或终端里的 Agent 换一个自定义模型时,先确认这个模型支不支持原生工具调用,再去填 Base URL 和密钥——顺序反过来,你会把一整个下午花在排查”配置是不是填错了”上,而真正的原因是这个模型根本不具备 Agent 需要的能力。
这件事之所以容易被跳过,是因为”接进去”和”能干活”看起来像同一件事。你把端点和密钥填好,对话框里能出字,看上去一切正常;但 Agent 类工具真正依赖的是模型能不能主动发起工具调用——读文件、改文件、跑命令、再看结果。这一步不通,前面填得再对也只能当聊天框用。
本站已经有几篇文章分别讲了协议和排错:MCP 与 function calling 的区别讲的是两种机制在协议层上各自负责什么,大模型工具调用是怎么回事讲的是工具调用本身的原理,Agent 工具调用出错怎么排讲的是已经跑起来之后调用失败的排查。本篇的分工不同:只谈换模型之前这一道准入判断,以及 Roo Code、Continue、Zed 三家在配置层面把这道判断放在了什么位置。以下产品事实均来自各自官方文档,核对日期 2026-08-07,实际以官方文档最新版为准。
一、先分清「接入方式」和「模型能力」
这是两件独立的事,混在一起想就会一直找错方向。
接入方式,指的是客户端要你填哪些配置项才能把请求发出去:端点地址、密钥、模型标识。绝大多数第三方模型走的是「OpenAI 兼容端点」——服务商把自家接口做成与 OpenAI 那套请求/响应格式一致的形态,客户端不用为每家单独写适配,改个地址就能发请求。这是协议层的通用做法,不是某一家产品的特性。
模型能力,指的是这个模型本身会不会做某些事。其中和 Agent 关系最大的一项叫原生工具调用(native tool calling,也常写作 function calling):模型在回复里输出一段结构化的调用请求(要调哪个工具、参数是什么),客户端解析出来去执行,把执行结果再塞回对话继续。Agent 的整个工作循环就架在这个机制上。
两者的关系是:接入方式通了,只说明请求能发到服务端;模型能力不够,Agent 该做的事一样做不了。一个 OpenAI 兼容的端点,不等于挂在这个端点后面的每个模型都支持工具调用。 这也是为什么换自定义模型时这道判断格外要紧:端点后面挂哪个模型是你自己决定的,这一步的核对责任落在你身上,客户端内部会不会做额外校验,以官方文档为准。
顺带说一句上下文窗口:它指的是模型单次能处理的输入加输出的 token 上限。它和工具调用是两条线上的事,但在下面几家的配置里经常挨着出现,别把两栏搞混。想细看这个概念可以读上下文窗口是什么。
二、Roo Code:把工具调用写成明确的硬限制
Roo Code 的配置形态是图形界面表单,选 OpenAI Compatible 后有三个主参数:Base URL、API Key、Model。文档提示 Base URL 不会是官方 OpenAI 那个地址——这条提醒本身就说明了常见误填是什么。
真正值得单独拎出来的是文档里关于工具协议的一句话。官方文档的原话是:
“Roo Code uses native tool calling exclusively. This is the only supported tool protocol — there is no XML-based fallback.”
这是官方文档的说法,不是本文的判断。它的含义很直接:所选模型必须支持 OpenAI 兼容的 function calling,不支持原生工具调用的模型用不了,也没有基于 XML 的降级路径可以兜底。文档还给了对应的动作建议——先去查服务商的文档,确认该模型是否支持工具调用。
这句话为什么重要?关键在”没有 XML 回退”这半句。所谓 XML 回退,指的是这样一种一般思路:模型不会原生工具调用时,就在提示词里教它用一段约定的文本格式(比如某种 XML 标签)写出”我要调用什么工具”,客户端再用文本解析把它抠出来。这条路能兼容更多模型,代价是解析脆弱、格式容易漂移——这是对该做法本身的机制说明,不是对任何产品实现的描述。Roo Code 文档写明的是它不提供这条降级路径。对你的实际影响就是:选模型这一步的容错空间被压缩了,必须先确认再配。
Roo Code 表单里另可自定义的项,文档列出的名字有 Max Output Tokens、Context Window、Image Support、Computer Use,以及输入/输出价格。需要说明的是,核对当天这一页只列出了这些项的名称,并没有逐条说明客户端内部拿它们做什么,所以本篇不替它们编解释——你只需要知道这几栏由你自己填,具体行为以官方文档为准。这也是本篇通篇的处理原则:文档写了名字的,只说名字;文档说了什么行为的,注明是文档这么写;剩下按协议通用道理推出来的,一律标成推理。
三、Continue 与 Zed:能力被写成配置里的一栏
Roo Code 是把门槛写在文档正文里,另外两家的做法是把”这个模型有什么能力”变成配置文件里一个可写的字段。
Continue 用 config.yaml,模型配置放在 models 块下。必填三项是 name(唯一标识)、provider(如 openai、ollama、mistral)、model(具体模型名)。可选项里和本篇相关的两个是:
capabilities:文档举出的取值包括tool_use、image_input。roles:取值有chat、autocomplete、embed、rerank、edit、apply、summarize,默认是[chat, edit, apply, summarize]。
roles 里的 embed 和 rerank 值得解释一句:嵌入是把文本转成向量、便于按语义检索;重排是对检索出来的一批候选结果重新打分排序。这两件事通常由专门的模型做,和聊天模型不是一回事——roles 这个字段的存在,让你能按角色把不同模型分派到不同岗位上。要留意的是文档给出的默认值里并不包含这两项,想用就得显式写上;客户端对每个角色具体怎么调度,文档这一页没有逐条说明,以官方文档为准。
另外,Continue 覆盖默认端点的字段叫 apiBase,别和别家的字段名混用。官方文档给的示例长这样:
models:
- name: GPT-4o
provider: openai
model: gpt-4o
roles:
- chat
- edit
defaultCompletionOptions:
temperature: 0.7
maxTokens: 1500
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(上下文窗口上限);另有 capabilities 对象控制能力开关,包含 tools、images、parallel_tool_calls 等。可以看出,Zed 这边”这个模型能不能用工具”同样落在配置文件里的一项上,而模型数组按文档是要你手写的。至于客户端读到这些开关之后具体怎么处理,文档这两页没有逐条展开,以官方文档为准。
密钥这块 Zed 说得很硬。文档原话是 “Do not put API keys in settings.json.”,凭据走两条路:provider 设置界面,或者环境变量,命名规则是 <PROVIDER_NAME>_API_KEY——provider 名为 my-provider 时对应 MY_PROVIDER_API_KEY。configuration 页还有一句原话:“Provider keys saved through Zed are stored in the system keychain, not in settings.json.”。keychain 指的是操作系统自带的凭据保管服务,密钥交给它保管,不会以明文躺在你的配置文件里——这对于会进版本库的配置文件来说是关键区别。相关命令文档里给出的有 agent: open settings、zed: open settings、zed: open settings file;另外 disable_ai 设置(写法 "disable_ai": true)可以关闭全部 AI 功能。
顺带补一个同类思路:Gemini CLI 的 settings.json 支持环境变量插值,写 $VAR_NAME 或 ${VAR_NAME},加载时自动解析。环境变量插值就是配置文件里只写变量名、真值从环境里取,这样配置能进版本库而密钥不进。Zed 和 Gemini CLI 这两处针对的是同一个问题,落点不同:一个是把密钥挪出配置文件,一个是让配置文件里只留变量名。密钥管理的通用做法可以另看 API Key 安全管理。
四、三家字段对照表
下表里的字段名逐字来自各家官方文档,别跨家套用——apiBase、api_url、Base URL 不是同一个东西,串台就是自己给自己造 bug。
| 配置项 | 出现在哪家 | 文档给出的含义 | 出处(URL 见文末) |
|---|---|---|---|
| Base URL | Roo Code | 表单三个主参数之一;文档提示不会是官方 OpenAI 那个地址 | Roo Code 官方文档 |
| API Key | Roo Code | 表单三个主参数之一 | Roo Code 官方文档 |
| Model | Roo Code | 表单三个主参数之一 | Roo Code 官方文档 |
| Context Window | Roo Code | 文档列为可自定义项,仅给出名称,未逐条说明客户端如何使用 | Roo Code 官方文档 |
| Max Output Tokens | Roo Code | 同上,文档只列出名称 | Roo Code 官方文档 |
| Image Support / Computer Use | Roo Code | 同上,文档只列出名称 | Roo Code 官方文档 |
capabilities | Continue | 可选字段,文档举出的取值含 tool_use、image_input | Continue 官方文档 |
roles | Continue | 取值 chat/autocomplete/embed/rerank/edit/apply/summarize,默认 [chat, edit, apply, summarize] | Continue 官方文档 |
apiBase | Continue | 可选字段,覆盖默认 API 端点 | Continue 官方文档 |
api_url | Zed | 自定义 base URL | Zed 官方文档 |
available_models | Zed | 模型数组,需在配置里手写 | Zed 官方文档 |
max_tokens | Zed | available_models 每项内的字段,上下文窗口上限 | Zed 官方文档 |
capabilities | Zed | 能力开关对象,含 tools、images、parallel_tool_calls 等 | Zed 官方文档 |
把这张表竖着看,能读出一条对比:三家在”工具调用”这件事上的着力点不一样——Roo Code 把它写成协议层的硬限制并要求你去服务商那边确认;Continue 和 Zed 把它变成配置里一个由你填写的能力声明。这只是设计取向的差别,没有高下之分,但会实实在在影响你的操作顺序。
另外注意模型列表的来源:Zed 要在 available_models 里手写,Continue 在 models 块里手写。手写意味着写错模型标识不会有人替你纠正,抄的时候逐字核对服务商文档给的模型 ID。
五、边界与代价:这一步管不了什么
把”先确认工具调用”当成准入检查,是有代价的,也有明确管不着的地方。说清楚才不会误判。
它只是准入,不是质量保证。 一个模型支持原生工具调用,只代表它能按结构化格式发出调用请求,不代表它调得准、调得少、调得对。参数拼错、该调不调、无谓地反复调同一个工具,都属于跑起来之后的问题,这些要看Agent 工具调用出错怎么排那条线,不在本篇范围。
它管不了上下文和成本。 上下文窗口、最大输出、缓存、计费,是另一套独立的配置项,和能不能工具调用没有因果关系。你确认了工具调用不代表窗口够用。
能力声明只是声明。 Continue 的 capabilities、Zed 的 capabilities 都是你在配置文件里写下的内容。按协议层的一般道理推:你在本地写下 tool_use,改不了服务端那一侧模型的真实能力——这是机制推理,不是哪家文档的记载。这两处字段在客户端内部究竟被拿去做什么,文档只给了字段名和取值,没有逐条说明,以官方文档为准。能确定的是,核对模型能力这一步仍然要回到服务商文档,这也正是 Roo Code 文档建议的动作。
本篇只覆盖了三家,且只覆盖了配置层。 本篇依据的这几页记录里没有涉及各家界面的具体样子、报错文案、校验时机(什么时候拦住你、拦得住拦不住),这些一律以你实际看到的界面为准。同样,本篇依据的那些页面记录里没有出现的项,不等于该产品没有这一项——这是记录范围的限制,不是产品能力的结论。
一律不写的部分:各家价格、免费额度、订阅档位、版本号、完整模型清单。这类内容变动频繁且本次未逐一核实,写进来只会误导人,请以各产品官方文档为准。
六、避坑清单
坑一:先填端点,最后才想起来查模型能力。 为什么会踩:填端点有即时反馈,对话框能出字就像成了;能力问题只有在 Agent 真正要动手时才暴露,中间隔了好几步,很难把因果连起来。 怎么避:把顺序倒过来——先打开服务商这个模型的文档页,找它对 function calling / tools 的说明;页面上明确写了该模型支持工具调用,才算过关,只写了”OpenAI 兼容”不算过关,因为兼容说的是请求格式,不是模型能力。确认完再去动配置。Roo Code 文档给的建议正是这个动作。
坑二:把 A 家的字段名搬到 B 家。
为什么会踩:几家的字段功能相近,脑子里容易简化成”就是那个 base url”,于是在 Continue 的 YAML 里写了 api_url,或在 Zed 的 JSON 里写了 apiBase。
怎么避:配任何一家时,只照该家官方文档抄字段名。Continue 是 apiBase,Zed 是 api_url,Roo Code 表单里叫 Base URL——三个词,三家,不通用。
坑三:把自己手写的能力声明,当成了对模型的体检结论。
为什么会踩:capabilities 这个词读起来像”客户端探到的能力”,其实按文档它就是配置文件里一项由你填的内容。
怎么避:动手前先分清哪些是你写的。打开 Zed 的 settings.json,看 available_models 数组是不是你自己敲进去的;打开 Continue 的 config.yaml,看 models 块下的条目是不是你自己列的。答案都是”是”,那 capabilities 自然也一样——它记录的是你的意图,不是核对结果。真正的核对动作在服务商文档那边。
坑四:把密钥写进会进版本库的配置文件。
为什么会踩:示例里字段挨着放,顺手就把 key 填在旁边了。
怎么避:Zed 文档明确写着 “Do not put API keys in settings.json.”,凭据走 provider 设置界面或环境变量 <PROVIDER_NAME>_API_KEY。需要让配置文件进版本库又不泄密时,参考 Gemini CLI 那种 $VAR_NAME 插值的思路。
坑五:把 roles 的默认值当成全集。
为什么会踩:Continue 默认 [chat, edit, apply, summarize] 已经覆盖了日常使用,容易以为不用管。
怎么避:如果你要用嵌入或重排,得显式写上 embed、rerank,并且这两个角色通常需要另配专门的模型,不要指望聊天模型顺手兼任。
坑六:把通用协议机制当成某家产品的承诺。 为什么会踩:读文档时容易把”OpenAI 兼容协议一般是这样”和”这家文档写了这样”混成一句话记下来。举例:最大输出设得太小可能导致回复被截断、上下文窗口填得比服务端上限还大可能引发报错——这些是按 OpenAI 兼容协议推出来的一般机制,不是上述任何一家文档的记载。 怎么避:写文档笔记时给每条事实标上来源。分不清的时候,按”机制推理”处理,别当成产品承诺去做设计决策。
配好之后要做的第一件事,是拿一个必然触发工具调用的小任务跑一遍——比如让它读一个具体文件再改一行。能走通,说明这条链路的准入这一关过了;走不通,回到第二节那句原话去对照,而不是继续调 Base URL。想系统看接入侧的配置差异,可以再读编辑器接自定义 API 的通用做法。
数据来源与核对日期
本篇涉及的全部产品事实来自以下官方文档页面,核对日期均为 2026-08-07,实际以官方文档最新版为准:
- Roo Code(OpenAI Compatible 配置与原生工具调用限制):https://roocodeinc.github.io/Roo-Code/providers/openai-compatible(核对日
docs.roocode.com/providers/openai-compatible为 301 永久跳转到该域名) - Continue(
config.yaml的models块、capabilities、roles、apiBase及 YAML 示例):https://docs.continue.dev/reference - Zed(
settings.json示例、api_url、available_models、capabilities、密钥与 keychain 相关原话、disable_ai):https://zed.dev/docs/ai/use-api-access 与 https://zed.dev/docs/ai/configuration - Gemini CLI(
settings.json的$VAR_NAME/${VAR_NAME}环境变量插值):https://google-gemini.github.io/gemini-cli/docs/get-started/configuration.html
文中引用的英文原句均为上述官方文档的说法,本文不代任何产品做能力背书。
本篇没有写什么,以及为什么:
- 不写价格、免费额度、订阅档位、限速数字。这类内容变动频繁,本次未逐一核实,写下来很快就会过期并误导决策,请以各产品官方定价与文档页为准。
- 不写完整模型清单和版本号。模型上下线的节奏远快于文章更新,任何清单都会过时;需要确认某个模型是否可用、是否支持工具调用,请查服务商自己的文档。
- 不写界面长什么样。本篇依据的是各家的配置层文档,其中没有记录面板位置、菜单层级、提示文案、报错文案与校验时机,这些以你实际看到的界面为准。
- 不写各家文档之外的推断。凡本文中属于 OpenAI 兼容协议通用机制的说明(如截断、上限报错),文中已标明是机制推理而非某家文档的记载;三家在设计取向上的差异也仅作客观对照,不做优劣排序。
延伸阅读:同一组里的 你的 API key 躺在哪、上下文窗口要你手填的那几家;接完之后照 接完自定义模型别急着干活 逐项过一遍,才算真接通。