什么是 Agent Skill

在与 AI Agent 协作开发时,我们常常希望它能遵循一些特定的、可复用的操作流程,比如按照固定格式创建 Git Release、执行项目代码检查、或是生成符合团队规范的文档。OpenCode Agent Skill 提供了一种机制,允许我们将这些可复用的指令和行为封装起来,供 Agent 在需要时发现并调用。

一个 Skill 本质上是一份包含了特定指令的 Markdown 文件,它定义了一项任务的名称、描述以及具体的执行步骤。通过这种方式,我们可以将复杂的、重复性的工作流程标准化,让 Agent 能够像调用工具一样,精确、一致地执行这些预定义的任务。这不仅提升了协作效率,也确保了输出结果的规范性。

创建一个 Skill

创建一个 Skill 的过程非常直接,核心是在指定的目录中放置一个名为 SKILL.md 的文件。

Skill 的存放位置

OpenCode 会在特定路径下搜索 SKILL.md 文件。这些路径分为项目本地和全局两种,方便我们将 Skill 应用于特定项目或是在所有项目中共享。

项目本地路径允许我们将 Skill 与代码仓库绑定在一起,当其他开发者克隆项目后,也能立即使用这些为项目定制的 Skill。OpenCode 会从当前工作目录向上搜索,直到 Git 仓库的根目录,并加载所有符合以下模式的 Skill 文件:

  • .opencode/skill/<skill-name>/SKILL.md
  • .claude/skills/<skill-name>/SKILL.md

全局路径则用于存放那些通用的、与具体项目无关的 Skill。这些 Skill 定义在用户的主目录下,对所有项目都可见:

  • ~/.config/opencode/skill/<skill-name>/SKILL.md
  • ~/.claude/skills/<skill-name>/SKILL.md

这里的 <skill-name> 是一个目录名,它必须与 Skill 本身的名称保持一致。这种目录结构使得每个 Skill 的定义都清晰地隔离在自己的文件夹内。下面的两种方式,选一种就好:

OpenCode Agent Skills 使用指南!一文介绍

Skill 的文件内容

每个 SKILL.md 文件都由两部分组成:YAML Frontmatter 和 Markdown 正文。

Frontmatter 位于文件的最顶端,使用 --- 分隔,用于定义 Skill 的元数据。Agent 正是通过这些元数据来发现和理解 Skill 的用途。

一个合法的 SKILL.md 文件必须包含 namedescription 两个字段。

---
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.

在上面的例子中,namedescription 是必填项,它们直接影响 Agent 如何识别和选择 Skill。而 licensecompatibilitymetadata 等字段是可选的,用于提供额外的信息。

name 字段的值必须符合特定的命名规范:

  • 长度在 1 到 64 个字符之间。
  • 只能包含小写字母、数字和单个连字符 -
  • 不能以连字符开头或结尾。
  • 不能包含连续的连字符。
  • 最重要的一点是,它必须与存放 SKILL.md 文件的目录名完全相同。

description 字段的长度限制在 1 到 1024 个字符之间。它的作用是向 Agent 清晰地描述这个 Skill 的功能,以便 Agent 在众多可用 Skill 中做出正确的选择。一个好的描述应该具体、明确,准确传达 Skill 的核心用途。

文件的正文部分则使用标准的 Markdown 语法,详细说明 Skill 的具体行为、使用场景和执行逻辑。这部分内容是 Agent 加载 Skill 后获取的核心指令,因此编写得越清晰,Agent 的执行效果就越好。

Agent 如何发现和使用 Skill

当 OpenCode 启动时,它会自动扫描所有预定路径,发现可用的 Skill。然后,它会将这些 Skill 的 namedescription 提取出来,以工具描述的形式呈现给 Agent。你也可以直接问:

OpenCode Agent Skills 使用指南!一文介绍

Agent 看到的可用 Skill 列表大致如下所示:

<available_skills>
  <skill>
    <name>git-release</name>
    <description>Create consistent releases and changelogs</description>
  </skill>
</available_skills>

Agent 会根据当前任务的需求,分析这个列表中的 description,判断哪个 Skill 最适合解决问题。一旦决定使用某个 Skill,它就会调用内置的 skill 工具,并通过 name 来指定要加载的具体 Skill。

例如,当 Agent 决定使用 git-release 这个 Skill 时,它会执行如下调用:

skill({ name: "git-release" })

这个调用会触发 OpenCode 加载对应的 SKILL.md 文件的完整内容(包括 Markdown 正文),并将其作为上下文提供给 Agent。Agent 接收到这些详细指令后,就会按照文件中定义的方式继续执行任务。整个过程实现了 Skill 的按需加载,既高效又灵活。

配置 Skill 的访问权限

在团队协作中,并非所有 Skill 都适合对所有 Agent 或所有场景开放。例如,一些具有高风险操作的内部 Skill 可能只希望被特定的维护者 Agent 使用。OpenCode 提供了基于模式匹配的权限系统,可以精细化地控制 Agent 对 Skill 的访问。

权限配置在项目根目录的 opencode.json 文件中进行。我们可以在 permission.skill 对象里定义一系列规则。

一个基础的配置可能如下所示,它允许所有 Agent 访问所有 Skill:

{
  "permission": {
    "skill": {
      "*": "allow"
    }
  }
}

规则的键是匹配 Skill 名称的模式,支持 * 通配符。例如,internal-* 可以匹配 internal-docsinternal-tools 等所有以 internal- 开头的 Skill。规则的值则决定了权限行为。

权限行为描述
allowAgent 可以直接加载并使用该 Skill。
deny该 Skill 对 Agent 完全隐藏,Agent 无法发现也无法访问。
ask当 Agent 尝试加载该 Skill 时,系统会向用户发起确认请求,只有在用户批准后才能继续。

通过组合这些规则,我们可以实现复杂的权限控制。例如,以下配置允许访问 pr-review,禁止访问所有 internal- 系列的 Skill,并在访问 experimental- 系列 Skill 时向用户确认。

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

为特定 Agent 覆盖权限

除了全局配置,我们还可以为特定的 Agent 单独设置权限,覆盖全局默认规则。

对于自定义 Agent,可以直接在其定义的 Frontmatter 中添加 permission 块:

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

对于像 plan 这样的内置 Agent,则可以在 opencode.json 文件中进行配置:

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

这种分层配置的能力为管理复杂的 Agent 体系提供了极大的便利。

彻底禁用 Skill 工具

在某些情况下,我们可能希望某个 Agent 完全不使用任何 Skill。OpenCode 也支持彻底禁用 skill 工具。

对于自定义 Agent,在其 Frontmatter 中设置 tools.skillfalse 即可:

---
tools:
  skill: false
---

对于内置 Agent,同样在 opencode.json 中配置:

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

skill 工具被禁用后,Agent 将不会看到 <available_skills> 列表,也无法调用 skill 工具,从而完全隔离了它与 Skill 系统的交互。

解决加载问题

如果发现某个 Skill 没有按预期出现在可用列表中,可以从以下几个方面进行排查:

  1. 文件名检查:确保文件名是 SKILL.md,全大写。
  2. Frontmatter 检查:确认 SKILL.md 文件中包含了必需的 namedescription 字段。
  3. 名称唯一性:检查所有扫描路径下是否存在同名的 Skill。Skill 名称必须是唯一的,如果出现冲突,加载行为可能不确定。
  4. 权限检查:检查 opencode.json 中的权限配置,deny 规则会直接将 Skill 从列表中隐藏。

通过这些检查,通常可以快速定位并解决 Skill 加载失败的问题。

标签: none

添加新评论