在终端里敲命令,让 opencode 直接调用本地显卡上的模型,这件事我折腾了将近一周才彻底跑通。起因很简单:某天下午我手里的云端 API 额度见底,手头一个改动又等不起排队,我就想把一直在用的 opencode 从云端 API 切到本地模型试试。试过之后发现,配置本身说难不难,但坑是真的多——有的教程让你改两行环境变量就完事,结果我怎么都连不上;有的模型看起来参数不小,一让它处理多文件改动就开始胡言乱语。这篇把我在调试过程中沉淀下来的选型思路、配置方法和排查清单整理出来,如果你想在 opencode 里用本地模型,或者只是好奇本地推理到底能不能扛住编程 Agent 的活,这篇应该能帮你少走不少弯路。
1. 先说结论:opencode 接本地模型到底靠不靠谱
1.1 为什么有人要把 opencode 接到本地模型上
opencode 是一个跑在终端里的开源编码代理,你可以把它理解成一个"能和代码仓库直接对话的 AI 结对编程工具"。平时我们用云端 API 确实省事,但有两个场景很难受:一是代码涉及未公开的内部逻辑,不想把完整上下文发给云端;二是断网或者 API 配额用尽,工作就得停摆。本地模型的价值正好在这里——数据不出机器,离线也能用,而且跑在自有一张显卡上,几乎等于边际成本为零。
但说白了,把 opencode 配置成本地模型,不是为了让所有人都扔掉云端 API,而是给自己留一条可切换的路线。比如我有一个模拟项目 X,里面有些数据脱敏规则属于不能外传的类型,那我就会把 opencode 切到本地模型来处理那部分代码改动;等处理普通的开源项目时再切回云端。这种"双轨制"是我现在用得最舒服的方式。
1.2 本地模型的真实能力边界
先说扎心的实话:本地模型在写代码这件事上,跟最强的那批云端模型确实有差距,差距主要体现在长上下文推理和多步工具调用上。但这不代表它没用。我实际用了半个月,总结下来是这样的:
| 任务类型 | 本地模型表现 | 备注 |
|---|---|---|
| 单函数补全、正则、脚本 | 很好用 | 7B 级别的模型都能应付 |
| 解释报错、翻译代码 | 非常好用 | 这个场景本地模型完全不虚 |
| 写 SQL、写单元测试 | 够用 | 需要把需求拆清楚,给足上下文 |
| 多文件小重构 | 勉强可用 | 14B 以上模型才比较稳 |
| 大型跨仓重构 | 不建议 | 本地模型很容易"忘掉"前面读过的文件 |
| 多步工具调用(改文件、跑命令、看结果) | 看模型 | 这是最容易翻车的地方 |
所以,如果你指望本地模型一步到位帮你把一个几千行的大仓库重构成微服务架构,那肯定要失望。但如果把它定位成"随时待命的编程搭档",处理那些体量不大、隐私要求高、又需要反复试错的改动,它完全能顶上来。理解了这一点,后面的配置才有意义——我们不是用本地模型去硬刚大模型跑分的,而是要在合适的工作流里发挥它的优势。
2. 本地推理服务选型与部署
2.1 Ollama:个人开发者的首选
Ollama 是我最推荐先试的方案,因为它对个人开发者最友好。安装很简单,Linux 或者 macOS 上一条命令就能装好:
curl -fsSL https://ollama.com/install.sh | sh装完之后,拉一个模型:
ollama pull qwen2.5-coder:14b然后启动服务:
ollama serve默认监听在http://localhost:11434,它同时提供一个 OpenAI 兼容接口/v1,这一点是我们后面配置 opencode 的关键。你可以先手动验证一下服务通不通:
curl http://localhost:11434/v1/models如果返回一个 JSON 列表,说明服务和接口都没问题。Ollama 的好处是模型管理简单,ollama list看模型、ollama rm删模型,每个模型还能通过 Modelfile 自定义运行参数,后续调上下文长度和温度都很方便。
2.2 LM Studio:图形化方案
如果你不太习惯命令行操作,LM Studio 是更直观的选择。它自带图形界面,下载模型、加载模型、启动本地服务全程鼠标点按。启动服务之后,默认地址是http://localhost:1234/v1,同样是 OpenAI 兼容接口,可以直接给 opencode 用。
一个细节:LM Studio 启动服务前需要先加载一个模型,并从界面里把"Serve on local network"之类的选项和端口确认好。我第一次用的时候,模型加载了半天没注意端口,opencode 那边一直连接超时,后来才发现是服务根本没启起来。图形化工具容易让人忽略"服务开关"这一步,操作上反而比 Ollama 多了一个心眼。
2.3 vLLM:给"要跑正经服务"的人
如果你手头的显卡比较好,或者你打算把本地模型做成一个团队都能用的服务,那 vLLM 更合适。它吞吐量高、显存控制好,生产环境很多服务栈都用它。基本用法是:
pip install vllm vllm serve Qwen/Qwen2.5-Coder-14B-Instruct --port 8000服务起来之后,同样是http://localhost:8000/v1的 OpenAI 兼容端点。vLLM 的配置项多,比如--max-model-len控制上下文长度、--quantization选量化方式,适合愿意折腾的后端玩家。但对大多数人来说,Ollama 和 LM Studio 已经足够了,vLLM 更像是一个"往上走"的可选项。
2.4 三个方案的取舍与硬件门槛
我把三个方案放在一起对比:
| 方案 | 上手难度 | 接口地址 | 适合场景 |
|---|---|---|---|
| Ollama | 低 | http://localhost:11434/v1 | 个人开发机,命令行习惯 |
| LM Studio | 更低 | http://localhost:1234/v1 | 新手、图形化操作 |
| vLLM | 中高 | http://localhost:8000/v1 | 大显存、多用户、服务化部署 |
对应的硬件门槛也很关键。本地跑模型主要吃显存,模型参数量、精度和上下文长度都会直接决定占用。我给的参考值是这样的:
| 模型规模 | 量化精度 | 最小显存 | 推荐显存 |
|---|---|---|---|
| 7B | Q4_K_M | 约 5-6GB | 8GB+ |
| 7B | FP16 | 约 16GB | 16GB+ |
| 14B | Q4_K_M | 约 9-10GB | 12GB+ |
| 32B | Q4_K_M | 约 20-22GB | 24GB+ |
这里有个大概的估算公式:模型加载后的显存占用约等于"参数量 × 每参数字节数"。“Q4 量化”下来,每个参数大约占 0.5-0.6 字节;FP16 则是每个参数 2 字节。以 7B 模型为例,Q4 大约 4-5GB,FP16 约 14GB,再算上 KV cache 和推理中间变量,实际占用的就是表格里那个数。所以配之前先看一眼自己的显卡,不然模型拉下来根本跑不动。
注意:如果显存低于 8GB,也不是完全没救。能用小一点的 7B 模型,或者上 CPU 推理,但速度会慢到让你怀疑人生,opencode 这种要反复调用工具的 Agent 会非常痛苦。
3. 让 opencode 用上本地模型的两条配置路径
3.1 思路A:环境变量直连——最快但容易踩坑
网上很多教程会告诉你,opencode 底层走的是 Anthropic 兼容协议,所以只要把 API 地址改成本地服务就行。对应的环境变量是这样:
export ANTHROPIC_BASE_URL="http://localhost:11434/v1" export ANTHROPIC_AUTH_TOKEN="ollama" opencode这个思路本身没错,但我实测下来发现一个坑:opencode 默认期望的是 Anthropic 风格的/v1/messages接口,而 Ollama 和 LM Studio 提供的 OpenAI 风格/v1/chat/completions接口。两者格式不一样,直接设置环境变量后,很多旧版本服务端根本接不住,会返回 400 或者 404。能用这个方案的朋友,要么是本地服务端已经实现了 Anthropic 协议兼容,要么是中间加了一层协议转换代理,并不是每个环境都能一步到位。
所以我的建议是:如果只是想做个快速验证,你可以先试试环境变量直连;但如果你想要一套稳定可复现的配置,请直接看方案B。不要在环境变量这条路上死磕,我因为不信邪浪费了整整一个下午。
3.2 思路B:配置文件注册自定义 provider——推荐做法
更稳妥的方法是在 opencode 的配置文件里显式注册一个自定义 provider,让它按 OpenAI 兼容协议去请求本地服务。配置目录一般是~/.config/opencode/,不同版本可能是opencode.json或者多个 JSON 文件的组合,具体可以用opencode --help确认一下路径。核心配置长这样:
{ "provider": { "local-ollama": { "baseURL": "http://localhost:11434/v1", "apiKey": "ollama", "model": "qwen2.5-coder:14b" } } }如果是 LM Studio,就改成"baseURL": "http://localhost:1234/v1",apiKey 随便填一个占位符即可,因为本地服务通常不做鉴权。vLLM 同理,换成http://localhost:8000/v1。
这里要提醒一点:opencode 不同版本的配置字段名会有细微差异,我上面用的是最核心的三个字段——baseURL、apiKey、model。你配置时如果发现字段名对不上,重点留意 TUI 里有没有/provider或/models这样的交互式入口,很多版本其实支持直接在界面里添加和切换 provider,比手改 JSON 更不容易出错。我自己的习惯是:先用交互式入口添加 provider,让它自动生成配置文件,再手工微调模型名和默认模型,这样最稳妥。
配置完成后,启动 opencode,进入界面后把当前模型切到local-ollama/qwen2.5-coder:14b,然后随便让它解释一段代码,能正常返回就说明接通了。
3.3 哪些本地模型适合给 opencode 当后端
模型选不好,配置再对也白搭。我给 opencode 配本地模型时前后试了好几个,最终留下的候选名单和心得是这样的:
| 模型 | 参数量 | 我的体感 | 适合谁 |
|---|---|---|---|
| Qwen2.5-Coder-7B/14B | 7B/14B | 代码补全和工具调用均衡,14B 明显更稳 | 绝大多数人,首选 |
| Qwen2.5-Coder-32B | 32B | 能力接近小号云端模型,显存要求高 | 24GB 以上显卡用户 |
| DeepSeek-Coder-V2-Lite | 16B MoE | 推理速度不错,但工具调用稍弱 | 显存和速度折中的用户 |
| Llama-3.1-8B | 8B | 通用能力好,代码专项不如 Qwen-Coder | 什么都想跑一点的用户 |
我个人最后长期用的是 Qwen2.5-Coder-14B 的 Q4 量化版,原因很现实:14B 量化后显存占用在 9-10GB 左右,一张 12GB 显卡刚好跑得动,同时给 KV cache 留出了余量;代码能力和工具调用在同类模型里又是第一梯队。如果你的显卡是 24GB,直接上 32B 的 Q4 量化版,体验会再上一个台阶。
4. 关键参数与性能调优
4.1 上下文窗口、温度和 max tokens 怎么定
配置成功只是第一步,真正影响使用体验的是那几个参数。先说上下文窗口,很多本地模型默认只有 2048 或者 4096,这个长度对 Agent 任务是严重不够的——它要读文件、看报错、分析上下文,很容易就把窗口占满,然后开始"失忆"。我建议至少开到 8192,有条件开到 16384。Ollama 下可以通过 Modelfile 调整:
FROM qwen2.5-coder:14b PARAMETER num_ctx 8192 PARAMETER temperature 0.2然后创建新的模型实例:
ollama create qwen2.5-coder-14b-8k -f ./Modelfile这样就能得到一个自定义上下文长度的模型。再做一次验证调用,确认窗口确实生效。
温度这个参数容易被忽略。如果是普通聊天,温度高一点显得"有创意",但给 Agent 用,它需要的是稳定、可复现的工具调用和代码生成,温度太高会开始编造不存在的文件路径。我的经验是温度设在 0.1-0.2,接近贪心解码的效果,代码任务的表现会稳定很多。
max tokens 同样关键。opencode 经常让模型一次性生成一个完整文件或者大段 diff,如果输出上限太小,生成到一半就被截断,Agent 后续步骤全乱。Ollama 默认的 max tokens 经常偏小,我推荐至少调到 4096,个人习惯是 8192。别怕浪费,代码任务宁肯多生成一点,也不能反复截断重试。
4.2 量化与显存:让一张显卡发挥最大价值
本地模型的显存管理是个长期课题。量化精度选择很直接:Q4_K_M 是性价比之王,质量损失在代码任务里基本感知不到,显存占用却能砍掉一半还多;Q8_K_M 更接近原版但显存明显变大;FP16 只推荐在显存非常充裕的情况下用。以 14B 模型为例,Q4 量化后 9-10GB,FP16 要 28GB 左右,同样是写代码,体验差距没有显存差距那么大。
还要意识到 KV cache 会随着对话长度增长不断吃掉显存。上下文越长,KV cache 占用越大,如果你的服务端支持,把上下文从 16K 降到 8K 能省出不少显存,而通常 8K 对大多数编程 Agent 任务已经够用。这本质上是一个"上下文长度"和"可用显存"的平衡,没有绝对正确的值,需要你看自己的任务规模来调。
4.3 Agent 工具调用的稳定性问题
这是本地模型做 Agent 时最隐蔽的坑。opencode 的工作方式是让模型决定调用什么工具、传什么参数,如果模型的 function calling 能力弱,就会出现三种情况:反复调用同一个命令不停止、生成一个不存在的文件路径、或者干脆拒绝调用工具。Qwen 系列的 tool calling 训练做得比较好,这是我推荐它的重要原因。
如果你发现模型文字能力还行,但一进入工具调用流程就"发疯",不要试图通过调温度解决,直接换模型更实际。另外可以观察 opencode 的日志输出,看看它在调用工具时的 JSON 参数是否畸形。很多本地框架会做"智能容错",但多轮工具调用的稳定性上限还是由模型本身决定的,选对模型比写对配置重要得多。
5. 常见问题与排查清单
5.1 请求失败类问题
这类问题最好定位,按"从服务端到客户端"的顺序排查,通常十几分钟就能解决。我把高频问题整理成了速查表:
| 现象 | 排查方向 | 解决办法 |
|---|---|---|
connect ECONNREFUSED | 本地服务是否启动 | curl http://localhost:11434/v1/models验证,没起就ollama serve |
| 404 Not Found | baseURL 路径不对 | 确认结尾是/v1而不是/v1/messages这种 |
| 401 Unauthorized | token 不匹配 | Ollama 随便填ollama,LM Studio 填任意占位 |
| 400 Bad Request | 接口协议不匹配 | 检查 opencode 是否用了 OpenAI 兼容 provider 而不是原生协议 |
| 连接超时 | 服务端卡死 | 重启 Ollama 进程,再看端口有没有被占 |
这里面最值得说的是 400 和 404。我在 3.1 里说过,环境变量直连方案很可能是协议不匹配,如果你已经按方案B配置了还是 400,那大概率是配置里的baseURL拼错了,比如多写了一个/chat/completions后缀。记住:provider 配置里只需要指到/v1这个根路径,具体的路由由 opencode 自己拼。
5.2 输出质量类问题
| 现象 | 原因 | 解决办法 |
|---|---|---|
| 代码生成到一半中断 | max_tokens 太小 | 调到 4096 以上 |
| 上下文一长就前后矛盾 | num_ctx 太小 | 通过 Modelfile 或服务端参数加大窗口 |
| 总是编造不存在的 API | 模型能力不足 | 换 14B 以上模型,或换 Qwen-Coder 系列 |
| 中文乱码/混合语言 | 模型没有系统提示适配 | 检查服务的 prompt 模板,用默认模板别乱改 |
| 工具调用反复循环 | 模型 tool calling 弱 | 换支持函数调用的模型,Qwen-Coder 优先 |
这里我想多说一句,很多人遇到"模型乱回答"第一时间就去调 prompt,但本地 Agent 场景下,模型的系统提示词是由 opencode 自动拼接的,你不应该自行改动。如果模型在标准配置下还是乱来,基本就是模型选错了,换模型比改提示词有效得多。
5.3 性能与资源类问题
最典型的性能问题是"开始很快,多聊几句就明显变慢"。这往往是 KV cache 把显存挤爆后,部分层被 offload 到内存,推理速度断崖式下降。排查方法很简单:跑任务时开着nvidia-smi看显存,如果利用率接近 100%,同时模型开始吃内存,就说明显存不足。方案是降量化、缩减上下文窗口,或者换更小的模型。
另一个常见现象是"同样的配置,别人快我慢很多"。检查一下服务端是不是被多个进程占用了,比如同时跑着两个 Ollama 实例,或者 vLLM 被别的前台任务抢占了显存。这类问题排查起来不难,但容易被人忽略,我遇到过两三次,都是在后台默默挂着其他推理进程导致的。
6. 实战记录:我当前在用的配置和推荐工作流
6.1 一份可以直接参考的完整配置
最后把我当前在用的整套配置贴出来,给想"抄作业"的朋友一个底稿。我的硬件是 12GB 显存的显卡,长期使用的是 Qwen2.5-Coder-14B Q4 量化版,通过 Ollama 跑服务。Modelfile 是这样的:
FROM qwen2.5-coder:14b PARAMETER num_ctx 8192 PARAMETER temperature 0.2 PARAMETER num_predict 8192然后:
ollama create qwen2.5-coder-14b-8k -f ./Modelfile ollama serveopencode 配置文件里的 provider 部分:
{ "provider": { "local": { "baseURL": "http://localhost:11434/v1", "apiKey": "ollama", "model": "qwen2.5-coder-14b-8k" } } }启动 opencode 后切换到 local 这个 provider,就可以正常干活了。这套配置被我连续用了两个多星期,单文件补全、单元测试生成、代码解释都非常稳定,多文件小重构也能应对,虽然偶尔要手动纠正方向,但整体可用的程度超出我最初的预期。
6.2 适合本地模型的工作流
经过这段时间的磨合,我给自己定了一个分工原则:云端 API 模型负责需要长上下文、强推理的重活,比如大型重构、跨模块分析;本地模型负责轻量编程任务、隐私敏感代码,以及"断网应急"。具体来说,这几类任务我会专门切到本地模型:脱敏算法调整、内部工具的脚本开发、整段代码风格统一、报错信息的一步步解释。这些任务的共同点是上下文规模不大、不需要太多外部知识,正好是本地模型的舒适区。
反过来,如果任务需要同时理解几个大文件、还要参考框架文档,我就会切回云端。不要为了"显得本地模型厉害"而强行让它干力不能及的活,工具适配场景,场景适配工具,这才是正确的使用方法。
折腾完这一趟,我最大的感受是:opencode 配置本地模型这件事,真正的难点不在于把接口地址填对,而在于建立一套适合本地模型能力边界的工作流。模型、显存、参数、工具调用稳定性,每个环节都可能卡你一下,但只要选型合理,本地模型的体验完全可以作为日常开发的兜底方案。最后再分享一个小心得:很多看起来高深的配置问题,第一步永远是curl直接打服务端接口,别急着改 opencode 的配置。当你把"服务端本身是否能正常返回内容"这件事先确认了,剩下的多半只是字段拼接的小问题。