背景
这里我们讨论从anthropics 提供的skill-creator来讨论怎么去创建SKILL,当然
How to create custom Skills这里也有说明,但是这里讲的比较笼统。
SKILL是什么,与AGENT的关系
AGNET是什么
Agent是智能代理,能够主动的感知上下文信息,做决策并采取行动的计算实体。
SKILL是什么
SKILL是一套由指令,脚本,以及资源组成的可以指导大模型怎么完成一项特定任务的任务流的详细说明,它可以保证完成该任务的稳定性。
AGENT和SKILL的关系
AGENT要有所动作(感知上下文采取行动),他得知道怎么做,SKILL就是告诉AGNET去怎么做的一套行为准则或者SOP(标准流程),所以说AGENT会调用SKILL去真正的做事。SKILL引导 AGENT去怎么做。
skill-creator是什么
skill-creator是anthropics官方维护一个有效的编写SKILL的SKIll.它的目的是让大模型知道怎么去写一个高效的SKILL。并且以迭代的方式去改进该SKILL.
在最新的版本中,采用的是交互式(尽可能提供有用的信息)的方式。
文件结构
├── skill-creator
│ │ ├── agents # 子代理说明
│ │ │ ├── analyzer.md # 事后分析代理 - 分析基准结果
│ │ │ ├── comparator.md # 盲比较代理
│ │ │ └── grader.md # 评分代理 - 如何评估断言
│ │ ├── assets # 资源文件
│ │ │ └── eval_review.html
│ │ ├── eval-viewer # 评估查看器
│ │ │ ├── generate_review.py
│ │ │ └── viewer.html
│ │ ├── LICENSE.txt
│ │ ├── references # 参考文档
│ │ │ └── schemas.md
│ │ ├── scripts # 创建、测试和优化技能的脚本
│ │ │ ├── __init__.py
│ │ │ ├── aggregate_benchmark.py
│ │ │ ├── generate_report.py
│ │ │ ├── improve_description.py
│ │ │ ├── package_skill.py
│ │ │ ├── quick_validate.py
│ │ │ ├── run_eval.py
│ │ │ ├── run_loop.py
│ │ │ └── utils.py
│ │ └── SKILL.md # SKILL主文件 - 完整的工作流程和使用指南
以上是创建SKILL的SKILL的文件布局。
该`SKILL`要表达的创建`SKILL`的大致过程如下:
1. 想清楚这个skill是要干什么以及要怎么做
2. 写一个简单的skill手稿
3. 创建一些测试prompts,并运行他们
4. 帮助用户定性或者定量的评估模型
- 当评估测试prompts在后台运行的时候,起草一些定量评估,并向用户解释该prompts
- 使用`eval-viewer/generate_review.py`脚本去展示测试评估结果,同时让他们查看定量指标
5. 基于用户对结果的反馈评估重写SKIll
6. 重复直到满意为止
7. 扩大测试集,并再次尝试更大规模
skill-creator元数据字段
元数据的描述以YAML格式来进行描述
---
name: skill-creator
description: Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, update or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
---
| 字段 | 解释 | 说明 |
|---|---|---|
| name | 该技能的名字 | 必选 |
| description | 对技能功能及其使用时机的清晰描述 | 必选 |
这里的name必须和创建skill的文件夹的名字保持一致;
这个skill相比之前的增加了衡量该skill的性能基准测试,A/B测试,以便进行评估.具体的可以查看chore: export latest skills
创建一个SKILL
捕获意图
首先需要了解写该SKILL的意图,:使用的工具、步骤顺序、用户所做的更正、观察到的输入/输出格式
1. 这个skill需要干什么
2. 这个skill什么时候触发(触发的上下文)
3. 输出格式是什么
4. 是否应该设置测试用例来验证技能是否有效?有客观可验证的结果的Skill是好的(文件转换、数据提取、代码生成、固定工作流步骤),主观性的输出(写作风格,技巧)通常我们不太需要
访谈和查找
主动询问边界情况、输入/输出格式、成功标准和依赖项等问题。在您成这部分之前,不要编写测试prompts。
检查可用的 MCPS服务–如果有用(搜索文档、查找类似技能、查找最佳实践),如果子代理可用,请通过子代理并行查找,否则内部查找。做好准备以减少用户的负担。
注意:从这里可以看出,该skill的创建是基于交互式的,让用户回答问题来尽可能的让该SKILL更加高效的满足用户的需求
编写SKILL.md
基于用户的采访,填充name和description以及compatibility
| 字段 | 解释 | 说明 |
|---|---|---|
| name | 该技能的名字 | 必选 |
| description | 对技能功能及其使用时机的清晰描述,这里是主要的触发机制:包括skill做什么以及使用它的场景,这里的什么时候触发信息应该在这里,而不是在正文中,而且这个描述要应该更加的积极一点 | 必选 |
| compatibility | 所需工具、依赖项 | 可选 |
SKILL写作指南
SKILL的结构
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)
渐进式解析
SKILL使用三级加载系统:
1. 元数据 (name + description) - 始终在上下文中(小于100 字)
2. SKILL.md 正文 - 技能触发时在上下文中(<500 行)
3. 捆绑资源 - 根据需要(无限制,脚本可以在不加载的情况下执行)
关键点:
- 将 SKILL.md 保持在 500 行以下;如果接近这个限制,请添加额外的层级结构,并清楚地向使用该SKILL的模型(agents)指出下一步应该去哪里跟进
- 在 SKILL.md 中清楚地引用文件,并提供指导何时读取它们
- 对于大型参考引用文件(>300 行),包含目录
领域组织:当SKILL支持多个领域/框架时,按照领域组织:
cloud-deploy/
├── SKILL.md (工作流 + 选择)
└── references/
├── aws.md
├── gcp.md
└── azure.md
常规原则
SKILL不能包含恶意软件、漏洞利用代码或任何可能损害系统安全的内容。SKILL的内容不应该让用户对其意图感到惊讶。不要建误导性的SKILL或设计用于未经授权访问、数据泄露或其他恶意活动的SKILL。
注意:从这里可以看出,skill的创建不应该犯法以及损害系统安全
写作模式
优先使用祈使句形式,向模型解释为什么事情很重要,而不是用老旧的必,因为这样会让SKILL更加通用化一点,而不是具体到某个案例。
注意:这里为什么向模型解释为什么是因为这样能够让大模型理解这种原因,才能够进行更加广泛的语义匹配,从而达到智能的效果
定义输出格式
您可以这样做:
## 报告结构
始终使用这个确切的模板:
# [标题]
## 执行摘要
## 主要发现
## 建议
示例模式 - 包括示例很有用。
比如说您可以这样格式化:
## git提交commit格式
**示例 1:**
输入:使用 JWT 令牌添加用户身份验证
输出:feat(auth): implement JWT-based authentication
prompt测试案例
在边写好了SKILL的初稿以后,想出2到3个真是的测试prompt,以以下格式保存到evals/evals.json文件下:
{
"skill_name": "example-skill",
"evals": [
{
"id": 1,
"prompt": "User's example prompt",
"expected_output": "Description of expected result",
"files": ["evals/files/sample1.pdf"],
"expectations": [
"The output includes X",
"The skill used script Y"
]
}
]
}
字段说明:
skill_name:与技能 frontmatter 匹配的名称evals[].id:唯一整数标识符evals[].prompt:要执行的prompt任务evals[].expected_output:可读的成功的描述evals[].files:输入文件路径的可选列表(相对于技能根目录)evals[].expectations:可验证声明的列表
运行和评估测试用例(A/B测试)
第 1 步:在同一回合中生成所有AGENT(带SKILL的AGENT 和 baseline AGENT)
对于每个测试用例,在同一回合中生成两个子agent——一个带SKILL,一个不带。这很重要:不要先运行带SKILL的子AGENT,然后再生成基线AGENT。一次启动所有内容,这样它们都会在大致相同的时间完成。
带SKILL的AGENT以以下格式运行
执行此任务:
- 技能路径:<path-to-skill>
- 任务:<eval prompt>
- 输入文件:<eval files if any, or "none">
- 保存输出到:<workspace>/iteration-<N>/eval-<ID>/with_skill/outputs/
- 要保存的输出:<what the user cares about — e.g., "the .docx file", "the final CSV">
基线运行(相同的prompt,但基线取决于上下文):
- 创建新SKILL:根本没有SKILL。相同的提示,保存到
without_skill/outputs/。 - 改进现有SKILL:旧版本。在编辑之前,快照技能(
cp -r <skill-path> <workspace>/skill-snapshot/),然后将基线子AGENTS指向快照。保存到old_skill/outputs/。
注意:这里说的都是让大模型去做的,根据是不是新SKILL来进行A/B测试
对于相同的prompt:
1. 如果是新建SKILL,则运行带SKILL的AGENT(基线)和不带SKILL的AGENT
2. 如果是改进SKILL,则运行旧版本的SKILL的AGENT(基线)和新版本的SKILL的AGENT
为每个测试用例编写一个 eval_metadata.json(断言暂时可以为空)。如果有必要的话根据eval_name来新建目录。
{
"eval_id": 0,
"eval_name": "descriptive-name-here",
"prompt": "The user's task prompt",
"assertions": []
}
这里的eval_metadata.json是对于每个测试用例判断好与不好的原数据信息
第 2 步:在Agent运行时起草断言
不要只是等待AGENT运行完成——您可以有效地利用这段时间。为每个测试用例起草定量断言,并更新 eval_metadata.json 文件和 evals/evals.json,
好的断言是客观可验证的,并且有描述性名称——它们应该在benckmark查看器中清晰易读,以便有人在查看结果时立即理解每个断言检查什么,描述了什么。
第 3 步:运行完成时捕获时序指标数据
当每个子AGENT任务完成时,您会收到包含 total_tokens 和 duration_ms 的通知。立即将此数据保存到此次运行目录中的 timing.json:
{
"total_tokens": 84852,
"duration_ms": 23332,
"total_duration_seconds": 23.3
}
第 4 步:评分、聚合并启动查看器
一旦所有测试完成:
-
对每个测试评分 启动一个评分
子agent,读取agents/grader.md并针对输出评估每个断言。将结果保存到每个运行目录中的grading.json.
grading.json格式如下{ "expectations": [ { "text": "The output includes the name 'John Smith'", "passed": true, "evidence": "Found in transcript Step 3: 'Extracted names: John Smith, Sarah Johnson'" }, { "text": "The spreadsheet has a SUM formula in cell B10", "passed": false, "evidence": "No spreadsheet was created. The output was a text file." }, { "text": "The assistant used the skill's OCR script", "passed": true, "evidence": "Transcript Step 2 shows: 'Tool: Bash - python ocr_script.py image.png'" } ], "summary": { "passed": 2, "failed": 1, "total": 3, "pass_rate": 0.67 }, "execution_metrics": { "tool_calls": { "Read": 5, "Write": 2, "Bash": 8 }, "total_tool_calls": 15, "total_steps": 6, "errors_encountered": 0, "output_chars": 12450, "transcript_chars": 3200 }, "timing": { "executor_duration_seconds": 165.0, "grader_duration_seconds": 26.0, "total_duration_seconds": 191.0 }, "claims": [ { "claim": "The form has 12 fillable fields", "type": "factual", "verified": true, "evidence": "Counted 12 fields in field_info.json" }, { "claim": "All required fields were populated", "type": "quality", "verified": false, "evidence": "Reference section was left blank despite data being available" } ], "user_notes_summary": { "uncertainties": ["Used 2023 data, may be stale"], "needs_review": [], "workarounds": ["Fell back to text overlay for non-fillable fields"] }, "eval_feedback": { "suggestions": [ { "assertion": "The output includes the name 'John Smith'", "reason": "A hallucinated document that mentions the name would also pass — consider checking it appears as the primary contact with matching phone and email from the input" }, { "reason": "No assertion checks whether the extracted phone numbers match the input — I observed incorrect numbers in the output that went uncaught" } ], "overall": "Assertions check presence but not correctness. Consider adding content verification." } } -
聚合到基准 — 从技能创建器目录运行聚合脚本:
python -m scripts.aggregate_benchmark <workspace>/iteration-N --skill-name <name>这会产生
benchmark.json和benchmark.md,其中包含每个配置的通过率、时间和标记,带有 mean ± stddev 和增量。如果手动生成 benchmark.json,请参阅references/schemas.md查看查看器期望的确切模式。
benchmark.json格式如下:{ "metadata": { "skill_name": "pdf", "skill_path": "/path/to/pdf", "executor_model": "claude-sonnet-4-20250514", "analyzer_model": "most-capable-model", "timestamp": "2026-01-15T10:30:00Z", "evals_run": [1, 2, 3], "runs_per_configuration": 3 }, "runs": [ { "eval_id": 1, "eval_name": "Ocean", "configuration": "with_skill", "run_number": 1, "result": { "pass_rate": 0.85, "passed": 6, "failed": 1, "total": 7, "time_seconds": 42.5, "tokens": 3800, "tool_calls": 18, "errors": 0 }, "expectations": [ {"text": "...", "passed": true, "evidence": "..."} ], "notes": [ "Used 2023 data, may be stale", "Fell back to text overlay for non-fillable fields" ] } ], "run_summary": { "with_skill": { "pass_rate": {"mean": 0.85, "stddev": 0.05, "min": 0.80, "max": 0.90}, "time_seconds": {"mean": 45.0, "stddev": 12.0, "min": 32.0, "max": 58.0}, "tokens": {"mean": 3800, "stddev": 400, "min": 3200, "max": 4100} }, "without_skill": { "pass_rate": {"mean": 0.35, "stddev": 0.08, "min": 0.28, "max": 0.45}, "time_seconds": {"mean": 32.0, "stddev": 8.0, "min": 24.0, "max": 42.0}, "tokens": {"mean": 2100, "stddev": 300, "min": 1800, "max": 2500} }, "delta": { "pass_rate": "+0.50", "time_seconds": "+13.0", "tokens": "+1700" } }, "notes": [ "Assertion 'Output is a PDF file' passes 100% in both configurations - may not differentiate skill value", "Eval 3 shows high variance (50% ± 40%) - may be flaky or model-dependent", "Without-skill runs consistently fail on table extraction expectations", "Skill adds 13s average execution time but improves pass rate by 50%" ] } -
做一次分析师传递 — 读取基准数据并显现处聚合统计可能隐藏的模式,。请参阅
agents/analyzer.md("分析基准结果"部分)了解要查找的内容–例如无论SKILL如何总是通过的断言(无区分能力)、高方差评估,时间/标记权衡 -
启动查看器,同时显示定性输出和定量数据:
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=$!
改进技能
如何思考改进
- 从反馈中概括。
- 保持提示精简。
- 解释原因。
- 寻找跨测试用例的重复工作。
迭代循环
改进SKILL后:
- 将您的改进应用到SKILL
- 将所有测试用例重新运行到新的
iteration-<N+1>/目录,包括基线运行。如果您正在创建新SKILL,基线始终是without_skill(无技能)——这在迭代中保持不变。如果您正在改进现有技能,使用您认为有意义的基线:用户带来的原始版本,或者之前的迭代。 - 使用
--previous-workspace指向前一个迭代启动审查器 - 等待用户查看并告诉您他们完成了
- 阅读新的反馈,再次改进,重复
继续直到:
- 用户说他们很高兴
- 反馈都是空的(一切看起来都不错)
- 您没有取得有意义的进展
高级:盲比较
对于您想要更严格地比较SKILL两个版本的情况(例如,用户问"新版本真的更好吗?"),有一个盲比较系统。阅读 agents/comparator.md 和 agents/analyzer.md 了解详细信息。基本想法是:将两个输出交给一个独立agent,不告诉它是哪一个,让它判断质量。然后分析为什么获胜者赢了。
这是可选的,需要子agent,大多数用户不需要。人工审查循环通常就足够了。
描述优化
SKILL.md frontmatter 中的 description 字段是决定 agent 是否调用SKILL的主要机制。在创建或改进技能后,提供优化描述以获得更好的触发准确性。
技能触发的工作原理
了解触发机制有助于设计更好的评估查询。技能出现在 Claude 的 available_skills 列表中,包含其名称和描述,Claude 根据该描述决定是否咨询技能。需要知道的重要一点是,Claude 只为它不能轻易自行处理的任务咨询技能——简单、一步到位的查询如"读取此 PDF"可能不会触发技能,即使描述完全匹配,因为 Claude 可以用基本工具直接处理它们。复杂、多步骤或专门的查询在描述匹配时可靠地触发技能。
这意味着您的评估查询应该足够实质性,以便 Claude 实际上会从咨询SKILL中受益。简单的查询如"读取文件 X"是糟糕的测试用例——无论描述质量如何,它们都不会触发技能。
参考文件
agents/ 目录包含用于专门子代理的说明。在需要生成相关子代理时阅读它们。
agents/grader.md- 如何针对输出评估断言agents/comparator.md- 如何在两个输出之间进行盲 A/B 比较agents/analyzer.md- 如何分析为什么一个版本击败了另一个
references/ 目录有其他文档:
references/schemas.md- evals.json、grading.json 等的 JSON 结构

2

被折叠的 条评论
为什么被折叠?



