本文档是《OpenCode 进阶使用指南》的第二章专注于 Skills 技能系统的深入讲解,预计阅读时间:30-40 分钟
目录
- [什么是 Skills 系统](#什么是 Skills 系统 "#%E4%BB%80%E4%B9%88%E6%98%AF-skills-%E7%B3%BB%E7%BB%9F")
- [Skills 的核心概念](#Skills 的核心概念 "#skills-%E7%9A%84%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5")
- [创建你的第一个 Skill](#创建你的第一个 Skill "#%E5%88%9B%E5%BB%BA%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA-skill")
- [SKILL.md 文件详解](#SKILL.md 文件详解 "#skillmd-%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3")
- 高级技能编写技巧
- 技能调试与优化
- 团队协作与技能共享
- 实战案例集
- 底层原理剖析
- 常见问题与解决方案
什么是 Skills 系统
2.1.1 从重复劳动说起
想象一个场景:你刚入职一家新公司,发现团队的代码审查流程非常规范------每次提交都要检查代码风格、潜在 bug、性能问题、安全漏洞。这些检查点有十几条,每次审查都要一条条过。
刚开始你觉得这个流程很好,能保证代码质量。但几周后,你开始觉得烦了。每次审查都要重复同样的检查项,写同样的评论格式,提同样的修改建议。
你会想:"如果能把这个流程自动化就好了。"
Skills 系统就是来解决这个问题的。
2.1.2 Skills 的本质
Skills 是一套可复用的指令模板。
当你发现自己在重复做某类任务时,你可以:
- 把这类任务的步骤、标准、注意事项整理出来
- 写成 SKILL.md 文件
- 放到特定目录
- 以后让 AI 自动按照这个模板执行
简单来说,Skills 就是把"你的经验"变成"AI 的能力"。
2.1.3 Skills vs Agent 模式的区别
很多人问:"Skills 和 Agent 模式有什么区别?"
| 维度 | Agent 模式 | Skills 系统 |
|---|---|---|
| 定位 | 执行能力 | 知识封装 |
| 作用 | 让 AI 能动手 | 让 AI 懂规则 |
| 使用方式 | 临时指令 | 预定义模板 |
| 复用性 | 每次都要说 | 一次定义多次使用 |
| 适用场景 | 具体任务 | 标准化流程 |
举例说明:
Agent 模式就像你让一个程序员"去重构代码"。他会自己思考怎么做。
Skills 系统就像你给程序员一本《代码重构手册》,告诉他:"以后重构都按这个手册来"。
两者可以结合使用:用 Skills 定义流程,用 Agent 模式执行流程。
2.1.4 Skills 能做什么
代码质量类:
- 代码审查检查清单
- 重构标准流程
- 性能优化指南
- 安全审计规范
开发流程类:
- 新功能开发流程
- Bug 修复标准流程
- 测试用例生成规范
- 文档编写模板
团队协作类:
- 代码提交规范
- PR 审查标准
- 发布流程检查
- 新人入职指南
领域专业类:
- 前端组件开发规范
- API 设计最佳实践
- 数据库操作规范
- 微服务拆分原则
Skills 的核心概念
2.2.1 技能发现机制
OpenCode 是如何找到 Skills 的?这涉及到一个"发现机制"。
搜索路径:
当你启动 OpenCode 时,它会从当前目录开始,向上查找所有包含 .opencode/skills/ 或 .claude/skills/ 的目录。
搜索顺序:
bash
当前工作目录/.opencode/skills/
当前工作目录/.claude/skills/
父目录/.opencode/skills/
父目录/.claude/skills/
...
直到 git 仓库根目录
~
~/.config/opencode/skills/ (全局)
~/.claude/skills/ (全局兼容)
为什么要向上查找?
考虑一个 monorepo 项目结构:
bash
my-project/ ← git 根目录
├── .opencode/skills/ ← 项目级 Skills
│ ├── code-review/
│ └── api-design/
├── packages/
│ ├── frontend/
│ │ └── .opencode/skills/ ← 前端专属 Skills
│ │ └── react-component/
│ └── backend/
│ └── .opencode/skills/ ← 后端专属 Skills
│ └── express-route/
如果你在 packages/frontend/ 目录下工作,OpenCode 会加载:
packages/frontend/.opencode/skills/- 前端专属my-project/.opencode/skills/- 项目级~/.config/opencode/skills/- 全局
这样设计的好处:子项目可以覆盖或扩展父项目的 Skills。
2.2.2 技能加载过程
当一个 Skill 被发现后,OpenCode 会:
- 读取 SKILL.md:解析 YAML frontmatter 和 Markdown 内容
- 验证格式:检查必填字段、格式规范
- 解析依赖:如果有依赖其他 Skills,先加载依赖
- 注入上下文:将 Skill 信息注入到 AI 的上下文中
- 注册工具:如果 Skill 定义了自定义工具,注册到工具集
加载时机:
- 启动时:加载所有发现的 Skills
- 运行时 :可以动态加载新 Skills(通过
/skill reload) - 按需加载:某些 Skills 可以设置 lazy loading
2.2.3 技能匹配机制
OpenCode 怎么知道什么时候该用哪个 Skill?
关键词匹配:
Skill 的 description 字段包含关键词,AI 会根据用户输入匹配最合适的 Skill。
例如:
- 用户说"帮我审查代码" → 匹配 code-review Skill
- 用户说"生成 API 文档" → 匹配 api-doc Skill
显式调用:
用户可以直接指定使用某个 Skill:
bash
> /skill use code-review
> 开始审查 src/components/Button.tsx
自动推荐:
OpenCode 会分析当前上下文,主动推荐可能相关的 Skills:
markdown
看起来你正在写 React 组件。
可用的 Skills:
1. react-component - React 组件开发规范
2. code-review - 代码审查检查清单
3. testing - 测试用例生成
要使用哪个?(输入编号或名称)
2.2.4 技能生命周期
一个 Skill 从创建到使用,经历以下阶段:
1. 开发阶段:
- 编写 SKILL.md
- 本地测试
- 迭代优化
2. 发布阶段:
- 提交到 Git
- 版本标记
- 文档更新
3. 分发阶段:
- 团队成员拉取
- 全局安装(可选)
- 内部 npm 包(可选)
4. 使用阶段:
- 自动匹配
- 显式调用
- 结果反馈
5. 维护阶段:
- 收集反馈
- 更新优化
- 版本迭代
创建你的第一个 Skill
2.3.1 准备工作
环境要求:
- OpenCode 0.1.40+
- 一个 Git 仓库(推荐)
- 基本的 Markdown 知识
选择技能类型:
第一次创建 Skill,建议从简单的开始。比如:
- 代码风格检查
- 提交信息规范
- 简单的代码生成
2.3.2 实战:创建一个代码提交规范 Skill
场景:团队要求所有提交信息都要遵循 Conventional Commits 规范,但新人总是记不住格式。
目标:创建一个 Skill,帮助生成符合规范的提交信息。
Step 1:创建目录结构
bash
mkdir -p .opencode/skills/conventional-commit
cd .opencode/skills/conventional-commit
Step 2:编写 SKILL.md
创建文件 SKILL.md:
yaml
---
name: conventional-commit
description: 帮助生成符合 Conventional Commits 规范的提交信息
version: 1.0.0
author: your-name
tags:
- git
- workflow
- automation
---
# Conventional Commit 助手
## 什么时候用
当你需要写 Git 提交信息时,使用这个 Skill 来生成符合团队规范的提交信息。
## 规范说明
我们团队使用 Conventional Commits 规范,格式如下:
### Type 类型
- **feat**: 新功能
- **fix**: 修复 bug
- **docs**: 文档修改
- **style**: 代码格式修改(不影响功能)
- **refactor**: 重构
- **perf**: 性能优化
- **test**: 测试相关
- **chore**: 构建过程或辅助工具变动
### Scope 范围
根据修改的内容选择:
- **api**: API 相关
- **ui**: 界面相关
- **db**: 数据库相关
- **config**: 配置相关
- **deps**: 依赖相关
## 使用步骤
1. 询问用户本次修改的主要内容
2. 分析修改的文件,判断 type 和 scope
3. 生成多个提交信息选项
4. 让用户选择或修改
5. 输出最终的提交命令
## 示例
**示例 1:新功能**
用户:添加了用户登录功能
生成:
git commit -m "feat(auth): 添加用户登录功能
- 实现 JWT token 验证
- 添加登录页面 UI
- 集成后端登录接口
Closes #123"
**示例 2:Bug 修复**
用户:修复了登录按钮点击无响应的问题
生成:
git commit -m "fix(ui): 修复登录按钮点击无响应
问题原因:事件监听器未正确绑定
解决方案:使用 useEffect 确保 DOM 加载完成后再绑定
Fixes #456"
**示例 3:文档更新**
用户:更新了 API 文档
生成:
git commit -m "docs(api): 更新用户认证接口文档
- 添加 JWT 认证说明
- 补充错误码列表
- 添加请求示例"
## 注意事项
1. subject 首字母不要大写
2. subject 末尾不要加句号
3. body 每行不超过 72 个字符
4. 如果有关联的 issue,在 footer 中引用
Step 3:测试 Skill
在 OpenCode 中测试:
bash
> /skill list
可用的 Skills:
- conventional-commit: 帮助生成符合 Conventional Commits 规范的提交信息
> 我要提交代码,帮我写提交信息
[AI 会使用 conventional-commit Skill]
AI:请描述一下本次修改的主要内容:
> 修复了用户列表页面分页不生效的问题
AI:分析修改内容...
↓
AI:为你生成了以下提交信息选项:
选项 1:
git commit -m "fix(ui): 修复用户列表分页不生效
- 修正分页参数传递错误
- 添加分页边界检查
Fixes #789"
选项 2:
git commit -m "fix(api): 修复用户列表接口分页参数处理
问题原因:page 参数未正确解析
解决方案:使用 parseInt 转换并添加默认值
Fixes #789"
请选择一个(输入 1 或 2),或告诉我修改建议:
> 1
AI:好的,使用选项 1。请复制以下命令执行:
git commit -m "fix(ui): 修复用户列表分页不生效
- 修正分页参数传递错误
- 添加分页边界检查
Fixes #789"
2.3.3 进阶:添加智能分析
上面的 Skill 还需要用户手动描述修改内容。我们可以让它更智能------自动分析修改的文件。
更新 SKILL.md:
yaml
---
name: conventional-commit
description: 智能生成符合 Conventional Commits 规范的提交信息
version: 1.1.0
author: your-name
tags:
- git
- workflow
- automation
- smart-analysis
---
# Conventional Commit 助手(智能版)
## 新增功能
### 自动分析修改
使用以下命令自动分析工作区的修改:
git diff --name-only # 查看修改了哪些文件
git diff # 查看具体修改内容
git status # 查看文件状态
### 文件类型映射
根据修改的文件自动推断 type 和 scope:
**文件路径 → Type 推断**:
- `src/**/*.test.ts` → test
- `docs/**/*.md` → docs
- `package.json`, `package-lock.json` → chore
- 其他 → 需要人工判断(feat 或 fix)
**文件路径 → Scope 推断**:
- `src/components/**/*.tsx` → ui
- `src/api/**/*.ts` → api
- `src/db/**/*.ts` → db
- `src/utils/**/*.ts` → utils
- `config/**/*.js` → config
## 使用步骤(智能版)
1. 执行 `git status` 和 `git diff --name-only`,了解修改了哪些文件
2. 执行 `git diff`,了解具体的修改内容
3. 根据文件路径和修改内容,自动推断 type 和 scope
4. 生成提交信息草稿
5. 询问用户确认或修改
6. 输出最终的提交命令
## 示例流程
用户:帮我生成提交信息
AI:[执行 git status]
修改的文件:
- src/components/UserList.tsx
- src/api/users.ts
- src/components/UserList.test.tsx
AI:[执行 git diff]
UserList.tsx: 添加了分页功能
users.ts: 添加了分页参数支持
UserList.test.tsx: 添加了分页测试
AI:分析结果:
- Type: feat (新功能)
- Scope: ui (主要是 UI 组件)
- 涉及 API 修改,需要在 body 中说明
生成提交信息:
git commit -m "feat(ui): 添加用户列表分页功能
- 实现前端分页组件和交互
- 后端 API 添加分页参数支持
- 添加单元测试覆盖
涉及文件:
- src/components/UserList.tsx
- src/api/users.ts
- src/components/UserList.test.tsx
Closes #234"
请确认或修改:
2.3.4 提交到团队仓库
创建好 Skill 后,记得提交到 Git:
bash
git add .opencode/skills/conventional-commit/
git commit -m "feat(devtools): 添加 Conventional Commit 助手 Skill
- 自动生成符合规范的提交信息
- 支持智能分析修改内容
- 提供多种选项供选择"
git push
团队成员拉取代码后就能使用这个 Skill 了。
SKILL.md 文件详解
2.4.1 YAML Frontmatter 完整字段
SKILL.md 文件以 YAML frontmatter 开头,放在 --- 之间。
必需字段:
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| name | string | 技能名称,必须唯一,只能用小写字母、数字和连字符 | code-review |
| description | string | 技能描述,用于匹配和展示 | 自动进行代码审查 |
可选字段:
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| version | string | 版本号,遵循 semver | 1.2.3 |
| author | string | 作者信息 | 张三 <zhangsan@example.com> |
| license | string | 许可证 | MIT |
| tags | array | 标签,用于分类和搜索 | ["testing", "automation"] |
| compatibility | string | 兼容性标识 | opencode>=0.1.40 |
| dependencies | array | 依赖的其他 Skills | ["base-coding", "testing-utils"] |
| metadata | object | 自定义元数据 | { "team": "frontend", "priority": "high" } |
完整示例:
yaml
---
name: react-component-review
description: 针对 React 组件的代码审查,检查 hooks 使用、性能优化、可访问性等
version: 2.1.0
author: 前端团队 <frontend@company.com>
license: MIT
tags:
- react
- review
- performance
- a11y
compatibility: opencode>=0.1.40
dependencies:
- base-code-review
metadata:
team: frontend
priority: high
review_level: strict
---
2.4.2 Markdown 内容结构
YAML frontmatter 之后是 Markdown 内容,用来详细说明技能的使用方法。
推荐结构:
markdown
# 技能标题
## 什么时候用
描述使用场景和触发条件。
## 前置条件
列出使用这个技能前需要满足的条件。
## 输入参数
如果技能需要参数,说明参数格式和示例。
## 使用步骤
详细说明执行步骤,可以包含:
1. 第一步做什么
2. 第二步做什么
3. ...
## 检查清单
列出需要检查的项目,用复选框表示。
## 示例
提供具体的使用示例。
### 示例 1:场景 A
详细说明...
### 示例 2:场景 B
详细说明...
## 输出格式
说明执行结果的格式。
## 注意事项
列出常见问题和注意事项。
## 相关资源
- 链接 1
- 链接 2
2.4.3 特殊语法
变量替换:
可以在 Skill 中使用变量,这些变量会在执行时被替换:
markdown
## 使用步骤
1. 读取文件 {{file_path}}
2. 检查 {{check_item}}
3. 输出结果到 {{output_path}}
使用时:
bash
> /skill use code-review file_path=src/App.tsx check_item=performance
条件逻辑:
可以使用条件注释:
markdown
<!-- if: framework == "react" -->
## React 特定检查
- 检查 hooks 规则
- 检查 JSX 语法
<!-- endif -->
<!-- if: framework == "vue" -->
## Vue 特定检查
- 检查模板语法
- 检查生命周期使用
<!-- endif -->
代码块:
使用代码块展示示例代码:
```typescript
// 示例代码
function example() {
return "Hello";
}
```
表格:
使用表格展示对照信息:
markdown
| 情况 | 处理方式 | 示例 |
| ---- | ---------- | ----------- |
| 正常 | 直接通过 | - |
| 警告 | 提示但允许 | console.log |
| 错误 | 必须修复 | eval() |
高级技能编写技巧
2.5.1 条件技能
根据不同的条件执行不同的逻辑。
示例:根据项目类型使用不同的检查规则
yaml
---
name: project-lint
description: 根据项目类型自动选择合适的代码检查规则
---
# 项目类型检测
## 检测项目类型
1. 检查 package.json 中的依赖:
- 如果有 react → 前端项目
- 如果有 express → 后端项目
- 如果有 pytest → Python 项目
2. 根据类型加载对应的检查规则:
<!-- if: project_type == "frontend" -->
## 前端项目检查规则
### JavaScript/TypeScript
- ESLint 规则
- Prettier 格式
- TypeScript 类型检查
### React 特定
- Hooks 规则检查
- JSX 语法检查
- 组件命名规范
<!-- endif -->
<!-- if: project_type == "backend" -->
## 后端项目检查规则
### Node.js
- 异步处理检查
- 错误处理检查
- 安全问题检查
### API 设计
- RESTful 规范
- 参数校验
- 错误码规范
<!-- endif -->
2.5.2 组合技能
一个 Skill 可以调用其他 Skills。
示例:完整的代码提交流程
yaml
---
name: complete-code-submit
description: 完整的代码提交流程:检查 → 测试 → 生成提交信息 → 提交
dependencies:
- code-review
- conventional-commit
- pre-commit-check
---
# 完整代码提交流程
## 流程步骤
1. **代码检查**(调用 code-review Skill)
- 运行 linter
- 类型检查
- 安全检查
2. **测试验证**(调用 pre-commit-check Skill)
- 运行单元测试
- 运行集成测试
- 检查测试覆盖率
3. **生成提交信息**(调用 conventional-commit Skill)
- 分析修改内容
- 生成符合规范的提交信息
4. **执行提交**
- git add
- git commit
- (可选)git push
## 失败处理
如果某一步失败:
- 停止后续步骤
- 报告失败原因
- 提供修复建议
2.5.3 交互式技能
让 Skill 支持交互式输入。
示例:交互式项目初始化
yaml
---
name: interactive-init
description: 交互式项目初始化,根据用户选择生成项目结构
---
# 交互式项目初始化
## 步骤 1:选择项目类型
询问用户:
"你要创建什么类型的项目?"
选项:
1. React 前端应用
2. Node.js 后端 API
3. Python 脚本
4. 其他
根据选择进入不同分支。
## 步骤 2:收集项目信息
<!-- if: project_type == "react" -->
询问:
- 项目名称?
- 使用 TypeScript 吗?
- 使用哪个 UI 库?(Ant Design / Material-UI / Tailwind)
- 需要路由吗?
- 需要状态管理吗?
<!-- endif -->
## 步骤 3:确认配置
展示将要生成的配置:
项目:my-app 类型:React + TypeScript UI 库:Ant Design 路由:是状态管理:Redux Toolkit
确认生成吗?(y/n)
## 步骤 4:生成项目
根据确认的配置生成项目文件。
## 步骤 5:安装依赖并启动
cd {{project_name}}
npm install
npm run dev
2.5.4 模板技能
使用模板引擎生成代码。
示例:组件生成器
yaml
---
name: component-generator
description: 根据模板生成 React 组件
templates:
- name: functional-component
path: ./templates/FunctionalComponent.tsx
- name: class-component
path: ./templates/ClassComponent.tsx
---
# React 组件生成器
## 使用方法
> /skill use component-generator name=Button type=functional props="onClick: () => void; children: ReactNode"
## 模板变量
模板中可以使用以下变量:
- `{{component_name}}` - 组件名(大驼峰)
- `{{component_name_lower}}` - 组件名(小写)
- `{{props}}` - 属性定义
- `{{imports}}` - 导入语句
- `{{today}}` - 当前日期
## 生成的文件
- `src/components/{{component_name}}/index.tsx` - 组件主体
- `src/components/{{component_name}}/index.test.tsx` - 测试文件
- `src/components/{{component_name}}/index.stories.tsx` - Storybook 文档
- `src/components/{{component_name}}/styles.module.css` - 样式文件
模板文件示例 (templates/FunctionalComponent.tsx):
tsx
import React from 'react';
import styles from './styles.module.css';
export interface {{component_name}}Props {
{{props}}
}
/**
* {{component_name}} 组件
*
* @example
* ```tsx
* <{{component_name}} {{example_props}} />
* ```
*/
export const {{component_name}}: React.FC<{{component_name}}Props> = (props) => {
const { {{prop_names}} } = props;
return (
<div className={styles.container}>
{/* 组件内容 */}
</div>
);
};
{{component_name}}.displayName = '{{component_name}}';
export default {{component_name}};
技能调试与优化
2.6.1 调试技巧
本地测试:
在提交 Skill 前,先在本地测试:
bash
# 创建测试目录
mkdir /tmp/skill-test
cd /tmp/skill-test
# 复制 Skill
cp -r /path/to/your/skill ./.opencode/skills/
# 启动 OpenCode 测试
opencode --agent
# 测试 Skill
> /skill list
> /skill use your-skill-name
日志输出:
在 Skill 中添加调试信息:
markdown
## 调试模式
如果设置环境变量 `DEBUG_SKILL=true`,输出详细的执行日志。
```bash
DEBUG_SKILL=true opencode --agent
```
shell
**逐步执行**:
使用 `step_by_step` 模式查看每一步的执行:
```bash
> /agent config mode step_by_step
> /skill use your-skill
2.6.2 性能优化
减少上下文大小:
- 只加载必要的文件
- 使用摘要而非完整内容
- 压缩历史记录
yaml
---
name: optimized-skill
description: 优化过的技能,只加载必要信息
---
# 优化执行
## 文件读取优化
不要读取整个文件:
❌ cat src/large-file.ts
只读取相关部分:
✅ head -n 50 src/large-file.ts
✅ grep -n "function target" src/large-file.ts
## 上下文管理
- 使用 `max_lines_per_file: 100` 限制每文件读取行数
- 使用 `compression: true` 启用上下文压缩
缓存机制:
对于重复使用的数据,可以缓存:
markdown
## 缓存配置
缓存以下数据以提高性能:
- 项目结构(5 分钟)
- 依赖列表(1 小时)
- 检查规则(24 小时)
2.6.3 错误处理
优雅降级:
markdown
## 错误处理
如果某一步失败:
1. 尝试备用方案
2. 如果备用方案也失败,报告错误
3. 提供手动操作指南
### 示例:文件读取失败
错误:无法读取 src/config.ts
可能原因:
- 文件不存在
- 权限不足
- 文件被占用
解决方案:
- 检查文件是否存在:ls src/
- 检查权限:ls -la src/config.ts
- 手动创建文件(提供模板)
重试机制:
markdown
## 网络操作重试
对于网络请求(如 API 调用):
- 失败时自动重试 3 次
- 每次重试间隔 1 秒
- 如果都失败,报错并退出
2.6.4 版本管理
语义化版本:
遵循 semver 规范:
- MAJOR(主版本):不兼容的修改
- MINOR(次版本):新增功能,向后兼容
- PATCH(修订):Bug 修复,向后兼容
示例:
sql
1.0.0 - 初始版本
1.1.0 - 添加自动分析功能
1.1.1 - 修复 scope 检测 bug
2.0.0 - 重构 API,不兼容 1.x
变更日志:
维护 CHANGELOG.md:
markdown
# Changelog
## [2.0.0] - 2026-01-15
### 重大变更
- 重构 API,使用新的配置格式
- 不再支持 OpenCode < 0.1.40
### 新功能
- 支持 Vue 项目
- 添加自定义规则
### 修复
- 修复了 Windows 路径问题
团队协作与技能共享
2.7.1 团队 Skills 仓库
集中管理:
创建一个专门的仓库管理团队 Skills:
objectivec
company-opencode-skills/
├── README.md
├── skills/
│ ├── code-review/
│ │ └── SKILL.md
│ ├── commit-message/
│ │ └── SKILL.md
│ └── pr-template/
│ └── SKILL.md
├── templates/
│ └── component/
├── scripts/
│ └── install.sh
└── package.json
安装脚本 (scripts/install.sh):
bash
#!/bin/bash
# 安装团队 Skills 到全局
SKILLS_DIR="$HOME/.config/opencode/skills"
REPO_URL="https://github.com/yourcompany/opencode-skills.git"
# 克隆或更新
if [ -d "$SKILLS_DIR/.git" ]; then
cd "$SKILLS_DIR" && git pull
else
git clone "$REPO_URL" "$SKILLS_DIR"
fi
echo "✓ 团队 Skills 已安装到 $SKILLS_DIR"
echo "可用的 Skills:"
ls "$SKILLS_DIR/skills/"
2.7.2 项目级 Skills
与项目代码一起管理:
将项目特定的 Skills 放在项目仓库中:
perl
my-project/
├── .opencode/
│ └── skills/
│ ├── domain-specific/ # 领域特定
│ ├── framework-specific/ # 框架特定
│ └── team-conventions/ # 团队约定
├── src/
├── package.json
└── README.md
Git 子模块(可选):
如果多个项目共享同一套 Skills,可以使用 Git 子模块:
bash
# 添加 Skills 子模块
git submodule add https://github.com/yourcompany/opencode-skills.git .opencode/skills
# 克隆项目时递归克隆子模块
git clone --recursive https://github.com/yourcompany/my-project.git
2.7.3 Skills 市场(未来规划)
虽然目前 OpenCode 还没有官方的 Skills 市场,但可以预见未来的发展方向:
社区共享:
- 类似 npm 的 Skills 仓库
- 版本管理和依赖解析
- 评分和评论系统
企业内部市场:
- 私有 Skills 仓库
- 权限管理
- 审计日志
实战案例集
2.8.1 案例一:前端代码审查 Skill
yaml
---
name: frontend-code-review
description: 针对前端项目的全面代码审查,包括 React/Vue、性能、安全、可访问性
tags:
- frontend
- review
- react
- vue
---
# 前端代码审查
## 审查范围
### 1. 代码规范
- ESLint 规则合规性
- Prettier 格式
- 命名规范
- 文件组织
### 2. React 特定检查
- Hooks 使用规范
- 不要在循环、条件中调用 Hooks
- 依赖数组完整性
- useEffect 清理函数
- 组件设计
- 单一职责原则
- Props 类型定义
- 默认 Props
- 性能优化
- useMemo/useCallback 使用
- 不必要的重渲染
- 代码分割
### 3. Vue 特定检查
- Composition API 使用
- Props/Emits 类型定义
- 生命周期使用
- 响应式数据
### 4. 样式检查
- CSS-in-JS 规范
- 样式隔离
- 响应式设计
- 浏览器兼容性
### 5. 可访问性 (a11y)
- 语义化 HTML
- ARIA 属性
- 键盘导航
- 屏幕阅读器支持
### 6. 安全检查
- XSS 防护
- 不安全的 innerHTML
- 敏感信息泄露
## 输出格式
```markdown
## 代码审查报告
### 概览
- 审查文件:{{file_count}} 个
- 问题总数:{{issue_count}} 个
- 严重:{{critical_count}} 个
- 警告:{{warning_count}} 个
- 建议:{{suggestion_count}} 个
### 详细问题
#### 1. [严重] src/components/UserForm.tsx:45
**问题**:useEffect 缺少依赖项
**代码**:
useEffect(() => {
fetchUser(userId);
}, []); // ❌ userId 未在依赖数组中
**修复**:
useEffect(() => {
fetchUser(userId);
}, [userId]);
#### 2. [警告] src/utils/api.ts:12
**问题**:缺少错误处理 ...
### 建议改进
1. ...
2. ...
## 使用示例
> /skill use frontend-code-review path=src/components/
2.8.2 案例二:API 设计审查 Skill
yaml
---
name: api-design-review
description: RESTful API 设计审查,包括规范、安全性、性能
tags:
- backend
- api
- rest
---
# API 设计审查
## 审查清单
### 1. RESTful 规范
- [ ] URL 设计是否符合资源导向
- [ ] HTTP 方法使用是否正确
- [ ] 状态码返回是否恰当
- [ ] 版本控制策略
### 2. 请求/响应设计
- [ ] 请求参数校验
- [ ] 响应格式统一
- [ ] 错误信息规范
- [ ] 分页设计
### 3. 安全性
- [ ] 认证机制
- [ ] 权限控制
- [ ] 输入验证
- [ ] 防注入
- [ ] 敏感数据保护
### 4. 性能
- [ ] 响应时间
- [ ] 缓存策略
- [ ] 并发处理
- [ ] 数据库查询优化
### 5. 文档
- [ ] OpenAPI/Swagger 文档
- [ ] 示例请求/响应
- [ ] 错误码说明
## 示例审查
**待审查 API**:
GET /api/getUserData?id=123
**问题**:
1. URL 不符合 RESTful 规范(动词 getUserData)
2. 使用 query 参数传递 ID(应该是路径参数)
3. 缺少版本号
**建议**:
GET /api/v1/users/123
2.8.3 案例三:数据库迁移 Skill
yaml
---
name: database-migration
description: 安全的数据库迁移流程,包括备份、迁移、验证、回滚
tags:
- database
- migration
- devops
---
# 数据库迁移
## 流程
### 1. 迁移前检查
- [ ] 确认迁移脚本已测试
- [ ] 检查数据库连接
- [ ] 验证磁盘空间
- [ ] 通知相关人员
### 2. 备份
# 创建备份
mysqldump -u root -p database_name > backup_$(date +%Y%m%d_%H%M%S).sql
# 验证备份
mysql -u root -p -e "source backup_xxx.sql" test_db
### 3. 执行迁移
# 使用迁移工具
npx prisma migrate deploy
# 或
npm run migration:up
### 4. 验证
- [ ] 检查表结构
- [ ] 验证数据完整性
- [ ] 运行关键查询
- [ ] 检查应用日志
### 5. 回滚准备
如果失败,执行:
# 方式1:使用迁移工具回滚
npx prisma migrate rollback
# 方式2:从备份恢复
mysql -u root -p database_name < backup_xxx.sql
## 迁移脚本模板
-- 迁移:添加用户表
-- 作者:张三
-- 日期:2026-01-15
-- 开始事务
BEGIN;
-- 检查表是否存在
DROP TABLE IF EXISTS users;
-- 创建表
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- 创建索引
CREATE INDEX idx_users_email ON users(email);
-- 验证
SELECT COUNT(*) FROM users;
-- 提交事务
COMMIT;
底层原理剖析
2.9.1 Skills 加载机制
发现阶段:
javascript
// 伪代码
function discoverSkills(startPath) {
const skills = [];
let currentPath = startPath;
while (currentPath !== root) {
// 检查项目级 Skills
if (exists(join(currentPath, '.opencode/skills'))) {
skills.push(...loadSkillsFromDir(join(currentPath, '.opencode/skills')));
}
// 检查兼容的 Claude Skills
if (exists(join(currentPath, '.claude/skills'))) {
skills.push(...loadSkillsFromDir(join(currentPath, '.claude/skills')));
}
currentPath = parent(currentPath);
}
// 加载全局 Skills
skills.push(...loadSkillsFromDir('~/.config/opencode/skills'));
return skills;
}
**解析阶段**:
```javascript
function parseSkill(skillPath) {
const content = readFile(skillPath + '/SKILL.md');
// 解析 YAML frontmatter
const { frontmatter, body } = parseFrontmatter(content);
// 验证必填字段
validateRequiredFields(frontmatter, ['name', 'description']);
// 解析 Markdown
const ast = parseMarkdown(body);
return {
meta: frontmatter,
content: body,
ast: ast,
path: skillPath,
};
}
注入阶段:
javascript
function injectSkillToContext(skill, context) {
// 将 Skill 信息添加到 AI 上下文
context.availableSkills.push({
name: skill.meta.name,
description: skill.meta.description,
});
// 如果 Skill 定义了工具,注册工具
if (skill.tools) {
for (const tool of skill.tools) {
context.registerTool(tool);
}
}
}
2.9.2 技能匹配算法
关键词匹配:
javascript
function matchSkill(userInput, skills) {
const scores = skills.map((skill) => {
let score = 0;
// 名称匹配
if (userInput.includes(skill.meta.name)) {
score += 10;
}
// 描述匹配
const descriptionWords = skill.meta.description.toLowerCase().split(' ');
const inputWords = userInput.toLowerCase().split(' ');
const commonWords = intersection(descriptionWords, inputWords);
score += commonWords.length * 2;
// 标签匹配
if (skill.meta.tags) {
for (const tag of skill.meta.tags) {
if (userInput.includes(tag)) {
score += 5;
}
}
}
return { skill, score };
});
// 按分数排序
scores.sort((a, b) => b.score - a.score);
// 返回分数最高的
return scores[0]?.score > threshold ? scores[0].skill : null;
}
上下文感知:
javascript
function contextualMatch(userInput, skills, context) {
// 根据当前上下文调整匹配权重
const currentFile = context.currentFile;
const projectType = detectProjectType(context.projectRoot);
return skills.map((skill) => {
let score = baseMatchScore(userInput, skill);
// 文件类型匹配
if (skill.fileTypes && skill.fileTypes.includes(currentFile.extension)) {
score += 3;
}
// 项目类型匹配
if (skill.projectTypes && skill.projectTypes.includes(projectType)) {
score += 5;
}
return { skill, score };
});
}
2.9.3 技能执行流程
css
[用户输入]
↓
[意图识别] ← 使用 LLM 分析用户意图
↓
[技能匹配] ← 根据意图匹配 Skills
↓
[技能加载] ← 读取 SKILL.md 内容
↓
[参数提取] ← 从输入中提取参数
↓
[提示词构建] ← 构建执行提示词
↓
[LLM 执行] ← AI 执行 Skill 指令
↓
[结果输出] ← 返回执行结果
2.9.4 提示词工程
系统提示词片段:
markdown
你是一名专业的软件开发助手。你可以使用以下 Skills 来帮助用户:
<available_skills>
{{#each skills}}
<skill>
<name>{{this.name}}</name>
<description>{{this.description}}</description>
</skill>
{{/each}}
</available_skills>
当用户需要执行特定任务时,你可以选择最合适的 Skill 来帮助他们。
使用 Skill 的方式:
1. 分析用户需求
2. 匹配最合适的 Skill
3. 调用 skill({ name: "skill-name" }) 加载 Skill
4. 根据 Skill 的指引执行任务
5. 报告执行结果
约束:
- 只在用户需要时使用 Skill
- 不要主动推荐不相关的 Skill
- 执行过程中可以询问用户确认
任务提示词构建:
javascript
function buildSkillPrompt(skill, userInput, context) {
return `
# 当前任务
用户输入:${userInput}
当前上下文:
- 项目类型:${context.projectType}
- 当前文件:${context.currentFile}
- 相关文件:${context.relatedFiles.join(', ')}
# 使用的 Skill
名称:${skill.meta.name}
描述:${skill.meta.description}
## Skill 内容
${skill.content}
# 执行要求
请根据上述 Skill 的指引,帮助用户完成任务。
如果需要更多信息,可以向用户提问。
`;
}
常见问题与解决方案
2.10.1 Skill 不生效
问题:创建了 Skill,但 OpenCode 没发现。
检查清单:
-
路径是否正确
- 必须在
.opencode/skills/<name>/或.claude/skills/<name>/ - 文件名必须是
SKILL.md(全大写)
- 必须在
-
YAML 格式是否正确
- 必须用
---包裹 name和description必须存在- 缩进必须用空格,不能用 Tab
- 必须用
-
名字是否符合规范
- 只能用小写字母、数字和连字符
- 必须和文件夹名完全一致
-
是否重新加载
- 重启 OpenCode
- 或执行
/skill reload
2.10.2 Skill 匹配错误
问题:OpenCode 总是匹配到错误的 Skill。
解决方案:
-
优化 description
- 使用更具体、独特的描述
- 包含关键词
-
使用显式调用
/skill use skill-name
-
调整标签
- 添加更多标签帮助匹配
-
上下文感知
- 在 Skill 中指定
fileTypes或projectTypes
- 在 Skill 中指定
2.10.3 Skill 执行失败
问题:Skill 匹配成功,但执行时报错。
排查步骤:
- 检查 YAML 语法
- 检查 Markdown 格式
- 查看 OpenCode 日志
- 简化 Skill 内容,逐步测试
- 检查依赖的 Skills 是否存在
2.10.4 性能问题
问题:使用 Skill 后,响应变慢。
优化建议:
-
减少上下文大小
- 限制加载的文件数量
- 使用文件摘要而非完整内容
-
使用缓存
- 缓存不变的数据
- 设置合理的缓存时间
-
延迟加载
- 只在需要时加载大型资源
- 使用
lazy: true标记
-
优化提示词
- 减少不必要的说明
- 使用更简洁的语言
总结与下一步
本章要点
- Skills 是什么:可复用的指令模板,把经验变成工具
- 如何创建:编写 SKILL.md 文件,放到指定目录
- 高级技巧:条件技能、组合技能、交互式技能、模板技能
- 调试优化:本地测试、性能优化、错误处理
- 团队协作:共享 Skills、版本管理
- 底层原理:发现机制、匹配算法、执行流程
学习路径
初级:
- 理解 Skills 概念
- 创建简单的 Skill
- 在团队内共享
中级:
- 掌握高级技巧
- 优化 Skill 性能
- 处理复杂场景
高级:
- 开发 Skill 框架
- 贡献开源社区
- 设计 Skill 生态
下一步
学完 Skills 系统后,建议继续学习:
- 第三章:MCP 集成 - 让 AI 能使用外部工具
- 第五章:最佳实践 - 掌握使用技巧
文档信息
- 字数:约 8,000 字
- 适用版本:OpenCode 0.1.40+
相关资源
(第二章完)