ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

opencode 中 Agent Skills(技能系统)配置指南:SKILL.md 与 opencode.json 骨架

opencode 中 Agent Skills(技能系统)配置指南:SKILL.md 与 opencode.json 骨架 1. opencode Agent Skills 技能系统到底解决什么问题如果你已经在用 opencode 写代码大概率遇到过这种场景项目里有一套固定的发版流程、代码审查清单、或者某个内部框架的初始化步骤你希望 AI 每次都按这个套路来但写进 AGENTS.md 之后每次对话都要把这一大段塞进上下文token 消耗肉眼可见地涨而且大部分对话根本用不到这些流程。opencode 的 Agent Skills 技能系统就是冲着这个痛点来的。简单说Skills 是 AGENTS.md 之外的可复用行为定义它不会在启动时自动注入而是按需加载——只有当 AI 判断当前任务需要某个技能时才会通过skill()工具去调用它。这意味着你的通用规范可以继续放在 AGENTS.md 里始终生效而专项操作流程比如发版、代码审查、数据库迁移则拆成独立技能用到才占上下文。适合谁用三类人最明显一是维护中大型项目的开发者项目里有大量约定俗成的操作流程二是团队协作场景需要把某些规范固化成可复用单元三是想控制 token 成本、又不想牺牲 AI 行为一致性的用户。我试过把一个 300 行的发版流程从 AGENTS.md 拆成 Skill 之后日常对话的上下文占用直接降了一半以上。技能系统的核心概念只有两个SKILL.md声明技能内容opencode.json注册和加载路径。前者定义这个技能是什么、什么时候用后者定义技能放在哪、权限怎么控。理解这两者的分工整个配置就通了。从加载机制看opencode 支持三个层级的技能目录项目级.opencode/skills/name/SKILL.md、全局级~/.config/opencode/skills/name/SKILL.md以及兼容 Claude Code 的.claude/skills/name/SKILL.md。项目级优先级最高适合跟项目强绑定的流程全局级适合你个人跨项目复用的习惯Claude Code 兼容路径则是给已有技能库的用户平滑迁移用的。命名规则这块有个容易踩的坑技能目录名必须和 SKILL.md 里声明的name字段完全一致而且 name 要满足正则^[a-z0-9](-[a-z0-9])*$——1 到 64 字符只能小写字母、数字和连字符不能以连字符开头或结尾不能有连续连字符。我第一次配的时候用了下划线结果技能死活加载不出来排查了半天才发现是命名不合规。权限控制是另一个关键点。在 opencode.json 里每个技能可以配allow、deny、ask三种值allow表示立即加载AI 可以直接调用deny表示对 AI 完全不可见ask表示每次调用都需要用户确认。这个设计很实用——比如涉及生产环境操作的技能你可以设成ask避免 AI 自作主张。对比 AGENTS.mdSkills 的差异可以用一张表说清楚维度AGENTS.mdSkills加载方式启动时自动注入按需调用skill()工具作用域始终生效只在 AI 判断需要时加载适合场景通用规范、项目结构专项操作流程发版、代码审查体积影响每次对话都占上下文只在用时占上下文这个对比不是要你二选一而是组合使用。通用规范放 AGENTS.md专项流程拆成 Skills各司其职。接下来我会从零开始带你走一遍完整的配置流程包括目录结构、SKILL.md 写法、opencode.json 注册以及新增技能后怎么验证它真的被 Agent 识别和调用了。2. TaoToken 统一 Key 与 API 通道的前置准备在动手配 Skills 之前得先把 opencode 的模型通道打通。opencode 本身是个客户端它需要连到一个兼容 OpenAI 或 Anthropic 协议的 API 端点才能工作。如果你已经在用官方 Key可以跳过这节但如果你想让多个模型走统一通道、方便切换和计费TaoToken 是个值得考虑的接入点。TaoToken 的定位是统一 Key 与 API 通道官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 。它的价值在于你只需要维护一个 Key就能在 opencode 里调用不同厂商的模型不用为每个模型单独配 Key 和端点。对于经常在 Claude、GPT 之间切换的开发者来说省事不少。前置准备分三步。第一步是拿到 API Key。登录 TaoToken 控制台在 API Keys 页面创建一个新 Key复制保存好——这个 Key 只会显示一次。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite API Keys 页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。第二步是确认你要用的模型 ID。TaoToken 支持多种模型具体可用列表可以在模型对话页面查看https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。记下你要用的模型 ID比如claude-sonnet-4-20250514或gpt-4o这类后面配 opencode.json 要用。第三步是理解 opencode 的配置结构。opencode 的模型配置有两种方式一种是通过环境变量一种是在 opencode.json 里写 provider 配置。推荐后者因为可以跟 Skills 配置放在同一个文件里管理起来方便。这里有个关键点opencode 的 provider 配置需要指定baseURL和apiKey。TaoToken 的 baseURL 是https://taotoken.net/api注意不要加 UTM 参数那是给网页链接用的API 端点保持干净。apiKey 就是你刚才创建的那个 Key。如果你用的是 Claude Code 兼容模式opencode 也支持通过ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY环境变量来配置。这种方式适合你已经在用 Claude Code、想复用现有配置的场景。环境变量的写法是export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEY你的_TaoToken_Key不过环境变量的缺点是每次开新终端都要重新 export或者写进 shell 配置文件。相比之下opencode.json 里的配置更持久、更清晰也方便跟 Skills 配置一起版本管理。所以我建议优先用 opencode.json 的方式。还有一点要注意opencode 的配置文件位置。项目级配置放在项目根目录的opencode.json全局配置放在~/.config/opencode/opencode.json。Skills 的注册既可以写在项目级配置里也可以写在全局配置里取决于你的技能是项目专用还是跨项目复用。准备工作的最后一步是确认 opencode 版本。Skills 系统是较新版本才引入的功能建议用最新版。可以用opencode --version查看当前版本如果太旧就去官网更新。版本太旧的话即使配置写对了技能也不会被加载这个坑后面排障章节会细说。把 Key、模型 ID、配置文件位置这三样准备好就可以进入下一步的实际配置了。下面我会给出完整的目录结构和可复制的配置骨架你照着改改就能用。3. SKILL.md 与 opencode.json 可复制配置骨架这节是全文的核心我会给出完整的目录结构、SKILL.md 模板、opencode.json 配置片段以及一个新增技能的具体示例。所有配置都可以直接复制修改。先看目录结构。假设你的项目叫my-project项目级技能放在.opencode/skills/下每个技能一个子目录目录名就是技能名my-project/ ├── opencode.json ├── AGENTS.md └── .opencode/ └── skills/ ├── release-check/ │ └── SKILL.md └── code-review/ └── SKILL.md全局级技能放在~/.config/opencode/skills/下结构一样~/.config/opencode/ └── skills/ └── db-migration/ └── SKILL.mdClaude Code 兼容路径是.claude/skills/如果你已有 Claude Code 技能库直接软链或复制过来就能用my-project/ └── .claude/ └── skills/ └── existing-skill/ └── SKILL.md接下来是 SKILL.md 的格式。一个完整的 SKILL.md 包含 frontmatter 和正文两部分。frontmatter 用 YAML 语法声明技能的元信息正文描述技能的具体内容。模板如下--- name: release-check description: 发版前的检查清单包括版本号、CHANGELOG、测试覆盖 --- # 发版检查流程 当用户要求发版或准备 release 时按以下步骤执行 1. 检查 package.json 中的 version 字段是否已更新 2. 确认 CHANGELOG.md 有对应版本的条目 3. 运行 npm test 确认测试全部通过 4. 检查是否有未提交的改动 5. 生成 release commit 并打 tag ## 注意事项 - 版本号遵循 semver 规范 - CHANGELOG 条目要包含日期和变更类型frontmatter 里name必须和目录名一致description是给 AI 判断是否调用这个技能的依据写得越清楚AI 判断越准。正文部分就是技能的实际内容AI 调用时会读取这部分。然后是 opencode.json 的配置。这个文件同时承载模型通道和技能注册两部分。完整骨架如下{ $schema: https://opencode.ai/config.json, provider: { taotoken: { npm: ai-sdk/openai-compatible, name: TaoToken, options: { baseURL: https://taotoken.net/api, apiKey: 你的_TaoToken_Key }, models: { claude-sonnet-4-20250514: { name: Claude Sonnet 4 }, gpt-4o: { name: GPT-4o } } } }, model: taotoken/claude-sonnet-4-20250514, skills: { paths: [ .opencode/skills, ~/.config/opencode/skills, .claude/skills ], permissions: { release-check: allow, code-review: allow, db-migration: ask } } }这个配置里有几个关键点。provider部分定义了 TaoToken 作为模型提供方baseURL是https://taotoken.net/apiapiKey填你的 Key。models里列出你要用的模型 ID这些 ID 要和 TaoToken 支持的模型对应。model字段指定默认使用的模型。skills部分是技能系统的配置。paths数组列出技能搜索路径opencode 会按顺序扫描这些目录。permissions对象控制每个技能的权限allow立即加载deny对 AI 不可见ask每次需确认。没在 permissions 里列出的技能默认行为取决于 opencode 版本的默认策略建议显式声明。如果你用的是 Claude Code 兼容模式provider 配置可以换成 Anthropic 格式{ provider: { anthropic: { options: { baseURL: https://taotoken.net/api, apiKey: 你的_TaoToken_Key } } } }现在演示新增一个技能。假设我要加一个db-migration技能用于数据库迁移流程。第一步创建目录和文件mkdir -p .opencode/skills/db-migration第二步写 SKILL.md--- name: db-migration description: 数据库迁移流程包括生成迁移文件、审查 SQL、执行迁移 --- # 数据库迁移流程 当用户要求创建或执行数据库迁移时按以下步骤 1. 确认当前 ORM 类型Prisma / TypeORM / Drizzle 2. 生成迁移文件npx prisma migrate dev --name migration-name 3. 审查生成的 SQL确认没有破坏性操作DROP TABLE / DROP COLUMN 4. 在测试库执行迁移并验证 5. 确认无误后在开发库执行 ## 安全约束 - 禁止直接在生产库执行迁移 - 破坏性操作必须先备份 - 迁移文件要提交到版本控制第三步在 opencode.json 的 permissions 里注册{ skills: { permissions: { db-migration: ask } } }这里设成ask是因为数据库迁移涉及数据安全每次调用让用户确认更稳妥。配置完成后重启 opencode技能就会被加载。下一节我会讲怎么验证技能真的被识别和调用了。4. 验证技能被 Agent 识别与调用的完整流程配置写完不代表技能就能用得实际验证一遍。这节我给出从启动到调用的完整验证流程包括怎么确认技能被加载、怎么触发调用、怎么检查调用结果。第一步是启动 opencode 并检查技能加载日志。在项目根目录运行opencode启动时 opencode 会扫描配置里skills.paths指定的目录加载所有合法的 SKILL.md。如果加载成功日志里会有类似输出[skills] loaded 3 skills: release-check, code-review, db-migration如果某个技能没出现在列表里说明加载失败常见原因是命名不合规或 frontmatter 格式错误。这时候可以加--verbose参数看详细日志opencode --verbose第二步是确认技能对 AI 可见。在 opencode 的对话界面里可以直接问你现在能调用哪些技能AI 会列出它识别到的技能列表。如果db-migration不在列表里但日志显示已加载那可能是 permissions 配置成了deny或者技能描述不够清晰导致 AI 没识别到。第三步是触发技能调用。以release-check为例在对话里输入帮我准备发版AI 判断这个请求匹配release-check技能的 description就会调用skill()工具加载技能内容然后按 SKILL.md 里的步骤执行。你会看到类似输出[调用技能] release-check 正在检查 package.json 版本号... 当前版本1.2.3 检查 CHANGELOG.md... 发现 1.2.3 条目日期 2025-01-15 运行 npm test... 测试通过42 passed 检查未提交改动... 工作区干净 准备生成 release commit...如果 AI 没有调用技能而是直接回答说明 description 写得不够明确或者请求措辞跟技能不匹配。可以调整 description加入更多触发关键词。第四步是验证ask权限的技能。对于db-migration输入帮我创建一个用户表的迁移因为权限设成了askopencode 会先弹出确认提示技能 db-migration 请求执行是否允许[y/N]输入y后才会加载技能内容并执行。如果输入n技能不会被加载AI 会用默认方式处理。这个机制在涉及敏感操作时很有用。第五步是检查技能是否真的按需加载。这是 Skills 系统的核心价值验证方法是观察上下文占用。在调用技能前后分别问 AI当前对话的上下文里包含哪些技能内容调用前AI 应该回答没有加载任何技能内容调用后AI 会回答已加载 release-check 技能。这说明技能确实是按需加载的不是启动时就注入的。第六步是验证全局技能和 Claude Code 兼容路径。把db-migration复制到~/.config/opencode/skills/下重启 opencode确认全局技能也能被加载。再把一个技能放到.claude/skills/下确认兼容路径生效。这三个路径的优先级是项目级 全局级 Claude Code 兼容同名技能项目级会覆盖全局级。验证过程中如果遇到问题下一节我整理了常见报错和排查方法。这里先给一个快速自检清单目录名和 name 是否一致、name 是否符合正则、frontmatter 是否有语法错误、opencode.json 是否是合法 JSON、permissions 是否误设成 deny、opencode 版本是否支持 Skills。这六项覆盖了 90% 的加载失败场景。5. 常见报错排查401、技能不加载、OAuth 失败配置过程中最容易卡住的就是报错。这节我按真实遇到的报错分类整理给出原因和解决方法。每个报错都附上实际日志片段方便你对照。报错一401 UnauthorizedError: 401 Unauthorized at provider.taotoken.chat response: {error:{message:Invalid API key}}这个报错说明 API Key 有问题。排查顺序先确认 opencode.json 里的apiKey字段填的是 TaoToken 的 Key不是其他厂商的再确认 Key 没有过期或被删除去控制台 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 检查最后确认baseURL是https://taotoken.net/api没有多余路径或参数。如果 Key 是从环境变量读的确认环境变量名拼写正确且在当前 shell 会话里已 export。报错二local proxy failedError: local proxy failed: dial tcp 127.0.0.1:7890: connect: connection refused这个报错通常是因为系统里配了本地代理但代理服务没启动。opencode 会读取HTTP_PROXY/HTTPS_PROXY环境变量如果这些变量指向一个没运行的代理就会报这个错。解决方法是检查环境变量echo $HTTP_PROXY echo $HTTPS_PROXY如果有值且代理没运行要么启动代理要么 unset 掉unset HTTP_PROXY unset HTTPS_PROXY注意这里说的是本地网络配置问题不涉及任何网络访问方式的选择只是清理无效的环境变量。报错三reading choices 相关错误Error: failed to parse response: reading choices: unexpected end of JSON input这个报错说明 API 返回的内容不是预期的 JSON 格式。常见原因是baseURL配错了比如漏了/api或者多了/v1。TaoToken 的 baseURL 是https://taotoken.net/apiopencode 会自动拼接/chat/completions等路径。如果你手动加了/v1就会变成https://taotoken.net/api/v1/chat/completions路径不对导致返回 HTML 错误页。检查 opencode.json 里的 baseURL确保是干净的https://taotoken.net/api。报错四OAuth 相关失败Error: OAuth callback failed: state mismatch如果你用的是需要 OAuth 的 provider可能会遇到这个。opencode 的 OAuth 流程需要浏览器回调如果回调 URL 被拦截或 state 参数不匹配就会失败。解决方法是检查 opencode 的 OAuth 配置确认回调端口没被占用。如果用的是 TaoToken 的 API Key 模式不涉及 OAuth可以忽略这个报错。对于 Claude Code 兼容模式确认ANTHROPIC_API_KEY设置正确不要跟 OAuth 混用。报错五技能不加载[skills] loaded 0 skills日志显示加载了 0 个技能但目录里明明有 SKILL.md。排查顺序第一确认目录名和 SKILL.md 里的name完全一致包括大小写第二确认 name 符合正则^[a-z0-9](-[a-z0-9])*$不能有下划线、大写字母、连续连字符第三确认 frontmatter 是合法的 YAML---分隔符不能少第四确认 opencode.json 的skills.paths包含了技能所在目录第五确认 permissions 里没把这个技能设成deny。报错六技能被识别但不调用AI 能列出技能但触发请求时不用。这通常是 description 的问题。description 要包含足够多的触发关键词让 AI 能匹配用户意图。比如release-check的 description 写发版前的检查清单用户说帮我准备发布可能匹配不上改成发版、发布、release 前的检查清单包括版本号、CHANGELOG、测试就更容易命中。报错七opencode.json 解析失败Error: failed to parse config: invalid character } looking for beginning of object key string这是 JSON 语法错误通常是多了或少了逗号、括号不匹配。用jq验证一下jq . opencode.json如果报错jq 会指出具体行号。修好后再重启 opencode。排查完这些报错技能系统基本就能稳定运行了。如果遇到本文没覆盖的报错可以去接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 查 API 相关的说明或者在模型对话页面 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 测试模型通道是否正常。6. 长期编码场景下的技能管理与接入入口技能系统配好之后真正的挑战是长期维护。项目在演进技能也要跟着更新。这节我分享几个实战中总结的管理习惯以及不同场景下该走哪个接入入口。先说技能管理的三个原则。第一技能粒度要适中。一个技能只做一件事比如release-check只管发版检查不要把代码审查也塞进去。粒度太粗会导致 AI 判断困难粒度太细又会导致技能数量爆炸。我的经验是一个技能对应一个明确的用户意图description 能用一句话说清楚。第二技能要版本化。SKILL.md 跟代码一样应该提交到版本控制。项目级技能放在.opencode/skills/下跟项目一起 commit全局技能可以单独建一个 git 仓库用软链挂到~/.config/opencode/skills/。这样技能变更可追溯团队协作时也能同步。第三定期清理。项目重构后有些技能可能已经过时。建议每个季度过一遍技能列表删掉不再用的更新描述不准的。过时的技能比没有技能更危险因为 AI 会按错误流程执行。再说接入入口的分流。不同使用场景对应不同的入口选对了能省不少事。如果你主要是排障和接入配置比如 Key 配错了、baseURL 不对、技能加载失败走 API Keys 页面和接入文档API Keys 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。这两个页面覆盖了大部分配置问题。如果你要验证模型是否可用、测试不同模型的输出效果走模型对话页面https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。在这里可以直接跟模型对话确认通道正常后再配到 opencode 里。如果你是长期编码、跑 Agent 任务需要稳定的额度和更长的上下文支持走 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。Coding Plan 针对编码场景做了优化适合把 opencode 作为日常开发工具的用户。如果你用 Claude Code 并且想复用现有配置走 Claude Code 接入页面https://taotoken.net/claude-code?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-codeutm_campaignrewrite 。这里有针对 Claude Code 的专门配置说明包括ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY的设置方法。最后说一个实战技巧技能和 AGENTS.md 的边界怎么划。我的判断标准是——如果这段内容每次对话都需要放 AGENTS.md如果只在特定任务时需要放 Skill。比如这个项目用 TypeScript缩进用 2 空格这种通用规范放 AGENTS.md发版时先跑 lint 再跑 test 再打 tag这种流程放 Skill。按这个标准划分上下文占用能控制在合理范围AI 的行为一致性也有保障。技能系统不是配完就完事的它需要跟着项目一起演进。把技能当成代码资产来管理定期 review、版本化、清理才能真正发挥它的价值。配好之后你会发现 opencode 在处理专项任务时越来越顺手而日常对话的 token 消耗反而降下来了。
返回列表