Roo Code 只认原生工具调用:选模型前你必须先确认哪几件事
在 Roo Code 里接一个自定义模型,第一件要确认的事不是价格,也不是上下文窗口,而是这个模型在你打算用的那个端点上到底支不支持 OpenAI 兼容的 function calling。 因为截至 2026-08-07 的 Roo Code 官方文档,它只支持原生工具调用这一种工具协议,并且写明没有基于 XML 的回退。这句话的实际分量是:模型对话再流畅、写代码再顺手,只要工具调用这一环走不通,接进去也干不了活,而且这个失败不会因为你换个提示词就消失。
这篇只谈一件事——这条硬限制对”选模型”这个动作意味着什么,以及你在填配置之前该按什么顺序去核。协议层面 MCP 与 function calling 到底是什么关系,看 MCP 与 function calling 的分工;模型侧工具调用的原理与常见失效形态,看 大模型工具调用是怎么回事;你自己写 Agent 时怎么设计工具签名,看 Agent 工具设计。本文站在这三者之间:不讲协议史,不讲工具怎么写,只讲客户端把这条协议做成硬门槛之后,你的选型动作要怎么改。
一、原生工具调用是什么,为什么它能卡住你
先把名词摊开。**原生工具调用(native tool calling,也叫 function calling)**指的是:你在请求里按 API 规定的结构声明有哪些工具、每个工具收什么参数,模型返回的不是一段自然语言,而是一个结构化字段,里面写着”我要调用哪个工具、参数是什么”。客户端拿到这个字段直接解析执行,不用猜。这是 OpenAI 兼容接口约定好的一部分能力,服务端要实现,模型本身也要训练过才能稳定产出。
与之相对的另一类做法是:不依赖 API 的结构化字段,而是在系统提示词里跟模型约定一套文本格式(例如让它把要调用的工具写成一段 XML 标签),模型照常吐纯文本,客户端再用解析器把标签抠出来。这条路的好处是任何能跟着格式写字的模型都能凑合用,坏处是解析脆、格式一乱就前功尽弃。
Roo Code 官方文档在 OpenAI 兼容 provider 这一页给出的说法是:
“Roo Code uses native tool calling exclusively. This is the only supported tool protocol — there is no XML-based fallback.”
这是官方文档的原话,不是本文的概括。它的意思很直白:上面那条”文本协议兜底”的退路,在这个客户端里被显式排除了。所以模型侧的工具调用能力从”影响体验的加分项”变成了”能不能接入的判断条件”。同一页还给了一条操作建议——先去看服务商文档,确认那个模型是否支持工具调用。这条建议值得当成流程执行,而不是当成提醒读过就算。
二、接入之前的确认顺序:先协议、再端点、最后才是规格
第一步,查协议能力。 到你要用的那家服务商的文档里,找这个具体模型 ID 是否支持工具调用 / function calling。注意粒度是”模型 + 端点”,不是”厂商”。同一家服务商下不同模型的能力经常不一致,同一个模型放在不同端点上也可能表现不同。这一步查不到明确说法,就不要往下走——省下的是后面几小时排查。
第二步,确认端点形态和 Base URL。 所谓 OpenAI 兼容端点,指的是这个服务把接口做成了跟 OpenAI 那套请求/响应结构一样的形状,于是任何按 OpenAI 格式发请求的客户端都能对上话。Roo Code 在 API Provider 里选 OpenAI Compatible 之后,三个主参数是 Base URL、API Key、Model。文档提示 Base URL 不会是官方 OpenAI 的那个地址——换句话说,你要填的是服务商给你的那个端点,不是照抄教程里的默认值。
第三步,才轮到那些规格栏。 Roo Code 文档列出的可自定义项包括 Max Output Tokens、Context Window、Image Support、Computer Use、输入/输出价格。文档对这一批的表述就是「可自定义」,也就是说值由你在客户端这边给定;客户端是否另有自动获取的途径,页面上没有说。这里要提醒一个容易被忽略的细节——上下文窗口指的是模型一次请求里能容纳的 token 总量(提示词加历史加输出都算在内)。它是模型和服务端的属性,你在客户端填的只是一个你告诉客户端的数字,两者是两回事。
三、这几栏各自写明了什么、没写明什么
下面这张表只做一件事:把”文档写明了的”和”文档没逐条说明的”分开摆。字段名逐字来自各家官方文档在核对日的写法。
| 配置项(字段名) | 所属产品 | 官方文档写明的部分 | 官方文档未逐条说明的部分 | 出处 |
|---|---|---|---|---|
| Base URL | Roo Code | 三个主参数之一;文档提示它不会是官方 OpenAI 的地址 | 各服务商端点是否需要带路径后缀,需看服务商文档 | roocodeinc.github.io/Roo-Code/providers/openai-compatible |
| API Key | Roo Code | 三个主参数之一 | 存放位置与作用域,页面未展开 | 同上 |
| Model | Roo Code | 三个主参数之一 | 这一栏的具体填法(能选还是只能手输)页面未展开;模型是否支持工具调用也不由此栏体现,需查服务商文档 | 同上 |
| Max Output Tokens | Roo Code | 列为可自定义项 | 客户端内部如何使用这个数,页面未说明 | 同上 |
| Context Window | Roo Code | 列为可自定义项 | 客户端内部如何使用这个数,页面未说明 | 同上 |
| Image Support | Roo Code | 列为可自定义项 | 开关行为的具体影响,页面未说明 | 同上 |
| Computer Use | Roo Code | 列为可自定义项 | 开关行为的具体影响,页面未说明 | 同上 |
| 输入/输出价格 | Roo Code | 列为可自定义项 | 填入的数值被用于什么,页面未说明 | 同上 |
capabilities | Continue | 可选字段,取值示例含 tool_use、image_input | —— | docs.continue.dev/reference |
capabilities | Zed | 能力开关对象,含 tools、images、parallel_tool_calls 等 | —— | zed.dev/docs/ai/configuration |
表里”未逐条说明”这一列要认真看待。像 Context Window、Image Support、Computer Use、价格这几栏,官方文档在核对日只把字段名列了出来,并没有说明客户端内部拿这些值去做什么。所以本文只说”这一项由你填、填的是什么量纲”,不替产品定义行为。若你确实需要知道某一栏影响什么,去看官方文档最新版或做小规模实测,别照搬别人博客里的解释。
另外,“填错会怎样”这类问题,很大一部分答案属于 OpenAI 兼容协议的通用机制推理,而不是某个产品文档写下的事实。举例来说:最大输出设得过小时,服务端按协议会在达到上限处结束生成,你看到的就是回答被截断;你在客户端填的窗口值与服务端真实上限不一致时,最终起决定作用的仍是服务端。这些是从协议层面推出来的,写在这里是帮你定位方向,具体到某个客户端的实际表现,还要以它的官方文档和你自己的观察为准。
四、别家把工具调用放在了什么位置
横着看几家的设计取向,能更清楚 Roo Code 这条限制是个什么性质的选择。以下都是各家官方文档在 2026-08-07 的记载。
Continue 用 config.yaml 配模型,models 块下必填 name、provider、model,可选字段里有一个 capabilities,文档给出的取值示例包含 tool_use 和 image_input。也就是说,工具调用能力在这里是一个由你声明的属性。
Zed 走 settings.json,openai_compatible 下每个 provider 写 api_url 和 available_models,每个模型项含 name、display_name、max_tokens,另有 capabilities 对象控制能力开关,文档列出的项包含 tools、images、parallel_tool_calls。
goose 在自述里说支持 40+ 个 LLM provider,并说 “works best with Claude 4 models”,给出的理由是这些模型的工具调用能力。这是官方文档的说法,本文只做转述,不替任何模型背书。
Kilo Code 的做法是:凭据有效时从 /v1/models 端点自动拉取模型列表,自动检测失败可手填模型 ID。这里要提醒一句判断——自动拉回来的是一份模型清单,清单里有某个 ID,跟这个 ID 支不支持工具调用是两个问题,前者不能推出后者。这是常识层面的推理,不是 Kilo 文档的说法。
Cline 在 OpenAI Compatible 这一页也要填 Base URL、API Key、Model 三项,Model Configuration 区列出的高级项有 Max Output Tokens、Context Window size、Image Support、Computer Use、Input Price、Output Price。核对日这一页记载的是上面这些配置项本身;至于它把工具协议做成什么样,本文没有核对,也就不做任何推断——想知道就去它的官方文档里查,别拿 Roo Code 那句话往它身上套。
配置形态也顺带一提:图形界面表单、YAML 配置文件、JSON settings、环境变量与 CLI 子命令,四种路子各家都有人走。相关的接入细节可以看 编辑器接入自定义 API 的做法对比。
五、边界与代价:这个设计放弃了什么
放弃了兼容面。 只认原生工具调用,等于把一批不支持 function calling 的模型排除在外——这里面可能有你手头正想省钱跑起来的小模型、某些本地部署的模型、以及一些只提供纯补全接口的老端点。想用它们,你要么换模型,要么换客户端,没有第三条路可以在这个客户端里凑合。
把兼容性判断的责任转给了你。 文档的建议是先查服务商文档确认模型是否支持工具调用,也就是说,这道判断题的答案不在客户端里,得你自己去别处找。对同时管几个服务商、十几个模型 ID 的团队,这是一份实打实的维护成本。
它明确不管的事。 支持工具调用只是能接入的前提,不代表模型能把工具用对:参数拼错、该调不调、连着调不停,这些属于模型行为,不在这条限制的管辖范围。它同样不管你填的上下文窗口数值对不对、不管端点稳不稳、不管价格两栏你写了什么。工具调用调不通的排查思路,可以参考 Agent 工具调用调错怎么定位。
什么场景下这条限制不构成问题。 如果你只用它做代码补全式的问答、不打算让它读写文件跑命令,工具调用能力的权重自然就低。但这类用法本身就不太需要这一层客户端,值不值得为它折腾配置,你自己掂量。
六、避坑清单
坑一:拿”能对话”当”能用”。 为什么会踩——填完 Base URL、API Key、Model 之后随手问一句”你好”,模型回了,看起来就是通了。可对话走的是最基础的那条路径,跟工具调用是两码事。怎么避:验收动作换成一个必须动工具的小任务,比如让它读一个具体文件再说出里面第一行是什么,而不是聊天。
坑二:从别家的配置里搬字段名。 为什么会踩——各家管”服务端地址”这件事的叫法完全不一样:Roo Code 界面上是 Base URL,Continue 写 apiBase,Zed 写 api_url,goose 用 OPENAI_HOST(另有 OPENAI_BASE_PATH),Crush 是命令行参数 --base-url。名字长得像,位置和拼法都不同,照搬就是配错。怎么避:只看你正在用的那家的官方文档,别信跨产品的”通用写法”。
坑三:把模型清单当能力清单。 为什么会踩——有些客户端能从服务商那边自动把模型列表拉下来(Kilo Code 从 /v1/models 拉取就是一例),列表一出来,人就默认”列出来的都能用”。但列表回答的是”有哪些模型”,不是”哪些模型支持工具调用”。怎么避:能力这一栏永远回到服务商文档里逐个确认。
坑四:规格栏随手填一个数。 为什么会踩——Context Window、Max Output Tokens 这些栏空着不舒服,很容易凭印象敲个数字。但这些值由你填,文档在核对日并未逐条说明客户端拿它们做什么,你填的东西也改变不了服务端的真实上限。怎么避:按服务商文档里该模型的实际规格填,填不准就先去查,别拿它当调优旋钮使。
坑五:把价格两栏当账单。 为什么会踩——界面上摆着输入/输出价格,看着像是能算钱。可这两栏同样是你手填的,文档没有说明它被用于什么。怎么避:账单以服务商控制台为准,客户端里的数字只当参考。
坑六:密钥落到会进版本库的文件里。 为什么会踩——配置和密钥挨着放最省事,一提交就出去了。这里有一条明确写在文档里的对照:Zed 的说法是 “Do not put API keys in settings.json.”,凭据走 provider 设置界面或环境变量(命名规则是 <PROVIDER_NAME>_API_KEY),且 configuration 页写明通过 Zed 保存的 provider 密钥存在系统 keychain(操作系统提供的凭据保管服务,由系统管理加密与访问授权)里而不是 settings.json。另一种常见做法是配置文件里只写变量引用,值来自环境——Gemini CLI 的 settings.json 支持 $VAR_NAME 或 ${VAR_NAME} 这样的环境变量插值(加载配置时把变量名替换成运行环境里的实际值),这样配置能进版本库而密钥不进。怎么避:先确认你用的客户端支持哪种方式,再决定密钥放哪,别默认哪种都行。
数据来源与核对日期
以下 URL 均为各产品官方文档页,核对日期 2026-08-07。文中提到的字段名、原句与跳转行为,都是该日期当天页面上的情况,请以官方文档最新版为准。
- Roo Code(OpenAI 兼容 provider,原生工具调用那句原话的出处):https://roocodeinc.github.io/Roo-Code/providers/openai-compatible (核对日
docs.roocode.com/providers/openai-compatible为 301 永久跳转到此域名) - Cline(OpenAI Compatible 配置项):https://docs.cline.bot/provider-config/openai-compatible
- Kilo Code(
/v1/models自动拉取模型列表):https://kilo.ai/docs/providers/openai-compatible (核对日kilocode.ai/docs/...为 308 永久跳转到kilo.ai) - Continue(
config.yaml与capabilities):https://docs.continue.dev/reference - Zed(
settings.json、capabilities、密钥存放那句原话):https://zed.dev/docs/ai/use-api-access、https://zed.dev/docs/ai/configuration - goose(40+ provider 与 works best with Claude 4 的自述、
OPENAI_HOST与OPENAI_BASE_PATH):https://goose-docs.ai/docs/getting-started/providers/ (核对日block.github.io/goose/docs/getting-started/providers返回 404) - Crush(自定义 provider 的命令行参数
--base-url):https://raw.githubusercontent.com/charmbracelet/crush/main/README.md - Gemini CLI(
settings.json的$VAR_NAME/${VAR_NAME}环境变量插值):https://google-gemini.github.io/gemini-cli/docs/get-started/configuration.html
本文没有写什么,以及为什么。 价格、免费额度、订阅档位、限速数字、版本号与完整模型清单,一律没写:这类信息变动频繁,本次也未逐项核实,写进来只会误导你按过期数字做决定,请以各产品与各服务商官方文档、控制台为准。各产品界面菜单的逐级层级同样没写,因为界面会改,文档里没写明的层级本文不做补全。文中标注为”未逐条说明”的字段用途,是官方文档在核对日确实没有展开,本文不替产品补写行为定义;涉及 OpenAI 兼容协议的通用机制之处已就地说明那是机制推理,不是某家文档的记载。
延伸阅读:同一组里的 Roo Code 接自定义 OpenAI 兼容 API、Kilo Code 加自定义 provider;接完之后照 接完自定义模型别急着干活 逐项过一遍,才算真接通。