如果最近你也在折腾 OpenCode、Claude Code 和 VS Code 这三样东西,大概率会遇到一个很常见但特别烦人的问题——同一个任务,我在 Claude Code 里写了一段很顺手的提示词,到了 OpenCode 里又要重新组织一遍,换到 VS Code 插件里又是另一套说法。更别提换一台电脑、换一个团队之后,这些东西全都要从零再来一次。我花了大概一周时间,把日常高频操作沉淀成了一套可复用的“技能包”,一次编写,三处使用,彻底把重复劳动解放了。这篇东西就是我这次实践的全过程记录,包含踩过的坑、试过的方案和最终稳定跑起来的配置方式,希望对同样被重复配置折磨的人有点帮助。
先说明一下这适合谁看:如果你已经在用 Claude Code 或 OpenCode 做日常开发,或者习惯在 VS Code 里通过插件让 AI 辅助写代码,但总觉得每次对话都要重新解释上下文、每次换工具就要重写提示词,那这篇内容就是为你准备的。我会先拆解“技能”到底是什么,再讲如何设计一个通用的技能包,然后分别打通三个工具的落地路径,最后附上我整理出来的问题排查表。
1. 重复建设的问题,出在“技能”没有被当资产
1.1 三个工具,三个临时工
先说一个很直观的场景。假设你是一个前端负责人,团队里定了规矩:所有代码提交之前必须过一遍安全性检查,重点看 XSS、CSRF、敏感信息泄露这三类问题。在 Claude Code 里,你可能已经写过一段不错的提示词,让它逐文件审查;到了 OpenCode 里,因为用的模型可能不一样,你发现同样一段话效果有偏差,得重新调;再到了 VS Code 的 AI 插件里,又是另一套交互方式。结果就是,你在三个工具里维护了三套“口头禅”。
这就像同时雇了三个临时工,每个人都要重新培训一遍怎么做安全检查。每次迭代规则,还得跑到三个人面前各讲一遍。时间一长,你自然会发现这里面有一个结构性的问题——你沉淀下来的不是可复用的能力,而是散落在各个对话历史里的碎片。
我这次实践的起点很简单:我要把团队那套代码规范、审查逻辑、提交信息规则,变成一份独立于任何工具的文件。谁需要谁拿去,模型不认识没关系,文件认识就行。
1.2 技能与提示词、脚本的边界
很多人分不清“技能(Skill)”“提示词(Prompt)”“脚本(Script)”这三者的区别,这直接导致资产化无从下手。
- 提示词是一次性的对话输入,它只存在于当前会话里,无法被其他会话引用。它的优点是灵活,缺点是死了就没了。
- 脚本是可以执行的一段程序,它能自动化完成明确的操作,但脚本不负责“思考”,它只负责执行。
- 技能是介于两者之间的东西:它是一份结构化的指令文件,告诉 AI 在遇到某类任务时应该按什么流程、用什么标准来处理。它既包含提示词的上下文,又具备脚本的可复用性。
用大白话说,提示词是“一句话吩咐”,脚本是“一张施工图”,技能则是“一套岗位说明书”。AI 看到技能文件之后,会按照说明书上的流程来思考和输出,而不是仅仅盯着你这一句话。
认清这个边界之后,我的设计思路就清晰了——把“岗位说明书”做好,工具只是执行这套说明书的载体。这样无论底层是 Claude 还是 OpenCode 里的其他模型,只要它们能读取技能文件,效果就会稳定得多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技能资产化的通用结构:一个文件夹就是一个能力
2.1 SKILL.md 就是技能的“说明书”
目前 Claude Code 和 OpenCode 对技能的定义基本对齐,核心都是一个文件夹下放一个 SKILL.md 文件,再附带一些可选资源。SKILL.md 本质上是 Markdown 格式,但文件开头必须有一段 YAML 格式的 frontmatter,用来声明技能的名称和描述。
一个最朴素的目录结构长这样:
code复制my-skill/
├── SKILL.md
└── resources/
├── 模板.md
└── 示例代码.js
SKILL.md 的内容分两部分:frontmatter 和正文。frontmatter 里最重要的字段是 name 和 description。别看就两个字段,实际写的门道不少。name 要短、要唯一,它是你后续通过 @技能名 调用的凭据;description 则要写清楚“什么时候该用这个技能”,因为模型主要是靠读 description 来判断要不要自动加载这个技能。
正文部分才是技能的灵魂。我一般会拆成几个小节:目标、适用场景、执行步骤、输出格式、注意事项。执行步骤尤其重要,步骤写得越具体,模型的行为越可控。
2.2 先写一个最简技能:代码审查清单
直接上一个我日常用得最多的例子——代码审查技能。最初我是在团队里用 Word 文档维护审查清单,后来发现让 AI 带着这个清单去做 review,比它自由发挥要靠谱得多。
先建目录:
code复制code-review/
├── SKILL.md
└── resources/
└── security-checklist.md
SKILL.md 的内容可以这样写:
markdown复制---
name: code-review
description: 对代码变更进行系统性审查,重点检查逻辑错误、安全隐患和可维护性问题。当用户要求审查代码、检查提交、评估 MR 时使用。
---
# 代码审查技能
## 目标
对给定的代码变更进行深入审查,输出结构化审查报告。
## 执行步骤
1. 先定位变更范围,明确哪些文件、哪些函数被改动。
2. 逐文件检查逻辑错误:边界条件、空指针、并发问题。
3. 对照安全清单检查常见漏洞。
4. 评估可读性与可维护性,给出优化建议。
## 输出格式
- 问题按严重程度分为:致命、重要、建议、疑问。
- 每个问题标注文件、行号和修改建议。
- 最后给出总体结论。
## 注意事项
- 只报告真实存在的问题,不编造问题。
- 对于不确定的隐患,归类为疑问,不要扩大化。
resources/security-checklist.md 里放团队整理的安全检查项,比如 SQL 注入、XSS、敏感信息硬编码、越权访问等等。AI 在执行技能时,会自动把这部分内容读进去作为判断依据。
这里有个很关键的设计:判断标准不在提示词里,而在资源文件里。这样迭代清单的时候只需要改资源文件,不用动技能的主体逻辑。这个分离思路,后面会反复用到。
3. 打通第一步:在 Claude Code 里跑通技能
3.1 技能放哪里:全局与项目
Claude Code 读技能的路径是固定的,全局技能放在 ~/.claude/skills/ 目录下,项目级技能放在项目根目录的 .claude/skills/ 下。识别规则很简单:目录下必须有 SKILL.md 文件。
我的建议是:通用能力(比如代码审查、提交信息生成、API 接口文档整理)放全局,项目特有规则(比如这个项目用哪种测试框架、目录结构约定)放项目级。这样换项目时,项目级技能能跟着仓库走,团队其他人 clone 下来就直接生效。
我把 code-review 技能放到全局后,在 Claude Code 对话里做了几轮测试。基础调用方式是直接输入 @code-review,模型会立刻读取这个技能文件并进入审查模式。但更好的方式是直接在对话里说“帮我 review 一下刚才改动的这些文件”,让模型自己去匹配 description,自动加载技能。实测下来,只要 description 写得具体,自动触发的概率非常高。
3.2 从 CLAUDE.md 到技能资产的演进
很多老用户可能已经习惯在 CLAUDE.md 里写一堆项目规则,这没问题,但需要注意边界。CLAUDE.md 更适合存“项目是什么”的静态信息,比如技术栈、目录结构、启动命令;而技能更适合存“任务怎么做”的动态能力,比如审查流程、代码生成规范、问题排查路径。
把两者混淆是常见误区。举个例子,你可以在 CLAUDE.md 里写“这个项目使用 pnpm”,但“如何为这个项目新增一个 API 接口”这种流程性知识,就应该做成技能文件。项目信息是上下文,技能是可复用操作,分开管理之后,你会发现换新项目时技能可以直接带走,而不会被困在旧项目里。
我实际验证过这样一个场景:写提交信息。以前每次 commit 之前我都要手动组织语言,后来我写了一个 commit-message 技能,定义好格式模板、type 枚举、scope 的写法、以及什么情况用 ! 标记破坏性变更。调用之后,Claude Code 会先 git diff 获取变更内容,再按技能规则生成信息,我只需要确认一下即可。这个技能花了十分钟写,但省下来的时间远超十分钟。
4. 打通第二步:在 OpenCode 里复用同一套技能
4.1 安装与配置 OpenCode
OpenCode 是一个开源的 AI 编码终端,它的核心卖点是模型无关——你可以接 OpenAI、Anthropic、本地模型等等。安装很直接,如果你有 Node.js 环境:
bash复制npm install -g opencode-ai
装完在终端输入 opencode 就能进入交互界面,也可以直接用 opencode run "你的任务" 做一次性调用,这个特性后面在 VS Code 集成时会特别有用。
我第一次跑通 OpenCode 时候有个先入为主的错误认识,以为技能的目录结构和 Claude Code 不一样。查了文档之后发现,OpenCode 同样支持读取 SKILL.md 格式的技能文件,全局路径默认在 ~/.config/opencode/skills/。
关键在于,你完全可以把技能目录指到同一个地方。我直接在 opencode.json 里把技能目录配置成和 Claude Code 共用的路径,实现一份技能包,两边同时生效。这种方式省掉了很多重复维护的麻烦。
4.2 技能目录与 Claude Code 对齐
实际操作中,我建议不要在配置文件里把技能目录指向 ~/.claude/skills 这个原始目录,而是自己建一个统一目录来统一管理,比如 ~/ai-skills,再把两边都指向这个目录。这样做的原因很实际:不同的工具可能会有自己的内部命名规则,而且技能包里可能会有各工具专属的兼容层,拆开更干净。
Claude Code 的技能目录改写不那么直接,我用的办法是在 ~/.claude/settings.json 里通过环境变量或者 symlink 的方式做指向。如果你不想折腾,更省事的方案是:把技能包目录建好,然后在 ~/.claude/skills 和 ~/.config/opencode/skills 下各放一个符号链接,指向同一个技能包目录。
bash复制ln -s ~/ai-skills/code-review ~/.claude/skills/code-review
ln -s ~/ai-skills/code-review ~/.config/opencode/skills/code-review
在 Linux 和 macOS 下都是这样,Windows 下面建议直接用 junction,不要用普通快捷方式,否则部分终端工具读不到。
4.3 实测:同一个技能在两边效果对比
我拿同一个代码审查技能在两个环境里跑了一遍。先说结论:技能的稳定性,取决于你写步骤的颗粒度,而不是底层模型。Claude Code 默认用的是 Claude 系列模型,OpenCode 我配置的是另一家模型,两者对同样技能的遵循程度确实有差异,但大体框架是一致的。
差异主要体现在细节上:Claude Code 对“注意事项”的执行力更强,OpenCode 对“输出格式”的遵守度更高。这也给了我一个启发——技能正文里的约束不要过于依赖某一种模型的天性,尽量把判断标准写明确。比如“检查 SQL 注入”就不如“检查所有 SQL 拼接处,确认是否使用参数化查询”有效,后面这种写法模型几乎不会走偏。
如果你打算长期使用 OpenCode,我还建议你花点时间了解它的 agent 机制。OpenCode 里每个 agent 可以绑定不同的模型和技能列表,你可以做一个 reviewer agent,专门加载审查类技能,再做一个 coder agent,加载代码生成类技能,两个 agent 在同一个会话里各司其职。
5. 打通第三步:在 VS Code 里串联 Claude 与 OpenCode
5.1 VS Code 与 Claude Code 官方插件
前两步打通之后,你已经拥有了一套跨工具复用的技能资产。第三步是把它们“用”进 VS Code 这个日常主阵地。
Claude Code 官方提供了 VS Code 插件,安装后在侧边栏会多出一个 Claude 面板。在这个面板里,你可以直接像在终端里一样和 Claude 对话,而且它天然读取你的技能目录。换句话说,全局技能在这个插件里直接生效,不需要额外配置。
需要注意的是,使用这个插件需要登录 Anthropic 账号,并通过订阅或 API 额度来计费。我第一次配置时卡在登录环节,命令行里明明已经认证过了,插件却显示未登录。后来发现需要在 VS Code 的命令面板里手动执行一次 Claude Code: Sign In 操作,而不是依赖终端的登录态。
如果你不想订阅收费额度,也可以用 Codex、Cline 这类支持自定义模型接入的插件。Cline 比较适合需要技能文件支撑的玩法,因为它对规则文件的读取做得比较到位,你可以在项目里让它加载 SKILL.md 作为系统的补充约束。
5.2 在集成终端里跑 OpenCode,用任务串联
VS Code 插件的方案有一个天然短板——插件能读你的技能,但它的自由度受限于插件作者的设计。有些操作,比如跨文件重构、批量处理脚本,最终还是回到终端跑 opencode 更顺手。
我的做法是:在 VS Code 左下角设置里加上几个自定义任务,把 opencode run 命令封装成按钮。比如按一个快捷键,就能对当前选中的文件执行“生成单元测试”技能。
.vscode/tasks.json 里大致是这样的结构:
json复制{
"version": "2.0.0",
"tasks": [
{
"label": "Generate Tests",
"type": "shell",
"command": "opencode run \"根据当前文件${file}生成单元测试,使用仓库现有测试框架\"",
"problemMatcher": []
}
]
}
这样实际上把 OpenCode 变成了 VS Code 里的一个“命令执行器”,你可以把任何技能调用封装成一个任务按钮。个人体验是,比起在对话面板里一遍遍输入同样的话,这种快捷键方式更快,尤其适合脚本化、规则明确的任务。
5.3 本地模型兜底:VS Code + Ollama
线上 API 偶尔会有额度不够或者网络波动的情况,所以我还做了一手准备:本地模型兜底。做法很简单,通过 Ollama 在本地跑一个小参数量模型,然后在 VS Code 里用一个支持自定义 API 的插件指向 http://localhost:11434。
这样的配置对技能文件的兼容性如何?实测结论是:大模型能力越强,对技能文件的遵循度越高。本地小模型不是不能用,但你需要把技能文件写得非常直白,不要用隐含的领域知识,最好把每一步都拆到让新手也能照着做的程度。所以如果你主要依赖本地模型,写技能的时候不妨把“注意事项”和“反面示例”写得更足一些。
这个本地配置更大的意义在于调试验证——当线上模型不可用的时候,至少本地还能跑通流程,不会卡死在分析问题上。
6. 技能资产的工程化:设计、迭代与避坑
6.1 技能命名的艺术和描述的黄金法则
很多人写技能时忽略了最重要的一件事:模型是通过 description 来发现技能的。description 写不好,技能就永远是僵尸资产,根本不会被自动调用。
我的经验是,description 要满足三条:
- 以动词开头,比如“审查”“生成”“排查”,让模型一眼看到这是动作能力。
- 明确触发场景,写清楚“当用户XX时”使用。
- 不要写形容词,要写使用条件。比如“快速审查代码”就不如“在提交代码前检查变更文件是否包含安全漏洞”更容易被正确匹配。
名称本身则要克制。尽量用两个以内的单词,用连字符连接。code-review、commit-message、api-doc 都是好名字,快速代码审查工具v2 这种就不用考虑了,输入麻烦且容易被误解析。
6.2 版本管理与团队共享
技能本质上是文本资产,所以完全可以放进 Git 仓库管理。我的习惯是建一个单独的 ai-skills 仓库,每个技能一个目录,配套一个 README.md 说明这个技能适用于什么场景、依赖哪些模型能力。
团队共享的时候,不用强制大家用 Git,直接把技能文件夹压缩发送也能用,但长期来看 Git 更利于追溯变更记录。更重要的是,当团队成员都在用同一套技能时,你改一条规则,所有人下次自动生效,这种协同效率比以前在微信群发文档高很多。
另外要留意权限问题。如果你把技能包放在共享盘里,记得检查子目录是否对所有成员可读。我在公司电脑上踩过这个坑:技能目录挂在公司网盘,同事反馈技能不生效,排查了半天,最后发现是同步工具没把子文件夹同步下来。
6.3 常见问题速查表
最后整理几个我实际遇到的高频问题,几乎每个都折腾了我一阵子:
| 问题 | 原因 | 解决方式 |
|---|---|---|
| 技能没有被自动调用 | description 写得太宽泛或不够具体 | 重写 description,加入触发场景,用动词开头 |
| 技能调用了但效果不稳定 | 正文步骤过于抽象 | 拆步骤,每步写清楚输入、判断标准、输出 |
| 换电脑后技能全部丢了 | 技能目录在本地,没有做版本管理 | 用 Git 管理技能包,或存储在云同步目录 |
| Windows 下技能读不到 | 用了软链接方式但权限不足 | 改用 junction 方式,或者直接在配置里指定绝对路径 |
| 同一个技能在 Claude 和 OpenCode 表现差异大 | 底层模型对指令的理解能力不同 | 在技能文件里加入“反面示例”,明确禁止行为 |
| 技能文件加载后对话变慢 | 资源文件过大,模型每次都要读一堆内容 | 拆分技能,把不常用的细节放到 resources 目录下,按需加载 |
最后再分享一个小技巧:不要等到技能很完美才投入使用。先写一版能用的,跑几轮真实任务之后你就会发现哪些步骤表述不清楚、哪些规则模型总是忽略,然后针对性修改。我最初几个技能都改过七八版,这个过程本身也是技能资产化的必经之路。技能文件就像代码一样,没有一次写对的,都是在真实场景里迭代出来的。
