摘要:本文档是《OpenCode 进阶使用指南》的第二章专注于 Skills 技能系统的深入讲解,预计阅读时间:30-40 分钟
目录
什么是 Skills 系统 Skills 的核心概念 创建你的第一个 Skill SKILL.Skills 系统就像你给程序员一本《代码重构手册》,告诉他:"以后重构都按这个手册来"。 检查表是否存在 DROP TABLE IF EXISTS users;
-- 创建表 CREATE TABLE users ( id BIGINT PRIMARY KEY AUTO_
本文档是《OpenCode 进阶使用指南》的第二章专注于 Skills 技能系统的深入讲解,预计阅读时间:30-40 分钟
想象一个场景:你刚入职一家新公司,发现团队的代码审查流程非常规范——每次提交都要检查代码风格、潜在 bug、性能问题、安全漏洞。这些检查点有十几条,每次审查都要一条条过。
刚开始你觉得这个流程很好,能保证代码质量。但几周后,你开始觉得烦了。每次审查都要重复同样的检查项,写同样的评论格式,提同样的修改建议。
你会想:"如果能把这个流程自动化就好了。"
Skills 系统就是来解决这个问题的。
Skills 是一套可复用的指令模板。
当你发现自己在重复做某类任务时,你可以:
简单来说,Skills 就是把"你的经验"变成"AI 的能力"。
很多人问:"Skills 和 Agent 模式有什么区别?"
举例说明:
Agent 模式就像你让一个程序员"去重构代码"。他会自己思考怎么做。
Skills 系统就像你给程序员一本《代码重构手册》,告诉他:"以后重构都按这个手册来"。
两者可以结合使用:用 Skills 定义流程,用 Agent 模式执行流程。
代码质量类:
开发流程类:
团队协作类:
领域专业类:
OpenCode 是如何找到 Skills 的?这涉及到一个"发现机制"。
搜索路径:
当你启动 OpenCode 时,它会从当前目录开始,向上查找所有包含 .opencode/skills/ 或 .claude/skills/ 的目录。
.opencode/skills/
.claude/skills/
搜索顺序:
当前工作目录/.opencode/skills/ 当前工作目录/.claude/skills/ 父目录/.opencode/skills/ 父目录/.claude/skills/ ... 直到 git 仓库根目录 ~ ~/.config/opencode/skills/ (全局) ~/.claude/skills/ (全局兼容)
为什么要向上查找?
考虑一个 monorepo 项目结构:
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/
packages/frontend/.opencode/skills/
my-project/.opencode/skills/
~/.config/opencode/skills/
这样设计的好处:子项目可以覆盖或扩展父项目的 Skills。
当一个 Skill 被发现后,OpenCode 会:
加载时机:
/skill reload
OpenCode 怎么知道什么时候该用哪个 Skill?
关键词匹配:
Skill 的 description 字段包含关键词,AI 会根据用户输入匹配最合适的 Skill。
例如:
显式调用:
用户可以直接指定使用某个 Skill:
> /skill use code-review > 开始审查 src/components/Button.tsx
自动推荐:
OpenCode 会分析当前上下文,主动推荐可能相关的 Skills:
看起来你正在写 React 组件。 可用的 Skills: 1. react-component - React 组件开发规范 2. code-review - 代码审查检查清单 3. testing - 测试用例生成 要使用哪个?(输入编号或名称)
一个 Skill 从创建到使用,经历以下阶段:
1. 开发阶段:
2. 发布阶段:
3. 分发阶段:
4. 使用阶段:
5. 维护阶段:
环境要求:
选择技能类型:
第一次创建 Skill,建议从简单的开始。比如:
场景:团队要求所有提交信息都要遵循 Conventional Commits 规范,但新人总是记不住格式。
目标:创建一个 Skill,帮助生成符合规范的提交信息。
Step 1:创建目录结构
mkdir -p .opencode/skills/conventional-commit cd .opencode/skills/conventional-commit
Step 2:编写 SKILL.md
创建文件 SKILL.md:
SKILL.md
--- 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 中测试:
> /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"
上面的 Skill 还需要用户手动描述修改内容。我们可以让它更智能——自动分析修改的文件。
更新 SKILL.md:
--- 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" 请确认或修改:
创建好 Skill 后,记得提交到 Git:
git add .opencode/skills/conventional-commit/ git commit -m "feat(devtools): 添加 Conventional Commit 助手 Skill - 自动生成符合规范的提交信息 - 支持智能分析修改内容 - 提供多种选项供选择" git push
团队成员拉取代码后就能使用这个 Skill 了。
SKILL.md 文件以 YAML frontmatter 开头,放在 --- 之间。
---
必需字段:
code-review
自动进行代码审查
可选字段:
1.2.3
张三 <zhangsan@example.com>
MIT
["testing", "automation"]
opencode>=0.1.40
["base-coding", "testing-utils"]
{ "team": "frontend", "priority": "high" }
完整示例:
--- 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 ---
YAML frontmatter 之后是 Markdown 内容,用来详细说明技能的使用方法。
推荐结构:
# 技能标题 ## 什么时候用 描述使用场景和触发条件。 ## 前置条件 列出使用这个技能前需要满足的条件。 ## 输入参数 如果技能需要参数,说明参数格式和示例。 ## 使用步骤 详细说明执行步骤,可以包含: 1. 第一步做什么 2. 第二步做什么 3. ... ## 检查清单 列出需要检查的项目,用复选框表示。 ## 示例 提供具体的使用示例。 ### 示例 1:场景 A 详细说明... ### 示例 2:场景 B 详细说明... ## 输出格式 说明执行结果的格式。 ## 注意事项 列出常见问题和注意事项。 ## 相关资源 - 链接 1 - 链接 2
变量替换:
可以在 Skill 中使用变量,这些变量会在执行时被替换:
## 使用步骤 1. 读取文件 {{file_path}} 2. 检查 {{check_item}} 3. 输出结果到 {{output_path}}
使用时:
> /skill use code-review file_path=src/App.tsx check_item=performance
条件逻辑:
可以使用条件注释:
<!-- if: framework == "react" --> ## React 特定检查 - 检查 hooks 规则 - 检查 JSX 语法 <!-- endif --> <!-- if: framework == "vue" --> ## Vue 特定检查 - 检查模板语法 - 检查生命周期使用 <!-- endif -->
代码块:
使用代码块展示示例代码:
// 示例代码 function example() { return "Hello"; }
表格:
使用表格展示对照信息:
| 情况 | 处理方式 | 示例 | | ---- | ---------- | ----------- | | 正常 | 直接通过 | - | | 警告 | 提示但允许 | console.log | | 错误 | 必须修复 | eval() |
根据不同的条件执行不同的逻辑。
示例:根据项目类型使用不同的检查规则
--- 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 -->
一个 Skill 可以调用其他 Skills。
示例:完整的代码提交流程
--- 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 ## 失败处理 如果某一步失败: - 停止后续步骤 - 报告失败原因 - 提供修复建议
让 Skill 支持交互式输入。
示例:交互式项目初始化
--- 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
使用模板引擎生成代码。
示例:组件生成器
--- 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):
templates/FunctionalComponent.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}};
本地测试:
在提交 Skill 前,先在本地测试:
# 创建测试目录 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 中添加调试信息:
## 调试模式 如果设置环境变量 `DEBUG_SKILL=true`,输出详细的执行日志。 DEBUG_SKILL=true opencode --agent
逐步执行:
使用 step_by_step 模式查看每一步的执行:
step_by_step
> /agent config mode step_by_step > /skill use your-skill
减少上下文大小:
--- 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` 启用上下文压缩
缓存机制:
对于重复使用的数据,可以缓存:
## 缓存配置 缓存以下数据以提高性能: - 项目结构(5 分钟) - 依赖列表(1 小时) - 检查规则(24 小时)
优雅降级:
## 错误处理 如果某一步失败: 1. 尝试备用方案 2. 如果备用方案也失败,报告错误 3. 提供手动操作指南 ### 示例:文件读取失败
错误:无法读取 src/config.ts
可能原因:
解决方案:
重试机制:
## 网络操作重试 对于网络请求(如 API 调用): - 失败时自动重试 3 次 - 每次重试间隔 1 秒 - 如果都失败,报错并退出
语义化版本:
遵循 semver 规范:
示例:
1.0.0 - 初始版本 1.1.0 - 添加自动分析功能 1.1.1 - 修复 scope 检测 bug 2.0.0 - 重构 API,不兼容 1.x
变更日志:
维护 CHANGELOG.md:
# Changelog ## [2.0.0] - 2026-01-15 ### 重大变更 - 重构 API,使用新的配置格式 - 不再支持 OpenCode < 0.1.40 ### 新功能 - 支持 Vue 项目 - 添加自定义规则 ### 修复 - 修复了 Windows 路径问题
集中管理:
创建一个专门的仓库管理团队 Skills:
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):
scripts/install.sh
#!/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/"
与项目代码一起管理:
将项目特定的 Skills 放在项目仓库中:
my-project/ ├── .opencode/ │ └── skills/ │ ├── domain-specific/ # 领域特定 │ ├── framework-specific/ # 框架特定 │ └── team-conventions/ # 团队约定 ├── src/ ├── package.json └── README.md
Git 子模块(可选):
如果多个项目共享同一套 Skills,可以使用 Git 子模块:
# 添加 Skills 子模块 git submodule add https://github.com/yourcompany/opencode-skills.git .opencode/skills # 克隆项目时递归克隆子模块 git clone --recursive https://github.com/yourcompany/my-project.git
虽然目前 OpenCode 还没有官方的 Skills 市场,但可以预见未来的发展方向:
社区共享:
企业内部市场:
--- 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/
--- 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
--- 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;
发现阶段:
// 伪代码 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, }; }
注入阶段:
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); } } }
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; }
上下文感知:
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 }; }); }
[用户输入] ↓ [意图识别] ← 使用 LLM 分析用户意图 ↓ [技能匹配] ← 根据意图匹配 Skills ↓ [技能加载] ← 读取 SKILL.md 内容 ↓ [参数提取] ← 从输入中提取参数 ↓ [提示词构建] ← 构建执行提示词 ↓ [LLM 执行] ← AI 执行 Skill 指令 ↓ [结果输出] ← 返回执行结果
系统提示词片段:
你是一名专业的软件开发助手。你可以使用以下 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 - 执行过程中可以询问用户确认
任务提示词构建:
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 的指引,帮助用户完成任务。 如果需要更多信息,可以向用户提问。 `; }
问题:创建了 Skill,但 OpenCode 没发现。
检查清单:
路径是否正确
.opencode/skills/<name>/
.claude/skills/<name>/
YAML 格式是否正确
name
description
名字是否符合规范
是否重新加载
问题:OpenCode 总是匹配到错误的 Skill。
优化 description
使用显式调用
/skill use skill-name
调整标签
上下文感知
fileTypes
projectTypes
问题:Skill 匹配成功,但执行时报错。
排查步骤:
问题:使用 Skill 后,响应变慢。
优化建议:
减少上下文大小
使用缓存
延迟加载
lazy: true
优化提示词
初级:
中级:
高级:
学完 Skills 系统后,建议继续学习:
文档信息
相关资源
(第二章完)
暂无回复,快来抢沙发吧!
目录
什么是 Skills 系统 Skills 的核心概念 创建你的第一个 Skill SKILL.Skills 系统就像你给程序员一本《代码重构手册》,告诉他:"以后重构都按这个手册来"。 检查表是否存在 DROP TABLE IF EXISTS users;
-- 创建表 CREATE TABLE users ( id BIGINT PRIMARY KEY AUTO_
目录
什么是 Skills 系统
2.1.1 从重复劳动说起
想象一个场景:你刚入职一家新公司,发现团队的代码审查流程非常规范——每次提交都要检查代码风格、潜在 bug、性能问题、安全漏洞。这些检查点有十几条,每次审查都要一条条过。
刚开始你觉得这个流程很好,能保证代码质量。但几周后,你开始觉得烦了。每次审查都要重复同样的检查项,写同样的评论格式,提同样的修改建议。
你会想:"如果能把这个流程自动化就好了。"
Skills 系统就是来解决这个问题的。
2.1.2 Skills 的本质
Skills 是一套可复用的指令模板。
当你发现自己在重复做某类任务时,你可以:
简单来说,Skills 就是把"你的经验"变成"AI 的能力"。
2.1.3 Skills vs Agent 模式的区别
很多人问:"Skills 和 Agent 模式有什么区别?"
举例说明:
Agent 模式就像你让一个程序员"去重构代码"。他会自己思考怎么做。
Skills 系统就像你给程序员一本《代码重构手册》,告诉他:"以后重构都按这个手册来"。
两者可以结合使用:用 Skills 定义流程,用 Agent 模式执行流程。
2.1.4 Skills 能做什么
代码质量类:
开发流程类:
团队协作类:
领域专业类:
Skills 的核心概念
2.2.1 技能发现机制
OpenCode 是如何找到 Skills 的?这涉及到一个"发现机制"。
搜索路径:
当你启动 OpenCode 时,它会从当前目录开始,向上查找所有包含
.opencode/skills/或.claude/skills/的目录。搜索顺序:
为什么要向上查找?
考虑一个 monorepo 项目结构:
如果你在
packages/frontend/目录下工作,OpenCode 会加载:packages/frontend/.opencode/skills/- 前端专属my-project/.opencode/skills/- 项目级~/.config/opencode/skills/- 全局这样设计的好处:子项目可以覆盖或扩展父项目的 Skills。
2.2.2 技能加载过程
当一个 Skill 被发现后,OpenCode 会:
加载时机:
/skill reload)2.2.3 技能匹配机制
OpenCode 怎么知道什么时候该用哪个 Skill?
关键词匹配:
Skill 的 description 字段包含关键词,AI 会根据用户输入匹配最合适的 Skill。
例如:
显式调用:
用户可以直接指定使用某个 Skill:
自动推荐:
OpenCode 会分析当前上下文,主动推荐可能相关的 Skills:
看起来你正在写 React 组件。 可用的 Skills: 1. react-component - React 组件开发规范 2. code-review - 代码审查检查清单 3. testing - 测试用例生成 要使用哪个?(输入编号或名称)2.2.4 技能生命周期
一个 Skill 从创建到使用,经历以下阶段:
1. 开发阶段:
2. 发布阶段:
3. 分发阶段:
4. 使用阶段:
5. 维护阶段:
创建你的第一个 Skill
2.3.1 准备工作
环境要求:
选择技能类型:
第一次创建 Skill,建议从简单的开始。比如:
2.3.2 实战:创建一个代码提交规范 Skill
场景:团队要求所有提交信息都要遵循 Conventional Commits 规范,但新人总是记不住格式。
目标:创建一个 Skill,帮助生成符合规范的提交信息。
Step 1:创建目录结构
mkdir -p .opencode/skills/conventional-commit cd .opencode/skills/conventional-commitStep 2:编写 SKILL.md
创建文件
SKILL.md:--- 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 中测试:
> /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:--- 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:
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 开头,放在
---之间。必需字段:
code-review自动进行代码审查可选字段:
1.2.3张三 <zhangsan@example.com>MIT["testing", "automation"]opencode>=0.1.40["base-coding", "testing-utils"]{ "team": "frontend", "priority": "high" }完整示例:
--- 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 内容,用来详细说明技能的使用方法。
推荐结构:
# 技能标题 ## 什么时候用 描述使用场景和触发条件。 ## 前置条件 列出使用这个技能前需要满足的条件。 ## 输入参数 如果技能需要参数,说明参数格式和示例。 ## 使用步骤 详细说明执行步骤,可以包含: 1. 第一步做什么 2. 第二步做什么 3. ... ## 检查清单 列出需要检查的项目,用复选框表示。 ## 示例 提供具体的使用示例。 ### 示例 1:场景 A 详细说明... ### 示例 2:场景 B 详细说明... ## 输出格式 说明执行结果的格式。 ## 注意事项 列出常见问题和注意事项。 ## 相关资源 - 链接 1 - 链接 22.4.3 特殊语法
变量替换:
可以在 Skill 中使用变量,这些变量会在执行时被替换:
## 使用步骤 1. 读取文件 {{file_path}} 2. 检查 {{check_item}} 3. 输出结果到 {{output_path}}使用时:
条件逻辑:
可以使用条件注释:
<!-- if: framework == "react" --> ## React 特定检查 - 检查 hooks 规则 - 检查 JSX 语法 <!-- endif --> <!-- if: framework == "vue" --> ## Vue 特定检查 - 检查模板语法 - 检查生命周期使用 <!-- endif -->代码块:
使用代码块展示示例代码:
// 示例代码 function example() { return "Hello"; }表格:
使用表格展示对照信息:
高级技能编写技巧
2.5.1 条件技能
根据不同的条件执行不同的逻辑。
示例:根据项目类型使用不同的检查规则
--- 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。
示例:完整的代码提交流程
--- 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 支持交互式输入。
示例:交互式项目初始化
--- 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 dev2.5.4 模板技能
使用模板引擎生成代码。
示例:组件生成器
--- 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):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 前,先在本地测试:
# 创建测试目录 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 中添加调试信息:
## 调试模式 如果设置环境变量 `DEBUG_SKILL=true`,输出详细的执行日志。 DEBUG_SKILL=true opencode --agent逐步执行:
使用
step_by_step模式查看每一步的执行:2.6.2 性能优化
减少上下文大小:
--- 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` 启用上下文压缩缓存机制:
对于重复使用的数据,可以缓存:
## 缓存配置 缓存以下数据以提高性能: - 项目结构(5 分钟) - 依赖列表(1 小时) - 检查规则(24 小时)2.6.3 错误处理
优雅降级:
## 错误处理 如果某一步失败: 1. 尝试备用方案 2. 如果备用方案也失败,报告错误 3. 提供手动操作指南 ### 示例:文件读取失败错误:无法读取 src/config.ts
可能原因:
解决方案:
重试机制:
## 网络操作重试 对于网络请求(如 API 调用): - 失败时自动重试 3 次 - 每次重试间隔 1 秒 - 如果都失败,报错并退出2.6.4 版本管理
语义化版本:
遵循 semver 规范:
示例:
1.0.0 - 初始版本 1.1.0 - 添加自动分析功能 1.1.1 - 修复 scope 检测 bug 2.0.0 - 重构 API,不兼容 1.x变更日志:
维护 CHANGELOG.md:
# Changelog ## [2.0.0] - 2026-01-15 ### 重大变更 - 重构 API,使用新的配置格式 - 不再支持 OpenCode < 0.1.40 ### 新功能 - 支持 Vue 项目 - 添加自定义规则 ### 修复 - 修复了 Windows 路径问题团队协作与技能共享
2.7.1 团队 Skills 仓库
集中管理:
创建一个专门的仓库管理团队 Skills:
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):#!/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 放在项目仓库中:
my-project/ ├── .opencode/ │ └── skills/ │ ├── domain-specific/ # 领域特定 │ ├── framework-specific/ # 框架特定 │ └── team-conventions/ # 团队约定 ├── src/ ├── package.json └── README.mdGit 子模块(可选):
如果多个项目共享同一套 Skills,可以使用 Git 子模块:
# 添加 Skills 子模块 git submodule add https://github.com/yourcompany/opencode-skills.git .opencode/skills # 克隆项目时递归克隆子模块 git clone --recursive https://github.com/yourcompany/my-project.git2.7.3 Skills 市场(未来规划)
虽然目前 OpenCode 还没有官方的 Skills 市场,但可以预见未来的发展方向:
社区共享:
企业内部市场:
实战案例集
2.8.1 案例一:前端代码审查 Skill
--- 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
--- 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/1232.8.3 案例三:数据库迁移 Skill
--- 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 加载机制
发现阶段:
// 伪代码 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, }; }注入阶段:
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 技能匹配算法
关键词匹配:
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; }上下文感知:
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 技能执行流程
[用户输入] ↓ [意图识别] ← 使用 LLM 分析用户意图 ↓ [技能匹配] ← 根据意图匹配 Skills ↓ [技能加载] ← 读取 SKILL.md 内容 ↓ [参数提取] ← 从输入中提取参数 ↓ [提示词构建] ← 构建执行提示词 ↓ [LLM 执行] ← AI 执行 Skill 指令 ↓ [结果输出] ← 返回执行结果2.9.4 提示词工程
系统提示词片段:
你是一名专业的软件开发助手。你可以使用以下 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 - 执行过程中可以询问用户确认任务提示词构建:
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必须存在名字是否符合规范
是否重新加载
/skill reload2.10.2 Skill 匹配错误
问题:OpenCode 总是匹配到错误的 Skill。
解决方案:
优化 description
使用显式调用
/skill use skill-name调整标签
上下文感知
fileTypes或projectTypes2.10.3 Skill 执行失败
问题:Skill 匹配成功,但执行时报错。
排查步骤:
2.10.4 性能问题
问题:使用 Skill 后,响应变慢。
优化建议:
减少上下文大小
使用缓存
延迟加载
lazy: true标记优化提示词
总结与下一步
本章要点
学习路径
初级:
中级:
高级:
下一步
学完 Skills 系统后,建议继续学习:
文档信息
相关资源
(第二章完)