OpenCode Skill(技能)系统完全指南:用可复用技能模块为 AI 编程助手注入专业知识

OpenCode Skill(技能)系统完全指南:用可复用技能模块为 AI 编程助手注入专业知识

引言

在使用 AI 编程助手的过程中,你是否遇到过这样的场景:想让 AI 按照特定的发布流程创建版本、按照团队规范审查代码、或者执行某个特定的运维操作——但每次都需要在提示词里详细解释一遍规则?OpenCode 的 Skill(技能)系统正是为解决这个问题而生。它让开发者可以将专业知识和操作流程封装为可复用的技能模块,AI 代理在需要时自动发现并加载,无需反复灌输上下文。

本文将全面介绍 OpenCode Skill 系统的设计理念、文件结构、配置方法与实践技巧,帮助你打造属于自己的 AI 技能库。

什么是 Skill

Skill 是 OpenCode 中一种轻量级的指令复用机制。简单来说,它是一个放在特定目录下的 SKILL.md 文件,包含 YAML 头信息和 Markdown 格式的详细指令。AI 代理通过内置的 skill 工具自动发现可用的技能列表,按需加载完整的技能内容。

Skill 的核心设计理念是"声明式发现"——你只需要把文件放在正确的位置,OpenCode 会自动将其注册为可用的技能,代理在合适的场景下会自动调用,无需手动干涉。

Skill 与插件、子代理的区别

很多初次接触 Skill 的用户会把它和 OpenCode 的插件系统、子代理系统混淆,它们三者的定位截然不同:

  • 插件(Plugin):通过 Hooks 和自定义工具在代码层面扩展 OpenCode 的功能,需要 JavaScript/TypeScript 编程能力。适用于需要深度集成外部系统或实现复杂逻辑的场景。
  • 子代理(Sub-agent):独立的 AI 代理实例,拥有自己的指令、工具和权限配置。适用于需要分工协作的复杂任务。
  • Skill(技能):纯指令层面的复用机制,本质是一个 Markdown 文件,无需任何编程。适用于封装特定领域的专业知识、操作流程和最佳实践。

简单来说:插件扩展能力,子代理分配任务,Skill 注入知识。

Skill 目录结构

每个 Skill 对应一个独立的目录,目录名即技能名称,目录内必须包含一个 SKILL.md 文件。OpenCode 在多个位置搜索 Skill:

# 项目级(优先)
.opencode/skills/<name>/SKILL.md

# 用户全局
~/.config/opencode/skills/<name>/SKILL.md

# 兼容 Claude 格式
.claude/skills/<name>/SKILL.md
~/.claude/skills/<name>/SKILL.md

# 兼容通用代理格式
.agents/skills/<name>/SKILL.md
~/.agents/skills/<name>/SKILL.md

搜索路径的优先级从高到低排列,项目级配置优先于全局配置。OpenCode 会从当前工作目录向上遍历直到 Git 根目录,收集沿途发现的所有 Skill。

编写 SKILL.md

每个 SKILL.md 文件必须以 YAML 头信息开头,包含以下字段:

---
name: git-release
description: Create consistent releases and changelogs
license: MIT
compatibility: opencode
metadata:
  audience: maintainers
  workflow: github
---

必填字段

  • name:技能名称,必须为 1-64 字符的小写字母数字组合,单词间用单连字符分隔,且必须与所在目录名一致。
  • description:技能描述,1-1024 字符,用于代理判断何时加载该技能。描述要足够具体,让代理能准确匹配场景。

可选字段

  • license:许可证信息
  • compatibility:兼容性标识
  • metadata:自定义键值对,可用于分类和筛选

命名规范

名称必须匹配正则表达式 ^[a-z0-9]+(-[a-z0-9]+)*$,以下是合法和非法命名的示例:

# 合法名称
git-release
pr-review
docker-deploy
db-migration
api-test

# 非法名称
Git-Release        # 包含大写字母
git_release        # 包含下划线
git release        # 包含空格
-git-release       # 以连字符开头
git-release-       # 以连字符结尾
git--release       # 连续连字符

实战:创建一个代码审查 Skill

假设你的团队希望 AI 在审查 Pull Request 时遵循特定的规范。我们来创建一个 pr-review 技能:

---
name: pr-review
description: Review pull requests against team coding standards and best practices
license: MIT
compatibility: opencode
metadata:
  audience: developers
  workflow: github
---

## 审查范围

1. **代码质量**:检查是否有重复代码、过长函数、不合理的命名
2. **安全性**:检查 SQL 注入、XSS、敏感信息泄露等常见安全问题
3. **性能**:识别 N+1 查询、未使用索引、内存泄漏等性能隐患
4. **测试覆盖**:检查新增代码是否有对应的单元测试或集成测试
5. **文档**:检查公共 API 是否有合适的注释和文档

## 审查流程

1. 先理解 PR 的整体变更范围和目标
2. 逐文件审查,从业务逻辑层到基础设施层
3. 对每个问题标注严重级别:blocker / major / minor / suggestion
4. 每个问题必须附带具体的修改建议和代码示例
5. 最终汇总为一个结构化的审查报告

## 输出格式

PR 审查报告

阻塞性问题(Blocker)

问题描述 | 文件位置 | 建议方案
... | ... | ...

主要问题(Major)

...

次要问题(Minor)

...

建议(Suggestion)

...

总体评价

代码质量评分:A/B/C/D
主要风险点:
改进建议:


将这个文件保存到 .opencode/skills/pr-review/SKILL.md,之后当 AI 执行代码审查任务时,会自动发现并加载这个技能。

Skill 的自动发现机制

当 AI 代理运行时,OpenCode 会在系统提示词中注入可用技能列表,格式如下:

<available_skills>
  <skill>
    <name>git-release</name>
    <description>Create consistent releases and changelogs</description>
  </skill>
  <skill>
    <name>pr-review</name>
    <description>Review pull requests against team coding standards</description>
  </skill>
</available_skills>

代理根据任务上下文判断是否需要加载某个技能,通过调用 skill 工具传入技能名称来加载完整内容:

skill({ name: "pr-review" })

加载后,SKILL.md 中的完整指令会注入到代理的系统提示中,指导其行为。

权限控制

在多项目或多代理环境中,你可能需要精细控制哪些技能可以被哪些代理使用。在 opencode.json 中配置权限规则:

{
  "permission": {
    "skill": {
      "*": "allow",
      "pr-review": "allow",
      "internal-*": "deny",
      "experimental-*": "ask"
    }
  }
}

三种权限模式的说明:

| 权限 | 行为 |
|------|------|
| allow | 技能立即可用,无需确认 |
| deny | 技能被隐藏,代理无法访问 |
| ask | 加载前询问用户是否允许 |

权限模式支持通配符,internal-* 会匹配 internal-docsinternal-tools 等所有以 internal- 开头的技能。

按代理覆盖权限

对于自定义代理,可以在代理的前置配置中覆盖权限:

---
permission:
  skill:
    "documents-*": "allow"
---

对于内置代理,在 opencode.json 中配置:

{
  "agent": {
    "plan": {
      "permission": {
        "skill": {
          "internal-*": "allow"
        }
      }
    }
  }
}

禁用 Skill

某些代理可能不需要使用任何技能,可以通过配置完全禁用 skill 工具:

对于自定义代理:

---
tools:
  skill: false
---

对于内置代理:

{
  "agent": {
    "plan": {
      "tools": {
        "skill": false
      }
    }
  }
}

禁用后,<available_skills> 部分将从系统提示中完全移除。

最佳实践

1. 单一职责原则

每个 Skill 只负责一个领域的知识。不要创建一个大而全的"万能技能",而是拆分为多个专注的小技能。例如将"部署"拆分为 docker-deployk8s-deployserverless-deploy 三个独立的技能。

2. 描述要精准

description 字段是代理判断是否加载技能的唯一依据。过于宽泛的描述会导致代理误加载,过于狭窄的描述则会让代理错过合适的场景。好的描述应该类似:"Review pull requests against team coding standards and best practices",包含领域、动作和约束条件。

3. 使用 metadata 分类

利用 metadata 字段为技能添加标签和分类信息,便于管理和筛选:

metadata:
  audience: backend
  language: go
  framework: gin

4. 版本控制

将团队共享的 Skill 纳入 Git 版本管理,推荐放在项目目录下的 .opencode/skills/ 中。这样所有团队成员自动获得一致的技能配置。

5. 渐进式复杂度

Skill 的内容可以从简单到复杂逐步演进。初期只需包含核心规则和检查点,随着使用反馈不断补充细节和边界情况。

常见问题排查

如果创建了 Skill 但代理无法发现,按以下顺序检查:

文件名必须为 SKILL.md,注意是大写字母,skill.mdSkill.md 都不会被识别

YAML 头信息必须包含 namedescription,缺少任一字段会导致技能被忽略

技能名称在所有搜索路径中必须唯一,同名技能会导致加载冲突

检查权限配置,被设为 deny 的技能不会出现在代理的可用列表中

目录名必须与 name 字段完全一致,包括大小写

总结

OpenCode Skill 系统提供了一种优雅的方式来封装和复用专业知识。与插件系统的代码级扩展不同,Skill 只需要一个 Markdown 文件即可完成定义,门槛极低,适合团队中的任何人都能参与贡献。通过合理的 Skill 设计,你可以让 AI 编程助手在审代码、发版本、写文档、做运维等各个场景下表现得更加专业和一致。

从今天开始,为你的项目创建第一个 Skill 吧——将团队的知识沉淀下来,让 AI 替你传承。