aider 不认识你的模型:用元数据文件注册上下文上限与单价
注册模型元数据这件事,改的是 aider 本地对这个模型的认知,不是服务端的真实能力。 你在 .aider.model.metadata.json 里写 32000,服务端不会因此多给你一个 token;你写的单价再低,账单也不会变。想清楚这一点,后面所有字段该怎么填、填错会怎样,逻辑就顺了。
这篇只讲一件事:aider 遇到它没见过的模型 ID 时,你手上有哪些可写的配置位、每个位置写什么。站内另外几篇管的是相邻但不同的问题——模型别名失效与漂移风险讲的是模型 ID 本身会变、别名会指向别的东西;上下文窗口到底是什么讲的是这个数字在推理侧的物理含义;API 账单爆涨怎么查讲的是钱真的花超了以后怎么定位。本篇不重复那三件事,只负责把 aider 这几个配置文件里的字段讲到你能自己动手填。
以下所有字段名、文件名、示例,都来自截至 2026-08-07 核对的 aider 官方文档「模型高级设置」那一页(URL 见文末来源小节);aider 后续版本可能增删字段,动手前请以官方文档最新版为准。
一、这个问题到底是什么问题
先分清两件常被混在一起的事。
接入方式,指的是 aider 用什么地址、什么密钥、走什么协议去调你的模型。模型能力,指的是这个模型能吃多长的输入、能吐多长的输出、一个 token 收多少钱。前者配错了,请求根本发不出去;后者配错了,请求发得出去,但客户端对它的判断是歪的。
「上下文窗口」在这里就是一次请求里模型能同时看到的 token 总量上限,包括你的系统提示、历史对话、贴进去的代码,加上它即将生成的回复。这个上限是模型和服务端定的,客户端只是知不知道它。
aider 内部维护着一份它认识的模型信息。当你用的是自建端点、私有部署、或者某家新上线的模型,模型 ID 不在这份信息里,aider 就处于「不认识」状态。官方文档给出的办法是:用 .aider.model.metadata.json 这个文件,把这个模型的上下文上限与价格注册进去。
注意这句话本身就是文档的说法——这个文件的用途是注册上下文上限与价格。至于文件里每一个具体字段客户端内部拿去做什么运算,官方文档并没有逐条展开,下面凡是涉及「这个字段被拿来干什么」的说法,我都会标出来那是按字段名语义读出来的判断。
二、.aider.model.metadata.json 长什么样
官方文档给出的示例如下(原样引用,未改字段名):
{
"provider/model-name": {
"max_tokens": 4096,
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"input_cost_per_token": 0.00000014,
"output_cost_per_token": 0.00000028,
"litellm_provider": "provider",
"mode": "chat"
}
}
这段示例里的数字是官方文档的示例值,不是任何真实模型的报价或规格。 你照抄数字不照抄结构,等于给 aider 塞了一份错误的认知,比不填还糟。
结构上很直白:最外层是一个对象,键是模型标识(示例里写作 provider/model-name),值是这个模型的一组元数据。你要注册几个模型,就在最外层放几个键。
input_cost_per_token 和 output_cost_per_token 这两个字段名里的量纲值得留意:示例值是 0.00000014 这种量级,也就是每个 token 的价格,不是每千 token、也不是每百万 token。服务商的价目表常见按每百万 token 报价,抄进来之前先自己换算,别把小数点位置搞错。关于单价这件事本身怎么读,可以看模型单价怎么看。
三、字段逐个讲清
下表里的字段名全部逐字来自官方文档示例。第三列写的是「填错你可能看到什么」——这一列不是官方文档的记载,是按字段名语义与 OpenAI 兼容协议的通用行为推出来的判断,请当作排查线索而不是产品行为的定论。(「OpenAI 兼容」指服务端把接口做成与 OpenAI API 相同的请求/响应格式,客户端因此可以不改代码地换后端。)
| 配置项 | 它是什么(字段名语义) | 填错时你可能看到什么(机制推理,非文档记载) | 出处 |
|---|---|---|---|
max_tokens | 一个 token 数量上限值 | 与另外两个 token 字段互相矛盾时,客户端的判断依据不明确,行为以官方文档为准 | aider 官方文档(见文末来源) |
max_input_tokens | 输入侧的 token 上限值 | 填得比服务端真实上限大,客户端不拦你,请求打到服务端才被拒;填得太小,你会觉得这模型「窗口怎么这么小」 | 同上 |
max_output_tokens | 输出侧的 token 上限值 | 填得过小,长回复可能在写到一半时被截断,看起来像模型「话说一半」 | 同上 |
input_cost_per_token | 输入侧每个 token 的价格 | 数量级抄错(例如把每百万 token 的报价直接填进来),本地看到的成本估算会离谱 | 同上 |
output_cost_per_token | 输出侧每个 token 的价格 | 同上;两栏对调填反时,本地算出来的数字会朝一个方向系统性地偏 | 同上 |
litellm_provider | provider 标识字符串,示例值为 provider | 与你实际使用的 provider 对不上时的行为,文档未说明,以官方文档为准 | 同上 |
mode | 模式标识,示例值为 chat | 同上 | 同上 |
有几处要特意说清楚。
上限字段是「告诉客户端」,不是「向服务端申请」。 无论 max_input_tokens 还是 max_output_tokens,写进本地文件不会改变服务端的任何限制。这是 OpenAI 兼容协议的通用机制:请求里带的参数超过服务端上限,服务端会拒;本地配置只影响客户端在发请求之前的自我约束。
价格字段是「本地记的账」。 写在本地文件里的单价,至多影响客户端自己算出来的那个数字,不可能影响服务商真实扣费——真实扣费永远以服务商控制台为准。(客户端具体拿这两个字段做什么展示或统计,官方文档并未逐条说明,这里只是按字段名语义做的判断,实际以官方文档为准。)如果你发现本地看到的数字和账单对不上,先怀疑这两栏的数量级,再去查别的。token 怎么数、估算为什么天然对不齐,见token 到底怎么算。
四、另一个文件:.aider.model.settings.yml 与它的四处位置
元数据文件解决的是「aider 不知道这个模型的规格」。还有一类问题是「aider 知道这个模型,但我要改它的行为参数」,那走的是另一个文件 .aider.model.settings.yml。
官方文档写明这个文件可以放四处,按顺序加载,后加载的优先:
- home 目录
- git 仓库根目录
- 启动 aider 的当前目录
--model-settings-file <filename>指定的自定义路径
这个顺序值得记一下。它意味着仓库里提交的一份团队公共设置,会被开发者在自己启动目录放的一份覆盖;而命令行显式指定的那份,优先级最高。团队里出现「同一个仓库,两个人跑出来行为不一样」,第一件事就是各自确认这四处到底存在几份文件。
文档里还提到这个文件支持 extra_params,作用是把任意参数透传给 litellm.completion(),其中包括 extra_headers。官方示例:
- name: provider/model-name
extra_params:
extra_headers:
Custom-Header: value
max_tokens: 8192
这条对接自建网关的人很有用:网关要求带某个自定义 HTTP 头做路由或计量时,不必去改 aider 本体,写进 extra_headers 就能带上。
另有一个特殊模型名 aider/extra_params,官方文档说明它可以让设置对所有模型全局生效。你有一批模型都走同一个网关、都要带同一个头时,这个写法能省掉逐个模型重复。
文档还提到了这几个设置项名:edit_format、weak_model_name、use_repo_map、cache_control、accepts_settings。它们各自的取值与语义,文档里有对应说明,本文不逐条转述,需要时直接查官方页面。
五、边界与代价:这套做法明确不管什么
配置写完之前,先接受它的四条边界。
第一,它不改变模型的真实能力。 注册元数据是让客户端「知道」,不是让服务端「同意」。一个真实窗口只有几万 token 的模型,你写多大都不会变长。反过来说,如果你发现请求被服务端拒了,不要试图靠改这个文件绕过去,那是在给自己制造更难查的问题。
第二,它不管接入通不通。 端点地址、密钥、协议兼容性都不在这个文件的职责范围内。而且要特别提醒:各家工具的「base URL 该填哪个字段」差异很大,Continue 叫 apiBase、Zed 叫 api_url、goose 用 OPENAI_HOST、Crush 用命令行参数 --base-url,而 Cline / Roo Code / Kilo Code 的图形界面里叫 Base URL。把 A 家的字段名套到 B 家上,是这类配置里最常见的自坑方式。
第三,它不保证模型能干 aider 让它干的活。 尤其是工具调用(function calling,即模型按结构化格式请求调用外部函数的能力)这类硬门槛。参考 Roo Code 官方文档里那句原话:Roo Code uses native tool calling exclusively,并明确说这是唯一支持的工具协议、没有基于 XML 的回退。这是 Roo Code 文档的说法,不是 aider 的;但它说明了一个通用道理——模型支不支持某项协议能力,是模型和服务端的事实,任何客户端配置文件都改不了。
第四,它不替你核账。 单价填得再准,也只是本地的估算口径。真实扣费与本地估算之间总会有差,原因包括缓存、计费粒度、服务商自己的口径等等,这些都超出了一个 JSON 文件能覆盖的范围。
还有一个代价常被忽略:这份文件是需要维护的。服务商调整了模型规格或价格,你的本地元数据不会自动跟着变,它会安安静静地继续按旧值工作。这类「配置对过、后来悄悄过期」的问题,往往比一开始就配错更难发现。
六、避坑清单
坑一:直接把官方文档示例里的数字抄进生产配置。 为什么会踩:示例长得像一份能用的配置,复制粘贴的成本比查文档低太多。 怎么避:把示例只当结构模板。数字全部换成你从服务商文档里查到的值;查不到的字段宁可先不写,也别拿示例值顶上。
坑二:单价数量级抄错。 为什么会踩:服务商报价常见按每百万 token 计,而字段名写的是 per_token。中间差六个数量级,抄的时候脑子转不过来是常事。 怎么避:填完之后做一次反向验算——用你填的单价乘以一百万,看结果是不是等于服务商页面上的那个数。这一步只花十秒。
坑三:max_output_tokens 填得比实际需要小。
为什么会踩:很多人直接把示例里那个较小的值留着没动。
怎么避:先想清楚你让 aider 干的活最长要吐多少内容——整文件重写和改一行是完全不同的量级。设小了的典型表现是回复被截断,看起来像模型能力问题,其实是配置问题。
坑四:四处 settings 文件互相覆盖,查不到当前生效的是哪份。
为什么会踩:加载顺序是 home、仓库根、当前目录、--model-settings-file,后加载的优先。你在 home 里改了半天,仓库根那份一直压着它。
怎么避:排查时先把这四处逐个列出来,确认各自存不存在。团队协作场景下,把「哪一层放什么」写进仓库约定,比每次现场查快得多。
坑五:把元数据文件当成解决报错的万能开关。 为什么会踩:接入不通时人会本能地到处改配置,而这个文件恰好看起来很像「模型相关的配置」。 怎么避:先分清报错来自哪一层。连不上、鉴权失败、端点 404,这些都在接入层,跟元数据文件没关系;只有当模型能调通、但 aider 对它的规格判断明显不对时,才轮到这个文件出场。
坑六:只在自己机器上配,没管仓库里的那份。
为什么会踩:本地跑通了就以为事情结束了。
怎么避:想清楚这份配置该不该进版本库。要注意的是,元数据里没有密钥,进库通常没问题;但如果你在 extra_headers 里塞了带凭据的自定义头,那份文件就不能提交。凭据的存放,各家工具设计取向不同——例如 Zed 官方文档写得很直接:Do not put API keys in settings.json(这是 Zed 文档的说法),凭据走系统 keychain(操作系统提供的加密凭据存储)或环境变量。aider 这边的凭据管理方式请以官方文档为准,本文不展开。
数据来源与核对日期
以下 URL 为本文所依据的官方文档页面,核对日期均为 2026-08-07。文档随版本更新,读者动手前请以各产品官方文档最新版为准。
- aider 模型高级设置文档页(
.aider.model.settings.yml的四处加载位置与优先级、.aider.model.metadata.json示例、extra_params与extra_headers示例、aider/extra_params、edit_format等设置项名):https://aider.chat/docs/config/adv-model-settings.html - Roo Code OpenAI Compatible(本文引用的 native tool calling 原话出处):https://roocodeinc.github.io/Roo-Code/providers/openai-compatible
- Zed(本文引用的 Do not put API keys in settings.json 原话、
api_url字段出处):https://zed.dev/docs/ai/use-api-access、https://zed.dev/docs/ai/configuration - Continue(本文提到的
apiBase字段出处):https://docs.continue.dev/reference - goose(本文提到的
OPENAI_HOST出处):https://goose-docs.ai/docs/getting-started/providers/ - Crush(本文提到的
--base-url参数出处):https://raw.githubusercontent.com/charmbracelet/crush/main/README.md - Cline(本文提到的界面上叫 Base URL 的出处):https://docs.cline.bot/provider-config/openai-compatible
- Kilo Code(本文提到的界面上叫 Base URL 的出处):https://kilo.ai/docs/providers/openai-compatible
本文没有写什么,以及为什么:
- 不写任何模型或服务商的真实价格、免费额度、限速数字。 这类数字变动频繁,本次也未逐一核实;文中出现的单价数字只有 aider 官方文档示例里的那两个示例值,已在正文标明它们不是真实报价。
- 不写完整模型清单,也不写具体某个模型的上下文窗口数值。 你要注册的模型规格,请到你所用服务商的官方文档里查,不要沿用任何第三方文章里的数字。
- 不写版本号、发布日期与产品的路线图。 上面所有字段的存续与语义都以核对日当天的文档为准,后续版本可能变化。
- 不写 aider 官方文档未逐条说明的字段内部行为。 表格第三列已标明属于机制推理,实际行为以官方文档为准。
延伸阅读:同一组里的 Continue 的 roles 七种取值、aider 模型设置文件放哪一层生效;接完之后照 接完自定义模型别急着干活 逐项过一遍,才算真接通。