Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Skill(技能) 系统

理解 Skill 的结构规范、发现路径与加载机制——从定义领域知识包到实现精确权限控制。

前置条件

  • 已完成 Agent(智能体) 编排,理解 Agent 的加载和执行机制
  • 已安装 OpenCode CLI 并完成基础配置
  • 已了解 YAML frontmatter 和 Markdown 格式

文章概述

Skill 是 OpenCode 中封装领域知识的核心载体,它让 Agent 不必每次从零学习,而是像加载驱动程序一样按需获取专业技能。本章节详细讲解 SKILL.md 的完整格式规范,包括 frontmatter 元数据字段(name、description、allowed-tools、target_agent)、正文结构(工作流 + 指令 + 输出规范)以及捆绑资源目录(scripts/、templates/、reference/)。读者将理解 Skill 与普通 Prompt(提示词) 的核心差异——权限控制、工具绑定和元数据索引——这是 Skill 能够工程化复用的根基。

Skill 的发现路径(项目级→用户级→内置)和加载机制是整个 Skill 系统的工作流核心。我们深入分析语义匹配的设计权衡——降低认知负荷的同时可能带来不精确触发——以及渐进式披露策略如何实现按需加载。在 OMO 扩展部分,我们介绍 Skills Marketplace(社区共享与版本管理)、Scoped Skills(target_agent 限定可见性)和 Skill Overrides 机制。学完本节,读者应能独立创建 Skill 文件,并为团队搭建可共享的 Skill 体系。

读完本文,你将能够编写符合规范的 SKILL.md 文件,掌握 Skill 的语义匹配与渐进式加载机制,以及利用 Scoped Skills 和 Overrides 实现精细的权限控制。

⏱ 时间有限?先读这些: SKILL.md 完整格式 → Skill 的发现与加载 → 权限控制 → OMO 扩展

⚠️ 重要说明:本节描述的 allowed-toolsagent 等字段是 oh-my-openagent (OMO) 扩展的功能,不是 OpenCode 原生 SKILL.md 规范的一部分。OpenCode 原生 SKILL.md 仅识别 namedescriptionlicensecompatibilitymetadata 字段,其他字段会被静默忽略。

最小示例

用一个最简单的 SKILL.md 来理解 Skill:

---
name: "hello-world"
description: "向世界打招呼的简单 Skill"
---

这就是一个 Skill 的最小单元:name 是唯一标识,description 用于语义匹配。Agent 读到这份文件就知道:“遇到打招呼的任务时,我可以加载这个 Skill 来处理。”

OMO 扩展的额外字段(非 OpenCode 原生):

---
name: "hello-world"
description: "向世界打招呼的简单 Skill"

# 以下是 OMO 扩展字段,OpenCode 原生不识别
agent: "build"
allowed-tools:
  - read
  - glob
  - grep
---

注意:

  • OpenCode 原生 SKILL.md 不识别 allowed-toolsagent(或 target_agent)等字段
  • 这些字段仅在 oh-my-openagent 插件中有效
  • OpenCode 原生权限控制通过 opencode.json 中的 "permission" 键实现

Skill 的本质

定义:结构化指令包

Skill 是 OpenCode 生态中将领域知识封装为可复用指令的核心载体。如果说 Agent 是执行者,Skill 就是方法论——它告诉 Agent “遇到这类问题时应该怎么思考、按什么步骤做”。

一个 Skill 的本质包含三个维度:

维度说明类比
知识特定领域的最佳实践、方法论、决策树教科书
权限完成任务所需的工具访问范围门禁卡
约束输出格式、质量标准、边界条件检查清单

Skill 与普通 Prompt 的核心差异在于工程化能力

graph LR
    subgraph Prompt[普通 Prompt]
        P1[自然语言指令]
        P2[无元数据]
        P3[无权限控制]
    end
    
    subgraph Skill[Skill 结构化指令包]
        S1[frontmatter 元数据]
        S2[正文指令]
        S3[allowed-tools 权限]
        S4[捆绑资源]
    end
    
    Prompt -->|"工程化升级"| Skill
    
    style Prompt fill:#f5f5f5,stroke:#999
    style Skill fill:#50C878,stroke:#333,color:#fff

操作系统类比:Skill = 驱动程序

理解 Skill 最直观的方式是将其类比为操作系统的驱动程序

操作系统概念OpenCode 对应说明
内核Agent 运行时提供基础执行能力
驱动程序Skill让内核“懂得“如何操作特定设备/领域
设备领域任务前端开发、安全审计、数据库设计等
设备驱动接口Skill 接口规范SKILL.md 格式标准

没有驱动程序,操作系统无法识别和使用硬件设备。同样,没有 Skill,Agent 只能执行通用任务,无法深入特定领域。加载一个 Skill,就像安装了一个驱动程序——Agent 瞬间获得了该领域的“专业知识“。

组件化视角:前端架构师的类比

对于前端开发者,可以用组件化思维来理解 Skill 系统:

graph TB
    subgraph React[React 组件模型]
        RP[Props] --> |"输入配置"| RC[Component]
        RS[State] --> |"内部状态"| RC
        RC --> |"渲染输出"| RD[DOM]
    end
    
    subgraph Skill[Skill 模型]
        SF[frontmatter] --> |"元数据配置"| SK[Skill Body]
        SA[allowed-tools] --> |"权限边界"| SK
        SK --> |"指令输出"| SAO[Agent 行为]
    end
    
    React --> |"概念映射"| Skill
    
    style React fill:#4A90D9,stroke:#333,color:#fff
    style Skill fill:#50C878,stroke:#333,color:#fff

Props = frontmatter

就像组件通过 Props 接收外部配置,Skill 通过 frontmatter 定义元数据:

React PropsSkill frontmatter作用
namename: "skill-name"组件/Skill 的唯一标识
propTypesdescription + metadata类型声明与文档
defaultProps默认值机制OMO Overrides 覆盖

Composition = 编排

多个组件组合成页面,多个 Skill 组合成 Workflow(工作流)

graph LR
    subgraph Page[页面 = 组件组合]
        C1[Header]
        C2[Content]
        C3[Footer]
    end
    
    subgraph Workflow[工作流 = Skill 组合]
        S1[需求分析 Skill]
        S2[代码生成 Skill]
        S3[测试验证 Skill]
    end
    
    C1 --> C2 --> C3
    S1 --> S2 --> S3
    
    style Page fill:#4A90D9,stroke:#333,color:#fff
    style Workflow fill:#FF9F43,stroke:#333,color:#fff
    style S1 fill:#50C878,stroke:#333,color:#fff
    style S2 fill:#50C878,stroke:#333,color:#fff
    style S3 fill:#50C878,stroke:#333,color:#fff

单一职责原则

优秀的组件只做一件事,优秀的 Skill 也只解决一个领域问题:

反模式正确做法
一个 Skill 处理“前端开发+后端开发+测试“拆分为 frontend-devbackend-devtest-engineer
一个组件包含“用户登录+商品列表+购物车“拆分为 LoginProductListCart

生命周期对比

React 生命周期Skill 生命周期触发时机
constructor元数据解析Skill 被发现时
render指令执行Agent 调用 Skill 时
componentDidMount资源加载首次使用捆绑资源时
componentWillUnmount清理会话结束

SKILL.md 完整格式

frontmatter 字段详解

SKILL.md 以 YAML frontmatter 开头,定义 Skill 的元数据。以下是完整的字段规范:

---
# 必填字段(OpenCode 原生)
name: "skill-name"              # Skill 的唯一标识符
description: "简短描述,用于语义匹配"  # 触发匹配的关键描述

# OMO 扩展字段(非 OpenCode 原生)
agent: "build"                  # 限定特定 Agent 可见(oh-my-openagent 扩展)
allowed-tools:                  # 允许访问的工具列表(oh-my-openagent 扩展)
  - read
  - glob
  - grep

# 元数据扩展(OpenCode 原生,但 metadata 是字符串到字符串的映射)
license: "MIT"
metadata:
  author: "your-name"           # 存储为字符串键值
  version: "1.0.0"

必填字段

字段类型说明示例
namestringSkill 的唯一标识符,用于日志和调试frontend-architect
descriptionstring简短描述,用于语义匹配触发"React/Vue 组件架构设计专家"

OMI 扩展字段(非 OpenCode 原生)

⚠️ OpenCode 原生 SKILL.md 规范不识别以下字段,它们会被静默忽略:

  • allowed-tools:工具列表声明(oh-my-openagent 扩展)
  • agent / target_agent:Agent 限定(oh-my-openagent 扩展)
  • category:分类字段(oh-my-openagent 扩展)
  • dependencies / pipeline:依赖和工作流声明

权限控制说明

OpenCode 原生使用 opencode.json 中的 "permission"(单数,不是复数)键来控制工具访问:

{
  "permission": {
    "edit": "ask",
    "bash": {
      "*": "ask",
      "git status": "allow",
      "rm -rf*": "deny"
    },
    "skill": {
      "*": "allow",
      "internal-*": "deny"
    }
  }
}

关于 allowed-tools 的重要说明:

  • 该字段在 SKILL.md 中被解析但不被 OpenCode 原生强制执行
  • 工具权限由 opencode.json 中的 "permission" 配置管理
  • 这是 oh-my-openagent 扩展的设计,OpenCode 原生实现不同

⚠️ 跨平台警告:依赖 allowed-toolstarget_agent 的 Skill 是 oh-my-openagent 特定,不是 OpenCode 原生功能。如果要在 OpenCode 和 oh-my-openagent 之间共享 Skill,请只使用 OpenCode 原生字段(namedescriptionlicensecompatibilitymetadata)。

正文结构

frontmatter 之后是 Skill 的正文,通常包含以下结构:

---
name: "frontend-architect"
description: "前端架构设计专家,精通 React/Vue 组件设计"
allowed-tools:
  - Read
  - Write
  - Glob
  - Grep
---

# 前端架构师 Skill

## 角色定义

你是一位资深前端架构师,专注于...

## 工作流程

1. **需求分析阶段**
   - 分析组件职责边界
   - 识别状态管理需求
   
2. **架构设计阶段**
   - 设计组件层次结构
   - 规划数据流向

## 输出规范

所有输出必须包含:
- 组件结构图(Mermaid 格式)
- 接口定义(TypeScript)
- 实现建议

## 约束条件

- 遵循单一职责原则
- 优先使用函数式组件
- ...

正文结构最佳实践

部分内容篇幅建议
角色定义明确 Skill 扮演的角色和职责2-3 段
工作流程分步骤描述执行逻辑核心部分,占 40-50%
输出规范定义输出的格式和质量标准1-2 段 + 示例
约束条件明确边界条件和禁止事项列表形式

捆绑资源目录

Skill 可以捆绑额外的资源文件,放在与 SKILL.md 同级的目录中:

my-skill/
├── SKILL.md              # Skill 定义文件
├── scripts/              # 可执行脚本
│   ├── setup.sh
│   └── validate.py
├── templates/            # 代码模板
│   ├── component.tsx.tmpl
│   └── test.spec.ts.tmpl
└── reference/            # 参考文档
    ├── best-practices.md
    └── examples.md

资源目录用途

目录用途典型内容
scripts/自动化脚本初始化脚本、验证脚本、部署脚本
templates/代码模板组件模板、配置模板、测试模板
reference/参考文档最佳实践、设计模式、示例代码

Skill 的发现与加载

六路搜索路径

OpenCode 按照以下优先级搜索 Skill(按优先级降序排列):

graph TB
    subgraph Search[Skill 搜索路径(6 个位置)]
        direction TB
        P1[.opencode/skills/] --> P2["~/.config/opencode/skills/"]
        P2 --> P3["~/.claude/skills/"]
        P3 --> P4["~/.claude/skills/"]
        P4 --> P5["~/.agents/skills/"]
        P5 --> P6["~/.agents/skills/"]
    end
    
    P1 --> |"最高优先级"| R1[项目特定 Skill]
    P2 --> |"全局配置"| R2[用户共享 Skill]
    P3 --> |"Claude 兼容"| R3[Claude Code 兼容]
    P4 --> |"全局 Claude 兼容"| R4[全局 Claude 兼容]
    P5 --> |"通用代理兼容"| R5[通用代理兼容]
    P6 --> |"全局通用兼容"| R6[全局通用兼容]
    
    style P1 fill:#50C878,stroke:#333,color:#fff
    style P2 fill:#4A90D9,stroke:#333,color:#fff
    style P3 fill:#FF9F43,stroke:#333,color:#fff
    style P4 fill:#A66CFF,stroke:#333,color:#fff
    style P5 fill:#FF9F43,stroke:#333,color:#fff
    style P6 fill:#A66CFF,stroke:#333,color:#fff

项目级 Skills

路径描述
.opencode/skills/OpenCode 项目级(最高优先级)
.claude/skills/Claude Code 兼容项目级
.agents/skills/通用代理兼容项目级

用户级 Skills

路径描述
~/.config/opencode/skills/OpenCode 全局用户级(推荐路径)
~/.opencode/skills/OpenCode 旧版用户级路径
~/.claude/skills/Claude Code 兼容全局
~/.agents/skills/通用代理兼容全局

ℹ️ 跨平台兼容:OpenCode 设计时考虑了与 Claude Code 和 .agents 生态系统的兼容性,因此会扫描多个来源以实现去重。

优先级规则

opencode-project > opencode-global > project (.claude + .agents) > user (.claude + .agents)

渐进式披露机制

Skill 的加载采用渐进式披露策略,按需加载不同层级的内容:

sequenceDiagram
    participant User as 用户
    participant Agent as Agent
    participant FS as 文件系统
    
    User->>Agent: 提交任务描述
    Agent->>FS: 扫描所有 Skill 的 description
    Note over Agent,FS: 第一阶段:元数据匹配<br/>只读取 frontmatter
    
    alt 匹配成功
        Agent->>FS: 加载匹配 Skill 的完整内容
        Note over Agent,FS: 第二阶段:正文加载<br/>读取 SKILL.md 全文
        
        alt 需要捆绑资源
            Agent->>FS: 加载 scripts/templates/reference
            Note over Agent,FS: 第三阶段:资源加载<br/>按需读取捆绑文件
        end
        
        Agent->>User: 执行 Skill 指令
    else 无匹配
        Agent->>User: 使用默认行为
    end

三阶段加载详解

阶段加载内容触发条件性能影响
元数据匹配只读取 frontmatter每次任务开始时极低,只解析 YAML
正文加载读取完整 SKILL.mddescription 匹配成功中等,解析 Markdown
资源加载读取捆绑目录Skill 执行需要时按需,可能较高

语义匹配机制

ℹ️ 技术说明:原生 OpenCode 使用基于名称的技能查找(通过 skill({ name: "..." }) 工具调用)。语义匹配功能来自第三方插件 opencode-agent-skills,不是 OpenCode 核心功能。

语义匹配插件的工作方式:

  • 使用 HuggingFace all-MiniLM-L6-v2 嵌入模型(本地,量化)
  • 计算用户消息和技能描述之间的余弦相似度
  • 阈值:0.35,Top-K: 5
  • 缓存嵌入在 ~/.cache/opencode-agent-skills/

优势

  • 降低认知负荷:用户无需记忆 Skill 名称,自然语言描述即可触发
  • 灵活扩展:新增 Skill 无需修改配置,自动参与匹配
  • 跨语言支持:多语言 description 可支持不同语言用户

挑战

  • 匹配不精确:相似描述可能导致错误触发
  • 调试困难:难以预测哪个 Skill 会被激活
  • 版本冲突:多个 Skill 匹配时的优先级问题
  • 非确定性:同一输入在不同会话或 LLM 版本下可能触发不同 Skill
  • 冷启动不可见性:新 Skill 需要用户知道正确的描述才能触发

最佳实践:编写精准的 description

# 反例:描述过于宽泛
description: "帮助开发"

# 正例:描述具体且包含关键词
description: "React 组件架构设计专家,精通状态管理、性能优化、TypeScript 类型设计"

权限控制

三级策略:allow/ask/deny

OpenCode 的权限系统采用三级策略模型,配置在 opencode.json 中:

策略行为适用场景
allow自动执行,无需确认安全操作,如读取文件
ask每次执行前询问用户敏感操作,如写入文件、执行命令
deny禁止执行,直接拒绝危险操作,如删除文件、访问敏感路径

OpenCode 原生权限配置

{
  "permission": {
    "edit": "ask",
    "bash": {
      "*": "ask",
      "git status": "allow",
      "rm -rf*": "deny"
    },
    "skill": {
      "*": "allow",
      "internal-*": "deny",
      "experimental-*": "ask"
    }
  }
}

⚠️ 配置说明

  • 键是 "permission"(单数),不是 "permissions"(复数)
  • 工具名使用小写editbashreadglobgrep
  • 技能权限通过 permission.skill 使用通配符模式控制

oh-my-openagent 扩展的额外功能

oh-my-openagent 允许在 opencode.json 中配置更细粒度的权限:

{
  "permissions": {
    "default": "ask",
    "tools": {
      "Read": "allow",
      "Write": "ask",
      "Bash": "ask"
    }
  }
}

注意这是 oh-my-openagent 特定 配置格式,OpenCode 原生使用上面所示的 "permission" 格式。

allowed-tools 安全含义

⚠️ 重要说明:以下讨论基于 oh-my-openagent 扩展。OpenCode 原生 不识别 allowed-tools 字段,该字段会被静默忽略。

权限边界即攻击面 — 这是安全架构师视角下技能权限设计的核心原则。

graph TB
    subgraph Attack[攻击面分析]
        S[Skill] --> |"allowed-tools"| T1[read]
        S --> T2[edit]
        S --> T3[bash]
        S --> T4[webfetch]
    end
    
    T1 --> |"信息泄露风险"| R1[读取敏感文件<br/>.env, credentials]
    T2 --> |"篡改风险"| R2[修改关键配置<br/>注入恶意代码]
    T3 --> |"命令执行风险"| R3[执行任意命令<br/>横向移动]
    T4 --> |"数据外泄风险"| R4[向外部发送数据<br/>SSRF 攻击]
    
    style S fill:#50C878,stroke:#333,color:#fff
    style R1 fill:#E74C3C,stroke:#333,color:#fff
    style R2 fill:#E74C3C,stroke:#333,color:#fff
    style R3 fill:#E74C3C,stroke:#333,color:#fff
    style R4 fill:#E74C3C,stroke:#333,color:#fff

最小权限原则

每个 Skill 的 allowed-tools 应遵循最小权限原则——只授予完成任务所需的最小权限集:

Skill 类型推荐 allowed-tools安全考量
代码审查read, glob, grep只读,无修改风险
代码生成read, edit, glob需要写入,但禁止命令执行
部署脚本read, edit, bash高风险,需严格审计
安全审计read, grep, bash需要执行扫描工具,但禁止写入

allowed-tools 配置示例

---
name: "code-reviewer"
description: "代码审查专家,识别代码异味和安全漏洞"
allowed-tools:
  - read      # 读取代码文件
  - glob      # 搜索文件
  - grep      # 搜索内容
  # 注意:没有 edit,禁止修改代码
  # 注意:没有 bash,禁止执行命令
---

权限提升攻击防护

恶意 Skill 可能尝试通过以下方式提升权限:

攻击方式防护措施
诱导用户执行命令bash 工具默认 ask 策略
修改配置文件获取权限敏感路径 deny 策略
链式调用其他 Skillagent 限制可见性
通过 WebFetch 外泄数据网络请求审计日志

⚠️ 重要提醒allowed-tools 的限制不是 OpenCode 原生强制执行的安全边界。真正的权限控制发生在 opencode.json"permission" 配置中。

技能审计日志

所有工具调用都会被记录(通过 oh-my-openagent 插件):

[2025-06-01 10:23:45] [skill-resolver] Called read on src/App.tsx
[2025-06-01 10:23:46] [skill-resolver] Called edit on src/components/Header.tsx
[2025-06-01 10:23:47] [skill-resolver] DENIED: Bash not in allowed-tools

⚠️ 技术说明:上述日志格式来自 oh-my-openagent 插件。OpenCode 原生使用结构化 JSON 格式的审计日志,详见 安全总览

审计日志可用于:

  • 安全事件调查
  • 合规审计
  • Skill 行为分析
  • 权限配置优化

OMO 扩展

技能市场(Skills Marketplace)

⚠️ 前瞻性说明:Skills Marketplace 是 oh-my-openagent 生态的远景规划功能。下文提到的分发机制是社区替代方案,不是 OpenCode 内置功能。

社区提供的技能分发方式:

  1. npm 包分发opencode-skills-collection(1000+ 技能)
  2. Git 仓库同步@jgordijn/opencode-remote-config
  3. CLI 注册表skills npm 包(支持 67 个平台)

** Marketplace 功能愿景**

功能说明当前状态
版本管理每个 Skill 有独立的版本号和更新历史社区方案提供
依赖声明Skill 可以声明对其他 Skill 的依赖社区方案提供
评分系统用户可以对 Skill 进行评分和评论社区方案提供
安全扫描上传的 Skill 经过安全检查社区方案提供

ℹ️ OpenCode 核心本身不包含内置的技能市场 UI 或注册表。技能分发基于文件系统(复制/符号链接从 npm/Git)。

Scoped Skills(oh-my-openagent 扩展)

⚠️ 重要说明:以下功能来自 oh-my-openagent 扩展,不是 OpenCode 原生功能。

agent 字段可以实现 Skill 的可见性控制:

---
name: "security-scanner"
description: "安全漏洞扫描专家"
agent: "security-audit"  # 只有 security-audit Agent 可见(oh-my-openagent 扩展)
allowed-tools:
  - read
  - grep
  - bash
---

使用场景

场景agent 设置
通用 Skill不设置,所有 Agent 可见
专业 Skill设置为专业 Agent,如 buildplan
安全敏感 Skill设置为专用安全 Agent,限制传播

配置覆盖(oh-my-openagent)

{
  "skills": {
    "frontend-architect": {
      "allowed-tools": ["read", "glob", "grep"],
      "agent": "build",
      "disabled": false
    }
  }
}

Skill vs Plugin(插件)

Skill 和 Plugin 是 OpenCode 生态中两个互补的概念:

graph TB
    subgraph SkillLayer[Skill 层:指令层]
        S1[Skill: 教 Agent 怎么做]
        S2[定义工作流程]
        S3[提供决策逻辑]
    end
    
    subgraph PluginLayer[Plugin 层:能力层]
        P1[Plugin: 改 Agent 能做什么]
        P2[扩展工具集]
        P3[连接外部服务]
    end
    
    SkillLayer --> |"调用"| PluginLayer
    
    style SkillLayer fill:#50C878,stroke:#333,color:#fff
    style PluginLayer fill:#A66CFF,stroke:#333,color:#fff
维度SkillPlugin
本质指令包能力扩展
作用教 Agent “怎么做”改 Agent “能做什么”
示例代码审查流程、架构设计方法论MCP(模型上下文协议) 服务器、自定义工具
配置SKILL.mdopencode.json plugins 字段
权限allowed-tools工具注册

组合使用示例

一个完整的“数据库迁移“任务可能需要:

  1. Plugin:提供数据库连接工具(能力层)
  2. Skill:定义迁移流程和最佳实践(指令层)

Skill 使用最佳实践

编写精准的 description

# 反例:过于宽泛
description: "帮助写代码"

# 正例:具体且包含关键词
description: "React Hooks 最佳实践专家,精通 useEffect/useMemo/useCallback 优化策略,专注性能调优和内存泄漏排查"

description 编写技巧

  • 包含领域关键词(React、安全、测试)
  • 说明核心能力(精通、专注、擅长)
  • 区分相似 Skill 的差异

版本迭代维护

---
name: "frontend-architect"
description: "前端架构设计专家"
metadata:
  version: "2.1.0"  # 语义化版本
---

在正文中维护变更日志:

## Changelog

- **2.1.0**: 新增 Server Components 支持
- **2.0.0**: 重构为 React 18 兼容
- **1.0.0**: 初始版本

ℹ️ OpenCode 原生 SKILL.md 没有内置 changelog 字段 — 变更日志应该在正文中维护。

团队共享规范

规范项建议
命名规范小写连字符,如 frontend-architect
目录结构每个 Skill 独立目录,包含 SKILL.md 和资源
版本控制项目级 Skill 纳入 Git,用户级可选
审查流程敏感 Skill(含 Bash 权限)需安全审查

小结

Skill 是 OpenCode 生态中将领域知识工程化的核心载体。通过 frontmatter 元数据、正文指令、权限控制的组合,Skill 实现了从“提示词“到“可复用能力模块“的跨越。

理解 Skill 的关键要点:

  1. 本质:结构化指令包 = 知识 + 权限 + 约束
  2. 类比:Skill = 驱动程序,让 Agent 获得领域专业能力
  3. 格式:frontmatter(元数据)+ 正文(指令)+ 资源(捆绑文件)
  4. 发现:项目级→用户级→内置的三级搜索路径
  5. 加载:渐进式披露,按需加载元数据→正文→资源
  6. 权限:allowed-tools 定义权限边界,权限边界即攻击面

在下一章 工作流模式 中,我们将看到多个 Skill 如何被编排成完整的工作流,实现复杂任务的自动化。


常见反模式

反模式一:一个 Skill 包罗万象

现象:创建一个名为“developer“的 Skill,description 写“帮助所有开发工作“,正文涵盖前端、后端、测试、部署等全部领域,单个 SKILL.md 长达数百行。

原因:图方便,不想管理多个 Skill 文件,低估了 Skill 单一职责原则的重要性。

对策:遵循单一职责原则——每个 Skill 只解决一个领域问题。拆分为 frontend-dev、backend-dev、test-engineer 等独立 Skill,每个 Skill 的描述和指令聚焦于单一领域。

反模式二:description 过于宽泛

现象:Skill 的 description 写成“帮助开发“、“代码工具“等模糊描述,语义匹配时频繁误触发或根本匹配不到。

原因:低估了 description 在语义匹配中的关键作用,认为反正自己知道这个 Skill 是做什么的。

对策:description 应包含领域关键词(React、安全、测试)和核心能力(精通、专注、擅长)。对比:❌“帮助写代码” ✅“React Hooks 最佳实践,专注状态管理、性能调优和内存泄漏排查”。

反模式三:权限配置与 Skill 需求不匹配

现象:一个只需要读取文件的代码审查 Skill 被授予了 edit 和 bash 权限,或者一个需要执行测试的 Skill 被禁止了 bash 命令。

原因:使用默认的全局权限配置,没有针对 Skill 的使用场景做差异化配置。

对策:基于最小权限原则,按 Skill 的实际需求配置工具权限。代码审查 Skill 只需 read/glob/grep,部署 Skill 需要 read/edit/bash。权限配置在 opencode.json 中集中管理。

常见错误与陷阱

场景一:Skill 名称冲突导致行为不一致

场景:项目级 Skill 和用户级 Skill 重名(如“code-review“),但内容不同。Agent 按优先级加载了其中一个,开发者在不同机器上看到不同的审查行为。

后果:团队内 Skill 行为不一致,代码审查标准因环境而异,降低协作效率。

预防:项目级 Skill 加项目名前缀(如“myproject-code-review“);在 AGENTS.md 中声明项目使用的 Skill 列表;定期检查 Skill 加载日志确认实际加载的版本。

场景二:跨平台兼容性问题

场景:在 oh-my-openagent 下创建的 Skill 包含 allowed-tools 和 target_agent 字段,在原生 OpenCode 中这些字段被静默忽略。Skill 在 OMO 下工作正常,但在 OpenCode 下权限不受控。

后果:Skill 行为在不同平台不一致,安全假设失效,“只读审查“的 Skill 在原生 OpenCode 下可能获得写入权限。

预防:明确标注 Skill 的目标平台;跨平台 Skill 只使用 OpenCode 原生字段(name/description/license/metadata);权限控制统一通过 opencode.json 而非 SKILL.md。

场景三:Skill 依赖未声明导致执行失败

场景:Skill 正文中使用了 scripts/ 目录下的 Python 脚本,但执行环境中没有安装所需的第三方库。Agent 调用脚本时直接失败。

后果:Skill 执行中断,Agent 无法完成任务,开发者需要手动排查环境问题。

预防:在 SKILL.md 正文首段声明所有外部依赖(如“需要 Python 环境和 requests 库“);在 scripts/ 目录加入 requirements.txt;Skill 首次加载时增加环境检测步骤,自动提示缺失的依赖。

适用场景与限制

Skill 系统最有效的场景:需要可复用的领域知识编码(如代码审查、安全扫描、架构设计)、团队需要统一 AI 辅助行为的规范流程、复杂的多步骤任务需要按步骤执行。在这些场景中,Skill 的结构化指令包显著优于普通 Prompt,权限控制提供了工程化复用的基础。

Skill 系统不太适用的场景:一次性任务(用完即弃)、极端快速的单步操作(如“修改变量名“)、需要与 Agent 高度交互的探索性对话。在这些场景中,创建和维护 Skill 的开销超过了收益,直接使用自然语言指令更高效。

高效使用 Skill 系统需要满足的前提条件:团队对 SKILL.md 格式和字段含义有共识;建立了合理的目录结构和命名规范;项目的 opencode.json 权限配置稳定且与 Skill 需求匹配;有定期审查和更新 Skill 的机制;清楚区分 OpenCode 原生字段和 OMO 扩展字段,避免平台依赖。


学习检查清单

完成本章学习后,请确认你能够:

  • 解释 Skill 与普通 Prompt 的核心差异(权限控制、工具绑定、元数据索引)
  • 编写符合规范的 SKILL.md 文件,包含 frontmatter 和正文结构
  • 描述 Skill 的三级搜索路径(项目级→用户级→内置)及其优先级
  • 配置 allowed-tools 字段并理解最小权限原则
  • 说明渐进式披露机制的三阶段加载过程

关联章节

  • Agent 编排:Skill 由 Agent 加载和执行,理解 Agent 是理解 Skill 的前提
  • 工作流模式:Command 可指定 Skill,工作流编排中 Skill 是能力单元
  • Skill 开发:Skill 模板和开发实操,最佳实践的深度展开
  • 安全总览:权限控制的深度分析和安全审计