接 Mellum2.1 到编辑器时,最容易出问题的地方不是模型本身,而是同时改了两侧配置:一边调服务端地址或参数,一边装插件、改插件设置,最后补全不出来,既不知道是服务没通,还是插件请求格式不对。建议的顺序是先用一条最小补全请求把模型服务跑通,拿到一段非空补全文本,再回到 IDE 插件里只改服务地址和模型名两项,其余保持默认,把变量压到一个。
先把 Mellum2.1 当普通补全接口对待:用一条最小 POST 请求拿到非空补全文本,并固定 model、max tokens、temperature、上下文行数这几项;服务侧闭环后,再在 IDE 插件里只改服务地址和模型名,其他配置保持默认。判断规则可以简单一些——服务测试就失败,先只查服务;服务通了但插件不补全,再按请求差异查插件。每次只改一侧并记一笔,避免两边同时改动后无法归因。
用一条最小请求确认 Mellum2.1 服务能返回补全
这一步的目的很单纯:证明模型服务本身能返回补全文本,不把 IDE 的问题混进来。用 curl 或任意 HTTP 客户端发一条请求即可,路径、字段名以你实际部署的接口为准,下面的方括号都是占位符。
POST [endpoint]/completions
Content-Type: application/json
Authorization: Bearer [token]
{
"model": "[model]",
"prompt": "def add(a, b):\n return ",
"max_tokens": 32,
"temperature": 0
}
验证方式只有两种结果算清晰:一是响应体里出现非空补全文本(哪怕只是 a + b 这种一行),说明服务可用;二是返回明确错误,例如 401 表示鉴权不对、404 表示路径不对、4xx/5xx 带 message 字段说明服务侧拒绝了这个请求。最怕的是 200 但补全字段为空——这通常要先怀疑 prompt 拼接和生成长度,而不是先怀疑插件。
记录请求里的模型名、上下文和生成长度
把上面这次成功的请求参数固定下来,抄到一张便签或工单里,后面和插件发出的请求逐项对照。通用字段大致是这些,Mellum2.1 是否支持某个参数需要结合它的实际接口确认,不要凭猜写:
- model:服务端实际加载或路由到的模型标识,注意它和插件设置里填的名字是否完全一致。
- max tokens:单次补全的最大生成长度,太小会返回空或截断。
- temperature:排查阶段建议用 0 或接近 0 的值,减少输出波动带来的误判。
- 上下文行数:光标前取多少行、光标后是否取后缀,以及前缀和后缀是拼接成一个 prompt 还是分成两个字段。
- 超时:请求超时时间,插件默认值往往和服务端预期不一致。
这组参数的意义在于可复现:下次补全失败时,用同一组参数再发一次,就能判断是环境变化还是插件改写。
在 IDE 插件里只改服务地址和模型名两项
插件装好之后,先不要动上下文行数、触发方式、内联补全开关这些项,只改两处:服务地址(有的插件叫 base URL 或 endpoint,注意是否要带 /v1 之类的路径前缀)和模型名。改完保存、重启插件或重载窗口,然后在编辑器里正常敲几个字符触发一次补全。
触发后要记三样东西:编辑器里出现了什么(补全文本、报错气泡、还是毫无反应);插件自己的日志或输出面板里有没有请求记录;服务端访问日志里是否出现了这次请求。如果服务端日志里根本没有这条请求,说明问题停在插件或网络出口,还没到达模型服务。
对比插件请求与服务测试请求的差异
把插件设置的地址、模型名、其他默认值,和前面手工测试的请求逐项对照。下面这张对照表可以照着填,四列分别是测试请求、插件请求、是否有差异、差异是否可疑:
| 对照项 | 手工测试 | 插件实际 | 备注 |
|---|---|---|---|
| 请求路径 | [endpoint]/completions | 插件拼接后的路径 | 是否多一层或少一层前缀 |
| 请求头 | Content-Type、Authorization | 是否带额外头 | 客户端标识类头通常不影响,鉴权头缺失是硬伤 |
| 请求体字段 | model、prompt、max_tokens、temperature | 可能多出 stream、stop、n、suffix 等 | 多出的字段服务端是否接受 |
| 上下文拼接 | 单个 prompt 字符串 | 前缀和后缀分字段,或自行截断 | 格式不同会导致服务端解析失败或补全质量下降 |
| 超时 | 命令行默认较宽松 | 插件默认往往偏短 | 表现为请求发出但超时中断 |
差异清单不要求全,找到第一条可疑差异就够继续下去了。常见的情况是插件走流式返回(stream),而手工测试用的是非流式,两边日志看起来完全不同。
按差异回退到服务侧或插件侧继续排查
接下来用一条回退规则控制变量,不要两边同时改:
- 手工测试就失败——先只查服务侧:地址和端口是否可达、鉴权 token 是否有效、模型名是否被服务端识别、服务日志里有没有对应条目。
- 手工测试成功、插件不补全——先只查插件侧:地址和模型名是否填成了同一份、是否需要补路径前缀、超时是否过短、插件是否默认开了服务端不支持的字段。
- 已经两边都改过——把其中一侧回退到最近一次确认可用的状态,再只动另一侧,保证每次只有一处变化。
每次改动记一行就够:改的是哪一侧、改了什么、触发结果如何。这样即便排查中断,下次接手的人也能从最后一行继续,而不是从头再来一遍。补全能稳定返回之后,再去调上下文行数和触发策略这类体验项,顺序上会舒服很多。