安装方式
命令行安装
在项目根目录执行以下命令,完成 Skill 安装。
npx bzskills add anthropics/skills --skill skill-creator 创建新技能、修改并改进现有技能,以及衡量技能表现。适用于用户希望从零开始创建技能、编辑或优化现有技能、运行测试以评估技能、通过方差分析基准测试技能表现,或优化技能描述以提高触发准确性的场景。
192.6k
下载量
命令行安装
在项目根目录执行以下命令,完成 Skill 安装。
npx bzskills add anthropics/skills --skill skill-creator name: skill-creator
description: 创建新技能、修改并改进现有技能,以及衡量技能表现。适用于用户希望从零开始创建技能、编辑或优化现有技能、运行测试以评估技能、通过方差分析基准测试技能表现,或优化技能描述以提高触发准确性的场景。一个用于创建新技能并迭代改进它们的技能。
概括来说,创建技能的过程是这样的:
eval-viewer/generate_review.py 脚本向用户展示结果供他们查看,同时让他们查看定量指标使用本技能时,你的任务是判断用户处于这个过程的哪个阶段,然后介入并帮助他们推进这些阶段。例如,用户可能会说"我想为X做一个技能"。你可以帮助他们明确具体需求,撰写草稿,编写测试用例,确定评估方式,运行所有提示词,然后重复迭代。
另一方面,用户可能已经有了技能草稿。这种情况下,你可以直接进入评估/迭代环节。
当然,你应该始终保持灵活,如果用户说"我不需要运行一堆评估,就凭感觉来",你也可以照做。
技能完成后(但同样,顺序可以灵活调整),你还可以运行技能描述优化器(我们有单独的脚本),以优化技能的触发效果。
明白了吗?明白了。
技能创建者可能会被各种不同编程术语熟悉程度的人使用。如果你还没听说过(当然你也不可能听说,这是最近才开始的趋势),现在有个潮流是Claude的强大功能正在激励管道工打开终端,父母和祖父母去搜索"如何安装npm"。另一方面,大多数用户可能还是相当懂电脑的。
所以请留意上下文线索,理解如何措辞沟通!在默认情况下,给你一些参考:
如果不确定,可以简要解释术语,如果担心用户不理解,也欢迎用简短的定义澄清。
---
首先理解用户的意图。当前对话可能已经包含了用户想要捕捉的工作流(例如,他们说"把这个做成技能")。如果是这样,先从对话历史中提取答案——用到的工具、步骤顺序、用户做的修正、观察到的输入/输出格式。用户可能需要补充缺失的部分,在进入下一步之前应确认。
主动询问关于边界情况、输入/输出格式、示例文件、成功标准和依赖项的问题。等到这部分确定后再编写测试提示词。
检查可用的MCP——如果对研究有用(搜索文档、查找类似技能、查找最佳实践),可以通过子代理并行研究(如果有的话),否则内联进行。提前准备好上下文,减少用户的负担。
根据用户访谈,填写这些组件:
#### 技能的构成
skill-name/
├── SKILL.md (必需)
│ ├── YAML 前置数据 (name、description 必需)
│ └── Markdown 指令
└── 附带资源 (可选)
├── scripts/ - 用于确定性/重复性任务的可执行代码
├── references/ - 根据需要加载到上下文中的文档
└── assets/ - 输出中使用的文件(模板、图标、字体)
#### 渐进式信息加载
技能使用三级加载系统:
这些字数是大致标准,如果需要可以适当增加。
关键模式:
领域组织:当技能支持多个领域/框架时,按变体组织:
cloud-deploy/
├── SKILL.md (工作流 + 选择)
└── references/
├── aws.md
├── gcp.md
└── azure.md
Claude 只读取相关的参考文件。
#### 无意外原则
不言而喻,技能不能包含恶意软件、利用代码或任何可能危及系统安全的内容。技能的内容不应让用户在阅读描述后对它的意图感到意外。不要同意创建误导性技能或设计用于未经授权访问、数据窃取或其他恶意活动的技能。像"扮演XYZ角色"这样的东西是可以的。
#### 编写模式
指令中优先使用祈使句。
定义输出格式 - 可以这样做:
## 报告结构
始终使用这个精确模板:
# [标题]
## 执行摘要
## 主要发现
## 建议
示例模式 - 包含示例很有用。可以这样格式化(但如果示例中有"输入"和"输出",你可能想稍微调整):
## 提交消息格式
**示例 1:**
输入:使用JWT令牌添加了用户认证
输出:feat(auth): implement JWT-based authentication
试着向模型解释为什么某些事情很重要,而不是使用生硬的强制性"必须"。运用心智理论,尽量使技能通用化,而不是局限于特定例子。先写草稿,然后用全新的眼光审视并改进。
写完技能草稿后,提出2-3个真实的测试提示词——真实用户会实际说的那种话。与用户分享:[你不用使用完全相同的语言]"这里有几个我想尝试的测试用例。这些看起来合适吗?或者你想添加更多?"然后运行它们。
将测试用例保存到 evals/evals.json。暂时不要写断言——只写提示词。你将在下一步(运行进行中)起草断言。
{
"skill_name": "example-skill",
"evals": [
{
"id": 1,
"prompt": "用户的任务提示",
"expected_output": "预期结果的描述",
"files": []
}
]
}
完整模式见 references/schemas.md(包括 assertions 字段,你稍后会添加)。
这部分是一个连续的序列——不要中途停下。不要使用 /skill-test 或任何其他测试技能。
将结果放在 <skill-name>-workspace/ 目录中,与技能目录同级。在工作区内,按迭代组织结果(iteration-1/、iteration-2/ 等),每个测试用例有一个子目录(eval-0/、eval-1/ 等)。不要预先创建所有目录——边进行边创建。
对于每个测试用例,在同一轮次中启动两个子代理——一个带技能,一个不带。这很重要:不要先启动带技能运行,然后回头再启动基准运行。一次性全部启动,这样它们大约同时完成。
带技能运行:
执行此任务:
- 技能路径:<技能路径>
- 任务:<评估提示词>
- 输入文件:<评估文件(如果有),否则为"无">
- 输出保存到:<工作区>/iteration-<N>/eval-<ID>/with_skill/outputs/
- 需保存的输出:<用户关心的内容——例如".docx文件"、"最终CSV">
基准运行(相同提示词,但基准取决于上下文):
without_skill/outputs/。cp -r <skill-path> <workspace>/skill-snapshot/),然后将基准子代理指向快照。保存到 old_skill/outputs/。为每个测试用例编写一个 eval_metadata.json(断言暂时可以为空)。根据测试内容给每个评估一个描述性名称——不仅仅是"eval-0"。目录也使用这个名称。如果本次迭代使用了新的或修改过的评估提示词,为每个新的评估目录创建这些文件——不要假设它们从之前的迭代继承。
{
"eval_id": 0,
"eval_name": "这里填写描述性名称",
"prompt": "用户的任务提示词",
"assertions": []
}
不要干等运行结束——这段时间可以高效利用。为每个测试用例起草定量断言,并向用户解释它们。如果 evals/evals.json 中已存在断言,审查它们并解释每个断言的检查内容。
好的断言是客观可验证的,并且有描述性名称——它们在基准查看器中应该清晰易读,让瞥一眼结果的人立即明白每个断言检查什么。主观技能(写作风格、设计质量)更适合定性评估——不要强行给需要人工判断的事情添加断言。
起草完成后更新 eval_metadata.json 文件和 evals/evals.json。同时向用户解释他们在查看器中会看到什么——包括定性输出和定量基准。
当每个子代理任务完成时,你会收到包含 total_tokens 和 duration_ms 的通知。立即将数据保存到运行目录的 timing.json 中:
{
"total_tokens": 84852,
"duration_ms": 23332,
"total_duration_seconds": 23.3
}
这是捕获这些数据的唯一机会——它们通过任务通知传来,不会在其他地方持久保存。逐个处理每个通知,而不是尝试批量处理。
所有运行完成后:
agents/grader.md,并评估每个断言与输出是否匹配。将结果保存到每个运行目录的 grading.json 中。grading.json 的 expectations 数组必须使用 text、passed 和 evidence 字段(而不是 name/met/details 或其他变体)——查看器依赖这些确切的字段名称。对于可以编程检查的断言,编写并运行脚本,而不是凭肉眼判断——脚本更快、更可靠,并且可以在多个迭代中复用。 python -m scripts.aggregate_benchmark <workspace>/iteration-N --skill-name <name>
这会生成 benchmark.json 和 benchmark.md,包含每个配置的通过率、时间和令牌数,显示平均值±标准差和差值。如果手动生成 benchmark.json,请参见 references/schemas.md 了解查看器期望的确切模式。将每个带技能版本放在其对应的基准版本前面。
agents/analyzer.md("分析基准结果"部分)了解需要关注的事项——比如无论是否有技能都始终通过的断言(非区分性)、高方差的评估(可能不稳定)、以及时间/令牌权衡。 nohup python <skill-creator-path>/eval-viewer/generate_review.py \
<workspace>/iteration-N \
--skill-name "my-skill" \
--benchmark <workspace>/iteration-N/benchmark.json \
> /dev/null 2>&1 &
VIEWER_PID=$!
对于第二次及后续迭代,还要传入 --previous-workspace <workspace>/iteration-<N-1>。
Cowork / 无头环境: 如果 webbrowser.open() 不可用或环境没有显示设备,使用 --static <output_path> 写入一个独立的 HTML 文件,而不是启动服务器。当用户点击"提交所有评论"时,反馈会作为 feedback.json 文件下载。下载后,将 feedback.json 复制到工作区目录中,供下次迭代使用。
注意:请使用 generate_review.py 创建查看器,无需编写自定义 HTML。
"输出"选项卡一次显示一个测试用例:
"基准"选项卡显示统计摘要:每个配置的通过率、时间和令牌使用情况,以及每个评估的细分和分析师观察。
导航通过上一个/下一个按钮或方向键。完成后,他们点击"提交所有评论",将所有反馈保存到 feedback.json。
当用户告诉你他们已完成时,读取 feedback.json:
{
"reviews": [
{"run_id": "eval-0-with_skill", "feedback": "图表缺少轴标签", "timestamp": "..."},
{"run_id": "eval-1-with_skill", "feedback": "", "timestamp": "..."},
{"run_id": "eval-2-with_skill", "feedback": "完美,非常喜欢", "timestamp": "..."}
],
"status": "complete"
}
空的反馈意味着用户认为没问题。集中精力改进那些用户有具体投诉的测试用例。
完成查看后关闭查看器服务器:
kill $VIEWER_PID 2>/dev/null
---
这是循环的核心。你已运行测试用例,用户已审查结果,现在你需要根据他们的反馈让技能变得更好。
create_docx.py 或 build_chart.py,这是一个强烈的信号,表明技能应该打包那个脚本。一次性编写它,放在 scripts/ 中,并告诉技能使用它。这样每次未来调用都可以避免重新发明轮子。这个任务非常重要(我们正在努力创造每年数十亿美元的经济价值!),你的思考时间不是瓶颈;慢慢来,认真思考。我建议先写一个修订草稿,然后重新审视并做出改进。尽最大努力进入用户的角度,理解他们想要和需要什么。
改进技能后:
iteration-<N+1>/ 目录中,包括基准运行。如果你在创建新技能,基准始终是 without_skill(无技能)——这在所有迭代中保持不变。如果你在改进现有技能,根据你的判断选择有意义的基准:用户最初带来的原始版本,还是之前的迭代。--previous-workspace 指向之前的迭代持续进行直到:
---
对于需要更严格比较两个技能版本的情况(例如,用户问"新版本真的更好吗?"),有一个盲测对比系统。阅读 agents/comparator.md 和 agents/analyzer.md 了解详情。基本思路是:将两个输出交给一个独立的代理,不告诉它哪个是哪个,让它评判质量。然后分析胜者胜出的原因。
这是可选的,需要子代理,大多数用户不需要。人工审查循环通常就足够了。
---
SKILL.md 前置数据中的 description 字段是决定 Claude 是否调用技能的主要机制。创建或改进技能后,提供优化描述以提高触发准确性的选项。
创建20个评估查询——混合应该触发和不应该触发的。保存为 JSON:
[
{"query": "用户提示词", "should_trigger": true},
{"query": "另一个提示词", "should_trigger": false}
]
查询必须真实,是 Claude Code 或 Claude.ai 用户实际会输入的内容。不是抽象请求,而是具体、详细、有足够细节的请求。例如,文件路径、关于用户工作或情况的个人背景、列名和值、公司名称、URL。一点点背景故事。有些可能全部小写,或包含缩写、拼写错误或口语化表达。使用不同长度的混合,重点放在边界情况上,而不是让它们清晰明确(用户将有机会签署确认)。
不好的例子:"格式化这些数据"、"从PDF中提取文本"、"创建图表"
好的例子:"ok my boss just sent me this xlsx file (its in my downloads, called something like 'Q4 sales final FINAL v2.xlsx') and she wants me to add a column that shows the profit margin as a percentage. The revenue is in column C and costs are in column D i think"
对于应该触发的查询(8-10个),考虑覆盖率。同一个意图的不同措辞——有些正式,有些随意。包括用户没有明确说出技能或文件类型名称,但明显需要它的情况。加入一些不常见的用例,以及这个技能与另一个技能竞争但应该胜出的情况。
对于不应该触发的查询(8-10个),最有价值的是那些"擦边球"——共享关键词或概念但实际上需要不同东西的查询。思考相邻领域,模棱两可的措辞,以及天真的关键词匹配会触发但实际上不应该触发的情况,还有那些触及技能能做某事但上下文更适合其他工具的查询。
要避免的关键点:不要让不应该触发的查询明显不相关。对于PDF技能,"写一个斐波那契函数"作为负面测试太容易了——它不测试任何东西。负面案例应该确实有难度。
使用HTML模板向用户展示评估集以供审查:
assets/eval_review.html 读取模板__EVAL_DATA_PLACEHOLDER__ → 评估项的JSON数组(周围不要加引号——它是个JS变量赋值)__SKILL_NAME_PLACEHOLDER__ → 技能的名称__SKILL_DESCRIPTION_PLACEHOLDER__ → 技能的当前描述/tmp/eval_review_<skill-name>.html)并打开它:open /tmp/eval_review_<skill-name>.html~/Downloads/eval_set.json——检查 Downloads 文件夹中最新版本,以防有多个(例如 eval_set (1).json)这一步很重要——糟糕的评估查询会导致糟糕的描述。
告诉用户:"这需要一些时间——我会在后台运行优化循环,并定期检查进度。"
将评估集保存到工作区,然后在后台运行:
python -m scripts.run_loop \
--eval-set <path-to-trigger-eval.json> \
--skill-path <path-to-skill> \
--model <model-id-powering-this-session> \
--max-iterations 5 \
--verbose
使用你系统提示中的模型ID(驱动当前会话的那个),这样触发测试与你用户实际体验的相匹配。
在运行过程中,定期查看输出,向用户更新当前迭代和分数情况。
这会自动处理完整的优化循环。它将评估集分为60%训练和40%保留测试,评估当前描述(每个查询运行3次以获得可靠的触发率),然后调用Claude根据失败情况提出改进建议。它重新评估每个新描述在训练和测试集上的表现,最多迭代5次。完成后,它会在浏览器中打开一个HTML报告,显示每次迭代的结果,并返回包含 best_description 的JSON——通过测试分数选择(而不是训练分数),以避免过度拟合。
了解触发机制有助于设计更好的评估查询。技能出现在Claude的 available_skills 列表中,带有名称和描述,Claude根据描述决定是否查阅该技能。需要知道的重要一点是,Claude只会在任务无法轻松自行处理时查阅技能——简单的、一步到位的查询如"读取这个PDF"可能不会触发技能,即使描述完全匹配,因为Claude可以直接使用基本工具处理它们。复杂、多步或专门的查询在描述匹配时能够可靠地触发技能。
这意味着你的评估查询应该足够充实,让Claude真正从查阅技能中受益。像"读取文件X"这样的简单查询是糟糕的测试用例——无论描述质量如何,它们都不会触发技能。
从JSON输出中获取 best_description,并更新技能的SKILL.md前置数据。向用户展示前后对比,并报告分数。
---
present_files 工具可用时)检查你是否能使用 present_files 工具。如果不能,跳过此步骤。如果可以,打包技能并向用户呈现 .skill 文件:
python -m scripts.package_skill <path/to/skill-folder>
打包后,告诉用户生成的 .skill 文件路径,以便他们安装。
---
在 Claude.ai 中,核心工作流是相同的(草稿→测试→审查→改进→重复),但由于 Claude.ai 没有子代理,一些机制需要调整。以下是需要适应的内容:
运行测试用例:没有子代理意味着无法并行执行。对于每个测试用例,读取技能的 SKILL.md,然后按照其指令完成测试提示词。逐一进行。这比独立的子代理严格性较低(你编写了技能,也运行它,所以你拥有完整的上下文),但这是一个有用的合理性检查——而且人工审查步骤可以弥补。跳过基准运行——只需按照请求使用技能完成任务。
审查结果:如果你无法打开浏览器(例如,Claude.ai 的虚拟机没有显示设备,或者你在远程服务器上),完全跳过浏览器查看器。相反,直接在对话中呈现结果。对于每个测试用例,显示提示词和输出。如果输出是用户需要查看的文件(如 .docx 或 .xlsx),将其保存到文件系统,并告诉用户位置,以便他们下载和检查。内联询问反馈:"这个看起来怎么样?有什么需要改的吗?"
基准测试:跳过定量基准测试——它依赖基准比较,没有子代理就没有意义。专注于用户的定性反馈。
迭代循环:与之前相同——改进技能,重新运行测试用例,询问反馈——只是没有中间的浏览器查看器。如果有文件系统,你仍然可以将结果整理到迭代目录中。
描述优化:这一部分需要 claude CLI 工具(特别是 claude -p),该工具仅在 Claude Code 中可用。如果在 Claude.ai 上,跳过它。
盲测对比:需要子代理。跳过它。
打包:package_skill.py 脚本可以在任何有 Python 和文件系统的地方工作。在 Claude.ai 上,你可以运行它,用户可以下载生成的 .skill 文件。
更新现有技能:用户可能要求你更新现有技能,而不是创建新技能。在这种情况下:
name 前置数据字段——保持不变。例如,如果已安装的技能是 research-helper,输出应该是 research-helper.skill(而不是 research-helper-v2)。/tmp/skill-name/,在那里编辑,然后从副本打包。/tmp/ 中暂存,然后复制到输出目录——直接写入可能因权限问题而失败。---
如果你在 Cowork 中,主要需要知道的是:
--static <output_path> 写入一个独立的 HTML 文件,而不是启动服务器。然后提供一个链接,用户可以点击在浏览器中打开 HTML。generate_review.py(而不是编写你自己的定制 html 代码)。提前抱歉,但我这里要用全大写:在你自己评估输入*之前*,先生成评估查看器。你要尽快把它们展示给人工!feedback.json 下载为文件。然后你可以从中读取(你可能需要先请求访问权限)。package_skill.py 只需要 Python 和文件系统。run_loop.py / run_eval.py)应该可以在 Cowork 中正常工作,因为它通过子进程使用 claude -p,而不是浏览器,但请等到你完全完成技能创建且用户确认技能状态良好后再进行。---
agents/ 目录包含专门子代理的指令。当你需要启动相关子代理时读取它们。
agents/grader.md — 如何评估断言与输出的匹配情况agents/comparator.md — 如何在两个输出之间进行盲测 A/B 比较agents/analyzer.md — 如何分析一个版本为什么胜过另一个references/ 目录有额外的文档:
references/schemas.md — evals.json、grading.json 等的 JSON 结构---
再次强调核心循环:
eval-viewer/generate_review.py 帮助用户审查它们请在你的待办事项列表中添加步骤(如果你有这样的功能),以确保你不会忘记。如果你在 Cowork 中,请特别在待办事项列表中添加"创建 evals JSON 并运行 eval-viewer/generate_review.py 让人工审查测试用例",以确保它一定发生。
祝你好运!