在使用 OpenCode 进行日常开发时,我们经常会遇到一些重复性的工作场景:发布新版本、审查代码、部署项目、编写特定格式的文档等等。每次遇到这些场景,你都需要用自然语言重新描述一遍完整的操作步骤,既低效又容易遗漏细节。
OpenCode 的 Agent Skills 系统正是为解决这个问题而设计的。它允许你将一组专业化的指令和流程封装成一个"技能模块",Agent 在需要时会自动发现并加载这些技能,从而以一致、可靠的方式完成特定类型的任务。
本文将深入介绍 Agent Skills 系统的完整用法,包括技能文件的创建、配置、权限管理以及实战案例。
Agent Skills 本质上是一个按需加载的指令集。你可以将它理解为给 AI 编程助手预先编写好的"标准操作流程"(SOP)。当 Agent 遇到匹配的任务时,它会通过内置的 skill 工具加载对应的技能定义,获取其中包含的详细指令和约束。
技能系统的工作流程大致如下:
OpenCode 启动时,自动扫描项目目录和全局配置目录中的技能定义
技能信息(名称和简介)被注入到 Agent 的系统提示中
当 Agent 判断当前任务适合使用某个技能时,调用 skill 工具加载技能的完整内容
技能内容被注入到对话上下文中,Agent 按照其中的指令执行任务
这种"按需加载"的设计意味着技能文件不会永久占用上下文窗口,只有在需要时才会被加载,兼顾了功能性和效率。
技能文件遵循特定的目录结构。每个技能独占一个文件夹,文件夹内包含一个 SKILL.md 文件:
.opencode/skills/<技能名称>/SKILL.md
OpenCode 会在以下路径中搜索技能定义:
| 位置 | 路径 |
|------|------|
| 项目配置 | .opencode/skills/<name>/SKILL.md |
| 全局配置 | ~/.config/opencode/skills/<name>/SKILL.md |
| Claude 兼容 | .claude/skills/<name>/SKILL.md 或 ~/.claude/skills/<name>/SKILL.md |
| Agent 兼容 | .agents/skills/<name>/SKILL.md 或 ~/.agents/skills/<name>/SKILL.md |
对于项目级别的技能,OpenCode 会从当前工作目录向上遍历,直到到达 Git 工作树的根目录,加载沿途所有匹配的技能定义。这意味着你可以在 monorepo 的不同子目录中放置不同的技能。
每个 SKILL.md 文件必须以 YAML Frontmatter 开头,后跟 Markdown 格式的技能内容。以下是一个完整的示例——创建一个 Git 发布技能:
在项目根目录下创建文件 .opencode/skills/git-release/SKILL.md:
--- name: git-release description: 创建一致的发布版本和变更日志 license: MIT compatibility: opencode metadata: audience: maintainers workflow: github --- ## 我的职责 - 从已合并的 PR 中草拟发布说明 - 根据变更内容建议版本号升级(major/minor/patch) - 生成可直接复制使用的 `gh release create` 命令 ## 何时使用我 当你准备创建带标签的正式发布时使用此技能。 如果版本号规则不明确,请向我询问澄清。 ## 工作流程 1. 运行 `git log` 查看自上次发布以来的提交记录 2. 根据 Conventional Commits 规范分类变更 3. 确定版本号升级类型 4. 生成 CHANGELOG 条目 5. 输出 `gh release create` 命令供用户确认执行
| 字段 | 必填 | 说明 |
|------|------|------|
| name | 是 | 技能名称,必须与文件夹名称一致 |
| description | 是 | 技能简介,Agent 据此判断是否加载该技能 |
| license | 否 | 许可证类型 |
| compatibility | 否 | 兼容性标注 |
| metadata | 否 | 键值对形式的自定义元数据 |
技能名称必须满足以下规则:
-)--)符合规范的正则表达式:^[a-z0-9]+(-[a-z0-9]+)*$
✅ 有效命名:git-release、code-review、api-docs、deploy-staging
❌ 无效命名:GitRelease(含大写)、-release(以-开头)、release--v2(连续-)、release_notes(含下划线)
description 字段的长度限制为 1-1024 个字符。描述应该足够具体,让 Agent 能够准确判断何时应该加载这个技能。过于模糊的描述可能导致技能在不合适的场景中被加载。
下面创建一个更贴近日常开发的技能——自动化代码审查:
--- name: code-review description: 对代码变更进行系统化审查,检查安全性、性能和代码风格 compatibility: opencode metadata: audience: developers severity: standard --- ## 审查清单 在审查任何代码变更时,逐项检查以下内容: ### 安全性 - SQL 查询是否使用了参数化绑定,有无拼接风险 - 用户输入是否经过了验证和清理 - 敏感信息(密钥、Token)是否被硬编码 - 认证和授权逻辑是否正确 ### 性能 - 数据库查询是否避免了 N+1 问题 - 是否有不必要的循环嵌套 - 大数据量操作是否考虑了分页或批量处理 - 缓存策略是否合理 ### 代码风格 - 变量和函数命名是否语义清晰 - 函数是否过长(超过 50 行建议拆分) - 是否遵循项目的现有代码风格 - 是否有无用的注释或调试代码 ## 输出格式 审查结果按以下结构输出: 1. **严重问题**(必须修复)- 安全问题 2. **建议改进**(推荐修复)- 性能和架构建议 3. **风格建议**(可选修复)- 命名、格式建议
当 OpenCode 启动时,它会扫描所有技能路径并将技能列表注入到 skill 工具的描述中。Agent 在系统提示中会看到如下结构:
<available_skills>
<skill>
<name>git-release</name>
<description>创建一致的发布版本和变更日志</description>
</skill>
<skill>
<name>code-review</name>
<description>对代码变更进行系统化审查,检查安全性、性能和代码风格</description>
</skill>
</available_skills>
Agent 通过调用工具方法来加载技能:
skill({ name: "code-review" })
加载后,技能文件的完整内容会被注入到当前对话的上下文中,Agent 即可按照技能中定义的规则和流程执行任务。
OpenCode 提供了精细的权限控制机制,你可以精确配置哪些技能对 Agent 可见。
在 opencode.json 中通过 permission.skill 字段进行配置:
{
"permission": {
"skill": {
"*": "allow",
"code-review": "allow",
"internal-*": "deny",
"experimental-*": "ask"
}
}
}
权限模式说明:
| 模式 | 行为 |
|------|------|
| allow | 技能立即可用,Agent 无需确认即可加载 |
| deny | 技能对 Agent 完全隐藏,无法访问 |
| ask | Agent 加载技能前会向用户请求确认 |
支持通配符匹配:internal-* 会匹配 internal-docs、internal-tools 等所有以 internal- 开头的技能。
你可以为某些 Agent 设置不同于全局的权限:
自定义 Agent(在 Agent 的 Frontmatter 中配置):
---
permission:
skill:
"documents-*": "allow"
---
内置 Agent(在 opencode.json 中配置):
{
"agent": {
"plan": {
"permission": {
"skill": {
"internal-*": "allow"
}
}
}
}
}
在上面的例子中,plan Agent 被赋予了访问 internal-* 系列技能的权限,而其他 Agent 仍然受全局规则约束。
如果你不希望某个 Agent 使用任何技能,可以直接禁用 skill 工具:
自定义 Agent:
--- tools: skill: false ---
内置 Agent:
{
"agent": {
"plan": {
"tools": {
"skill": false
}
}
}
}
当技能工具被禁用后,<available_skills> 部分将完全不在该 Agent 的系统提示中出现。
在实际项目中,你可能会创建多个技能来覆盖不同的工作流程。以下是一个典型的项目技能布局:
.opencode/ ├── skills/ │ ├── code-review/ │ │ └── SKILL.md │ ├── deploy-staging/ │ │ └── SKILL.md │ ├── db-migration/ │ │ └── SKILL.md │ └── api-docs/ │ └── SKILL.md
--- name: db-migration description: 创建和管理数据库迁移文件,确保迁移安全可回滚 compatibility: opencode metadata: audience: backend-developers framework: laravel --- ## 迁移规范 创建数据库迁移时必须遵循以下规则: ### 命名规范 - 迁移文件名使用蛇形命名法(snake_case) - 名称应清晰描述变更内容,如 `add_email_verified_at_to_users` ### 必须包含的内容 1. `up()` 方法:执行正向迁移 2. `down()` 方法:执行回滚操作 3. 所有字段添加有意义的注释 ### 安全检查 - 修改大表时使用 `->nullable()` 或先创建可空字段,后续再添加约束 - 删除列或表时,在注释中说明原因 - 涉及数据迁移(非仅结构变更)时,添加事务包裹 ### 示例
Schema::table('users', function (Blueprint $table) {
$table->timestamp('email_verified_at')->nullable()->after('email');
});
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('email_verified_at');
});
## 故障排查 如果技能没有出现在可用列表中,请依次检查: 1. **文件名大小写**:`SKILL.md` 必须全部大写。`skill.md` 或 `Skill.md` 都不会被识别。 2. **Frontmatter 完整性**:确保包含 `name` 和 `description` 字段,且格式正确。 3. **名称唯一性**:所有加载路径中的技能名称必须唯一。如果存在同名技能,只有一个会被加载。 4. **权限设置**:被设为 `deny` 的技能对 Agent 完全隐藏,检查 `opencode.json` 中的权限配置。 5. **名称与文件夹匹配**:`name` 字段的值必须与文件夹名称完全一致。 ## 总结 Agent Skills 系统是 OpenCode 中一个强大但容易被忽视的功能。它通过将专业领域知识模块化,让 AI 编程助手能够在特定场景下表现出更专业、更一致的行为。 本文涵盖的核心要点: - **技能定义**:通过 `SKILL.md` 文件定义,YAML Frontmatter + Markdown 内容 - **自动发现**:支持项目级别和全局级别的技能,兼容 Claude 和 Agent 目录格式 - **按需加载**:Agent 通过 `skill` 工具按需加载,不占用常驻上下文 - **权限管控**:支持 allow/deny/ask 三种模式,可针对特定 Agent 覆盖 - **命名规范**:严格的小写字母+数字+单连字符格式 建议从你最频繁的重复性工作开始创建第一个技能——也许是代码审查、也许是部署流程、也许是文档生成。一旦你体验到技能系统带来的效率提升,你就会想要为更多工作流创建专属技能。 将技能文件提交到 Git 仓库中,你的整个团队都能受益于这些经过精心设计的标准化工作流程。