OpenCode Skills
在 OpenCode 中,代理技能(Skills)是一种用于封装可复用行为的机制,通过 SKILL.md 文件定义,使 LLM 能够按需加载、按需执行特定能力。
相比普通提示词,技能更接近模块化能力单元,可以在多个项目或团队中复用。
Skills 是 OpenCode 的能力插件系统,它将 AI 行为从单次提示升级为可复用能力模块,使开发流程更加标准化、可组合,并适用于复杂工程体系。
更多 Skills 可以参考:
核心机制
Skills 通过内置的 skill 工具进行管理,工作流程如下:
- 扫描本地和全局技能目录
- 在上下文中暴露可用技能列表
- 代理根据任务自动选择技能
- 按需加载 SKILL.md 内容
这种机制避免了将所有规则一次性加载,提高了性能和上下文利用率。
文件放置位置
每个技能需要一个独立的文件夹,文件夹内放置 SKILL.md 文件(注意:文件名必须全部大写)。OpenCode 会自动搜索以下六个位置:
| 类型 | 路径 | 适用范围 |
|---|---|---|
| 项目配置 | .opencode/skills/<name>/SKILL.md |
仅当前项目 |
| 全局配置 | ~/.config/opencode/skills/<name>/SKILL.md |
所有项目 |
| 项目 Claude 兼容 | .claude/skills/<name>/SKILL.md |
仅当前项目 |
| 全局 Claude 兼容 | ~/.claude/skills/<name>/SKILL.md |
所有项目 |
| 项目代理兼容 | .agents/skills/<name>/SKILL.md |
仅当前项目 |
| 全局代理兼容 | ~/.agents/skills/<name>/SKILL.md |
所有项目 |
典型的项目目录结构如下:
your-repo/ ├── .opencode/ │ └── skills/ │ ├── git-release/ │ │ └── SKILL.md ← 发版流程技能 │ ├── code-review/ │ │ └── SKILL.md ← 代码审查技能 │ └── api-doc/ │ └── SKILL.md ← API 文档编写技能 ├── src/ └── package.json
发现机制
OpenCode 的技能发现分为两个层级:
项目本地技能:OpenCode 从当前工作目录开始,向上逐层遍历目录树,直到到达 Git 工作树的根目录为止。在此过程中,它会收集沿途每一层目录下 .opencode/skills/*/SKILL.md、.claude/skills/*/SKILL.md、.agents/skills/*/SKILL.md 中所有匹配的技能文件。
全局技能:同时从 ~/.config/opencode/skills/*/SKILL.md、~/.claude/skills/*/SKILL.md、~/.agents/skills/*/SKILL.md 中加载所有已定义的全局技能。
两个层级的技能会合并后一起提供给代理使用。如果项目本地技能与全局技能同名,项目本地技能优先。
编写 SKILL.md
1、Frontmatter 字段
每个 SKILL.md 文件必须以 YAML frontmatter 开头(即 --- 包裹的部分)。OpenCode 只识别以下字段,未知字段会被自动忽略:
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
name |
必填 | 字符串 | 技能的唯一标识名,必须与所在文件夹名称一致,且符合命名规则 |
description |
必填 | 字符串 | 技能的描述,代理依据此内容决定是否调用,1–1024 个字符 |
license |
可选 | 字符串 | 技能内容的许可证类型,如 MIT、Apache-2.0 |
compatibility |
可选 | 字符串 | 标注与哪个工具兼容,如 opencode、claude |
metadata |
可选 | 对象(字符串到字符串的映射) | 自定义的附加元数据,如目标受众、工作流类型等,键值均为字符串 |
2、命名规则
name 字段的值必须同时满足以下所有条件,否则技能将无法被加载:
- 长度为 1–64 个字符
- 只能包含小写字母和数字,单词之间可以用单个连字符(
-)分隔 - 不能以
-开头或结尾 - 不能包含连续的
-- - 必须与包含该
SKILL.md的文件夹名称完全一致
等效的正则表达式:
^[a-z0-9]+(-[a-z0-9]+)*$
合法命名示例:git-release、api-doc、code-review、deploy2prod
非法命名示例:Git-Release(含大写)、-release(以 - 开头)、git--release(连续 --)
3、编写描述
description 字段的内容直接影响代理是否能正确选择和调用该技能。建议描述要具体明确,说明该技能做什么、在什么场景下使用,避免过于笼统:
- ❌ 过于笼统:
帮助完成发版任务 - ✅ 具体明确:
从合并的 PR 中起草发版说明、提出版本号建议,并生成可直接使用的 gh release create 命令
4、完整示例
在项目中创建 .opencode/skills/git-release/SKILL.md,内容如下:
实例
name: git-release
description: Create consistent releases and changelogs
license: MIT
compatibility: opencode
metadata:
audience: maintainers # 自定义元数据:目标受众
workflow: github # 自定义元数据:工作流类型
---
## What I do
- Draft release notes from merged PRs
- Propose a version bump
- Provide a copy-pasteable `gh release create` command
## When to use me
Use this when you are preparing a tagged release.
Ask clarifying questions if the target versioning scheme is unclear.
Frontmatter 中的
name值必须与文件夹名称一致。本例中文件夹名为git-release,因此name也必须写git-release,否则技能无法被识别。
代理如何发现和加载技能
OpenCode 启动后,会将当前所有可用技能以 XML 格式注入到 skill 工具的描述中。代理可以通过查看工具描述来了解有哪些技能可用:
<available_skills>
<skill>
<name>git-release</name>
<description>Create consistent releases and changelogs</description>
</skill>
<skill>
<name>code-review</name>
<description>Perform structured code reviews with consistent criteria</description>
</skill>
</available_skills>
当代理判断某个技能与当前任务相关时,会主动调用 skill 工具来加载该技能的完整 SKILL.md 内容:
skill({ name: "git-release" })
加载完成后,技能中定义的指令和上下文信息会进入代理的工作记忆,从而影响后续的行为和输出。技能本身不会自动执行任何操作,只是为代理提供额外的上下文和行为规范。
配置技能权限
在 opencode.json 中,使用 permission.skill 字段控制代理可以访问哪些技能,支持精确名称和 Glob 通配符两种匹配方式:
实例
"$schema": "https://opencode.ai/config.json",
"permission": {
"skill": {
"*": "allow", // 兜底规则:默认允许加载所有技能
"pr-review": "allow", // 精确匹配:允许加载 pr-review 技能
"internal-*": "deny", // Glob 匹配:拒绝加载所有 internal- 开头的技能(对代理完全隐藏)
"experimental-*": "ask" // Glob 匹配:加载 experimental- 开头的技能前需用户确认
}
}
}
三种权限动作对技能的具体效果如下:
| 权限值 | 效果 |
|---|---|
"allow" |
技能立即加载,代理无需任何确认 |
"deny" |
技能对代理完全隐藏,<available_skills> 列表中不会出现该技能,代理无法感知其存在 |
"ask" |
代理尝试加载该技能时弹出确认提示,由用户决定是否允许 |
按代理覆盖权限
不同代理可能需要访问不同的技能集,可以为每个代理单独配置权限,覆盖全局默认值。
1、在自定义代理的 Frontmatter 中配置
实例
---
permission:
skill:
"documents-*": "allow" # 该代理可以加载所有 documents- 开头的技能
# 其他技能遵循全局权限配置
---
You are a documentation assistant.
2、在 opencode.json 中为内置代理配置
实例
"$schema": "https://opencode.ai/config.json",
"agent": {
"plan": { // 内置代理名称
"permission": {
"skill": {
"internal-*": "allow" // plan 代理可以加载 internal- 开头的技能,
// 即使全局配置中对其设置了 deny
}
}
}
}
}
禁用技能工具
对于完全不需要使用技能的代理,可以直接禁用 skill 工具。禁用后,<available_skills> 列表将从代理的上下文中完全移除,既节省 Token 消耗,又避免代理尝试加载任何技能。
1、在自定义代理的 Frontmatter 中禁用
实例
tools:
skill: false # 对该代理完全禁用技能功能,available_skills 列表不会出现在上下文中
---
You are a quick answer assistant. Just answer questions directly.
2、在 opencode.json 中为内置代理禁用
实例
"$schema": "https://opencode.ai/config.json",
"agent": {
"plan": {
"tools": {
"skill": false // plan 代理不使用任何技能
}
}
}
}
排查技能加载问题
如果某个技能没有出现在可用列表中,请按以下顺序逐项检查:
-
确认文件名大小写
SKILL.md的文件名必须全部大写,写成skill.md或Skill.md都不会被识别。 -
检查 Frontmatter 完整性
确保
SKILL.md开头有正确的 YAML frontmatter,且包含name和description两个必填字段。缺少任意一个,技能都不会被加载。 -
确认技能名称唯一且格式正确
如果不同路径下存在同名技能,可能产生冲突。同时检查
name字段是否符合命名规则(仅小写字母和数字,以连字符分隔),且与文件夹名称完全一致。 -
检查权限配置
在
opencode.json的permission.skill中,权限为"deny"的技能会对代理完全隐藏,不会出现在<available_skills>列表中。检查是否有通配符规则(如"*": "deny")意外匹配到了该技能。
点我分享笔记