文章目录
- OpenCode支持主流系统: macOS 10.15+ (Intel和Apple Silicon都行) Windows 10/11 Linux (Ubuntu 20.04+, Debian 11+, Arch等主流发行版) 我主要用macOS,所以下面的示例会以macOS为主,但其他系统也类似。
- 根据你的使用场景,可能需要以下软件: 必需的: Git (如果你从GitHub克隆项目或需要版本控制) Node.js 18+ 或 Bun (如果使用npm方式安装OpenCode) 可选的: Docker (如果Skills需要容器化环境) Python 3.8+ (如果Skills包含Python脚本) 其他语言运行时 (根据你的Skills需求) 安装命令我就不详细写了,这些都是标准工具,官方文档都有详细说明。
- 这个适合懒得折腾的人,一条命令搞定: curl -fsSL https://opencode.ai/install | bash 安装脚本会自动检测你的系统,选择最合适的安装路径。不过注意,安装前要卸载旧版本(0.1.x之前的版本)。
- 如果你习惯用包管理器,这种方式更符合你的工作流: macOS用户(推荐): # 第三方tap(更新更快) brew install anomalyco/tap/opencode # 官方formula(更新稍慢) brew install opencode Linux/Windows用户: # NPM/Bun npm install -g opencode-ai bun install -g opencode-ai # Arch Linux paru -S opencode-bin # Windows Scoop scoop install opencode
- 如果你对安装位置有特殊要求,可以手动下载: 1. 从 GitHub Releases 下载对应平台的二进制文件 2. 解压到指定目录 3. 添加到PATH环境变量 示例(Linux): # 下载 wget https://github.com/atomicdotdev/opencode/releases/latest/download/opencode-linux-x64.tar.gz # 解压 tar -xzf opencode-linux-x64.tar.gz # 安装到系统目录 sudo cp opencode /usr/local/bin/ sudo chmod +x /usr/local/bin/opencode
- 安装完成后,验证一下: opencode –version 应该会显示版本号,比如: OpenCode v1.1.26 如果显示"command not found",检查一下PATH是否配置正确。
- 第一次运行时,建议初始化配置: cd /path/to/your/project opencode init 这会在项目根目录创建 .opencode/ 文件夹,包含基础的配置文件。
- OpenCode会在以下位置搜索Skills(按优先级排序): 1. .opencode/skills/<name>/SKILL.md – 项目本地(最高优先级) 2. ~/.config/opencode/skills/<name>/SKILL.md – 全局配置 3. ~/.opencode/skills/<name>/SKILL.md – 全局兼容 4. .claude/skills/<name>/SKILL.md – Claude兼容 5. ~/.claude/skills/<name>/SKILL.md – Claude兼容 6. .agents/skills/<name>/SKILL.md – Agent兼容 7. ~/.agents/skills/<name>/SKILL.md – Agent兼容 这个设计挺有意思的。项目本地的Skills会覆盖全局的,这样你可以在不同项目里用不同的配置。
- 我们来创建一个简单的Skill——代码审查助手。
- mkdir -p .opencode/skills/code-review cd .opencode/skills/code-review
- SKILL.md是Skill的核心文件,必须包含YAML frontmatter: — name: code-review description: 自动化代码审查,检查代码质量、安全漏洞和最佳实践 license: MIT compatibility: opencode metadata: category: code-quality languages: [javascript, typescript, python, go] — Code Review Skill 这个Skill帮助你系统化地进行代码审查。 审查要点 1. 代码质量 – 检查代码复杂度,建议每个函数不超过20行 – 验证命名规范,变量名要有意义 – 确保适当的错误处理 2. 安全检查 – 检查SQL注入风险 – 验证输入验证 – 确认敏感信息不被硬编码 3. 性能优化 – 识别潜在的性能瓶颈 – 建议更高效的算法或数据结构 – 检查资源泄漏 4. 最佳实践 – 验证是否遵循项目编码规范 – 检查是否缺少文档注释 – 确保适当的测试覆盖 使用方法 在OpenCode中调用: skill({ name: “code-review” }) 或直接使用工具名: skillscodereview 注意事项 – 审查时请提供完整的文件内容或代码片段 – 对于大型项目,建议分模块审查 – 审查结果包含具体的问题位置和改进建议 注意几个关键点: name 必须和目录名完全一致(code-review) description 要具体,让AI知道什么时候用这个Skill 内容要清晰,列出具体的审查步骤
- 如果Skill需要额外的脚本、模板或参考文档,可以创建子目录: code-review/ ├── SKILL.md # 必需 ├── scripts/ # 可选 │ ├── check-complexity.py │ └── security-scan.sh ├── references/ # 可选 │ ├── best-practices.md │ └── security-checklist.md └── assets/ # 可选 └── review-template.md 比如,你可以写一个Python脚本来计算代码复杂度: scripts/check-complexity.py: #!/usr/bin/env python3 import ast import sys def calculate_complexity(code): “””计算圈复杂度””” tree = ast.parse(code) complexity = 1 for node in ast.walk(tree): if isinstance(node, (ast.If, ast.While, ast.For, ast.ExceptHandler)): complexity += 1 elif isinstance(node, ast.BoolOp): complexity += len(node.values) – 1 return complexity if __name__ == “__main__”: code = sys.stdin.read() complexity = calculate_complexity(code) print(f”Code complexity: {complexity}”) if complexity > 10: print(“WARNING: High complexity detected!”) 记得给脚本添加执行权限: chmod +x scripts/check-complexity.py
- OpenCode允许你通过配置文件控制哪些Skills可以被访问。 在 ~/.config/opencode/opencode.json 中配置: { “$schema”: “https://opencode.ai/config.json”, “permission”: { “skill”: { “*”: “allow”, “code-review”: “allow”, “internal-*”: “deny”, “experimental-*”: “ask” } } } 权限类型: allow – 立即加载Skill deny – 对Agent隐藏,拒绝访问 ask – 加载前提示用户批准 我建议: 开发环境:所有Skills设为 allow 生产环境:未测试的Skills设为 ask 或 deny 敏感操作:必须设为 ask
- 除了权限控制,OpenCode还支持其他配置: { “$schema”: “https://opencode.ai/config.json”, // 全局模型配置 “model”: “anthropic/claude-sonnet-4-20250514”, // 不同任务的模型选择 “models”: { “default”: “anthropic/claude-sonnet-4-20250514”, “big”: “anthropic/claude-sonnet-4-20250514”, “fast”: “anthropic/claude-3-5-haiku-latest” }, // Skills插件 “plugins”: [“opencode-skills”], // MCP服务器配置(可选) “mcp”: { “filesystem”: { “enabled”: true } }, // 日志级别 “log_level”: “INFO”, // 主题 “theme”: “opencode” } 这些配置可以根据你的需求调整。我平时默认用Sonnet,快速任务用Haiku,复杂任务也用Sonnet——因为我测下来Sonnet的性价比最高。
- 可能的原因: SKILL.md文件名大小写错误(必须全大写) 目录名和frontmatter中的name不匹配 权限被设置为 deny 解决方法: # 检查文件名 ls -la .opencode/skills/code-review/ # 验证frontmatter cat .opencode/skills/code-review/SKILL.md | head -10 # 检查权限 cat ~/.config/opencode/opencode.json | grep -A 10 “permission”
- 可能的原因: YAML frontmatter格式错误 缺少必需字段(name、description) Skill名称不符合规范(1-64字符,小写字母数字加连字符) 验证工具名称的正则: ^[a-z0-9]+(-[a-z0-9]+)*$ 正确示例: ✅ code-review ✅ git-release ✅ test-generator 错误示例: ❌ Code-Review(大写) ❌ code–review(连续连字符) ❌ -code-review(以连字符开头) ❌ code_review(使用下划线)
- 如果Skill中引用了相对路径的文件,AI可能无法正确解析。 解决方法:OpenCode会自动提供Skill的基础路径,AI会根据这个路径解析相对引用。 例如,SKILL.md中提到:参考 `scripts/check-complexity.py` 中的复杂度计算逻辑 OpenCode会告诉AI: SKILL DIRECTORY: /path/to/.opencode/skills/code-review/ 完整路径: /path/to/.opencode/skills/code-review/scripts/check-complexity.py
- 假设你经常需要为项目生成单元测试,每次都要: 1. 分析函数的输入输出 2. 考虑边界情况 3. 生成测试代码 4. 确保测试覆盖率达到80% 这个过程重复性很高,适合用Skill自动化。
-
- mkdir -p .opencode/skills/test-generator/{scripts,references} cd .opencode/skills/test-generator
- SKILL.md: — name: test-generator description: 自动化生成单元测试,支持多种语言,确保测试覆盖率达标 license: MIT compatibility: opencode metadata: category: testing coverage_target: 80 languages: [javascript, typescript, python, go, rust] — Test Generator Skill 这个Skill帮助你快速生成高质量的单元测试。 工作流程 1. 代码分析 – 识别目标函数的输入参数和返回值 – 分析函数的依赖关系 – 检查异常处理逻辑 2. 测试用例设计 – 正常路径测试(happy path) – 边界值测试(edge cases) – 异常情况测试(error cases) – 性能测试(如适用) 3. 测试代码生成 – 选择合适的测试框架 – 生成可读的测试代码 – 添加清晰的测试说明 4. 覆盖率验证 – 运行测试并生成覆盖率报告 – 确保覆盖率达到80%以上 – 如果不达标,补充测试用例 支持的语言和框架 JavaScript/TypeScript – Jest – Mocha + Chai – Vitest Python – pytest – unittest – nose Go – testing包 – testify Rust – built-in test framework 使用方法 基本用法 在OpenCode中输入: skill({ name: “test-generator” }) 然后提供需要测试的代码文件或函数。 高级用法 指定测试框架和覆盖率目标: skill({ name: “test-generator” }) 使用Jest框架,目标覆盖率90% 辅助工具 复杂度分析 运行 `scripts/analyze-complexity.py` 分析代码复杂度,帮助识别需要重点 测试的代码路径。 覆盖率报告 参考 `references/coverage-guide.md` 了解如何解读覆盖率报告。 最佳实践 1. 测试应该独立运行,不依赖外部状态 2. 每个测试只验证一个功能点 3. 使用有意义的测试描述 4. 及时清理测试数据 5. 持续集成时自动运行测试 注意事项 – 确保测试环境配置正确 – 对于涉及数据库或网络的代码,使用mock – 保持测试代码的简洁性和可维护性
- scripts/analyze-complexity.py: #!/usr/bin/env python3 “”” 分析代码复杂度,帮助识别需要重点测试的代码路径 “”” import ast import sys from typing import Dict, List class ComplexityAnalyzer(ast.NodeVisitor): def __init__(self): self.functions: Dict[str, int] = {} self.current_function = None self.complexity = 1 def visit_FunctionDef(self, node: ast.FunctionDef): self.current_function = node.name self.complexity = 1 super().generic_visit(node) self.functions[self.current_function] = self.complexity self.current_function = None def visit_If(self, node: ast.If): self.complexity += 1 super().generic_visit(node) def visit_For(self, node: ast.For): self.complexity += 1 super().generic_visit(node) def visit_While(self, node: ast.While): self.complexity += 1 super().generic_visit(node) def visit_ExceptHandler(self, node: ast.ExceptHandler): self.complexity += 1 super().generic_visit(node) def analyze_code(code: str) -> List[tuple]: “””分析代码并返回函数复杂度列表””” try: tree = ast.parse(code) analyzer = ComplexityAnalyzer() analyzer.visit(tree) results = sorted( analyzer.functions.items(), key=lambda x: x[1], reverse=True ) return results except SyntaxError: print(“Error: Invalid Python syntax”) return [] if __name__ == “__main__”: if len(sys.argv) > 1: # 从文件读取 with open(sys.argv[1], ‘r’) as f: code = f.read() else: # 从标准输入读取 code = sys.stdin.read() results = analyze_code(code) print(“n代码复杂度分析结果:”) print(“=” * 50) for func_name, complexity in results: priority = “高” if complexity > 10 else “中” if complexity > 5 else “低” print(f”{func_name}: {complexity} (测试优先级: {priority})”) if results: avg_complexity = sum(c for _, c in results) / len(results) print(f”n平均复杂度: {avg_complexity:.1f}”) 添加执行权限: chmod +x scripts/analyze-complexity.py
- references/coverage-guide.md: 测试覆盖率指南 覆盖率指标说明 行覆盖率(Line Coverage) 代码行被执行的比例 分支覆盖率(Branch Coverage) 条件判断分支的覆盖情况 函数覆盖率(Function Coverage) 函数被调用的比例 覆盖率目标建议 – 核心业务逻辑:90%+ – 工具函数:80%+ – UI组件:70%+ – 配置文件:50%+ 如何提高覆盖率 1. 添加边界测试 2. 测试异常路径 3. 覆盖所有条件分支 4. 测试错误处理逻辑 工具推荐 – JavaScript: Istanbul/NYC – Python: coverage.py – Go: go test -cover – Rust: tarpaulin 运行效果展示 现在来测试一下这个Skill。
- 假设有一个Python函数需要测试: example.py: def calculate_discount(price: float, is_member: bool = False) -> float: “””计算折扣价格””” if not is_member: return price if price >= 1000: return price * 0.8 # 20% discount elif price >= 500: return price * 0.9 # 10% discount else: return price * 0.95 # 5% discount
- python scripts/analyze-complexity.py example.py 输出: 代码复杂度分析结果:==================================================calculate_discount: 4 (测试优先级: 中)平均复杂度: 4.0
- 在OpenCode中输入: skill({ name: “test-generator” }) 然后提供函数代码和需求:为 example.py 中的 calculate_discount 函数生成单元测试,使用pytest框架,目标覆盖率90%
- OpenCode会自动生成: test_example.py: import pytest from example import calculate_discount def test_calculate_discount_non_member(): “””测试非会员情况(无折扣)””” assert calculate_discount(100, False) == 100 assert calculate_discount(1000, False) == 1000 def test_calculate_discount_member_no_discount(): “””测试会员但价格低于500(5%折扣)””” assert calculate_discount(100, True) == 95 assert calculate_discount(499, True) == 474.05 def test_calculate_discount_member_10_percent(): “””测试会员价格在500-999之间(10%折扣)””” assert calculate_discount(500, True) == 450 assert calculate_discount(999, True) == 899.1 def test_calculate_discount_member_20_percent(): “””测试会员价格>=1000(20%折扣)””” assert calculate_discount(1000, True) == 800 assert calculate_discount(2000, True) == 1600 def test_calculate_discount_boundary_values(): “””测试边界值””” # 499和500的边界 assert calculate_discount(499, True) == 474.05 # 5% discount assert calculate_discount(500, True) == 450 # 10% discount # 999和1000的边界 assert calculate_discount(999, True) == 899.1 # 10% discount assert calculate_discount(1000, True) == 800 # 20% discount def test_calculate_discount_zero_price(): “””测试价格为零的情况””” assert calculate_discount(0, True) == 0 assert calculate_discount(0, False) == 0 @pytest.mark.parametrize(“price,is_member,expected”, [ (100, False, 100), (100, True, 95), (500, True, 450), (1000, True, 800), (2000, True, 1600), ]) def test_calculate_discount_parametrized(price, is_member, expected): “””参数化测试各种组合””” assert calculate_discount(price, is_member) == expected 运行测试并检查覆盖率 # 安装pytest和coverage pip install pytest coverage.py # 运行测试 pytest test_example.py -v # 生成覆盖率报告 coverage run -m pytest test_example.py coverage report 输出: Name Stmts Miss Cover Missing———————————————example.py 6 0 100%———————————————TOTAL 6 0 100% 这个数据还挺猛的——100%的覆盖率,超过了90%的目标。
- 用了几个月OpenCode Skills,我有几个感受: 1. 复用性大幅提升 以前重复写prompt,现在一次编写,到处使用。我算了下,大概节省了60%的prompt编写时间。 2. 一致性更好 所有团队成员用同一个Skill,输出风格和标准都统一了。这在团队协作中挺重要的。 3. 可维护性提高 Skill更新一次,所有使用该Skill的地方都同步更新。不像以前,改个prompt要改所有地方。 4. 但也有局限性 太复杂的逻辑,AI可能执行不准确 需要一定的学习成本 不是所有场景都适合(比如完全创新的任务)
- 1. Skill设计原则 单一职责:每个Skill只做一件事 步骤清晰:明确列出执行步骤 输入输出明确:告诉AI需要什么、期望得到什么 2. 资源管理 脚本要高效,避免拖慢AI响应速度 参考文档要精简,只包含必要信息 资源文件要压缩,减少加载时间 3. 权限控制 生产环境用 ask 模式,避免意外执行 测试环境用 allow 模式,提高效率 敏感操作必须手动确认 4. 版本管理 用Git管理Skills,方便回滚 重要修改要做注释说明 定期清理不再使用的Skills
目录
- 为什么需要Skills环境?
- 环境准备
- 硬件配置
- 操作系统要求
- 前置软件
- 安装步骤
- 方案一:一键安装(最简单)
- 方案二:包管理器安装
- 方案三:手动安装
- 验证安装
- 初始化配置
- Skills环境搭建
- 理解Skills的目录结构
- 创建第一个Skill
- Step 1: 创建目录结构
- Step 2: 编写SKILL.md
- Step 3: 可选——添加辅助文件
- 配置权限控制
- 环境配置参数说明
- 常见问题解决方法
- 问题1:Skill没有被发现
- 问题2:Skill加载失败
- 问题3:相对路径引用失败
- 实战案例
- 需求分析
- 实现步骤
- Step 1: 创建Skill结构
- Step 2: 编写SKILL.md
- Step 3: 编写辅助脚本
- Step 4: 编写参考文档
- 测试代码
- 分析复杂度
- 调用Skill
- 生成的测试代码
- 总结与扩展
- 使用心得
- 性能优化建议
- 最后说几句
其实这个问题我之前也纠结过。
刚开始用AI编程工具的时候,我每次遇到类似的任务,都要重新写一遍prompt。比如写单元测试、代码审查、生成文档这些重复性工作,每次都要重新组织语言。
这不仅浪费时间,而且容易遗漏细节。你说这是不是挺烦的?
后来发现OpenCode有个Skills系统,可以把你常用的prompt、工作流程、工具整合成可复用的模块。一次编写,到处使用。
这个思路和我之前写的那篇《Claude Code之父的13大cc技巧》里提到的"团队共享CLAUDE.md"很像——把最佳实践固化下来,AI就不会"瞎猜"了。
不过OpenCode的Skills更进一步,它不只是简单的规则文件,而是完整的、包含脚本、模板、参考资料的"技能包"。
我测下来,用了Skills之后,重复任务的处理速度大概提升了3倍。而且一致性也好了很多,不会因为心情不好就漏掉某个步骤。
说完了为什么要用,接下来讲讲怎么搭建。
OpenCode本身对硬件要求不高:
- CPU:任何现代处理器即可,Intel/AMD都行
- 内存:建议8GB以上,16GB更流畅
- 硬盘:预留至少500MB用于OpenCode和Skills
不过如果你的Skills包含大量资源文件,或者需要运行本地模型,那建议配置更好一点。
OpenCode支持主流系统:
- macOS 10.15+ (Intel和Apple Silicon都行)
- Windows 10/11
- Linux (Ubuntu 20.04+, Debian 11+, Arch等主流发行版)
我主要用macOS,所以下面的示例会以macOS为主,但其他系统也类似。
根据你的使用场景,可能需要以下软件:
必需的:
Git (如果你从GitHub克隆项目或需要版本控制)
Node.js 18+ 或 Bun (如果使用npm方式安装OpenCode)
可选的:
- Docker (如果Skills需要容器化环境)
- Python 3.8+ (如果Skills包含Python脚本)
- 其他语言运行时 (根据你的Skills需求)
安装命令我就不详细写了,这些都是标准工具,官方文档都有详细说明。
OpenCode的安装方式还挺多的,我整理了几种常用方案。
这个适合懒得折腾的人,一条命令搞定:
curl -fsSL https://opencode.ai/install | bash
安装脚本会自动检测你的系统,选择最合适的安装路径。不过注意,安装前要卸载旧版本(0.1.x之前的版本)。
如果你习惯用包管理器,这种方式更符合你的工作流:
macOS用户(推荐):
# 第三方tap(更新更快) brew install anomalyco/tap/opencode # 官方formula(更新稍慢) brew install opencode
Linux/Windows用户:
# NPM/Bun npm install -g opencode-ai bun install -g opencode-ai # Arch Linux paru -S opencode-bin # Windows Scoop scoop install opencode
如果你对安装位置有特殊要求,可以手动下载:
1. 从 GitHub Releases 下载对应平台的二进制文件
2. 解压到指定目录
3. 添加到PATH环境变量
示例(Linux):
# 下载 wget https://github.com/atomicdotdev/opencode/releases/latest/download/opencode-linux-x64.tar.gz # 解压 tar -xzf opencode-linux-x64.tar.gz # 安装到系统目录 sudo cp opencode /usr/local/bin/ sudo chmod +x /usr/local/bin/opencode
安装完成后,验证一下:
opencode --version
应该会显示版本号,比如:
OpenCode v1.1.26
如果显示"command not found",检查一下PATH是否配置正确。
第一次运行时,建议初始化配置:
cd /path/to/your/project opencode init
这会在项目根目录创建 .opencode/ 文件夹,包含基础的配置文件。
到这里,OpenCode基础环境已经准备好了,接下来就是重点——Skills环境的搭建。
OpenCode会在以下位置搜索Skills(按优先级排序):
1. .opencode/skills/<name>/SKILL.md – 项目本地(最高优先级)
2. ~/.config/opencode/skills/<name>/SKILL.md – 全局配置
3. ~/.opencode/skills/<name>/SKILL.md – 全局兼容
4. .claude/skills/<name>/SKILL.md – Claude兼容
5. ~/.claude/skills/<name>/SKILL.md – Claude兼容
6. .agents/skills/<name>/SKILL.md – Agent兼容
7. ~/.agents/skills/<name>/SKILL.md – Agent兼容
这个设计挺有意思的。项目本地的Skills会覆盖全局的,这样你可以在不同项目里用不同的配置。
我们来创建一个简单的Skill——代码审查助手。
mkdir -p .opencode/skills/code-review
cd .opencode/skills/code-review
SKILL.md是Skill的核心文件,必须包含YAML frontmatter:
---
name: code-review
description: 自动化代码审查,检查代码质量、安全漏洞和最佳实践
license: MIT
compatibility: opencode
metadata:
category: code-quality
languages: [javascript, typescript, python, go]
---
Code Review Skill
这个Skill帮助你系统化地进行代码审查。
审查要点
1. 代码质量
- 检查代码复杂度,建议每个函数不超过20行
- 验证命名规范,变量名要有意义
- 确保适当的错误处理
2. 安全检查
- 检查SQL注入风险
- 验证输入验证
- 确认敏感信息不被硬编码
3. 性能优化
- 识别潜在的性能瓶颈
- 建议更高效的算法或数据结构
- 检查资源泄漏
4. 最佳实践
- 验证是否遵循项目编码规范
- 检查是否缺少文档注释
- 确保适当的测试覆盖
使用方法
在OpenCode中调用:
skill({ name: "code-review" })
或直接使用工具名:
skillscodereview
注意事项
- 审查时请提供完整的文件内容或代码片段
- 对于大型项目,建议分模块审查
- 审查结果包含具体的问题位置和改进建议
注意几个关键点:
- name 必须和目录名完全一致(code-review)
- description 要具体,让AI知道什么时候用这个Skill
- 内容要清晰,列出具体的审查步骤
如果Skill需要额外的脚本、模板或参考文档,可以创建子目录:
code-review/ ├── SKILL.md # 必需 ├── scripts/ # 可选 │ ├── check-complexity.py │ └── security-scan.sh ├── references/ # 可选 │ ├── best-practices.md │ └── security-checklist.md └── assets/ # 可选 └── review-template.md
比如,你可以写一个Python脚本来计算代码复杂度:
scripts/check-complexity.py:
#!/usr/bin/env python3
import ast
import sys
def calculate_complexity(code):
"""计算圈复杂度"""
tree = ast.parse(code)
complexity = 1
for node in ast.walk(tree):
if isinstance(node, (ast.If, ast.While, ast.For, ast.ExceptHandler)):
complexity += 1
elif isinstance(node, ast.BoolOp):
complexity += len(node.values) - 1
return complexity
if __name__ == "__main__":
code = sys.stdin.read()
complexity = calculate_complexity(code)
print(f"Code complexity: {complexity}")
if complexity > 10:
print("WARNING: High complexity detected!")
记得给脚本添加执行权限:
chmod +x scripts/check-complexity.py
OpenCode允许你通过配置文件控制哪些Skills可以被访问。
在 ~/.config/opencode/opencode.json 中配置:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"skill": {
"*": "allow",
"code-review": "allow",
"internal-*": "deny",
"experimental-*": "ask"
}
}
}
权限类型:
- allow – 立即加载Skill
- deny – 对Agent隐藏,拒绝访问
- ask – 加载前提示用户批准
我建议:
- 开发环境:所有Skills设为 allow
- 生产环境:未测试的Skills设为 ask 或 deny
- 敏感操作:必须设为 ask
除了权限控制,OpenCode还支持其他配置:
{
"$schema": "https://opencode.ai/config.json",
// 全局模型配置
"model": "anthropic/claude-sonnet-4-20250514",
// 不同任务的模型选择
"models": {
"default": "anthropic/claude-sonnet-4-20250514",
"big": "anthropic/claude-sonnet-4-20250514",
"fast": "anthropic/claude-3-5-haiku-latest"
},
// Skills插件
"plugins": ["opencode-skills"],
// MCP服务器配置(可选)
"mcp": {
"filesystem": {
"enabled": true
}
},
// 日志级别
"log_level": "INFO",
// 主题
"theme": "opencode"
}
这些配置可以根据你的需求调整。我平时默认用Sonnet,快速任务用Haiku,复杂任务也用Sonnet——因为我测下来Sonnet的性价比最高。
可能的原因:
- SKILL.md文件名大小写错误(必须全大写)
- 目录名和frontmatter中的name不匹配
- 权限被设置为 deny
解决方法:
# 检查文件名 ls -la .opencode/skills/code-review/ # 验证frontmatter cat .opencode/skills/code-review/SKILL.md | head -10 # 检查权限 cat ~/.config/opencode/opencode.json | grep -A 10 "permission"
可能的原因:
- YAML frontmatter格式错误
- 缺少必需字段(name、description)
- Skill名称不符合规范(1-64字符,小写字母数字加连字符)
验证工具名称的正则:
^[a-z0-9]+(-[a-z0-9]+)*$
正确示例:
- ✅ code-review
- ✅ git-release
- ✅ test-generator
错误示例:
- ❌ Code-Review(大写)
- ❌ code–review(连续连字符)
- ❌ -code-review(以连字符开头)
- ❌ code_review(使用下划线)
如果Skill中引用了相对路径的文件,AI可能无法正确解析。
解决方法:OpenCode会自动提供Skill的基础路径,AI会根据这个路径解析相对引用。
例如,SKILL.md中提到:参考 `scripts/check-complexity.py` 中的复杂度计算逻辑
OpenCode会告诉AI:
SKILL DIRECTORY: /path/to/.opencode/skills/code-review/ 完整路径: /path/to/.opencode/skills/code-review/scripts/check-complexity.py
光说不练假把式,我们来做一个完整的实战案例——创建一个自动化测试生成Skill。
假设你经常需要为项目生成单元测试,每次都要:
1. 分析函数的输入输出
2. 考虑边界情况
3. 生成测试代码
4. 确保测试覆盖率达到80%
这个过程重复性很高,适合用Skill自动化。
mkdir -p .opencode/skills/test-generator/{scripts,references}
cd .opencode/skills/test-generator
SKILL.md:
---
name: test-generator
description: 自动化生成单元测试,支持多种语言,确保测试覆盖率达标
license: MIT
compatibility: opencode
metadata:
category: testing
coverage_target: 80
languages: [javascript, typescript, python, go, rust]
---
Test Generator Skill
这个Skill帮助你快速生成高质量的单元测试。
工作流程
1. 代码分析
- 识别目标函数的输入参数和返回值
- 分析函数的依赖关系
- 检查异常处理逻辑
2. 测试用例设计
- 正常路径测试(happy path)
- 边界值测试(edge cases)
- 异常情况测试(error cases)
- 性能测试(如适用)
3. 测试代码生成
- 选择合适的测试框架
- 生成可读的测试代码
- 添加清晰的测试说明
4. 覆盖率验证
- 运行测试并生成覆盖率报告
- 确保覆盖率达到80%以上
- 如果不达标,补充测试用例
支持的语言和框架
JavaScript/TypeScript
- Jest
- Mocha + Chai
- Vitest
Python
- pytest
- unittest
- nose
Go
- testing包
- testify
Rust
- built-in test framework
使用方法
基本用法
在OpenCode中输入:
skill({ name: "test-generator" })
然后提供需要测试的代码文件或函数。
高级用法
指定测试框架和覆盖率目标:
skill({ name: "test-generator" })
使用Jest框架,目标覆盖率90%
辅助工具
复杂度分析
运行 `scripts/analyze-complexity.py` 分析代码复杂度,帮助识别需要重点 测试的代码路径。
覆盖率报告
参考 `references/coverage-guide.md` 了解如何解读覆盖率报告。
最佳实践
1. 测试应该独立运行,不依赖外部状态
2. 每个测试只验证一个功能点
3. 使用有意义的测试描述
4. 及时清理测试数据
5. 持续集成时自动运行测试
注意事项
- 确保测试环境配置正确
- 对于涉及数据库或网络的代码,使用mock
- 保持测试代码的简洁性和可维护性
scripts/analyze-complexity.py:
#!/usr/bin/env python3
"""
分析代码复杂度,帮助识别需要重点测试的代码路径
"""
import ast
import sys
from typing import Dict, List
class ComplexityAnalyzer(ast.NodeVisitor):
def __init__(self):
self.functions: Dict[str, int] = {}
self.current_function = None
self.complexity = 1
def visit_FunctionDef(self, node: ast.FunctionDef):
self.current_function = node.name
self.complexity = 1
super().generic_visit(node)
self.functions[self.current_function] = self.complexity
self.current_function = None
def visit_If(self, node: ast.If):
self.complexity += 1
super().generic_visit(node)
def visit_For(self, node: ast.For):
self.complexity += 1
super().generic_visit(node)
def visit_While(self, node: ast.While):
self.complexity += 1
super().generic_visit(node)
def visit_ExceptHandler(self, node: ast.ExceptHandler):
self.complexity += 1
super().generic_visit(node)
def analyze_code(code: str) -> List[tuple]:
"""分析代码并返回函数复杂度列表"""
try:
tree = ast.parse(code)
analyzer = ComplexityAnalyzer()
analyzer.visit(tree)
results = sorted(
analyzer.functions.items(),
key=lambda x: x[1],
reverse=True
)
return results
except SyntaxError:
print("Error: Invalid Python syntax")
return []
if __name__ == "__main__":
if len(sys.argv) > 1:
# 从文件读取
with open(sys.argv[1], 'r') as f:
code = f.read()
else:
# 从标准输入读取
code = sys.stdin.read()
results = analyze_code(code)
print("n代码复杂度分析结果:")
print("=" * 50)
for func_name, complexity in results:
priority = "高" if complexity > 10 else "中" if complexity > 5 else "低"
print(f"{func_name}: {complexity} (测试优先级: {priority})")
if results:
avg_complexity = sum(c for _, c in results) / len(results)
print(f"n平均复杂度: {avg_complexity:.1f}")
添加执行权限:
chmod +x scripts/analyze-complexity.py
references/coverage-guide.md:
测试覆盖率指南
覆盖率指标说明
行覆盖率(Line Coverage)
代码行被执行的比例
分支覆盖率(Branch Coverage)
条件判断分支的覆盖情况
函数覆盖率(Function Coverage)
函数被调用的比例
覆盖率目标建议
- 核心业务逻辑:90%+
- 工具函数:80%+
- UI组件:70%+
- 配置文件:50%+
如何提高覆盖率
1. 添加边界测试
2. 测试异常路径
3. 覆盖所有条件分支
4. 测试错误处理逻辑
工具推荐
- JavaScript: Istanbul/NYC
- Python: coverage.py
- Go: go test -cover
- Rust: tarpaulin
运行效果展示
现在来测试一下这个Skill。
假设有一个Python函数需要测试:
example.py:
def calculate_discount(price: float, is_member: bool = False) -> float: """计算折扣价格""" if not is_member: return price if price >= 1000: return price * 0.8 # 20% discount elif price >= 500: return price * 0.9 # 10% discount else: return price * 0.95 # 5% discount
python scripts/analyze-complexity.py example.py
输出:
代码复杂度分析结果:
==================================================
calculate_discount: 4 (测试优先级: 中)
平均复杂度: 4.0
在OpenCode中输入:
skill({ name: "test-generator" })
然后提供函数代码和需求:为 example.py 中的 calculate_discount 函数生成单元测试,使用pytest框架,目标覆盖率90%
OpenCode会自动生成:
test_example.py:
import pytest
from example import calculate_discount
def test_calculate_discount_non_member():
"""测试非会员情况(无折扣)"""
assert calculate_discount(100, False) == 100
assert calculate_discount(1000, False) == 1000
def test_calculate_discount_member_no_discount():
"""测试会员但价格低于500(5%折扣)"""
assert calculate_discount(100, True) == 95
assert calculate_discount(499, True) == 474.05
def test_calculate_discount_member_10_percent():
"""测试会员价格在500-999之间(10%折扣)"""
assert calculate_discount(500, True) == 450
assert calculate_discount(999, True) == 899.1
def test_calculate_discount_member_20_percent():
"""测试会员价格>=1000(20%折扣)"""
assert calculate_discount(1000, True) == 800
assert calculate_discount(2000, True) == 1600
def test_calculate_discount_boundary_values():
"""测试边界值"""
# 499和500的边界
assert calculate_discount(499, True) == 474.05 # 5% discount
assert calculate_discount(500, True) == 450 # 10% discount
# 999和1000的边界
assert calculate_discount(999, True) == 899.1 # 10% discount
assert calculate_discount(1000, True) == 800 # 20% discount
def test_calculate_discount_zero_price():
"""测试价格为零的情况"""
assert calculate_discount(0, True) == 0
assert calculate_discount(0, False) == 0
@pytest.mark.parametrize("price,is_member,expected", [
(100, False, 100),
(100, True, 95),
(500, True, 450),
(1000, True, 800),
(2000, True, 1600),
])
def test_calculate_discount_parametrized(price, is_member, expected):
"""参数化测试各种组合"""
assert calculate_discount(price, is_member) == expected
运行测试并检查覆盖率
# 安装pytest和coverage pip install pytest coverage.py # 运行测试 pytest test_example.py -v # 生成覆盖率报告 coverage run -m pytest test_example.py coverage report
输出:
Name Stmts Miss Cover Missing
———————————————
example.py 6 0 100%
———————————————
TOTAL 6 0 100%
这个数据还挺猛的——100%的覆盖率,超过了90%的目标。
用了几个月OpenCode Skills,我有几个感受:
1. 复用性大幅提升
以前重复写prompt,现在一次编写,到处使用。我算了下,大概节省了60%的prompt编写时间。
2. 一致性更好
所有团队成员用同一个Skill,输出风格和标准都统一了。这在团队协作中挺重要的。
3. 可维护性提高
Skill更新一次,所有使用该Skill的地方都同步更新。不像以前,改个prompt要改所有地方。
4. 但也有局限性
- 太复杂的逻辑,AI可能执行不准确
- 需要一定的学习成本
- 不是所有场景都适合(比如完全创新的任务)
1. Skill设计原则
- 单一职责:每个Skill只做一件事
- 步骤清晰:明确列出执行步骤
- 输入输出明确:告诉AI需要什么、期望得到什么
2. 资源管理
- 脚本要高效,避免拖慢AI响应速度
- 参考文档要精简,只包含必要信息
- 资源文件要压缩,减少加载时间
3. 权限控制
- 生产环境用 ask 模式,避免意外执行
- 测试环境用 allow 模式,提高效率
- 敏感操作必须手动确认
4. 版本管理
- 用Git管理Skills,方便回滚
- 重要修改要做注释说明
- 定期清理不再使用的Skills
OpenCode的Skills系统是个挺实用的功能。它不只是简单的prompt管理,而是一套完整的技能打包和复用方案。
我测下来,用了Skills之后:
- 重复任务效率提升3倍
- 团队协作一致性提高
- 知识沉淀更系统化
但Skills也不是万能的。对于高度创新的任务,还是需要人工介入。它的价值在于把重复的、标准化的工作自动化,让人可以专注于更有创造力的事情。
如果你也在用OpenCode,不妨试试Skills。从简单的开始,比如代码审查、测试生成这些,慢慢积累你的技能库。
时间久了,你会发现自己的工作流越来越顺畅,AI的产出质量也越来越稳定。
这就是我搭建OpenCode Skills环境的经验分享,希望能帮到你。
到此这篇关于基于OpenCode搭建Skills环境的实现的文章就介绍到这了,更多相关OpenCode搭建Skills内容请搜索风君子博客以前的文章或继续浏览下面的相关文章,希望大家以后多多支持风君子博客!