聊天能用补全不工作:补全模型要单独配,它和对话模型的要求不一样
你在编辑器里配了一个自定义模型,对话框问什么答什么,行内补全却一个字都不出——这种情况下先别怀疑网络和密钥,大概率是补全根本没被配上。 在不少工具的配置模型里,补全是一条和对话彼此独立的链路:对话那条配好了,补全那条仍然是空的,或者仍然指着默认值。更麻烦的是,就算你把对话那条原样复制过去,也未必能用——补全对模型的要求和对话不是同一套。
这篇和站内几篇相近的文章分工不同:代码补全丢失内容 讲的是补全出来了但内容残缺该怎么办,Cursor 补全不工作 和 Cursor Tab 使用技巧 讲的是某一款产品的补全体验和排查手法;本篇只管配置层的一件事——补全这条链路要不要单独配、配在哪个字段上、以及为什么它挑模型。
本篇涉及的产品字段,全部来自各家官方文档在 2026-08-07 的记录,来源 URL 列在文末。产品在演进,你动手前请以官方文档最新版为准。
一、先分清两件事:接入方式和模型能力
「接入方式」说的是:你的客户端用什么协议、往哪个地址、拿什么凭据去发请求。绝大多数编辑器接自定义模型走的是 OpenAI 兼容端点——服务商把自己的接口做成和 OpenAI 那套请求/响应格式一样的形状,客户端就不必为每家单独写适配。这类接入的关键就三样:地址、密钥、模型标识。这部分展开可以看 OpenAI 兼容端点是什么 和 编辑器接入自定义 API。
「模型能力」说的是另一回事:这个模型本身会不会某件事。比如:
- function calling(原生工具调用):模型按结构化格式声明「我要调用某个工具、参数是这些」,客户端据此去执行读文件、跑命令,再把结果喂回去。它是模型侧的能力,不是端点通不通的问题。
- 上下文窗口:一次请求里模型能同时看见的 token 上限(token 是模型切分文本的最小计数单位,一个汉字通常占一到两个)。超过上限之后会发生什么,属于服务端的实现细节,不同服务商的处理并不一致,以你用的那家的文档为准。
- 嵌入(embedding)与重排(rerank):嵌入是把文本变成向量以便做相似度检索,重排是把检索回来的一批候选重新打分排序。它们和「生成一段代码」是完全不同类型的模型,选型标准见 嵌入模型怎么选。
对话能跑通,只证明了第一件事——接入通了。它没有证明这个模型适合承担补全,更没有证明客户端已经知道该拿它做补全。
顺带说一句能力声明为什么重要:Roo Code 官方文档里有一句很硬的话,原文是 “Roo Code uses native tool calling exclusively. This is the only supported tool protocol — there is no XML-based fallback.”(这是该产品官方文档的说法,不是本文的断言)。意思是它只认原生工具调用、没有 XML 回退,模型不支持就用不了。这条限制针对的是它的 agent 工作方式,但道理是通的:同一个端点上,能不能干活取决于模型支持哪些协议特性,而不只是端点连不连得上。
二、补全通常是一条要显式声明的角色
拿 Continue 举例,因为它的配置是明文的、你可以自己打开核对。
Continue 的配置文件是 config.yaml,模型配置写在 models 块下。每条模型有三个必填字段:name(唯一标识)、provider(如 openai、ollama、mistral)、model(具体模型名)。可选字段里有 apiBase(覆盖默认 API 端点)、roles、capabilities(如 tool_use、image_input)、defaultCompletionOptions(temperature、maxTokens、topP 等)、autocompleteOptions、chatOptions、requestOptions(timeout、headers、proxy 等 HTTP 配置)。
关键在 roles。截至 2026-08-07 的官方文档,roles 的取值是 chat、autocomplete、embed、rerank、edit、apply、summarize,默认值是 [chat, edit, apply, summarize]。
把这两句话摆在一起,答案就出来了:autocomplete 不在默认值里,embed 和 rerank 也不在。你配一条模型什么都不写 roles,它拿到的是那四个默认角色——聊天能用、改写能用,补全不在其中。
官方文档给的示例是这样(可原样对照):
models:
- name: GPT-4o
provider: openai
model: gpt-4o
roles:
- chat
- edit
defaultCompletionOptions:
temperature: 0.7
maxTokens: 1500
注意这条只挂了 chat 和 edit。一旦你显式写了 roles,默认那四个就不再兜底——这条模型也就不再承担 apply 和 summarize。要让某条模型承担补全,就得在这条的 roles 里把对应取值显式列出来,具体写法请照官方文档那一页来(URL 见文末)。我不在这里替你拼一段 YAML,字段名拼错一个,排查成本比抄文档高得多。
另外提一句:可选字段里 autocompleteOptions 和 chatOptions 是分开的两项。本篇依据的这一页只列了字段名,没有逐条说明客户端内部拿它们做什么,所以这里只说「它们是分开的两项、由你来填」,不替产品描述行为。
三、跨产品的字段对照
不同产品把这些事放在不同的地方。下表里的字段名逐字取自各家官方文档在 2026-08-07 的记录:
| 配置项 | 出自 | 官方文档记录的内容 | 对补全这条链路意味着什么 |
|---|---|---|---|
models 块 | Continue | 模型配置写在这个块下 | 每条模型是独立一项,哪条干什么由你指派 |
name / provider / model | Continue | 三个必填字段 | 补全若单独一条,这三项要再填一遍 |
roles | Continue | 取值 chat、autocomplete、embed、rerank、edit、apply、summarize;默认 [chat, edit, apply, summarize] | autocomplete 不在默认值里,要显式写 |
apiBase | Continue | 覆盖默认 API 端点 | 补全那条若走另一个服务商,端点要写在那条上 |
capabilities | Continue | 可选字段,取值如 tool_use、image_input | 本篇依据的这一页只列了取值,未说明客户端如何使用 |
| Context Window size | Cline | Model Configuration 区可自定义的项之一 | 由你填,填的量纲是上下文窗口 |
| Max Output Tokens | Cline、Roo Code | 两家都列为可自定义项 | 由你填,填的量纲是单次输出上限 |
| Context Window | Roo Code | 可自定义项 | 同上,由你填 |
available_models 里的 max_tokens | Zed | 文档写明其含义是上下文窗口上限 | 手写模型条目时要一并给出 |
max_input_tokens / max_output_tokens | aider | 写在 .aider.model.metadata.json 里,用于给 aider 不认识的模型登记上下文上限与价格 | 冷门模型要自己登记 |
最后一列是按字段语义做的判断,用来帮你决定「这一格该由谁填」。各家官方文档并未逐条说明客户端内部如何使用这些值,实际行为以官方文档为准。
配置形态本身也分几类,知道自己在跟哪一类打交道,找配置位会快很多:Cline、Roo Code 是图形界面表单,Continue 的 config.yaml、aider 的 .aider.model.settings.yml 是 YAML 文件,Zed 和 Gemini CLI 用 settings.json。表单类改起来直观但不好进版本库,文件类反过来。
四、怎么查:按顺序三步
第一步,确认接入确实通了。 对话能正常出字,就说明地址、密钥、模型标识这三样没问题。这一步过了,后面就别再回来反复改 base URL。
第二步,找补全这条链路的配置位。 明文配置的产品直接打开配置文件搜角色/补全相关字段——Continue 就是看每条模型的 roles 里有没有 autocomplete。表单类产品以你实际看到的界面为准,本篇不描述任何一家的界面长相。
第三步,确认模型对得上这个角色。 补全和对话的负载特征不一样:补全是你每停一下就发一次请求、要求很快返回、每次只吐一小段;对话是低频、允许慢、可以长。这一段是补全场景的通用工程判断,不是任何一家文档的记载,但它决定了你不该把一个又慢又贵的长思考模型直接挂到补全角色上——即使配置写法上完全允许。
这一步怎么做:先在对话框里给这个模型发一句极短的问题(比如让它只回一个词),掐表看从回车到第一个字出现有多久。首字要等好几秒的,挂到补全角色上手感一定滞后——因为补全是你每敲几下就触发一次,等待会叠加。再去服务商文档确认这个模型标识对应的是不是带长思考的推理型模型:是的话,即使延迟看着能接受,也建议给补全另挑一条更轻的模型,而不是复用对话那条。通过的标准很朴素——首字延迟在你打字节奏能忍受的范围内,且模型不会为了一行补全先输出一大段推理。
五、边界与代价:这个做法放弃了什么
多一条配置就多一份维护。 补全单独配一条模型,意味着可能多一个端点、多一个密钥、多一份上下文窗口要填。哪天服务商改了模型 ID,你要改两处而不是一处。
密钥和配置文件的矛盾要单独处理。 明文配置文件好进版本库,但密钥不能跟着进。各家的处理方式不同:Zed 文档里写得很直白,原话是 “Do not put API keys in settings.json.”,凭据走 provider 设置界面或环境变量,变量命名规则是 <PROVIDER_NAME>_API_KEY;它的另一页还写了 “Provider keys saved through Zed are stored in the system keychain, not in settings.json.”(keychain 指操作系统自带的凭据保管服务,由系统而不是应用来存密文)。Gemini CLI 走的是另一条路:settings.json 内支持环境变量插值,写成 $VAR_NAME 或 ${VAR_NAME},加载时自动解析——所谓插值就是配置里只写变量名占位、真值运行时从环境里取,这样配置能进版本库而密钥不进。更系统的做法见 API 密钥安全管理。
它明确不管的事:
- 不管某一款产品的补全为什么不出候选框。那是产品侧的交互问题,本篇只处理配置层。
- 不管补全质量好不好。角色配对了只是让请求发得出去,模型合不合适是另一个话题。
- 不管价格和额度。多挂一条模型会不会更贵、贵多少,本篇不给数字。
- 不适用于「客户端根本没把补全做成可配项」的情况。本篇依据的几页文档记录里,只有 Continue 明确出现了补全这一角色取值;这不等于其它产品没有对应机制,只说明它不在本篇核对到的那几页里。
六、避坑清单
坑一:把对话那条配置原样复制,指望补全跟着生效。
为什么会踩:因为对话确实通了,直觉上「同一个模型、同一个端点」应该都能用。实际上角色是独立指派的,Continue 的 roles 默认值里就没有 autocomplete。
怎么避:改完先回头看这条模型的 roles 到底写了什么,而不是看对话能不能出字。
坑二:一写 roles 就丢了原来的默认角色。
为什么会踩:默认值 [chat, edit, apply, summarize] 是「不写才生效」的兜底,显式写了就以你写的为准。只写一个 autocomplete,这条模型就不再是对话模型了。
怎么避:想清楚这条模型到底要干几件事,需要的取值一次列全。
坑三:把 A 家的字段名抄到 B 家。
为什么会踩:各家做的是同一件事,名字却完全不同——Continue 叫 apiBase,Zed 叫 api_url,Cline 和 Roo Code 的界面里叫 Base URL。看着都是「填地址」,抄串了就是一个不存在的字段。
怎么避:换一家产品就重新翻那一家的文档,别凭记忆写字段名。配置文件类的产品,写错字段一般是静默不生效而不是报错,比报错更难查。
坑四:上下文窗口照抄别的模型的数值。 为什么会踩:这一格在多家产品里都是由你手填的(见上表),填什么它就信什么。看着像个可以随便填的展示项。 怎么避:去服务商文档查这个模型的真实上限再填。按 OpenAI 兼容协议的一般机制,请求里的窗口/输出上限超过服务端实际支持时,服务端可能直接拒绝请求;填得过小则可能提前截断——这是协议层的通用推理,不是某一家产品文档的记载,具体表现以你用的服务商为准。
坑五:补全那条走了另一个服务商,却忘了在这条上写端点。
为什么会踩:很多人给补全挑一个更快更便宜的小模型,服务商跟对话那条不是同一家,但配置上只改了模型名。
怎么避:Continue 里端点覆盖是 apiBase,它是每条模型上的可选字段——换服务商就得在那条上一并写。
坑六:把「文档里没写」当成「产品没有」。 为什么会踩:核对文档时只看了一页,就下了「它没有这一项」的结论。 怎么避:结论写成可复核的口径——「我查的那一页里没有出现这一项」,然后再去翻别的页或问服务商,而不是直接判死刑。
七、你可以带走的判断
补全不工作,先分层:端点通不通(对话验证)→ 补全这条链路配没配(找角色字段)→ 模型撑不撑得住这个角色(负载特征)。三层分开看,比在 base URL 上来回试有效得多。
再记一条:在明文配置的产品里,「没写」和「写了空」不是一回事,「没写」往往触发的是默认值,而默认值不一定包含你要的那个角色。Continue 的 roles 默认 [chat, edit, apply, summarize] 就是最典型的例子——它解释了为什么你的对话好好的,补全一声不吭。
数据来源与核对日期
以下 URL 全部为官方文档地址,核对日期均为 2026-08-07。页面内容会随产品演进变化,动手前请以官方文档最新版为准。
- Continue(
config.yaml、models块、roles取值与默认值、apiBase、capabilities、autocompleteOptions/chatOptions、YAML 示例):https://docs.continue.dev/reference - Cline(Base URL / API Key / Model 三项,Model Configuration 区的 Max Output Tokens、Context Window size 等):https://docs.cline.bot/provider-config/openai-compatible
- Roo Code(native tool calling 那句原话、Context Window 与 Max Output Tokens 等可自定义项):https://roocodeinc.github.io/Roo-Code/providers/openai-compatible
- Zed(
settings.json结构、api_url、available_models与max_tokens、“Do not put API keys insettings.json.”、<PROVIDER_NAME>_API_KEY):https://zed.dev/docs/ai/use-api-access - Zed(“Provider keys saved through Zed are stored in the system keychain, not in settings.json.”):https://zed.dev/docs/ai/configuration
- aider(
.aider.model.settings.yml、.aider.model.metadata.json的max_input_tokens/max_output_tokens):https://aider.chat/docs/config/adv-model-settings.html - Gemini CLI(
settings.json里的$VAR_NAME/${VAR_NAME}环境变量插值):https://google-gemini.github.io/gemini-cli/docs/get-started/configuration.html
本篇没有写什么,以及为什么:
- 不写任何产品的价格、免费额度、订阅档位、限速数字。这类信息变动最快,本次也未核实,写下来只会误导;请以各产品和各服务商官方页面为准。
- 不写版本号、发布日期、完整模型清单。同上,时效性太强。
- 不描写任何一家的界面长相——面板位置、菜单层级、提示文案、什么时候弹校验,本篇一律不写。以你实际看到的界面为准。
- 不写各家文档没说明的字段用途。凡是官方文档只给了字段名的,本篇只说「这一格由你填、填的是什么量纲」,并在表下标明了那是按字段语义做的判断,不是产品行为的事实断言。
- 不给各家排座次。上面的差异只是设计取向不同,能在各自文档里查到依据,不构成优劣评价。
延伸阅读:同一组里的 模型列表拉不出来怎么排查、模型接上了 Agent 却不动手;接完之后照 接完自定义模型别急着干活 逐项过一遍,才算真接通。