1. OpenCode 部署前必须搞清楚的 Agent Skills 运行链路
OpenCode 是一个开源的终端 AI 编码代理,你可以把它理解成跑在命令行里的 Claude Code 同类工具:它本身不产出智能,而是把「读文件、跑命令、改代码、调外部工具」这些动作编排起来,交给背后的大模型做决策。Agent Skills 则是这套编排体系里的「技能说明书」——一个装SKILL.md的目录,里面写清楚这个技能叫什么、什么场景该被激活、需要哪些参数、执行时走什么流程。模型读到这份说明书,就知道遇到 Excel 任务该调 xlsx 技能,而不是从零开始瞎写脚本。
这套机制适合谁?三类人最受益。第一类是想把日常重复操作(批量改表、日志分析、代码迁移)沉淀成可复用能力的前后端开发者;第二类是想统一管理模型 Key、不想在每个工具里重复填 API 地址的团队;第三类是想搞明白 Agent 到底怎么「思考—选技能—执行—纠错」这条链路的技术好奇者。OpenCode 的价值不在于它比别的工具聪明,而在于它的配置是纯文本、可版本化、可审计,你能清楚看到每一步发生了什么。
我先把整条链路摊开讲,后面所有配置都围绕这条链路展开。OpenCode 启动时会做三件事:加载全局配置(模型提供方、Base URL、API Key、默认模型 ID)、扫描技能目录(默认在配置目录下的skills/子目录,也支持项目级.opencode/skills/)、建立会话上下文。当你输入一个任务,运行原理大致是:主 Agent 拿到你的自然语言请求 → 结合当前可用技能列表做规划 → 决定是直接调用内置工具(bash、read、write、edit)还是激活某个 Skill → 执行后读取结果 → 如果报错(比如编码乱码、列名识别失败)就进入反思循环,改写脚本重试 → 直到产出可交付结果或判定失败。
技能加载流程有个容易踩的细节:OpenCode 不是把所有SKILL.md全文塞进上下文,而是先读 frontmatter 里的name和description做轻量索引,只有当任务语义和 description 匹配时才把完整技能文档加载进来。这就是为什么description写得越具体(列出支持的文件格式、典型场景),技能被正确触发的概率越高。很多人技能写了却从不触发,八成是 description 写得太笼统,模型判断不出该不该用。
配置项含义这块,核心就四个:provider(模型提供方标识)、baseURL(请求打到哪个兼容 OpenAI 协议的端点)、apiKey(鉴权凭证)、model(具体模型 ID)。这四项构成一次请求的最小闭环,缺一个就会在启动自检或首次调用时报错。把baseURL指向统一通道(比如 TaoToken 的https://taotoken.net/api),你就能用一套 Key 管理多个模型的调用,不用在 OpenCode、Cline、Codex 之间反复切换凭证。官网https://taotoken.net/?utm_source=taotoken_aicg_blog_end有接入说明,可以先对照看一遍再动手。
理解这条链路之后,部署就不再是「照着敲命令」,而是「我知道每一步在配什么、验证什么」。下一节进入前置准备,把 Key、端点、模型 ID 三件套先备齐。
2. TaoToken 前置准备:Base URL、API Key 与模型 ID 三件套
在动 OpenCode 之前,先把「三件套」备齐,否则后面配置写完一跑就 401,排查起来浪费时间。三件套指的是:Base URL(请求端点)、API Key(鉴权凭证)、Model ID(具体模型标识)。这三样在 OpenCode 的 settings 里是强绑定的,任何一个填错都会导致请求失败,而且报错信息往往不直观。
先说 Base URL。TaoToken 的 API 端点是https://taotoken.net/api,注意这里不要带任何查询参数,也不要自己拼/v1之外的路径——OpenCode 内部会按 OpenAI 兼容协议自动补全/chat/completions这类后缀。如果你填成https://taotoken.net/api/v1/chat/completions,请求会变成双后缀,直接 404。这个坑我见过太多次,配置里只写到/api就对了。
再说 API Key。登录控制台后进入 API Keys 页面创建,建议按用途分 Key:一个给 OpenCode 日常编码用,一个给测试脚本用,方便出问题时快速定位是哪个客户端在打请求。创建后立刻复制保存,页面刷新后就不再完整显示。Key 的格式通常是一串以固定前缀开头的长字符串,粘贴时注意别带首尾空格,YAML 和 JSON 对空格敏感,多一个空格就是 401。
最后是 Model ID。这个必须和你账号下实际可用的模型列表对齐,不能凭记忆瞎填。进模型对话页面或控制台的模型列表,复制准确的 ID 字符串(大小写、连字符、版本号都要一致)。常见的错误是把展示名称当 ID 用,比如界面上写「某某 Pro」,实际 ID 可能是xxx-pro-2024这种。填错 Model ID 的典型报错是model not found或invalid model,而不是 401,两者要区分开。
三件套备齐后,建议先用最轻量的方式验证一次,别急着配 OpenCode。打开终端用 curl 打一发最小请求:
curl -s https://taotoken.net/api/chat/completions \ -H "Authorization: Bearer 你的API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "你的模型ID", "messages": [{"role": "user", "content": "回复ok"}], "max_tokens": 16 }'返回里如果有choices数组且message.content有内容,说明三件套全部正确,可以进入 OpenCode 配置。如果返回 401,检查 Key 和 Authorization 头格式(Bearer后面一个空格);如果返回 404,检查 Base URL 是否多写了路径;如果返回模型相关错误,回去核对 Model ID。这一步花两分钟,能省掉后面半小时的排障。
注意:不要把 API Key 硬编码进会提交到 Git 的配置文件里。OpenCode 支持从环境变量读取,后面配置模板里我会用环境变量占位,实际使用时通过 shell 导出或写进本地不追踪的
.env。
三件套验证通过后,就可以开始写 OpenCode 的 settings 了。下一节给出可直接复制的配置片段,包含 JSON 和 TOML 两种形态,按你的 OpenCode 版本选一种。
3. 可复制配置:OpenCode settings 接入统一 Key/API 通道
OpenCode 的配置文件位置因平台而异:Linux/macOS 通常在~/.config/opencode/,Windows 在C:\Users\<用户名>\.config\opencode\。主配置文件常见为opencode.json(新版)或config.toml(部分发行版),技能目录则是同级的skills/。下面给出两种格式的完整片段,字段名和路径与官方结构保持一致,你按自己安装的版本二选一。
先看 JSON 形态,适合opencode.json:
{ "$schema": "https://opencode.ai/config.json", "provider": { "taotoken": { "npm": "@ai-sdk/openai-compatible", "name": "TaoToken", "options": { "baseURL": "https://taotoken.net/api", "apiKey": "{env:TAOTOKEN_API_KEY}" }, "models": { "your-model-id": { "name": "Your Model" } } } }, "model": "taotoken/your-model-id", "skills": { "paths": ["./skills"] } }几个字段逐个解释。provider.taotoken是你自定义的提供方键名,可以随便起,但要和后面model字段的前缀一致。npm指定用 OpenAI 兼容适配器,这是接统一通道的关键——TaoToken 的端点遵循 OpenAI 协议,用这个适配器就能直接对话。baseURL只写到/api,不要加/v1。apiKey用{env:TAOTOKEN_API_KEY}语法从环境变量读取,避免明文落盘。models里把你要用的 Model ID 作为键列出来,name只是展示用。顶层model写成提供方键名/模型ID的组合。skills.paths指向技能目录,相对路径基于配置文件所在目录解析。
再看 TOML 形态,适合config.toml:
model = "taotoken/your-model-id" [provider.taotoken] npm = "@ai-sdk/openai-compatible" name = "TaoToken" [provider.taotoken.options] baseURL = "https://taotoken.net/api" apiKey = "{env:TAOTOKEN_API_KEY}" [provider.taotoken.models.your-model-id] name = "Your Model" [skills] paths = ["./skills"]TOML 的层级用表头表达,语义和 JSON 完全一致。注意[provider.taotoken.models.your-model-id]这一行,如果你的 Model ID 里带点号或特殊字符,需要用引号包起来,比如[provider.taotoken.models."xxx-1.5"],否则 TOML 解析器会把点号当层级分隔符,导致模型注册失败。
配置写完后,设置环境变量。Linux/macOS 在~/.bashrc或~/.zshrc里加一行,Windows 用系统环境变量或 PowerShell 的$env::
export TAOTOKEN_API_KEY="你的API_KEY"然后准备技能目录。把从技能仓库下载解压的skills文件夹放到配置目录下,结构大致是skills/xlsx/SKILL.md、skills/pdf/SKILL.md这样,每个技能一个子目录,目录名和SKILL.md里的name保持一致最稳妥。如果你的技能放在项目里而非全局,把skills.paths改成["./.opencode/skills"]即可,项目级配置优先级高于全局。
提示:改完配置别急着跑复杂任务,先做启动自检。下一节给出验证动作,包括启动日志核对、技能触发确认、调用日志检查三步。
配置模板就这些,字段不多但每个都关键。填完后如果启动报local proxy failed或reading choices相关错误,先回看第 5 节的排错清单,八成是 baseURL 或适配器选错了。
4. 验证请求与成功结果:启动自检、技能触发、调用日志三步核对
配置写完不等于接通,必须做三步验证:启动自检看配置有没有被正确加载,技能触发看 Agent 会不会按 description 选中技能,调用日志看请求实际打到了哪个端点、返回了什么。这三步任何一步跳过,后面出问题都难定位。
第一步,启动自检。在终端直接运行opencode,观察启动输出。正常情况下它会打印已加载的提供方、默认模型、技能扫描结果。你要重点看三行信息:提供方名称是否显示为你在配置里起的键名(比如taotoken)、默认模型是否是你填的 Model ID、技能数量是否和你目录里的子目录数一致。如果技能数量是 0,说明skills.paths路径不对,相对路径的基准是配置文件所在目录,不是你执行命令的当前目录,这点容易搞混。如果提供方没加载出来,检查 JSON/TOML 语法——一个多余的逗号或漏掉的引号就会让整个配置被静默忽略。
第二步,技能触发验证。先做一个不依赖技能的基础测试,确认模型通道通:在 OpenCode 会话里输入「用一句话解释什么是闭包」,看它能否正常流式返回。这一步验证的是 Base URL、Key、Model ID 三件套。然后做技能触发测试,输入一个明确匹配某个技能 description 的任务,比如你装了 xlsx 技能,就输入「读取当前目录下的 test.xlsx,统计每列的非空数量」。观察 Agent 的规划输出里有没有出现「使用 xlsx 技能」或类似的技能激活标记。如果没有激活而是自己从头写 Python,说明技能的description没匹配上,回去把 description 改得更贴近你的实际提问措辞。
第三步,调用日志核对。OpenCode 一般会把会话日志写在配置目录的logs/或项目下的.opencode/logs/。打开最新日志,搜索请求记录,核对三件事:请求 URL 是否是https://taotoken.net/api/chat/completions(确认没多拼路径)、请求头里 Authorization 是否是 Bearer 加你的 Key(确认没读到空环境变量)、响应里choices[0].message是否有内容(确认模型真的返回了)。如果日志里 URL 显示的是localhost或某个代理地址,说明适配器或 baseURL 配错了,请求根本没出本机。
一个成功的完整结果长这样:你输入 Excel 分析任务,Agent 先输出思考过程(计划用 pandas 读取、检查文件存在),然后激活 xlsx 技能或直接执行脚本,中途如果遇到中文列名乱码会自我纠正改用 UTF-8 输出,最后给出结构化结论,比如「退单描述中出现最多的是系统自动驳回,共 111 次,占比 16.5%」。整个过程你能在日志里看到至少两次请求:一次是规划决策,一次是结果总结,中间可能还有纠错重试的请求。请求次数和内容对得上,说明链路完全打通。
注意:验证阶段建议用
max_tokens较小的简单任务,别一上来就跑大文件分析。小任务成功率高、日志短、好核对,等三步都过了再上真实业务数据。
三步验证都通过后,你已经有了一个可用的 OpenCode + 统一通道环境。接下来把常见报错对照一遍,把踩坑概率降到最低。
5. 本篇常见错排查:401、local proxy failed、reading choices 与 OAuth 报错对照
配置和验证过程中最容易撞上的四类报错,我按出现频率排一下,每个给出触发原因和修复动作。对照着查,基本能覆盖 90% 的失败场景。
第一类,401 Unauthorized。触发原因通常是三种:Key 没读到(环境变量没导出或变量名拼错)、Key 带了多余空格、Authorization 头格式不对。排查顺序是先确认环境变量在当前 shell 里真的存在,用echo $TAOTOKEN_API_KEY看有没有输出;再检查配置里{env:TAOTOKEN_API_KEY}的变量名和 export 的完全一致(大小写敏感);最后确认 Key 本身没过期没被删。如果 curl 能通但 OpenCode 报 401,八成是 OpenCode 启动的进程没继承到环境变量——图形界面启动的终端有时不读.bashrc,改成从终端手动启动即可。
第二类,local proxy failed或连接被拒。这个报错说明请求根本没发到远端,卡在本机网络层。常见原因是 baseURL 写成了http://localhost:xxxx这类本地代理地址(有些旧配置模板残留),或者适配器npm字段填了不存在的包导致初始化失败。修复动作:确认baseURL是https://taotoken.net/api,确认npm是@ai-sdk/openai-compatible,然后清掉 OpenCode 的缓存目录重启。如果报错里带ECONNREFUSED,基本就是端点地址错了。
第三类,reading choices或Cannot read properties of undefined (reading 'choices')。这是响应结构不符合预期导致的,根因是请求打到了不兼容 OpenAI 协议的端点,返回的不是标准choices数组。典型场景是 baseURL 多写了/v1导致 404 页面被当 JSON 解析,或者用错了适配器(比如该用 openai-compatible 却用了别的)。修复:baseURL 只写到/api,适配器确认是 openai-compatible,然后用第 2 节的 curl 命令单独验证端点返回结构。
第四类,OAuth 相关报错,比如提示需要登录或 token 刷新失败。OpenCode 某些版本对内置提供方走 OAuth 流程,如果你在配置里混用了内置提供方键名和自定义 baseURL,就会触发 OAuth 校验。修复动作:自定义提供方用一个全新的键名(比如taotoken),不要复用openai、anthropic这类内置名,避免触发内置的鉴权逻辑。同时确认配置里没有残留的oauth字段。
除了这四类,还有两个隐性坑值得提。一是 Model ID 大小写不一致,报model not found,回去逐字符核对控制台里的 ID。二是技能目录权限问题,Windows 下如果技能文件夹在受保护路径,OpenCode 读不到SKILL.md,表现为技能数量为 0,把技能目录移到用户目录下即可。
提示:排错时优先用最小请求验证,别在复杂任务上猜。curl 通、OpenCode 不通,问题在配置;curl 也不通,问题在三件套。这个二分法能快速缩小范围。
把上面四类报错对照完,你的环境基本就稳了。最后说下后续怎么把这套东西用起来。
6. 从能跑到好用:OpenCode + Agent Skills 的日常接入路径
环境跑通只是起点,真正省时间的是把常用能力沉淀成技能、把 Key 管理收敛到统一通道。日常使用我建议按这个顺序推进:先把最常做的两三件事写成SKILL.md(比如「批量重命名文件」「解析固定格式日志」「生成周报表格」),description 写清楚触发场景和支持的输入格式;然后在 OpenCode 里用真实任务反复触发,观察哪些提问能激活、哪些不能,据此微调 description 措辞;最后把验证过的技能目录纳入版本管理,团队里谁需要就同步过去。
Key 和端点这块,统一走 TaoToken 的 API 通道后,你只需要维护一份环境变量,OpenCode、Cline、Codex 这些工具都指向同一个baseURL和 Key,换模型时只改 Model ID,不用到处翻配置。需要看模型实际对话效果,可以去模型对话页面直接试;要长期跑编码和 Agent 任务,Coding Plan 更适合高频调用场景;Key 的创建和管理在 API Keys 页面;配置字段有疑问就查接入文档。这几个入口按需取用,别只收藏首页。
最后留一个实用习惯:每次改完配置,先跑第 4 节的三步验证再上真实任务;每次新增技能,先用一个明确匹配 description 的小任务确认能触发,再交给 Agent 自主规划。这套流程坚持下来,你的 OpenCode 会越用越顺手,而不是每次改动都靠运气。