Skip to content

优化 Skill 描述

本页为描述优化指南的非官方中文翻译

一个 Skill 只有在被激活时才有帮助。SKILL.md frontmatter 中的 description 字段是智能体用来决定是否为给定任务加载该 Skill 的主要机制。描述过于简略意味着 Skill 在应当触发时不会触发;描述过于宽泛意味着它在不应触发时也会触发。

本指南介绍如何系统地测试和改进 Skill 的描述,以提高触发准确率。

智能体使用 Progressive Disclosure / 渐进式披露 来管理上下文。在启动时,它们仅加载每个可用 Skill 的 namedescription — 仅够决定某个 Skill 何时可能相关。当用户的任务与某个描述匹配时,智能体会将完整的 SKILL.md 读入上下文,并遵循其中的指令。

这意味着描述承担着触发的全部重任。如果描述没有传达 Skill 的使用场景,智能体就不会知道去使用它。

一个重要的细节:智能体通常仅为需要超出其自身能力范围的知识或能力的任务而查询 Skills。像”阅读这份 PDF”这样简单的、单步的请求,即使描述完美匹配,也可能不会触发 PDF Skill,因为智能体可以使用基本工具来处理它。涉及专业知识(不熟悉的 API、特定领域的工作流或罕见的格式)的任务,才是精心编写的描述能够发挥作用的场景。

在测试之前,了解什么是好的描述会有所帮助。一些原则:

  • 使用祈使语气。 将描述构建为对智能体的指令:“Use this skill when…”(在以下情况下使用此 Skill…)而不是”This skill does…”(此 Skill 用于…)。智能体正在决定是否采取行动,因此请告诉它何时行动。
  • 关注用户意图,而非实现方式。 描述用户想要实现什么,而非 Skill 的内部机制。智能体是根据用户的要求进行匹配的。
  • 倾向于更主动地表达。 明确列出 Skill 适用的场景,包括用户没有直接提到该领域的情况:“even if they don’t explicitly mention ‘CSV’ or ‘analysis.’”
  • 保持简洁。 通常几句话到一个短段落即可 — 长度足以覆盖 Skill 的范围,短到不会在智能体跨多个 Skill 时膨胀其上下文。规范 强制规定了 1024 个字符的硬性上限。

要测试触发,你需要一个评估查询集 — 真实的用户提示,并标记其是否应当触发你的 Skill。

[
{ "query": "I've got a spreadsheet in ~/data/q4_results.xlsx with revenue in col C and expenses in col D — can you add a profit margin column and highlight anything under 10%?", "should_trigger": true },
{ "query": "whats the quickest way to convert this json file to yaml", "should_trigger": false }
]

目标大约为 20 个查询:8-10 个应当触发,8-10 个不应当触发。

这些测试用于检验描述是否覆盖了 Skill 的范围。请沿以下几个维度变换它们:

  • 措辞:有些正式,有些随意,有些带有拼写错误或缩写。
  • 显式程度:有些直接指出 Skill 的领域(“analyze this CSV”),有些描述需求但不指明(“my boss wants a chart from this data file”)。
  • 详细程度:混合使用简短提示和包含大量上下文的提示 — 一个简短的”analyze my sales CSV and make a chart”与一个包含文件路径、列名和背景信息的长消息并列。
  • 复杂度:在步骤数和决策点方面有所不同。包括单步任务以及多步工作流,以测试当 Skill 所处理的任务埋藏在更大的链条中时,智能体是否能识别其相关性。

最有用的应当触发查询是那些 Skill 可以提供帮助但仅从查询本身看不出来连接性的查询。这些情况下描述措辞会起到决定性作用 — 如果查询已经明确要求 Skill 所做的事情,任何合理的描述都会触发它。

最有价值的负面测试用例是 接近失误 — 与你的 Skill 共享关键词或概念但实际上需要不同内容的查询。这些测试可以检验描述是否精确,而不仅仅是宽泛。

对于一个 CSV 分析 Skill,较弱的负面示例是:

  • "Write a fibonacci function" — 明显无关,测试不出任何东西。
  • "What's the weather today?" — 没有关键词重叠,太容易了。

较强的负面示例:

  • "I need to update the formulas in my Excel budget spreadsheet" — 共享”spreadsheet”和”data”概念,但需要的是 Excel 编辑,而非 CSV 分析。
  • "can you write a python script that reads a csv and uploads each row to our postgres database" — 涉及 CSV,但任务是数据库 ETL,而非分析。

真实的用户提示包含通用测试查询所缺少的上下文。请包含:

  • 文件路径(~/Downloads/report_final_v2.xlsx
  • 个人上下文("my manager asked me to..."
  • 具体的细节(列名、公司名称、数据值)
  • 随意的语言、缩写和偶尔的拼写错误

基本方法是:在已安装 Skill 的情况下,将每个查询通过你的智能体运行,并观察智能体是否调用了它。请确保 Skill 已注册并可被你的智能体发现 — 其工作方式因客户端而异(例如 Skill 目录、配置文件或 CLI 标志)。

大多数智能体客户端都提供某种形式的可观测性 — 执行日志、工具调用历史或详细输出 — 可让你查看运行期间查询了哪些 Skills。有关详细信息,请查阅你的客户端文档。如果智能体加载了你的 Skill 的 SKILL.md,则该 Skill 被触发;如果智能体在没有查询它的情况下继续执行,则该 Skill 未被触发。

当以下情况时,查询”通过”:

  • should_triggertrue 且 Skill 被调用,或
  • should_triggerfalse 且 Skill 未被调用。

模型行为是非确定性的 — 同一个查询在一次运行中可能触发 Skill,而在下一次则不会。请多次运行每个查询(3 次是一个合理的起点),并计算 触发率:运行中 Skill 被调用的比例。

如果其触发率高于阈值(0.5 是一个合理的默认值),则应当触发查询通过。如果其触发率低于该阈值,则不应触发查询通过。

使用 20 个查询,每个查询运行 3 次,总共是 60 次调用。你可能希望将其脚本化。以下是一般的结构 — 用你的智能体客户端提供的相应部分替换 claude 调用和 check_triggered 中的检测逻辑:

#!/bin/bash
QUERIES_FILE="${1:?Usage: $0 <queries.json>}"
SKILL_NAME="my-skill"
RUNS=3
# This example uses Claude Code's JSON output to check for Skill tool calls.
# Replace this function with detection logic for your agent client.
# Should return 0 (success) if the skill was invoked, 1 otherwise.
check_triggered() {
local query="$1"
claude -p "$query" --output-format json 2>/dev/null \
| jq -e --arg skill "$SKILL_NAME" \
'any(.messages[].content[]; .type == "tool_use" and .name == "Skill" and .input.skill == $skill)' \
> /dev/null 2>&1
}
count=$(jq length "$QUERIES_FILE")
for i in $(seq 0 $((count - 1))); do
query=$(jq -r ".[$i].query" "$QUERIES_FILE")
should_trigger=$(jq -r ".[$i].should_trigger" "$QUERIES_FILE")
triggers=0
for run in $(seq 1 $RUNS); do
check_triggered "$query" && triggers=$((triggers + 1))
done
jq -n \
--arg query "$query" \
--argjson should_trigger "$should_trigger" \
--argjson triggers "$triggers" \
--argjson runs "$RUNS" \
'{query: $query, should_trigger: $should_trigger, triggers: $triggers, runs: $runs, trigger_rate: ($triggers / $runs)}'
done | jq -s '.'

译者注:如果你的智能体客户端支持,你可以提前停止运行,一旦结果明朗 — 智能体要么查询了该 Skill,要么在没有它的情况下开始工作。这可以显著减少运行完整评估集的时间和成本。

通过训练/验证集划分避免过拟合

Section titled “通过训练/验证集划分避免过拟合”

如果你针对所有查询优化描述,则存在过拟合的风险 — 精心设计一个适用于这些特定措辞但在其他措辞上失败的描述。

解决方案是拆分你的查询集:

  • 训练集(约 60%):你用来识别失败并指导改进的查询。
  • 验证集(约 40%):你留出的查询,仅用于检查改进是否具有普适性。

请确保两个集合都包含按比例混合的应当触发和不应触发查询 — 不要不小心将所有正面用例放在一个集合中。随机打乱并在整个迭代过程中保持拆分固定,这样你比较的就是苹果对苹果。

如果你使用类似 上文 中的脚本,可以将查询拆分为两个文件 — train_queries.jsonvalidation_queries.json — 并分别针对每个运行该脚本。

  1. 训练集和验证集 上评估当前描述。训练结果指导你的更改;验证结果告诉你这些更改是否具有普适性。
  2. 训练集 中识别失败:哪些应当触发的查询没有触发?哪些不应触发的查询触发了?
    • 仅使用训练集失败来指导你的更改 — 无论是你自己在修改描述还是提示 LLM,都请将验证集的结果排除在此过程之外。
  3. 修改描述。专注于归纳总结:
    • 如果应当触发的查询失败,则描述可能过于狭窄。请扩大范围或添加 Skill 适用场景的上下文。
    • 如果不应触发的查询被错误触发,则描述可能过于宽泛。请添加有关 Skill 做哪些事情的具体性,或阐明此 Skill 与相邻能力之间的边界。
    • 避免从失败的查询中添加特定关键词 — 那就是过拟合。相反,找出这些查询所代表的一般类别或概念,并加以解决。
    • 如果你在几次迭代后陷入困境,请尝试对描述采用结构上不同的方法,而不是增量调整。不同的框架或句子结构可能会突破增量调整无法突破的局限。
    • 请检查描述是否保持在 1024 个字符的限制以内 — 描述往往会在优化过程中变长。
  4. 重复步骤 1-3,直到所有 训练集 查询都通过,或者你不再看到有意义的改进。
  5. 根据验证通过率选择最佳迭代 — 验证集中通过的查询所占的比例。请注意,最佳描述可能不是你最后生成的描述;早期迭代可能比后期迭代的验证通过率更高,而后期迭代可能对训练集过拟合了。

通常五次迭代就足够了。如果没有看到改进,问题可能出在查询上(太容易、太困难或标记不佳),而非描述本身。

译者注:skill-creator Skill 可以端到端地自动化此循环:它拆分评估集、并行评估触发率、使用 Claude 提出描述改进,并生成你可以实时查看的实时 HTML 报告。

一旦你选择了最佳描述:

  1. 更新 SKILL.md frontmatter 中的 description 字段。
  2. 验证描述是否在 1024 个字符的限制 以内。
  3. 验证描述按预期触发。手动尝试几个提示作为快速的健全性检查。要进行更严格的测试,请编写 5-10 个新的查询(混合应当触发和不应触发的查询)并通过评估脚本运行它们 — 由于这些查询从未参与过优化过程,它们可以诚实地检查描述是否具有普适性。

前后对比:

# 优化前
description: Process CSV files.
# 优化后
description: >
Analyze CSV and tabular data files — compute summary statistics,
add derived columns, generate charts, and clean messy data. Use this
skill when the user has a CSV, TSV, or Excel file and wants to
explore, transform, or visualize the data, even if they don't
explicitly mention "CSV" or "analysis."

改进后的描述更具体地说明了 Skill 的功能(汇总统计、派生列、图表、清理),并更广泛地说明了其适用场景(CSV、TSV、Excel;即使没有显式关键词)。

一旦你的 Skill 能够可靠触发,你将需要评估它是否产生良好的输出。有关如何设置测试用例、评分结果和迭代的信息,请参阅 评估 Skill 输出质量