OpenCode 进阶使用指南(第二章:Skills 系统)

75 阅读22分钟

本文档是《OpenCode 进阶使用指南》的第二章专注于 Skills 技能系统的深入讲解,预计阅读时间:30-40 分钟


目录

  1. 什么是 Skills 系统
  2. Skills 的核心概念
  3. 创建你的第一个 Skill
  4. SKILL.md 文件详解
  5. 高级技能编写技巧
  6. 技能调试与优化
  7. 团队协作与技能共享
  8. 实战案例集
  9. 底层原理剖析
  10. 常见问题与解决方案

什么是 Skills 系统

2.1.1 从重复劳动说起

想象一个场景:你刚入职一家新公司,发现团队的代码审查流程非常规范——每次提交都要检查代码风格、潜在 bug、性能问题、安全漏洞。这些检查点有十几条,每次审查都要一条条过。

刚开始你觉得这个流程很好,能保证代码质量。但几周后,你开始觉得烦了。每次审查都要重复同样的检查项,写同样的评论格式,提同样的修改建议。

你会想:"如果能把这个流程自动化就好了。"

Skills 系统就是来解决这个问题的。

2.1.2 Skills 的本质

Skills 是一套可复用的指令模板。

当你发现自己在重复做某类任务时,你可以:

  1. 把这类任务的步骤、标准、注意事项整理出来
  2. 写成 SKILL.md 文件
  3. 放到特定目录
  4. 以后让 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/ 的目录。

搜索顺序:

当前工作目录/.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 会加载:

  1. packages/frontend/.opencode/skills/ - 前端专属
  2. my-project/.opencode/skills/ - 项目级
  3. ~/.config/opencode/skills/ - 全局

这样设计的好处:子项目可以覆盖或扩展父项目的 Skills。

2.2.2 技能加载过程

当一个 Skill 被发现后,OpenCode 会:

  1. 读取 SKILL.md:解析 YAML frontmatter 和 Markdown 内容
  2. 验证格式:检查必填字段、格式规范
  3. 解析依赖:如果有依赖其他 Skills,先加载依赖
  4. 注入上下文:将 Skill 信息注入到 AI 的上下文中
  5. 注册工具:如果 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:

> /skill use code-review
> 开始审查 src/components/Button.tsx

自动推荐

OpenCode 会分析当前上下文,主动推荐可能相关的 Skills:

看起来你正在写 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:创建目录结构

mkdir -p .opencode/skills/conventional-commit
cd .opencode/skills/conventional-commit

Step 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 开头,放在 --- 之间。

必需字段

字段类型说明示例
namestring技能名称,必须唯一,只能用小写字母、数字和连字符code-review
descriptionstring技能描述,用于匹配和展示自动进行代码审查

可选字段

字段类型说明示例
versionstring版本号,遵循 semver1.2.3
authorstring作者信息张三 <zhangsan@example.com>
licensestring许可证MIT
tagsarray标签,用于分类和搜索["testing", "automation"]
compatibilitystring兼容性标识opencode>=0.1.40
dependenciesarray依赖的其他 Skills["base-coding", "testing-utils"]
metadataobject自定义元数据{ "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
- 链接 2

2.4.3 特殊语法

变量替换

可以在 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()      |

高级技能编写技巧

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 dev

2.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 模式查看每一步的执行:

> /agent config mode step_by_step
> /skill use your-skill

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

可能原因:

  1. 文件不存在
  2. 权限不足
  3. 文件被占用

解决方案:

  1. 检查文件是否存在:ls src/
  2. 检查权限:ls -la src/config.ts
  3. 手动创建文件(提供模板)

重试机制

## 网络操作重试

对于网络请求(如 API 调用):

- 失败时自动重试 3 次
- 每次重试间隔 1 秒
- 如果都失败,报错并退出

2.6.4 版本管理

语义化版本

遵循 semver 规范:

  • MAJOR(主版本):不兼容的修改
  • MINOR(次版本):新增功能,向后兼容
  • PATCH(修订):Bug 修复,向后兼容

示例

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

2.7.3 Skills 市场(未来规划)

虽然目前 OpenCode 还没有官方的 Skills 市场,但可以预见未来的发展方向:

社区共享

  • 类似 npm 的 Skills 仓库
  • 版本管理和依赖解析
  • 评分和评论系统

企业内部市场

  • 私有 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/123

2.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;
}

解析阶段

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 没发现。

检查清单

  1. 路径是否正确

    • 必须在 .opencode/skills/<name>/.claude/skills/<name>/
    • 文件名必须是 SKILL.md(全大写)
  2. YAML 格式是否正确

    • 必须用 --- 包裹
    • namedescription 必须存在
    • 缩进必须用空格,不能用 Tab
  3. 名字是否符合规范

    • 只能用小写字母、数字和连字符
    • 必须和文件夹名完全一致
  4. 是否重新加载

    • 重启 OpenCode
    • 或执行 /skill reload

2.10.2 Skill 匹配错误

问题:OpenCode 总是匹配到错误的 Skill。

解决方案

  1. 优化 description

    • 使用更具体、独特的描述
    • 包含关键词
  2. 使用显式调用

    • /skill use skill-name
  3. 调整标签

    • 添加更多标签帮助匹配
  4. 上下文感知

    • 在 Skill 中指定 fileTypesprojectTypes

2.10.3 Skill 执行失败

问题:Skill 匹配成功,但执行时报错。

排查步骤

  1. 检查 YAML 语法
  2. 检查 Markdown 格式
  3. 查看 OpenCode 日志
  4. 简化 Skill 内容,逐步测试
  5. 检查依赖的 Skills 是否存在

2.10.4 性能问题

问题:使用 Skill 后,响应变慢。

优化建议

  1. 减少上下文大小

    • 限制加载的文件数量
    • 使用文件摘要而非完整内容
  2. 使用缓存

    • 缓存不变的数据
    • 设置合理的缓存时间
  3. 延迟加载

    • 只在需要时加载大型资源
    • 使用 lazy: true 标记
  4. 优化提示词

    • 减少不必要的说明
    • 使用更简洁的语言

总结与下一步

本章要点

  1. Skills 是什么:可复用的指令模板,把经验变成工具
  2. 如何创建:编写 SKILL.md 文件,放到指定目录
  3. 高级技巧:条件技能、组合技能、交互式技能、模板技能
  4. 调试优化:本地测试、性能优化、错误处理
  5. 团队协作:共享 Skills、版本管理
  6. 底层原理:发现机制、匹配算法、执行流程

学习路径

初级

  • 理解 Skills 概念
  • 创建简单的 Skill
  • 在团队内共享

中级

  • 掌握高级技巧
  • 优化 Skill 性能
  • 处理复杂场景

高级

  • 开发 Skill 框架
  • 贡献开源社区
  • 设计 Skill 生态

下一步

学完 Skills 系统后,建议继续学习:

  • 第三章:MCP 集成 - 让 AI 能使用外部工具
  • 第五章:最佳实践 - 掌握使用技巧

文档信息

  • 字数:约 8,000 字
  • 适用版本:OpenCode 0.1.40+

相关资源

(第二章完)