1. WSL 里跑 OpenCode 的真实痛点与场景拆解
如果你在 Windows 上做 AI 编程 Agent 的折腾,大概率会遇到一个尴尬局面:OpenCode 官方推荐用 WSL,但真到装的时候,从发行版选择、PATH 生效、到 skill 目录放哪、模型怎么接,每一步都能卡住人。我自己第一次装的时候,opencode命令敲下去提示 command not found,回头才发现.bashrc改了但当前 shell 没 source,白白折腾了十几分钟。
这篇要解决的就是这条完整链路:在 WSL(Ubuntu 24.04)里从零装好 OpenCode,然后用skill-creator这个元技能,生成、加载、触发一个自定义 Agent skill,最后用一个可验证的测试确认 skill 真的被 Agent 识别并执行了。不是只讲“装完就能用”,而是把目录结构、配置片段、触发验证、常见报错都摊开讲。
先说清楚 OpenCode 是什么。它是一个开源的、模型中立的 AI 编程 Agent,形态有命令行、桌面客户端、插件和云端环境四种。命令行版最适合在 WSL 里跑,因为它天然吃 Linux 那套文件系统和 shell 生态。Agent skills 则是它上面的一层能力抽象——把“一组工具调用 + 领域工作流 + 约束规则”打包成一个技能包,模型按需加载,而不是每次从零规划。这个“渐进式披露、按需加载”的机制,对 token 消耗的节省非常明显,尤其是你挂了一堆 skill 但一次只用一个的时候。
适合谁看:已经在 Windows 上用 WSL 做开发、想试 Agent skill 机制的人;或者你手上有一批重复性的查询/生成任务,想把它固化成 skill 让 Agent 自动跑。前置要求不高,WSL 能跑、能联网、有一个模型供应商的 API Key 就行。下面按“装环境 → 接模型 → 建 skill → 验证触发 → 排错”的顺序走,每一步都给可复制的命令和配置。
2. TaoToken 前置准备:模型接入与 API Key 获取
OpenCode 本身不带模型,它需要你接一个模型供应商。这里我用 TaoToken 来做接入层,原因是它同时提供 OpenAI 兼容接口和 Claude 系列模型的接入,配置上只需要改 Base URL 和 Key,不用为每个模型单独折腾 SDK。对 OpenCode 这种“模型中立”的 Agent 来说,接入层统一能省掉大量切换成本。
第一步是拿 Key。打开 TaoToken 的 API Keys 管理页(https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite),登录后创建一个新的 Key,复制出来先存到临时文件里。注意这个 Key 只在创建时完整显示一次,关掉页面就看不到了,所以别手滑。
第二步是确认你要用的模型 ID。TaoToken 的模型列表在文档里有,常用的比如 Claude 系列、GPT 系列都有对应的 Model ID。OpenCode 的配置里需要填的就是这个 ID,填错了会直接报模型不存在。你可以先在模型对话页(https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite)里手动发一条消息,确认这个 Key 和模型 ID 是通的,再去配 OpenCode,这样能少走弯路。
第三步是理解 OpenCode 的配置读取顺序。它优先读项目目录下的.opencode/配置,其次读全局配置。对 skill 测试来说,我建议全部放在项目级,这样不同项目之间互不干扰,也方便你把整个.opencode/目录提交到自己的仓库里做版本管理。全局配置适合放模型 Key 这种跨项目复用的东西,但为了演示清晰,这篇统一用项目级配置。
这里有个容易踩的坑:很多人把 Key 直接写进opencode.json然后提交到 Git,结果 Key 泄露。正确做法是把 Key 放到.env文件里,.gitignore里排除掉.env,配置文件里用环境变量引用。OpenCode 支持从环境变量读取,具体写法在下一节的配置片段里给。
如果你后面要长期跑编码任务或者做 Agent 编排,可以考虑 Coding Plan(https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite),它在额度上比按量付费更适合高频调用场景。但如果你只是先跑通 skill 测试,按量付费的 Key 就够了,不用一上来就上套餐。
3. 可复制配置:WSL 安装 OpenCode 与 skill 目录结构
这一节是整篇的核心操作区,所有命令和配置都可以直接复制。先装 WSL,再装 OpenCode,然后建 skill 目录,最后写模型配置。
3.1 WSL 安装与 Ubuntu 24.04 初始化
以管理员身份打开 PowerShell,执行:
wsl --install -d Ubuntu-24.04这条命令会下载并安装 Ubuntu 24.04 LTS。装完后会提示你创建 Unix 用户和密码,按提示输入即可。装完重启一下终端,然后在开始菜单里打开 Ubuntu,或者直接在 PowerShell 里用wsl进入。
验证 WSL 版本和发行版:
wsl --list --verbose如果显示 Ubuntu-24.04 且 VERSION 是 2,说明没问题。WSL2 的文件系统性能比 WSL1 好很多,跑 Node 生态的项目建议必须用 WSL2。
3.2 安装 OpenCode
进入 WSL 终端后,直接跑官方安装脚本:
curl -fsSL https://opencode.ai/install | bash安装脚本会把opencode加到~/.bashrc的 PATH 里。装完后当前 shell 还没生效,执行:
source ~/.bashrc opencode --version能打印出版本号就说明装好了。如果提示 command not found,先确认~/.bashrc里有没有export PATH那一行,再确认你当前 shell 是不是 bash(echo $SHELL)。
3.3 建项目目录与 skill 目录结构
mkdir -p ~/test-project/.opencode/skills cd ~/test-projectOpenCode 的 skill 目录约定是项目根目录下的.opencode/skills/,每个 skill 一个子目录,子目录里必须有一个SKILL.md作为入口描述文件。结构长这样:
test-project/ └── .opencode/ ├── opencode.json ├── .env └── skills/ ├── skill-creator/ │ └── SKILL.md └── site-users-count/ ├── SKILL.md └── scripts/ └── query.pySKILL.md里的 frontmatter 决定这个 skill 叫什么、什么时候被触发。下面是一个最小可用的SKILL.md模板:
--- name: site-users-count description: 查询指定站点在指定日期范围内的人数统计,支持导出 Excel 和图表。当用户提到站点人数、在线用户统计、site users count 时触发。 --- # Site Users Count ## 使用场景 当用户需要查询 wireless 数据库中 online_users_count 表的站点人数数据时使用。 ## 执行步骤 1. 从 .env 读取数据库连接信息 2. 根据用户给定的 site_code 和日期范围构造查询 3. 只读查询,禁止任何写操作 4. 结果导出为 Excel 或图表注意description字段,这是模型判断“要不要加载这个 skill”的关键。写得太泛会误触发,写得太窄会漏触发。我的经验是把用户可能说的几种自然语言表达都塞进去,比如“站点人数”“在线用户统计”“site users count”。
3.4 模型配置片段
在.opencode/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": { "claude-sonnet-4-5": { "name": "Claude Sonnet 4.5" } } } }, "model": "taotoken/claude-sonnet-4-5" }然后在.opencode/.env里放 Key:
TAOTOKEN_API_KEY=sk-你的实际Key再把.env加进.gitignore:
echo ".env" >> .opencode/.gitignore这里三件套必须齐全:Base URL 是https://taotoken.net/api,Key 从环境变量读,Model ID 是taotoken/claude-sonnet-4-5。少任何一个都会在启动时报错。配置写完后,在项目目录下跑opencode,如果能看到 TUI 界面且没有报模型错误,说明接入成功。
4. 验证请求:用 skill-creator 生成并触发第一个 skill
配置通了之后,接下来验证 skill 机制是否真的工作。我用skill-creator这个元技能来生成一个自定义 skill,然后触发它,看 Agent 是否真的加载并执行。
4.1 放入 skill-creator
从 Anthropic 官方 skills 仓库把skill-creator下载下来,放到.opencode/skills/skill-creator/下。确认目录里有SKILL.md:
ls ~/test-project/.opencode/skills/skill-creator/ # 应该看到 SKILL.md启动 OpenCode:
cd ~/test-project opencode在 TUI 里输入/skills或者直接问“当前有哪些 skill 可用”,如果skill-creator出现在列表里,说明它被识别了。
4.2 用 skill-creator 生成 site-users-count
在 OpenCode 对话里输入:
/skill-creator 我想创建一个 skill:site-users-count,目录已经在 .opencode/skills/site-users-count/ 建好了。场景是:我有一个数据库 wireless 中的表 online_users_count,存储每天各站点的人数统计,字段有 site_code、site_name、count、count_nac、count_controller、create_time。我想通过这个 skill 查询指定站点在指定日期范围内的人数,支持导出 Excel 和图表。数据库连接信息放在 .env 文件里,你只能读取,任何情况下不能修改数据库数据。skill-creator会反问几个问题,比如“日期范围是单天还是区间”“导出格式默认是什么”“site_code 是精确匹配还是模糊匹配”。回答完之后,它会在.opencode/skills/site-users-count/下生成SKILL.md和scripts/目录。
生成完后,退出 OpenCode 再重新进入,让它重新扫描 skill 目录。这一步很关键,因为 skill 列表是在启动时加载的,热更新不一定生效。
4.3 触发验证
重新进入后,直接问一个自然语言问题:
帮我查一下 site_code 为 SZ001 的站点最近 7 天的人数统计,导出成 Excel如果 skill 被正确触发,你会看到 Agent 先声明“正在使用 site-users-count skill”,然后执行scripts/里的查询脚本,最后返回一个 Excel 文件路径。这个过程就是可验证的触发测试:从自然语言 → skill 匹配 → 脚本执行 → 结果产出,整条链路跑通。
如果 Agent 没有触发 skill,而是直接自己写了一段 Python 查询,说明description写得不够精准,模型没把它和用户意图关联起来。这时候回去改SKILL.md的description,把用户可能用的表达补进去,再重启验证。
4.4 结果确认
验证成功的标志有三个:一是 Agent 明确提到使用了哪个 skill;二是scripts/里的脚本被实际调用(可以在脚本里加一行日志确认);三是输出文件真实生成。三个都满足,才算 skill 真正被识别执行,而不是模型“假装用了”。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
这一节把我在 WSL + OpenCode + skill 链路上踩过的报错集中列一下,对照着排查能省不少时间。
401 Unauthorized:最常见的原因是 Key 没读到。检查.opencode/.env里的变量名和opencode.json里{env:TAOTOKEN_API_KEY}是否完全一致,大小写敏感。另一个原因是 Key 本身失效或额度用完,去 API Keys 页面确认一下状态。还有一种情况是 Base URL 写成了带路径的形式,比如https://taotoken.net/api/v1,而 OpenCode 的 openai-compatible provider 会自己拼/v1,导致路径重复。正确写法就是https://taotoken.net/api。
local proxy failed:这个报错通常出现在你本地配了代理但代理没起来,或者 WSL 的网络和 Windows 宿主机的代理配置不一致。WSL2 的网络是 NAT 模式,默认不继承 Windows 的代理设置。如果你确实需要走代理,得在 WSL 里单独配,但更简单的做法是确认你的网络环境本身能直连 TaoToken 的 API 地址。用curl -I https://taotoken.net/api测一下连通性,返回 200 或 401 都说明网络通,返回超时才是网络问题。
reading choices 相关报错:这个一般出现在模型返回格式不符合预期时,比如你用的 Model ID 实际不支持 OpenAI 兼容的 chat completions 格式。确认你填的 Model ID 在 TaoToken 的模型列表里,并且是 chat 类型而不是 embedding 或 image 类型。如果 Model ID 写错,OpenCode 可能拿到一个非预期的响应体,解析choices字段时就炸了。
OAuth 相关报错:OpenCode 某些 provider 走 OAuth 流程,如果你混用了 OAuth 和 API Key 两种认证方式,可能会冲突。用 TaoToken 的 API Key 接入时,确保没有残留的 OAuth token 缓存。清一下~/.local/share/opencode/下的认证缓存,重新用 Key 登录。
skill 不触发:不是报错但更常见。排查顺序是:确认SKILL.md的 frontmatter 格式正确(---包裹,name和description都有);确认 skill 目录在.opencode/skills/下且重启过 OpenCode;确认description里的关键词和你的提问用词有重叠。如果三样都对还不触发,把description写得更直白一点,比如直接包含“当用户说 XXX 时使用”。
脚本执行权限问题:scripts/下的 Python 或 shell 脚本如果没有执行权限,Agent 调用时会失败。跑一下chmod +x .opencode/skills/*/scripts/*补上权限。另外确认脚本里的 shebang 指向的解析器在 WSL 里存在,比如#!/usr/bin/env python3。
6. 语义一致 CTA:把 skill 链路接到你的实际工作流
跑通一个 skill 只是起点。真正有价值的是把这条链路接到你日常的重复任务上——比如每天定时查数据、批量生成报表、自动检查服务状态。这些场景的共同点是:流程固定、输入输出明确、但手动做很烦。把它们固化成 skill,Agent 就能按需加载执行,你只需要用自然语言描述需求。
如果你要长期跑这类 Agent 任务,建议把模型接入层固定下来,避免每次换模型都改配置。TaoToken 的 API 接入方式在文档里有完整说明(https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite),包括不同语言的调用示例和错误码对照。Key 的管理在 API Keys 页面(https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite),建议给不同项目建不同的 Key,方便按项目追踪用量。
对于需要频繁调用模型做编码或 Agent 编排的场景,Coding Plan(https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite)在额度上更划算。但如果你只是偶尔跑几个 skill 测试,按量付费就够了,不用提前上套餐。
最后说一个我自己的经验:skill 的description值得反复打磨。我第一个 skill 的 description 写得太技术化,模型死活不触发;后来改成“当用户提到站点人数、在线用户统计、site users count 时触发”,命中率立刻上来了。skill 不是写完就完事,它需要你在真实提问中不断测试和修正,这跟调 prompt 是一个道理。把每次不触发的提问记下来,补进 description,几轮下来就稳了。