1. 从一次「图片发不出去」说起:OpenCode 配置到底卡在哪
OpenCode 是一个跑在终端里的 AI 编码助手,能读代码、改文件、跑命令,也能接不同厂商的模型。它本身不绑定某一家模型,而是通过provider配置去对接任意兼容 OpenAI 接口的服务。问题也恰恰出在这里:很多人第一次配 OpenCode,把baseURL和apiKey填完就以为完事了,结果一用就发现——发图片提示this model does not support image input,长文件一贴就报上下文超限,想让模型「先想再答」却看不到推理过程。
这些都不是 OpenCode 的 bug,而是modalities、attachment、reasoning、limit这几个字段没配对。OpenCode 的设计哲学是「能力必须显式声明」:你没写image,它就当这个模型不支持图片;你没写reasoning,它就不展示思考过程。默认值等于「不支持」,这是最容易踩的坑。
这篇就聚焦一件事:用 TaoToken 作为统一的 Key 和 API 通道,把 OpenCode 的模型能力、模态和常用选项一次配清楚。TaoToken 在这里扮演的角色是「一个 Key 对接多个模型」的入口,你不需要为每个模型单独申请密钥,改baseURL指向统一通道即可。下面会给出可直接复制的opencode.json骨架、逐项验证动作,以及我实际排障时遇到的几个典型报错。适合已经装好 OpenCode、正准备接模型,或者接了但多模态/推理功能不生效的读者。
2. 前置准备:TaoToken 通道与 OpenCode 的对接关系
在动手改配置前,先把两边的角色理清楚,后面看字段就不会晕。
TaoToken 提供的是兼容 OpenAI 规范的 API 通道,官网入口在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 根地址是 https://taotoken.net/api 。你需要在控制台生成一个 API Key,这个 Key 就是 OpenCode 配置里options.apiKey的值。模型对话调试入口、Coding Plan、控制台和 API Keys 管理页分别在:
- 模型对话:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- 控制台:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- API Keys:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
OpenCode 这边,配置文件默认在~/.config/opencode/opencode.json。它的加载顺序是 Remote → Global → Custom → Project,后面的层级会覆盖前面的同名字段。也就是说,你可以在全局配置里放通用 provider,在项目目录下用.opencode/opencode.json覆写某个模型的limit或modalities,不用重复写整份配置。
一个关键认知:OpenCode 里的provider是「供应商条目」,models是「这个供应商下的模型清单」。同一个 provider 下可以挂多个 model entry,每个 entry 单独声明自己的能力。TaoToken 作为统一通道,通常只需要一个 provider 条目,然后在models里列出你要用的模型即可。
注意:
options.baseURL填的是 API 根地址,不要带/v1/chat/completions这类具体路径,OpenCode 会自己拼接。填错路径最常见的表现是 404 或model not found。
3. 可复制的 opencode.json 骨架与字段逐项说明
下面这份骨架可以直接改 Key 后使用。为了让你看清结构,我把 TaoToken 作为 provider,挂了两个模型 entry:一个偏多模态,一个偏推理。
{ "$schema": "https://opencode.ai/config.json", "provider": { "taotoken": { "npm": "@ai-sdk/openai", "options": { "baseURL": "https://taotoken.net/api", "apiKey": "{file:~/.secrets/taotoken.key}" }, "models": { "gpt-5.1-codex": { "name": "GPT-5.1 Codex", "attachment": true, "reasoning": true, "modalities": { "input": ["text", "image"], "output": ["text"] }, "limit": { "context": 1000000, "output": 128000 } }, "claude-sonnet": { "name": "Claude Sonnet", "attachment": false, "reasoning": true, "modalities": { "input": ["text"], "output": ["text"] }, "limit": { "context": 200000, "output": 64000 } } } } } }逐项拆开看,每个字段都对应一个实际行为:
npm指定用哪个 SDK 适配器。接 OpenAI 兼容通道统一用@ai-sdk/openai,TaoToken 的接口遵循这套规范,所以不用换。
options.baseURL是通道根地址,options.apiKey是鉴权。这里用{file:~/.secrets/taotoken.key}从独立文件读取,避免把明文 Key 提交进 Git。你也可以直接写字符串,但强烈建议用文件引用。
models下的每个 key 是模型标识,name是显示名。真正决定能力的是下面四个字段:
| 字段 | 作用 | 缺省行为 |
|---|---|---|
modalities.input | 声明支持的输入类型 | 缺省视为不支持,图片/音频必须显式写 |
modalities.output | 声明输出类型 | 同上 |
attachment | 是否允许上传文件 | 缺省不允许,常与 modalities 联动 |
reasoning | 是否启用思考过程显示 | 缺省不显示 |
limit.context | 最大上下文 token | 缺省按模型默认,可能偏小 |
limit.output | 最大输出 token | 同上 |
只有modalities.input里包含image,OpenCode 才会把图片传给模型;否则前端直接拦截并提示this model does not support image input。attachment和modalities是联动的:开了attachment但没声明image,上传图片依然会被拒。
limit这两个值建议按你实际用的模型能力填。填太小,长文件一贴就截断;填太大超过模型真实上限,请求会被通道侧拒绝。TaoToken 的接入文档里对每个模型的上下文和输出上限有说明,配之前对一下最稳。
4. 验证配置是否生效:三步逐项确认
配完不是保存就完事,要逐项验证。下面三步从「通道通不通」到「能力开没开」逐级确认。
第一步,验证通道和 Key。在终端直接发一个最小请求,确认baseURL和apiKey没问题:
curl -s https://taotoken.net/api/chat/completions \ -H "Authorization: Bearer $(cat ~/.secrets/taotoken.key)" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5.1-codex", "messages": [{"role": "user", "content": "ping"}] }'返回里带choices字段就说明通道和 Key 都正常。如果返回 401,检查 Key 是否复制完整;返回 404,检查baseURL有没有多写路径。
第二步,在 OpenCode 里验证模型被识别。启动 OpenCode 后执行模型列表命令,看taotoken下的两个 entry 是否出现:
opencode models输出里应该能看到taotoken/gpt-5.1-codex和taotoken/claude-sonnet。如果没出现,多半是 JSON 语法错误,用jq . ~/.config/opencode/opencode.json校验一下。
第三步,验证多模态和推理。选gpt-5.1-codex,在对话里附一张图片,如果不再报does not support image input,说明modalities.input生效了。再问一个需要推理的问题,观察是否出现思考过程区块,出现即reasoning: true生效。这一步是很多人漏掉的——配置写了但没实测,等到真正用图片时才暴露问题。
提示:改完配置后 OpenCode 需要重启才会重新加载。热改文件不生效是常见误判,先重启再排查。
5. 本篇常见报错与排查清单
下面这几个是我实际配 OpenCode + TaoToken 时反复遇到的,按报错信息对照排查最快。
this model does not support image input:modalities.input没写image,或写了但attachment是false。两个都要对:input含image且attachment: true。
model not found或 404:baseURL写成了带具体路径的地址,或者models下的 key 和通道侧模型标识不一致。baseURL只填https://taotoken.net/api,模型 key 用通道文档里给的标识。
上下文一长就截断:limit.context填得比模型真实上限小。对照接入文档把值调到位,别凭感觉填。
看不到思考过程:reasoning没设成true,或者当前模型本身不支持推理。换支持推理的 entry 再试。
Key 泄露风险:直接把sk-开头的字符串写进opencode.json并提交了。改用{file:~/.secrets/taotoken.key}引用,并把 secrets 目录加进.gitignore。
项目级覆写不生效:加载顺序是 Remote → Global → Custom → Project,确认你的覆写文件在正确的层级,且字段名拼写一致。
排查时有个通用手法:先用第 4 节的 curl 确认通道层没问题,再回到 OpenCode 层看配置。把「通道问题」和「配置问题」分开,能省掉一半时间。
6. 接下来怎么走:按你的使用场景选入口
配置跑通之后,下一步取决于你主要拿 OpenCode 干什么。
如果你还在调模型、试不同 entry 的能力差异,先去模型对话页把各个模型的实际表现对比一遍,确认哪个适合你的任务,再回来固化到opencode.json:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
如果你准备长期用 OpenCode 做日常编码、跑 Agent 任务,建议直接看 Coding Plan,它更适合高频、长周期的编码场景,配额和模型覆盖也更省心:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
如果你在接入过程中遇到鉴权、路径、模型标识这类问题,或者想确认某个字段的准确写法,API Keys 管理页和接入文档是最直接的两个入口:
- API Keys:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
最后留一个我自己的习惯:每加一个新模型 entry,先只配baseURL、apiKey、limit三个字段跑通文本对话,确认没问题后再逐个加modalities、attachment、reasoning。一次只改一个变量,出问题时你立刻知道是哪个字段的锅。这比一次性写满配置再逐个排查要快得多。