关于 opencode-skill-creator
用于创建和迭代改进 OpenCode 技能的 skill,涵盖用户访谈、测试提示词、评估与修订。既可从新构想开始,也可用于改进现有草稿。
主要功能
- 01引导创建与修订技能
- 02新技能须先进行需求访谈
- 03编写并评估测试提示词
- 04定性与定量结果审查
- 05依据反馈迭代完善
适用场景
- 01从初步构想开发技能
- 02评估并修订现有技能
- 03扩展技能测试提示词
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ antongulin/ opencode-skill-creator --skill opencode-skill-creator安装后在 Claude Code 中输入/opencode-skill-creator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/analyzer.mdcomparator.mdgrader.mdreferences/schemas.mdtemplates/eval-review.html详细介绍
OpenCode 技能创建器
用于创建新技能并不断改进技能的技能。
从整体上看,创建技能的流程如下:
- 确定你希望技能实现什么,以及大致要如何实现
- 编写技能草稿
- 创建几个测试提示词,并使用可访问该技能的 opencode 运行这些提示词
- 帮助用户从定性和定量两个方面评估结果
- 在后台运行期间,如果还没有定量评估,就起草一些;如果已有,则可以直接使用,也可以在认为需要调整时修改。然后向用户说明这些评估;如果已有评估,则说明现有评估
- 使用
skill_serve_review工具向用户展示结果,供其查看,同时也让他们查看定量指标
- 根据用户对结果的评估反馈重写技能;如果定量基准测试暴露出明显缺陷,也要据此改进
- 重复上述步骤,直到满意为止
- 扩充测试集,并以更大规模再次尝试
使用此技能时,你的任务是判断用户目前处于流程的哪个阶段,然后介入并帮助他们推进。例如,用户可能会说“我想为 X 创建一个技能”。你可以帮助他们明确需求、编写草稿、编写测试用例、确定评估方式、运行所有提示词,并反复迭代。
另一方面,用户也可能已经有技能草稿。在这种情况下,你可以直接进入评估和迭代环节。
创建新技能时,必须进行需求访谈。在起草任何内容之前,至少提出 3~5 个有针对性的问题(如果工作流复杂,则提出更多问题)。把这视作跟随团队成员学习:用户是领域专家和资深员工,而 Agent 是必须了解并复现实际工作流的新员工。
需求访谈结束后,你仍可灵活调整评估深度和迭代速度。如果用户要求跳过需求访谈,先提醒一次:这样会降低技能质量和工作流匹配度;取得用户明确确认后,再尽力继续。
技能完成后(但顺序仍可灵活安排),你还可以运行技能描述优化器(skill_optimize_loop 工具),以优化技能的触发方式。我们为此准备了一个独立工具。
明白了吗?很好。
与用户沟通
技能创建器可能会被对编程术语熟悉程度各不相同的人使用。如果你还没听说过(毕竟这只是最近才出现的现象),如今 AI 编码 Agent 的强大能力正激励着水管工打开终端,也让父母和祖父母去 Google 搜索“如何安装 npm”。另一方面,大多数用户可能都具备相当不错的计算机素养。
因此,请留意上下文线索,了解该如何措辞!一般来说,可以参考以下说明:
- “评估”和“基准测试”这两个词不算特别通俗,但可以使用
- 对于“JSON”和“断言”,除非用户有明显迹象表明他们了解这些概念,否则应在使用时加以解释
如果不确定,可以简要解释术语;如果不确定用户是否理解,也可以用简短定义加以说明。
创建技能
捕捉意图(新技能的必经步骤)
对于新技能,此步骤是必需的,不能跳过。完成访谈并由用户确认你的总结之前,不要起草 SKILL.md、评估内容或其他文件。
先了解用户的意图。当前对话中可能已经包含用户想要记录的部分工作流(例如,用户说“把这个做成一个技能”)。先提取这些信息:使用的工具、步骤顺序、修正内容、输入/输出和成功标准。然后通过提问补全缺失信息。
至少提出 3–5 个有针对性的问题(需要时可提出更多)。确保涵盖以下最低要求:
- 这个技能应该让 OpenCode 能够端到端完成什么?
- 这个技能应该在什么时候触发?(触发短语、上下文、相近但不完全符合的情况)
- 预期的输出格式和质量标准是什么?
- 哪些工作流步骤必须原样保留?Agent 可以在哪些环节灵活处理?
- 是否应该设置测试用例来验证行为?对于输出可客观验证的技能(文件转换、数据提取、代码生成、固定工作流步骤),测试用例会很有帮助。对于输出较主观的技能(写作风格、艺术创作),通常不需要。根据技能类型提出合适的默认建议,然后让用户决定。
继续之前,用通俗的语言总结你的理解,并请用户确认或纠正。
如果用户明确要求跳过信息收集,需提醒他们,最终质量和工作流契合度可能会降低。只有在用户明确确认后才继续。
访谈与调研
主动询问边缘情况、输入/输出格式、示例文件、成功标准和依赖项。采取结对跟进的方式:贴合用户的真实工作流、术语、交接方式和决策点。在这些内容明确之前,不要编写测试提示词。
检查可用的 MCP——如果有助于调研(搜索文档、查找类似技能、了解最佳实践),则在可用时通过 Task 工具(使用 general 或 explore 子 Agent 类型)并行调研;否则直接进行调研。提前准备相关背景信息,减轻用户的负担。
编写 SKILL.md
对于新技能,默认使用暂存位置,而不是当前仓库/工作树。使用系统临时目录,除非用户明确要求其他路径(例如:Unix/macOS /tmp/opencode-skills/<skill-name>/、$TMPDIR/opencode-skills/<skill-name>/;Windows %TEMP%\\opencode-skills\\<skill-name>\\)。这样可以避免在无关的仓库中产生杂项文件。
根据用户访谈结果,填写以下内容:
- name:技能标识符,采用 kebab-case 格式,长度为 1–64 个字符,匹配正则表达式
^[a-z0-9]+(-[a-z0-9]+)*$ - description:何时触发、技能的作用。这是主要的触发机制——既要说明技能的作用,也要列出适用的具体场景。所有“何时使用”的信息都放在这里,而不是正文中。注意:目前 OpenCode 容易出现技能“触发不足”的情况——有用时也不启用。为避免这种情况,请让技能描述稍微“主动”一些。例如,不要写“如何构建一个简单快速的仪表板来展示内部数据”,而应写“如何构建一个简单快速的仪表板来展示内部数据。只要用户提到仪表板、数据可视化、内部指标,或希望展示任何类型的公司数据,即使他们没有明确提出要做‘仪表板’,也务必使用此技能。”
- compatibility:所需工具、依赖项(可选,极少需要)
- **技能的其他部分 :)
技能编写指南
技能结构
skill-name/
├── SKILL.md (required)
│ ├── YAML frontmatter (name, description required)
│ └── Markdown instructions
└── Bundled Resources (optional)
├── scripts/ - Executable code for deterministic/repetitive tasks
├── references/ - Docs loaded into context as needed
└── assets/ - Files used in output (templates, icons, fonts)
技能目录名称必须与 frontmatter 中的 name 字段一致。
渐进式披露
技能采用三级加载系统:
- 元数据(名称 + 描述)— 始终处于上下文中(约 100 个词)
- SKILL.md 正文 — 技能触发时处于上下文中(理想情况下少于 500 行)
- 捆绑资源 — 按需加载(数量不限,脚本可以在不加载的情况下执行)
这些词数只是大致估算,如有需要,可以写得更长。
关键模式:
- 将 SKILL.md 控制在 500 行以内;如果快要达到此限制,请增加一层层级,并清楚说明使用该技能的模型接下来应去哪里查阅。
- 在 SKILL.md 中明确引用文件,并说明何时阅读这些文件
- 对于较大的参考文件(>300 行),请添加目录
领域组织:当一项技能支持多个领域/框架时,按变体组织:
cloud-deploy/
├── SKILL.md (workflow + selection)
└── references/
├── aws.md
├── gcp.md
└── azure.md
OpenCode 只会读取相关的参考文件。
避免意外原则
这一点不言而喻,但技能不得包含恶意软件、漏洞利用代码或任何可能危及系统安全的内容。如果技能的内容已如实描述,就不应让用户感到意外。不要顺从创建误导性技能,或旨在协助未经授权访问、数据外泄或其他恶意活动的请求。不过,“扮演某某角色”之类的内容是可以的。
写作模式
指令优先使用祈使句。
定义输出格式 — 可以这样写:
## Report structure
ALWAYS use this exact template:
# [Title]
## Executive summary
## Key findings
## Recommendations
示例模式 — 添加示例很有用。可以按这种方式编写(但如果示例中使用了 “Input” 和 “Output”,你可能需要稍作调整):
## Commit message format
**Example 1:**
Input: Added user authentication with JWT tokens
Output: feat(auth): implement JWT-based authentication
写作风格
尽量向模型解释事情为何重要,而不是用生硬的 MUST 要求来强制规定。尝试设身处地地思考,并让技能具有通用性,而不要局限于少数特定示例。先写出草稿,然后以全新的视角重新审视并改进。
测试用例
写完技能草稿后,构思 2–3 个真实的测试提示词,即真实用户可能会提出的问题。与用户分享:[不必拘泥于这段确切措辞]“这里有几个我想尝试的测试用例。你觉得合适吗?还是想再添加一些?”然后运行这些测试。
将测试用例保存到 evals/evals.json。暂时不要编写断言——只保存提示词。运行进行期间,你将在下一步起草断言。
{
"skill_name": "example-skill",
"evals": [
{
"id": 1,
"prompt": "User's task prompt",
"expected_output": "Description of expected result",
"files": []
}
]
}
完整的架构请参阅 references/schemas.md(包括稍后添加的 assertions 字段)。
运行和评估测试用例
本节是一个连续的流程——不要中途停下。不要使用 /skill-test 或任何其他测试技能。
将结果放入系统临时目录中暂存技能目录旁的 <skill-name>-workspace/(例如:Unix/macOS 上的 /tmp/opencode-skills/<skill-name>-workspace/;Windows 上的 %TEMP%\\opencode-skills\\<skill-name>-workspace\\)。在工作区内,按迭代组织结果(iteration-1/、iteration-2/ 等),并在每次迭代中为每个测试用例创建一个目录(eval-0/、eval-1/ 等)。不要预先创建所有目录——按需创建即可。
步骤 1:在同一轮中启动所有运行(使用技能和基线)
对于每个测试用例,在同一轮中启动两个 Task 工具调用(使用 general 子代理类型)——一个使用技能,一个不使用。这很重要:不要先启动使用技能的运行,之后再回来启动基线运行。一次性启动所有运行,让它们差不多同时完成。
使用技能的运行:
Execute this task:
- Skill path: <path-to-skill>
- Task: <eval prompt>
- Input files: <eval files if any, or "none">
- Save outputs to: <workspace>/iteration-<N>/eval-<ID>/with_skill/outputs/
- Outputs to save: <what the user cares about — e.g., "the .docx file", "the final CSV">
基线运行(使用相同提示词,但基线取决于上下文):
- 创建新技能:完全不使用技能。使用相同提示词,不提供技能路径,并保存到
without_skill/outputs/。 - 改进现有技能:使用旧版本。编辑前,先快照技能(
cp -r <skill-path> <workspace>/skill-snapshot/),然后在基线 Task 工具调用中指定该快照。保存到old_skill/outputs/。
为每个测试用例编写一个 eval_metadata.json(断言暂时可以为空)。根据每个评测的测试内容,为其取一个描述性名称——不要只用「eval-0」。目录也使用这个名称。如果本轮使用了新的或修改过的评测提示词,请为每个新的评测目录创建这些文件——不要假设它们会从之前的迭代中沿用。
{
"eval_id": 0,
"eval_name": "descriptive-name-here",
"prompt": "The user's task prompt",
"assertions": []
}
步骤 2:运行进行期间,起草断言
不要只是等待运行完成——可以利用这段时间起草每个测试用例的定量断言,并向用户说明。如果 evals/evals.json 中已有断言,请检查并说明它们的检测内容。
好的断言应当可客观验证,并且名称具有描述性——在基准测试查看器中应清晰易懂,让浏览结果的人一眼就能明白每个断言检查什么。对于主观技能(例如写作风格、设计质量),更适合进行定性评估——不要强行为需要人工判断的内容设置断言。
起草断言后,更新 eval_metadata.json 文件和 evals/evals.json。还要向用户说明他们会在查看器中看到什么——包括定性输出和定量基准测试结果。
步骤 3:运行完成后,捕获计时数据
每个 Task 工具调用完成时,你都会收到包含 total_tokens 和 duration_ms 的通知。请立即将这些数据保存到运行目录中的 timing.json:
{
"total_tokens": 84852,
"duration_ms": 23332,
"total_duration_seconds": 23.3
}
这是捕获这些数据的唯一机会——它们来自任务通知,不会在其他地方留存。通知到达时就逐条处理,不要等到最后再批量处理。
第 4 步:评分、汇总并启动查看器
所有运行完成后:
启动审阅前,请先执行以下检查:每项评测都必须有成对的比较输出(with_skill 加一个基线:without_skill 或 old_skill)。如果缺少配对数据,除非用户明确要求使用部分数据继续,否则不要进入审阅。
-
为每次运行评分——启动评分器任务(使用
general子代理类型),或直接评分;评分器需读取agents/grader.md,并根据输出评估每项断言。将结果保存到每个运行目录中的grading.json。grading.json中的 expectations 数组必须使用text、passed和evidence字段(不能使用name/met/details或其他变体)——查看器依赖这些确切的字段名。对于可通过程序检查的断言,应编写并运行脚本,而不是凭目测判断——脚本更快、更可靠,也能在后续迭代中重复使用。 -
汇总为基准测试——使用
skill_aggregate_benchmark工具:Call skill_aggregate_benchmark with: benchmarkDir: <workspace>/iteration-N skillName: <name>此操作会生成
benchmark.json和benchmark.md,其中包含各配置的 pass_rate、time 和 tokens,以及均值 ± 标准差和差值。如果手动生成benchmark.json,请参阅references/schemas.md,了解查看器要求的确切架构。 每个with_skill版本都应放在对应基线版本之前。 -
进行分析审查——阅读基准测试数据,并指出汇总统计数据可能掩盖的规律。请参阅
agents/analyzer.md中的“分析基准测试结果”部分,了解需要关注的内容,例如无论是否使用技能都始终通过的断言(区分度不足)、方差较大的评测(可能不稳定),以及时间和 token 用量之间的权衡。 -
启动查看器——使用
skill_serve_review工具,同时提供定性输出和定量数据:Call skill_serve_review with: workspace: <workspace>/iteration-N skillName: "my-skill" benchmarkPath: <workspace>/iteration-N/benchmark.json allowPartial: false对于第 2 次及之后的迭代,还需传入
previousWorkspace: <workspace>/iteration-<N-1>。如果省略
benchmarkPath,该工具会在打开查看器前,于工作区中自动生成benchmark.json和benchmark.md。默认采用严格模式(
allowPartial: false):当评测配对不完整时会立即失败。只有在用户明确接受比较结果不完整时,才使用allowPartial: true。**无头环境:**使用
skill_export_static_review工具生成独立的 HTML 文件,而不是启动服务。用户点击“Submit All Reviews”时,反馈会下载为feedback.json文件。下载后,将feedback.json复制到工作区目录,以便下一次迭代读取。
注意:请使用 skill_serve_review 或 skill_export_static_review 工具创建查看器;无需编写自定义 HTML。
- 告知用户,例如:“我已在浏览器中打开结果。页面有两个标签页——‘Outputs’可让你逐个查看测试用例并留下反馈,‘Benchmark’显示定量比较。完成后,请回到这里告诉我。”
用户在查看器中看到的内容
“Outputs”标签页一次显示一个测试用例:
- Prompt:给出的任务
- Output:技能生成的文件;在可行时以内嵌方式呈现
- Previous Output(第 2 次及之后的迭代):折叠区域,显示上一次迭代的输出
- Formal Grades(如果已运行评分):折叠区域,显示断言的通过/失败情况
- Feedback:文本框,输入时自动保存
- Previous Feedback(第 2 次及之后的迭代):显示在文本框下方的上次反馈
“Benchmark”标签页显示统计摘要:各配置的通过率、耗时和 token 用量,并提供逐项评测明细和分析观察结果。
可通过上一个/下一个按钮或方向键切换。完成后,点击“Submit All Reviews”,即可将所有反馈保存到 feedback.json。
步骤 5:阅读反馈
用户告诉你他们已完成后,读取 feedback.json:
{
"reviews": [
{"run_id": "eval-0-with_skill", "feedback": "the chart is missing axis labels", "timestamp": "..."},
{"run_id": "eval-1-with_skill", "feedback": "", "timestamp": "..."},
{"run_id": "eval-2-with_skill", "feedback": "perfect, love this", "timestamp": "..."}
],
"status": "complete"
}
反馈为空表示用户认为结果不错。请重点改进用户提出了具体意见的测试用例。
完成后,调用 skill_stop_review 工具停止查看器服务。
改进技能
这是整个循环的核心。你已经运行了测试用例,用户也审阅了结果,现在你需要根据他们的反馈改进技能。
如何思考改进
-
从反馈中归纳规律。 这里发生的事情,概括来说,是我们正在尝试创建可以被使用上百万次的技能(也许确实如此,甚至可能更多),以适用于许多不同的提示词。你和用户在这里只是针对少数几个示例反复迭代,因为这样能加快进度。用户对这些示例非常熟悉,能快速评估新输出。但如果你和用户共同开发的技能只能用于这些示例,那它就毫无用处。不要做繁琐的过拟合修改,也不要施加过度严格的 MUST 要求;如果某个问题一直存在,不妨尝试换用不同的比喻,或建议采用不同的工作模式。试一试成本相对较低,也许就能找到很棒的方案。
-
让提示词保持精简。 删除没有发挥作用的内容。务必阅读完整对话记录,而不只是最终输出;如果技能似乎让模型浪费大量时间做无用功,可以尝试移除导致这种情况的部分,看看效果如何。
-
说明原因。 尽力解释要求模型这样做背后的原因。如今的大模型很聪明,具备良好的心智理论能力;只要提供合适的框架,它们就能超越机械遵循指令,真正推动事情取得进展。即使用户的反馈简短或令人沮丧,也要试着真正理解任务、用户为何这样写,以及他们实际写了什么,然后把这种理解融入指令。如果你发现自己把 ALWAYS 或 NEVER 全部大写,或者使用非常僵化的结构,就要提高警惕;如果可能,换一种方式解释,并说明原因,让模型理解你要求这样做的重要性。这种方法更有人情味,也更有力、更有效。
-
留意测试用例之间重复的工作。 阅读测试运行的对话记录,看看 Task 工具的调用是否都分别编写了类似的辅助脚本,或都采用了相同的多步骤方法。如果 3 个测试用例都让 Agent 编写了
create_docx.py或build_chart.py,这就强烈表明技能应该把该脚本打包进来。只编写一次,放进scripts/,并告诉技能使用它。这样可以避免今后的每次调用都重复造轮子。
这项任务相当重要(我们正努力创造每年数十亿美元的经济价值!),而思考时间并不是瓶颈;请花些时间认真斟酌。我建议先起草一版修改稿,再重新审视并改进。尽最大努力设身处地理解用户的想法,以及他们想要和需要什么。
迭代循环
改进技能后:
- 将改进应用到技能中
- 在新的
iteration-<N+1>/目录中重新运行所有测试用例,包括基线运行。如果你要创建新技能,基线始终是without_skill(不使用技能)——后续迭代也保持不变。如果你要改进现有技能,请自行判断哪种基线更合适:用户最初提供的版本,还是上一轮迭代的版本。 - 使用
skill_serve_review工具启动审查器,并将previousWorkspace指向上一轮迭代 - 等待用户审查并告知你已完成
- 阅读新的反馈,再次改进并重复
持续进行,直到:
- 用户表示满意
- 所有反馈均为空(看起来一切正常)
- 你已无法取得有意义的进展
高级:盲测比较
如果你希望更严谨地比较两个版本的技能(例如,用户询问“新版本真的更好吗?”),可以使用盲测比较系统。阅读 agents/comparator.md 和 agents/analyzer.md 了解详情。基本思路是:将两个输出交给独立 Agent,但不告知它们分别对应哪个版本,让它判断质量;然后分析胜出版本的原因。
这是可选操作,需要使用 Task 工具(general 子 Agent 类型),大多数用户都不需要。人工审查循环通常已足够。
描述优化
SKILL.md frontmatter 中的 description 字段是决定 OpenCode 是否调用技能的主要机制。创建或改进技能后,请主动提出优化 description,以提高触发准确率。
第 1 步:生成触发评估查询
创建 20 条评估查询,兼有应触发和不应触发的情况。保存为 JSON:
[
{"query": "the user prompt", "should_trigger": true},
{"query": "another prompt", "should_trigger": false}
]
查询必须真实可信,是 OpenCode 用户实际可能输入的内容。不要写抽象请求,而要写具体、明确且包含足够细节的请求。例如,包含文件路径、用户工作或处境相关的个人背景、列名及其值、公司名称、URL 等。适当加入一些背景信息。查询可以使用小写字母、缩写、拼写错误或随意的口语表达。长度也要有所变化,重点测试边界情况,而不是只写一眼就能判断的内容(用户之后有机会确认这些查询)。
不佳:"格式化这些数据"、"从 PDF 中提取文本"、"创建图表"
较好:"好吧,我老板刚发了我这个 xlsx 文件(在下载文件夹里,文件名好像是 'Q4 sales final FINAL v2.xlsx'),她要我添加一列,以百分比显示利润率。收入在 C 列,成本应该在 D 列吧"
对于应触发的查询(8–10 条),要考虑覆盖范围。针对同一意图采用不同表达方式——有些正式,有些随意。加入用户未明确提及技能或文件类型,但显然需要该技能的情况。加入一些不常见的用例,以及与其他技能存在竞争但应由此技能优先处理的情况。
对于不应触发的查询(8–10 条),最有价值的是容易误判的情况——它们与技能共享关键词或概念,但实际需要的是其他功能。考虑相邻领域、措辞含糊且容易触发简单关键词匹配但不应触发的请求,以及涉及该技能功能、但使用其他工具更合适的场景。
最重要的是避免:不要让不应触发的查询显得明显无关。对 PDF 技能来说,"编写一个斐波那契函数" 就是太简单的反例——它无法检验任何东西。不应触发的查询应该足够棘手。
步骤 2:与用户一起审查
使用 HTML 模板向用户展示评测集,以供审查:
- 从
templates/eval-review.html读取模板(位于 opencode-skill-creator 技能目录中,与此 SKILL.md 同级) - 替换占位符:
__EVAL_DATA_PLACEHOLDER__→ 评测项的 JSON 数组(不要加引号——这是一个 JS 变量赋值)__SKILL_NAME_PLACEHOLDER__→ 技能名称__SKILL_DESCRIPTION_PLACEHOLDER__→ 技能当前的描述
- 写入临时文件(例如
/tmp/eval_review_<skill-name>.html)并打开:open /tmp/eval_review_<skill-name>.html - 用户可以编辑查询、切换 should-trigger、添加或移除条目,然后点击“Export Eval Set”
- 文件会下载到
~/Downloads/eval_set.json——如果有多个版本(例如eval_set (1).json),请检查 Downloads 文件夹并选择最新版本
此步骤很重要——糟糕的评测查询会导致糟糕的描述。
步骤 3:运行优化循环
告诉用户:“这需要一些时间——我会运行优化循环,并定期检查进度。”
将评测集保存到工作区,然后使用 skill_optimize_loop 工具:
Call skill_optimize_loop with:
evalSetPath: <path-to-trigger-eval.json>
skillPath: <path-to-skill>
model: <model-id-powering-this-session>
maxIterations: 5
使用系统提示中提供的模型 ID(即为当前会话提供支持的模型),以确保触发测试符合用户的实际体验。
此工具会自动处理完整的优化循环。它会将评测集拆分为 60% 的训练集和 40% 的留出测试集,评估当前描述(每个查询运行 3 次,以获得可靠的触发率),然后调用 OpenCode,根据失败的情况提出改进建议。它会在训练集和测试集上重新评估每个新描述,最多迭代 5 次。完成后,它会返回包含 best_description 的 JSON——根据测试集分数而非训练集分数进行选择,以避免过拟合。
技能触发方式
了解触发机制有助于设计更好的评测查询。技能会以名称和描述的形式显示在 OpenCode 的 available_skills 列表中,OpenCode 会根据描述决定是否调用技能。需要注意的是,OpenCode 只会在无法轻松独立处理任务时调用技能——例如“读取此 PDF”这样的简单单步查询,即使描述完全匹配,也可能不会触发技能,因为 OpenCode 可以直接使用基本工具完成任务。对于复杂、多步骤或专业性强的查询,只要描述匹配,通常都能可靠地触发技能。
这意味着评测查询应该足够实质,让 OpenCode 确实能从调用技能中受益。像“读取文件 X”这样的简单查询不是好的测试用例——无论描述质量如何,它们都不会触发技能。
步骤 4:应用结果
从 JSON 输出中提取 best_description,并更新技能的 SKILL.md frontmatter。向用户展示修改前后的内容,并报告分数。
技能安装
技能创建并验证完成后,帮助用户安装技能。技能可以安装在以下两个位置:
- 项目级:
.opencode/skills/<skill-name>/SKILL.md——仅在此项目中可用 - 全局:
~/.config/opencode/skills/<skill-name>/SKILL.md——在所有项目中可用
将技能目录复制到所需位置。目录名称必须与 SKILL.md frontmatter 中的 name 字段一致。
将所有草稿和评测产物保留在暂存位置;只将最终验证通过的技能目录复制到项目级或全局安装路径。
安装前,可以调用 skill_validate 工具验证技能。
可用的插件工具
opencode-skill-creator 插件提供以下自定义工具,可在会话期间使用:
skill_validate— 验证技能的 SKILL.md 结构和 frontmatterskill_parse— 解析 SKILL.md 并返回其名称、描述和内容长度skill_eval— 针对一组评估查询测试触发准确度skill_improve_description— 根据评估失败情况,使用 LLM 改进描述skill_optimize_loop— 使用训练集/测试集划分进行完整的评估→改进优化循环skill_aggregate_benchmark— 将 grading.json 文件汇总为基准统计数据skill_generate_report— 生成 HTML 优化报告skill_serve_review— 启动评估审核查看器(HTTP 服务 + 浏览器)skill_stop_review— 停止正在运行的审核服务skill_export_static_review— 生成独立的 HTML 审核页面(无需服务)
参考文件
agents/ 目录包含专门任务的说明(通过 Task 工具使用)。需要启动相关任务时,请阅读这些说明。
agents/grader.md— 如何根据输出评估断言agents/comparator.md— 如何对两个输出进行盲测 A/B 对比agents/analyzer.md— 如何分析某个版本胜出的原因
references/ 目录包含其他文档:
references/schemas.md— evals.json、grading.json 等文件的 JSON 结构
这里再重复一次核心循环,以示强调:
- 弄清楚技能的用途
- 起草或编辑技能
- 在测试提示词上运行 opencode-with-access-to-the-skill
- 与用户一起评估输出:
- 创建 benchmark.json(通过
skill_aggregate_benchmark),并启动查看器(通过skill_serve_review),帮助用户审核输出 - 运行定量评估
- 创建 benchmark.json(通过
- 重复以上步骤,直到你和用户都满意
- 为用户安装最终技能。
如果你有 TodoList(使用 todowrite 工具),请添加步骤,以确保不会遗漏。请务必将“创建 evals JSON 并启动评估查看器(通过 skill_serve_review),以便人工审核测试用例”添加到 TodoList 中。
祝你顺利!