1. OpenCode Agent 项目配置 middleware 到底改什么:从 settings 定位到字段含义
OpenCode 这类 Agent 工具在本地跑起来之后,真正决定它能不能稳定调用模型的,往往不是主流程代码,而是项目配置里的 middleware 层。你可以把 middleware 理解成一道“关卡”:每次 Agent 发起请求之前,它都会先经过这里,决定用哪个 Base URL、带哪个 Key、走哪个 Model ID、日志打到哪、超时怎么算。如果这一层没配对,后面写再多 prompt 都是白搭。
我这次要解决的具体问题是:OpenCode 项目默认的 settings 指向的是官方端点,而我想把它切到 TaoToken 的 API 上,让本地 Agent 调用链完整跑通。场景很典型——你本地已经装好了 OpenCode,命令行能起来,但一执行实际对话就报 401 或者连接失败,因为 middleware 里的 provider 配置还指着旧地址。
先说清楚 OpenCode 的配置文件在哪。不同版本略有差异,常见位置有三个:
- 项目根目录下的
opencode.json或opencode.jsonc - 用户目录下的
~/.config/opencode/config.json - 环境变量
OPENCODE_CONFIG指向的自定义路径
你可以先用一条命令确认当前生效的是哪个:
opencode config path如果这条命令没输出,就直接找:
find . -maxdepth 3 -name "opencode.json*" 2>/dev/null ls -la ~/.config/opencode/ 2>/dev/null找到文件后,重点看这几个字段。第一个是provider,它决定了请求发往哪个服务商;第二个是model,指定默认模型 ID;第三个是middleware或plugins数组,里面挂着请求前后的钩子函数。很多人改配置只改了provider.baseURL,却忘了model还写着旧的服务商前缀,结果请求发出去了但模型名对不上,返回model not found。
middleware 在 OpenCode 里的执行顺序是这样的:解析用户输入 → 加载配置 → 执行 middleware 链 → 发起模型请求 → 返回结果。middleware 链里每个函数都能拿到当前的请求上下文,包括 headers、body、baseURL。你可以在这一层做鉴权注入、日志记录、请求重写。我实测下来,最稳妥的做法不是去改 OpenCode 的源码,而是在项目配置里声明一个 middleware 文件,让它统一往请求里塞 TaoToken 的鉴权头。
这里有个容易踩的坑:OpenCode 的 middleware 配置项在不同版本里叫法不一样。老版本叫middleware,新版本可能叫plugins或者hooks。你先用opencode --version确认版本,再对照官方文档里的配置 schema。如果配置项名字写错了,OpenCode 不会报错,而是静默忽略,你会以为配了但实际没生效。
还有一个关键点:middleware 里拿到的baseURL如果是undefined,说明 provider 配置没被正确加载。这时候不要急着在 middleware 里硬编码地址,而是回头检查provider字段的层级结构。OpenCode 的配置是嵌套的,provider下面通常还有options或settings子对象,baseURL要放在正确的层级里才会被读取。
我建议你在改之前先备份原文件:
cp opencode.json opencode.json.bak这样万一改崩了,一条命令就能回滚。接下来就是具体的字段修改和可复制配置片段。
2. TaoToken 前置准备:Base URL、API Key 与 Model ID 三件套
在动 OpenCode 的 settings 之前,你得先把 TaoToken 这边的三样东西准备好:Base URL、API Key、Model ID。这三件套缺一不可,而且必须和 OpenCode 配置里的字段一一对应。
Base URL 用这个:
https://taotoken.net/api注意这里不要加多余的路径后缀,也不要带 UTM 参数。OpenCode 在拼接请求时会自动补上/v1/chat/completions这类路径,你手动加了反而会变成双斜杠或者路径错位。
API Key 的获取入口在控制台的 API Keys 页面。你登录之后找到对应的创建按钮,生成一个 Key 并复制下来。这个 Key 只显示一次,丢了就得重新生成。我一般会把它存到本地环境变量里,而不是直接写死在配置文件中:
export TAOTOKEN_API_KEY="sk-你的实际key"然后在 OpenCode 配置里用${TAOTOKEN_API_KEY}这种占位符引用。这样配置文件可以进版本控制,Key 不会泄露。如果你用的是 Windows PowerShell,设置方式换成:
$env:TAOTOKEN_API_KEY="sk-你的实际key"Model ID 这块要特别注意。TaoToken 支持的模型列表可以在模型对话页面里看到,你选一个适合 Agent 场景的,比如带长上下文能力的模型。复制它的完整 ID,不要自己简写。OpenCode 配置里的model字段必须和这个 ID 完全一致,大小写都不能错。
三件套准备好之后,先别急着改 OpenCode,用 curl 单独验证一下 Key 和 Base URL 能不能通:
curl -s -X POST https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "你的Model ID", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 16 }'如果返回里能看到choices数组,说明三件套没问题。如果返回 401,检查 Key 有没有复制完整;如果返回 404,检查 Base URL 有没有多写路径;如果返回 model not found,检查 Model ID 拼写。
这一步很多人会跳过,直接去改 OpenCode,结果报错了分不清是 TaoToken 的问题还是 OpenCode 配置的问题。先用 curl 把变量隔离掉,后面排障会轻松很多。
另外提醒一点:不要把 API Key 提交到 Git 仓库。如果你用的是项目级opencode.json,建议把它加到.gitignore里,或者用opencode.json.example做模板,真实配置放本地。TaoToken 的控制台里也可以设置 Key 的权限范围,Agent 场景一般只需要对话权限,不需要开管理权限。
三件套确认无误后,就可以进入 OpenCode 的配置修改环节了。
3. 可复制配置:OpenCode settings 里 middleware 与 provider 的完整 JSON 片段
这一节是核心操作。我直接给你一份可以复制的配置片段,你对照着自己的文件改。先看项目根目录下的opencode.json:
{ "$schema": "https://opencode.ai/config.json", "provider": { "taotoken": { "type": "openai-compatible", "options": { "baseURL": "https://taotoken.net/api", "apiKey": "${TAOTOKEN_API_KEY}" } } }, "model": "taotoken/你的Model ID", "middleware": [ { "name": "taotoken-auth", "enabled": true, "config": { "baseURL": "https://taotoken.net/api", "apiKeyEnv": "TAOTOKEN_API_KEY", "timeout": 60000, "logLevel": "INFO" } } ], "logLevel": "INFO" }逐项解释一下。provider.taotoken.type设为openai-compatible,因为 TaoToken 的接口兼容 OpenAI 格式。options.baseURL就是刚才的 API 地址,options.apiKey用环境变量占位符。model字段里的taotoken/前缀是 OpenCode 用来匹配 provider 的,后面跟你的实际 Model ID。
middleware数组里我声明了一个名为taotoken-auth的中间件。enabled设为true才会生效。config里的apiKeyEnv告诉 middleware 从哪个环境变量读 Key,timeout设 60 秒,Agent 场景下模型响应可能比较慢,太短会频繁超时。
如果你用的是opencode.jsonc格式,可以加注释:
{ // TaoToken provider 配置 "provider": { "taotoken": { "type": "openai-compatible", "options": { "baseURL": "https://taotoken.net/api", "apiKey": "${TAOTOKEN_API_KEY}" } } }, // 默认模型,前缀必须和 provider key 一致 "model": "taotoken/你的Model ID", "middleware": [ { "name": "taotoken-auth", "enabled": true, "config": { "baseURL": "https://taotoken.net/api", "apiKeyEnv": "TAOTOKEN_API_KEY", "timeout": 60000 } } ] }有些版本的 OpenCode 把 middleware 配置放在plugins字段下,写法类似:
{ "plugins": { "middleware": [ { "name": "taotoken-auth", "enabled": true, "config": { "baseURL": "https://taotoken.net/api", "apiKeyEnv": "TAOTOKEN_API_KEY" } } ] } }你根据自己版本的 schema 选一种。判断方法很简单:改完之后跑opencode config validate,如果提示未知字段,就说明字段名不对,换另一种写法。
如果你用的是 Cline 或者 Claude Code 这类工具,配置思路一样,只是文件位置不同。Cline 的 MCP 配置在cline_mcp_settings.json里,Claude Code 的配置在~/.claude/settings.json或项目级.claude/settings.json。核心三件套不变:Base URL 填https://taotoken.net/api,Key 填你的实际值,Model ID 填完整 ID。
Codex 用户注意auth.json的写法:
{ "openai": { "apiKey": "sk-你的实际key", "baseURL": "https://taotoken.net/api" } }这个文件通常在~/.codex/auth.json。改完之后 Codex 的请求就会走 TaoToken。
配置改完,先别急着跑 Agent,用一条命令验证 middleware 有没有被加载:
opencode config show --json | grep -A 5 middleware如果输出里能看到你配的taotoken-auth,说明配置被正确解析了。看不到的话,检查文件路径和字段名。
4. 验证请求:确认 middleware 生效与 Agent 调用链跑通
配置写好了,接下来要验证它真的生效。分三步走:先验证配置加载,再验证 middleware 执行,最后验证完整 Agent 调用链。
第一步,确认配置被读取:
opencode config show输出里应该能看到provider.taotoken和middleware数组。如果baseURL显示的是${TAOTOKEN_API_KEY}这种未展开的占位符,说明环境变量没被正确读取。检查你的 shell 有没有 source 对应的 profile 文件,或者直接在启动命令前带上环境变量:
TAOTOKEN_API_KEY="sk-你的实际key" opencode config show第二步,验证 middleware 执行。OpenCode 一般有 debug 模式,打开后能看到 middleware 链的执行日志:
opencode --log-level DEBUG run "你好"在输出里找类似middleware taotoken-auth executed或者injecting auth header的日志行。如果看到了,说明 middleware 被调用了。如果没看到,检查enabled是不是true,以及 middleware 的name有没有和配置里的引用对上。
第三步,跑一个完整的 Agent 请求:
opencode run "用一句话解释什么是 middleware"正常的话,你会看到模型返回的内容。如果返回 401,说明鉴权头没注入成功,回头检查 middleware 的apiKeyEnv和环境变量名是否一致。如果返回连接超时,检查baseURL有没有写错,以及本地网络能不能访问taotoken.net。
我实测下来,middleware 生效的最直接证据是请求日志里的Authorization头。你可以在 middleware 配置里临时把logLevel调到DEBUG,然后看日志里有没有Bearer sk-开头的行。注意不要把完整 Key 打到日志里,生产环境要关掉这个级别。
如果你想更直观地验证,可以用模型对话页面手动发一条消息,对比 OpenCode 返回的内容格式是否一致。两边都能通,说明调用链没问题。
还有一个验证技巧:在 middleware 里加一个自定义 header,比如X-Agent-Source: opencode,然后在 TaoToken 的请求日志里看这个 header 有没有出现。如果出现了,说明 middleware 确实在请求发出前执行了。这个 header 不影响功能,纯粹用来调试。
完整调用链跑通之后,你可以试着跑一个稍微复杂的 Agent 任务,比如让它读一个本地文件然后总结。这一步能验证 middleware 在多轮请求里是否稳定生效。如果第一轮通了第二轮报错,多半是 middleware 里的状态管理有问题,比如 Key 被缓存后过期了。
验证通过后,把logLevel调回INFO,避免日志太多影响性能。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth 报错对照
这一节我把实际遇到过的报错和排查路径列出来,你对照着看。
401 Unauthorized。最常见。原因通常是 Key 没读到或者 Key 无效。排查顺序:先确认环境变量TAOTOKEN_API_KEY在当前 shell 里能echo出来;再确认 middleware 的apiKeyEnv字段名和环境变量名完全一致;最后确认 Key 本身没有过期或被删除。如果用的是${TAOTOKEN_API_KEY}占位符,确认 OpenCode 版本支持这种语法,老版本可能不支持,需要直接写值。
local proxy failed。这个报错说明 OpenCode 尝试走本地代理但失败了。检查你的环境变量里有没有HTTP_PROXY或HTTPS_PROXY指向一个不存在的本地端口。如果有,临时 unset 掉:
unset HTTP_PROXY HTTPS_PROXY然后重新跑。另外检查baseURL有没有被 middleware 重写成localhost或127.0.0.1。middleware 里的baseURL必须和 provider 里的一致,都是https://taotoken.net/api。
reading choices 报错。通常是响应格式不对,OpenCode 期望 OpenAI 格式的choices数组,但实际返回的不是。检查provider.type是不是openai-compatible。如果写成了别的类型,OpenCode 会用错误的解析器去读响应。另外确认 Model ID 没有写错,有些模型返回的格式略有差异。
OAuth 相关报错。如果你之前配过 OAuth 登录,OpenCode 可能还在尝试走 OAuth 流程而不是 API Key。检查配置里有没有残留的oauth字段,有的话删掉。middleware 里也不要混用 OAuth 和 API Key 两种鉴权方式,选一种。
model not found。Model ID 拼写错误,或者model字段的前缀和provider的 key 不一致。比如 provider 叫taotoken,model 写成了taotoken-api/xxx,就对不上。统一用taotoken/你的Model ID。
middleware 不执行。检查enabled是否为true,name是否唯一,以及配置文件的层级是否正确。有些版本要求 middleware 必须放在顶层,不能嵌套在provider里面。
超时。Agent 场景下模型响应可能超过默认超时时间。把 middleware 的timeout调到 60000 或更高。如果还是超时,检查网络到taotoken.net的延迟。
配置改了不生效。OpenCode 可能有缓存。删掉缓存目录再试:
rm -rf ~/.cache/opencode然后重新跑。另外确认你改的是当前生效的那个配置文件,用opencode config path确认路径。
排查的时候记住一个原则:先用 curl 验证 TaoToken 三件套,再验证 OpenCode 配置加载,最后验证 middleware 执行。一层一层隔离,不要跳步。
6. 长期编码与 Agent 场景的配置建议
如果你打算长期用 OpenCode 跑 Agent 任务,有几个配置习惯值得养成。
第一,把 API Key 放在环境变量里,配置文件用占位符引用。这样配置文件可以安全地进版本控制,团队协作时每个人用自己的 Key。
第二,middleware 里加请求日志,但不要打完整 Key。记录请求时间、模型 ID、响应状态码就够了。出问题的时候这些日志能帮你快速定位。
第三,给 middleware 加超时和重试逻辑。Agent 任务经常需要多轮请求,单次超时不应该让整个任务失败。你可以在 middleware 里配置重试次数,比如失败后重试两次。
第四,定期检查 Model ID 是否还有效。TaoToken 的模型列表会更新,旧模型可能下线。你可以在 middleware 里加一个启动时的模型校验,发现无效就提示。
第五,如果你同时用多个 Agent 工具,比如 OpenCode、Cline、Claude Code,把三件套统一管理。Base URL 都是https://taotoken.net/api,Key 用同一个,Model ID 按工具需求选。这样切换工具的时候不用重新配。
第六,Coding Plan 适合长期编码场景,如果你每天都要跑大量 Agent 任务,可以了解一下它的额度机制,比按次调用更划算。
配置这件事,一次配好,后面就省心了。我试过把 middleware 配好之后,OpenCode 的 Agent 调用链稳定跑了几周没出过鉴权问题。关键就是把三件套对齐,然后用 curl 和 debug 日志做双重验证。