codecamp

Ollama OpenCode

OpenCode 是开源的终端编码代理,能读项目、改文件、跑命令。Ollama 负责把它配好,指向本地或云端模型。

版本基线 v0.40.12,官方 docs.ollama.com/integrations/opencode。

一、快速启动

ollama launch opencode

二、接入后的能力

能力 说明
对话 针对仓库或任务提问
命令行 在当前工作目录执行命令
文件编辑 读写项目文件
子代理 拆分任务
网页抓取 抓取并总结网页
视觉 传图片和截图

三、上下文是硬门槛

OpenCode 要求上下文 64k 以上,低于这个值基本不可用(表现为频繁报错或直接截断)。

OLLAMA_CONTEXT_LENGTH=65536 ollama serve

调整方式见 6.1 Ollama 上下文长度。

四、手动配置

安装 OpenCode

curl -fsSL https://opencode.ai/install | bash

配置 Ollama 作为 provider

在 opencode.json 里加一段 provider 配置:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "ollama": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Ollama",
      "options": {
        "baseURL": "http://localhost:11434/v1"
      },
      "models": {
        "qwen3.5": {
          "name": "qwen3.5"
        }
      }
    }
  }
}

三个关键点:

  • npm 必须是 @ai-sdk/openai-compatible(Ollama 走 OpenAI 兼容协议)
  • baseURL 必须带 /v1
  • models 里的键名要和 ollama list 里的模型名一致

启动

opencode

只想配置、不想进交互界面:

ollama launch opencode --config

五、配置优先级:一个容易误解的点

ollama launch opencode 启动时用的是内联配置,它不会覆盖 ~/.config/opencode/opencode.json——你原有的 OpenCode 设置仍然生效。

反过来也有一条限制:只在 opencode.json 里定义的模型,不会出现在 ollama launch 的模型选择器里。想让某模型出现在选择器,得先用 ollama pull 拉到本地。

完整优先级规则见 OpenCode 官方文档的 config precedence 一节。

六、常见问题

现象 原因 处理
provider 连不上 baseURL 少了 /v1 补成 http://localhost:11434/v1
模型列表为空 models 里没写,或本地没拉模型 补配置并用 ollama pull 下载
长任务中途失败 上下文不足 64k 调大 num_ctx
自定义模型在选择器里看不到 只写在 opencode.json 用 ollama pull 拉到本地

动手试

## ① 确认兼容端点
curl http://localhost:11434/v1/models

## ② 启动
ollama launch opencode

第一条返回 JSON 模型列表,就说明 baseURL 层面的问题都排除了。

Ollama Claude Code
Ollama DeepSeek Harness
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

Ollama Cloud

Ollama CLI 命令行参考

Ollama Modelfile 参考

Ollama 上下文长度

Ollama 导入自定义模型

Ollama 常见问题

Ollama 硬件支持

Ollama 故障排查

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }