自定义模型接入后 token 变贵:先分清上下文变多还是缓存没生效

2026-08-07

换服务商之后 token 用量抬头,绝大多数情况下要怀疑的不是模型,而是你在接入这一层重新填了一遍的那些默认值。 同一个编辑器、同一套仓库、同一批任务,唯一变的是 provider 配置,那么用量差异的来源只可能在三处:客户端替你带进请求里的上下文变多了、调用次数变多了、或者原本能命中的缓存前缀被打断了。这三处都能在配置层查,不需要等账单出来才知道发生了什么。

先说清楚这篇和站内几篇同类文章的分工。token 统计怎么做 讲的是怎么把用量数据先采集下来、口径怎么定;token 成本优化 讲的是数据齐了之后有哪些降本手段;AI 评审的 token 成本 是把这套算法套在代码评审这个具体场景上。本文只管一件事:接入方式变了以后,用量变化的原因在配置层怎么定位,不涉及降本手段本身,也不给任何价格数字。

一、先分清「接入方式」和「模型能力」是两件事

这两个词经常被混着说,但排查用量时必须分开。

接入方式指的是编辑器怎么把请求发出去:填哪个地址、用哪个密钥、模型 ID 写成什么、请求里附带哪些参数。OpenAI 兼容端点是这一层最常见的形态——服务商把自己的接口做成和 OpenAI 那套请求/响应结构一致,客户端于是可以不改代码就换后端。截至 2026-08-07 的官方文档,Cline 的做法是 API Provider 选 OpenAI Compatible,然后填三项必填:Base URL(服务商给的 API 端点,文档明确提示这里不会是 https://api.openai.com/v1)、API Key、Model(选择或输入具体的模型 ID)。文档里的 v0 Quickstart 示例是 Base URL 填 https://api.v0.dev/v1、Model ID 填 v0-1.0-md

模型能力指的是这个模型本身能不能干某件事:上下文窗口多大、支不支持工具调用、能不能读图。上下文窗口就是单次请求里模型能容纳的 token 上限,包含你发过去的全部内容和它生成的内容;关于这个概念本身可以看 上下文窗口是什么原生工具调用(function calling)是指模型按接口约定输出结构化的函数调用请求,客户端据此去执行工具,而不是靠解析自然语言或 XML 文本猜意图。

为什么排查用量要先分这两件事?因为接入方式换了,模型能力的那些数字往往需要你手填一遍,而手填的值和真实值不一致时,表现出来的就是”用量莫名其妙”。对照 编辑器接入自定义 API 那一篇的配置流程看,你会发现每一家在这一步的取舍都不同。

二、第一刀:账单归服务商算,客户端里填的数字不改计费

这是最先要斩断的误会。

截至 2026-08-07 的官方文档,Cline 的 Model Configuration 区列出了这些可自定义的高级项:Max Output Tokens、Context Window size、Image Support、Computer Use、Input Price、Output Price。Roo Code 官方文档同样列出可自定义 Max Output Tokens、Context Window、Image Support、Computer Use 与输入/输出价格。aider 则是用 .aider.model.metadata.json 给它不认识的模型注册上下文上限与价格,文档示例里出现 max_tokensmax_input_tokensmax_output_tokensinput_cost_per_tokenoutput_cost_per_token 这些键,其中的数值是官方文档的示例值,不是任何真实模型的报价

这里必须说清一件事:这些文档页只列出了字段名,并没有逐条说明客户端内部拿这些值去做什么。所以本文不替它们定义行为。但有一个结论是纯逻辑的、不依赖任何产品内部实现:你在本地填的价格数字,不可能改变服务商那边的真实计费。计费发生在服务商侧,客户端拿到的只是一个数。因此排查”变贵了”这件事,起点永远是服务商侧的用量记录,本地任何数字都只能当参考。

如果你要的是”这段文本大概多少 token、按某个单价大概多少钱”这种快速估算,可以用本站的 token 计算器:粘贴任意中英文文本,即时估算 token 数量,配合单价快速换算调用成本;页面里还附了中英文 token 差异和账单对不上的排查思路。它能帮你的就这些——它是估算,精确切分以各服务商自己的 tokenizer 为准,真实账单还是要回服务商那边看。

三、第二刀:上下文这一端,谁在替你多带东西

换了接入方式之后,“每次请求带多少内容”这件事的决定权可能已经换手了。有两个地方值得逐一确认。

一是要你手填窗口的场景。 把各家文档横过来看,需要人工提供上下文相关数值的地方包括:Cline 的 Context Window size、Roo Code 的 Context Window、Zed 在 available_models 每项里写的 max_tokens(文档说明它是上下文窗口上限)、aider 在 .aider.model.metadata.json 里注册的 max_input_tokens / max_output_tokens。换服务商时这些值要跟着新模型重填,填成上一家的旧值就是给自己埋雷。注意这里同样只谈”这一项由你填、填的是什么量纲”,各家客户端拿它做什么用,文档这几页并未逐条说明,以官方文档最新版为准。

二是一个模型条目被几种任务共用。 Continue 的配置文件是 config.yaml,模型写在 models 块下,必填 nameprovidermodel,可选 apiBase(覆盖默认 API 端点)、rolescapabilitiesdefaultCompletionOptionsautocompleteOptionschatOptionsrequestOptions。其中 roles 的取值有 chatautocompleteembedrerankeditapplysummarize文档写明默认值是 [chat, edit, apply, summarize]

这条默认值值得单独盯一眼:你只写了一个模型条目、没写 roles,那么按文档,这一条同时承担聊天、编辑、应用改动、摘要四种角色。换句话说,触发调用的入口不止聊天框一个。至于每种角色在什么时机发请求、一次带多少内容,这一页文档没有逐条说明,别自己脑补。另外 autocomplete 不在默认值里,要用得显式写上;embed(把文本转成向量供检索)和 rerank(对检索结果重新排序)也是独立取值,属于另一类调用。文档给的示例长这样:

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

roles 显式写死,是这一层最容易做、也最容易被跳过的一步。

顺带一个和上下文无关但同样影响调用成败的硬门槛。 Roo Code 官方文档原话是:“Roo Code uses native tool calling exclusively. This is the only supported tool protocol — there is no XML-based fallback.”(这是官方文档的说法,不是本文的断言。)文档建议先查服务商文档确认所选模型是否支持工具调用。这条如果没过,你遇到的就不是”变贵”而是”根本用不了”,排查顺序上应该排在用量问题前面。

四、第三刀:缓存这一端,前缀还稳不稳

先把边界划清楚:本文依据的这几页记录里,没有出现各家编辑器如何处理提示缓存的说明(aider 文档提到过一个叫 cache_control 的设置项名,仅此而已,其行为以 aider 官方文档为准)。这不等于这些产品没有相关能力,只是本文不写没有核实过的东西。

能讲的是协议这一层的通用机制,下面这段是机制推理,不是任何一家产品文档的记载:OpenAI 兼容形态下的提示缓存普遍按”请求前缀是否完全一致”来判断能否复用,前缀里任何一处发生变化,从那一处往后就无法复用。因此换服务商之后缓存没生效的常见成因是结构性的——系统提示或工具定义换了一版、请求里附加的头信息变了、模型 ID 换了导致缓存池本来就不共享。Continue 的 requestOptions 能配 timeout、headers、proxy 等 HTTP 配置,Kilo Code 建 provider 时有可选的 Headers(自定义 HTTP 头,键值对形式),aider 的 extra_params 能透传参数给 litellm.completion() 包括 extra_headers——这些都是你亲手改过请求形状的地方,值得回头对一遍。

判断缓存到底有没有生效,唯一可靠的依据是服务商侧返回的用量数据,各家字段命名和是否提供都不一样,以你所用服务商的官方文档为准。客户端这一层给不了权威答案。

五、一张表:排查时手边该有的字段

下表字段名逐字取自各家官方文档(核对日期 2026-08-07),只写它出自哪里、是什么量纲,不替产品定义内部行为。

配置项(逐字)出自卡在文档里的定位排查时怎么用
Base URLCline / Roo Code / Kilo Code服务商给的 API 端点;其中 Cline 与 Roo Code 的文档都提示它不会是官方 OpenAI 那个地址(Kilo Code 一节没有这句)确认换的是不是你以为的那个后端
apiBaseContinue可选字段,覆盖默认 API 端点同上,注意这是 Continue 的写法,别和别家串
api_urlZedsettings.json 里的自定义 base URL同上,Zed 只认这个名字
OPENAI_HOST(另有 OPENAI_BASE_PATHgoose自建/企业内部 OpenAI 兼容端点的环境变量注意它是拆成两段的设计
Context Window sizeCline文档列出的可自定义高级项换模型后重填,别沿用上一家的值
Context WindowRoo Code文档列出的可自定义项同上
max_tokensavailable_models 内)Zed文档说明为上下文窗口上限同上
max_input_tokens / max_output_tokensaider.aider.model.metadata.json 注册的上下文上限同上;同文件里的价格键是文档示例值
Max Output TokensCline / Roo Code文档列出的可自定义项,只给了名字输出被提前收尾时先看这里——这一句是按字段名量纲做的一般推断,两家文档都没说明客户端拿它做什么,实际以官方文档为准
roles(默认 [chat, edit, apply, summarize]Continue取值 chat/autocomplete/embed/rerank/edit/apply/summarize确认这个模型被几种任务共用
requestOptionsContinuetimeout、headers、proxy 等 HTTP 配置改过请求形状的地方,缓存排查必看
HeadersKilo Code建 provider 时可选,自定义 HTTP 头,键值对形式同上
/v1/modelsKilo Code凭据有效时自动拉取模型列表的端点,失败可手填确认你用的模型 ID 是拉来的还是手写的

六、边界与代价:这套排查法不管什么

它不给你省钱的手段。 这篇只做归因,判断”多出来的量从哪来”。真要压成本,路径是另一套东西,见前面提到的成本优化那篇。

它不覆盖模型本身的差异。 换了模型,同一个任务需要的往返轮次、生成长度本来就会变;这部分差异靠配置层查不出来,只能靠同一批任务跑对照。

它不适用于用量数据都拿不到的场景。 如果服务商侧没有可查的用量记录,前面所有判断都会退化成猜测,这时候该做的是先把统计打通。

它对界面细节一概不谈。 各家客户端长什么样、什么时候会拦住你、拦不拦得住,以你实际看到的界面为准,本文一个字都不写。

它明确不涉及:任何产品的价格、免费额度、限速数字、完整模型清单。这些要么会过时,要么本文没有核实过。

七、避坑清单

把 A 家的字段名搬到 B 家。 为什么会踩:几家做的是同一件事,容易以为字段名也通用。怎么避:把上表当对照表用——Base URL(Cline / Roo Code / Kilo Code 界面上的写法)、apiBase(Continue)、api_url(Zed)、OPENAI_HOST(goose)、--base-url(Crush 的命令行参数)是五种彼此不通用的写法,逐字照抄各自文档,改一个字母就是配错。

/v1 加不加凭印象。 为什么会踩:各家示例形态不同。怎么避:照文档记录来——Cline 文档的 v0 示例含 /v1;Kilo Code 明确接受 https://api.provider.com/v1https://api.provider.com/v1/chat/completions 两种形态,文档说明第二种是为端点结构非标准的服务商与自建网关准备的;Zed 示例是 https://example.com/v1;Groq 官方 base URL 是 https://api.groq.com/openai/v1

换模型不重填上下文相关的数值。 为什么会踩:配置项还在原地,看起来”已经填过了”。怎么避:把换 provider 当成一次完整重配,Context Window 这类要你手填的项逐个过一遍。

Continue 里只写模型不写 roles 为什么会踩:默认值是隐式生效的,配置文件里看不见。怎么避:显式写出 roles,让”这个模型承担哪几种任务”变成配置文件里看得见的一行。

把本地填的价格当账单。 为什么会踩:这些字段就摆在模型配置旁边,容易当成结算依据。怎么避:记住计费在服务商侧发生,本地数字只是本地的数字;对账永远回服务商侧的用量记录。

密钥跟着配置文件进了版本库。 为什么会踩:换接入方式时为了省事,把密钥直接写进能提交的文件里。怎么避:照各家文档的规矩来——Zed 文档原话是 “Do not put API keys in settings.json.”,configuration 页还写了 “Provider keys saved through Zed are stored in the system keychain, not in settings.json.”(keychain 指操作系统提供的凭据存储);凭据走 provider 设置界面或环境变量,命名规则是 <PROVIDER_NAME>_API_KEY。Gemini CLI 的 settings.json 支持环境变量插值 $VAR_NAME${VAR_NAME}(配置文件里只写变量名、值由环境提供),加载时自动解析。密钥管理的完整做法见 API Key 安全管理

先排查用量、后排查能不能跑通。 为什么会踩:用量异常更显眼。怎么避:把工具调用这类硬门槛排在前面——Roo Code 官方文档说明它只用 native tool calling、没有 XML 回退,这一条不过,后面的排查全是白费。

数据来源与核对日期

以下 URL 均为本文引用事实的官方文档出处,核对日期 2026-08-07。文中提到的字段名、默认值、示例值均以该日期当天的官方文档页面为准,请以官方文档最新版复核。

本文没有写什么,以及为什么。 价格、免费额度、订阅档位、限速数字、各家完整模型清单,一律不写:这类信息变动频繁,且本次核对未逐项确认,写进来只会误导对账。各家客户端的界面长相、菜单层级、提示文案也不写:本文依据的是配置层的文档记录,不包含界面信息。文中凡属协议通用机制的推理(例如提示缓存按请求前缀复用、最大输出设置影响生成收尾),已在正文中标明是机制推理而非某家产品文档的说法。各产品的实际行为,请以其官方文档为准。

延伸阅读:同一组里的 编辑器请求被截断或报超上下文编辑器里报 401 但 curl 正常;接完之后照 接完自定义模型别急着干活 逐项过一遍,才算真接通。

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