Skill 系列(01):Skill 评测体系——如何量化一个 AI Skill 的质量

Skill 评测的两层问题

普通软件测试只有一层:代码跑对了吗?Skill 有两层:

sql 复制代码
层 1 --- Trigger 层:LLM 有没有判断"这句话需要调用这个 Skill"?
层 2 --- Execution 层:Skill 内部执行有没有完成任务?

漏掉任何一层,评测都不完整。Skill A 的成功率是 90%,但如果触发率只有 60%,真实体验远比"有点差"糟糕。

测试对象是 rnd-technical-writer(技术博客写作 Skill),20 个 Trigger 测试用例 + 两个 Task 完成率任务 + 一组 A/B Prompt 对比,全部数据来自真实运行。


评测框架设计

Trigger 评测

核心指标:

ini 复制代码
Recall    = TP / (TP + FN)  ← 该触发的有没有被触发
Precision = TP / (TP + FP)  ← 触发的里有多少是对的
F1        = 2 × Recall × Precision / (Recall + Precision)

测试集构成(20 个用例):

复制代码
TP(真正例,应触发)      ×8   ← 明确写文章、教程、深度解析
TN(真负例,不应触发)    ×8   ← 知识问答、系列规划、代码帮助
EDGE(边界用例)         ×4   ← 语义模糊、中英混合

清晰的 TP/TN 用例谁都能答对,边界用例才能暴露 Skill 描述的歧义。

自动化方式: 把 Skill 描述 + 用户输入交给 LLM,让它预测是否触发,返回 JSON:

python 复制代码
TRIGGER_EVAL_PROMPT = """You are evaluating whether a user message would trigger a specific AI Skill.

Skill specification:
{skill_description}

User message: "{user_input}"

Answer in valid JSON only:
{{
  "prediction": "trigger" or "no_trigger",
  "reasoning": "one sentence explanation"
}}"""

Task 完成率评测

两级检查:

erlang 复制代码
Level 2(结构性):规则检查,不依赖 LLM
  → 字数是否达标
  → 是否包含代码块
  → 是否有 H2 章节标题

Level 3(质量,LLM-as-Judge):4 个维度各打 1-5 分
  → 技术准确性(权重 35%)
  → 深度(权重 25%)
  → 清晰度(权重 20%)
  → 实用价值(权重 20%)

Judge Prompt 模板:

python 复制代码
JUDGE_PROMPT = """You are an expert technical content reviewer.
Evaluate the following AI-generated technical article.

Scoring dimensions (1--5 each):
1. Technical accuracy
2. Depth
3. Clarity
4. Practical value

Respond in valid JSON only:
{
  "technical_accuracy": <1-5>,
  "depth": <1-5>,
  "clarity": <1-5>,
  "practical_value": <1-5>,
  "summary": "<one sentence assessment>"
}"""

运行结果

Part 1:Trigger 评测

ini 复制代码
──────────────────────────────────────────────────────────────────────
Part 1: Trigger Evaluation
Skill: rnd-technical-writer  |  Test cases: 20
──────────────────────────────────────────────────────────────────────
  [ 1] TP    expect=trigger     got=trigger     ✓ TP
  [ 2] TP    expect=trigger     got=trigger     ✓ TP
  ...(8/8 TP 全部正确)
  [ 9] TN    expect=no_trigger  got=no_trigger  ✓ TN
  ...
  [15] TN    expect=no_trigger  got=trigger     ✗ FP   ← 唯一失败
  ...
  [17] EDGE  expect=trigger     got=trigger     ✓ TP
  [18] EDGE  expect=trigger     got=trigger     ✓ TP
  [19] EDGE  expect=trigger     got=trigger     ✓ TP
  [20] EDGE  expect=no_trigger  got=no_trigger  ✓ TN

  Confusion matrix: TP=11  TN=8  FP=1  FN=0
  Accuracy:  95%  (19/20)
  Recall:    100%
  Precision: 92%
  F1:        0.96

20 个用例,19 个正确,F1=0.96。唯一的失败是:

vbnet 复制代码
Input:    "帮我写一个解析 JSON 的 Python 函数"
Expected: no_trigger
Got:      trigger
Reason:   "The user is asking for a technical function to parse JSON in Python,
           which falls under the skill's purpose of writing technical articles."

Part 2:Task 完成率

yaml 复制代码
  [T001] Write a technical article about Redis TTL configuration...
    Level 2 (structural): ✓  All checks passed
    Level 3 (LLM-as-Judge):
      Technical accuracy: 4/5
      Depth:              3/5
      Clarity:            5/5
      Practical value:    4/5
      Weighted score:     3.95/5

  [T002] 写一篇关于 Python 类型注解的入门文章
    Level 2 (structural): ✗  Issues: ['Too short: 165 words (min 300)']
    Level 3 (LLM-as-Judge):
      Technical accuracy: 4/5
      Depth:              3/5
      Clarity:            5/5
      Practical value:    4/5
      Weighted score:     3.95/5

Part 3:A/B Prompt 对比

yaml 复制代码
  [Version A] Original system prompt
    Weighted: 4.20/5  (63.7s)
    technical_accuracy: 4/5  depth: 4/5  clarity: 5/5  practical_value: 4/5

  [Version B] Improved system prompt (pain-point hook + checklist)
    Weighted: 4.20/5  (71.8s)
    technical_accuracy: 4/5  depth: 4/5  clarity: 5/5  practical_value: 4/5

  Result: No significant difference (<0.1 delta)

三个工程发现

发现 1:1 个 FP 暴露了 Skill 描述的边界模糊

失败用例是:"帮我写一个解析 JSON 的 Python 函数"

模型的推断:用户要求写一段"技术性的 Python 代码",是在要求输出而不是提问,"写"这个动词触发了 Skill。

Skill 描述写的是 writing technical articles or tutorials,没有明确排除"写代码"。模型合理地把"写一个函数"解读成了"写作"任务。

在描述里加一条负面示例可以修复这个问题:

sql 复制代码
Do NOT trigger when:
  - User asks for code snippets, functions, or scripts (write the code directly)

1 个 FP 带来的信息比 F1=0.96 更有用,因为它直接指出了 Skill 描述的哪行有歧义。

发现 2:Level 2 的字数检查对中文文本失效

T002(写 Python 类型注解的入门文章)Level 2 报告"Too short: 165 words",但实际上文章内容很完整。

问题出在检查实现:

python 复制代码
word_count = len(article.split())  # ← 按空格分词

中文文本没有空格分隔词语,split() 只能按标点和空格分,中文内容几乎全部被当作"一个词"计算。此外,模型的输出被 ```````markdown```` 代码块包裹,进一步干扰了计数。

165 个"词"实际对应的是完整的中文文章------字符数可能超过 800 字。

修复方式:

python 复制代码
def count_content_length(text: str) -> int:
    """Count characters for CJK, words for Latin."""
    clean = re.sub(r"```.*?```", "", text, flags=re.DOTALL)  # strip code fences
    cjk_chars = len(re.findall(r"[一-鿿]", clean))
    latin_words = len(re.findall(r"[a-zA-Z]+", clean).split()) if not cjk_chars else 0
    return cjk_chars + latin_words

Level 2 规则检查背后有语言假设。在中英混合场景下,至少要对字数检查做语言分支处理。

发现 3:LLM 评委在细粒度差异上有局限

A/B 对比中,两个版本得到了完全相同的分数(4/4/5/4),结论是"无显著差异"。

Version B 的 Prompt 增加了三个要求:从痛点切入、至少 2 个带注释的代码示例、结尾 Checklist。这些是明确的结构性差异,但 Judge 给出了相同的评分。

两种可能:

  1. 对于这个输入和 glm-4-flash,两个 Prompt 确实产生了质量相当的输出
  2. Judge 的评分粒度不够细,4/5 两档区间太粗,无法区分"好"和"很好"

应对策略:

  • 不要依赖单次评分,改用 A/B 胜率(多次比较,统计胜率 > 60% 才认为有显著差异)
  • 增加开放式评测维度:在打分之外,让 Judge 列出两个版本的具体优劣
  • 换更强的 Judge 模型(这里用的是 glm-4-flash 既当 Skill 又当 Judge,评审者和被评审者是同一个模型)

实施路线图

arduino 复制代码
Week 1:
  □ 为最核心的 1 个 Skill 构造完整测试集(TP:TN:边界 = 8:8:4)
  □ 手动运行,得到 Trigger 召回率/精确率基线

Week 2:
  □ 加 Task 完成率评测(Level 2 结构检查 + Level 3 Judge 打分)
  □ 修复中文字数检查 Bug
  □ 记录分数到 Skill 文档

Week 3:
  □ 修改 Skill,用评测框架验证修改是否有改善
  □ 跑完整的"修改 → 评测 → 结论"循环

设计 Checklist

Trigger 评测

  • 测试集覆盖 TP / TN / 边界三类(8:8:4 是合理起点)
  • Skill 描述里包含负面示例(Do NOT trigger when)
  • 单次 F1 < 0.9 时,先检查 Skill 描述是否有歧义

Task 完成率评测

  • Level 2 字数检查对中文使用字符数,不用 split()
  • Level 2 在打分前剥离 markdown 代码块包裹
  • Judge 模型比被测 Skill 使用的模型更强

A/B 对比

  • 单次评分相同时,改用多次胜率(≥5 次比较)
  • 评委和被评审不用同一个模型

总结

  1. F1 数字不如失败用例:那 1 个 FP 告诉你 Skill 描述的哪行有歧义,比 F1=0.96 更有用
  2. Level 2 检查有语言假设 :中文字数用 split() 是 Bug;输出格式(是否包裹在代码块里)同样会让结构检查失效
  3. LLM-as-Judge 需要多次采样:单次评分粒度有限,A/B 对比改用胜率统计

参考资料


欢迎访问 PrimeSkills ------ 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。

更多实用知识和有趣产品,欢迎访问我的个人主页

相关推荐
IT_陈寒4 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
用户3521802454756 小时前
🎆从 Prompt 到 Skill:让 Spring AI Agent 学会"装新技能"
人工智能·spring boot·ai编程
米小虾6 小时前
手把手教你搭建第一个生产级AI Agent:从选型到实战的完整指南
人工智能·agent
任沫6 小时前
Agent之Function Call
javascript·人工智能·go
米小虾7 小时前
2026年AI Agent全面爆发:从开源生态到企业级应用的进化之路
人工智能·agent
用户6919026813397 小时前
Vibe Coding 开发项目的基本范式
人工智能·设计模式·代码规范
To_OC7 小时前
别再跟 AI 死磕 prompt 了,我写了个 Loop 让它自己改到满意为止
人工智能·aigc·agent
血小溅8 小时前
三大 AI 编码框架深度对比:GSD vs OpenSpec vs Superpowers
人工智能·后端
武子康11 小时前
调查研究-186 LangChain 和 LangGraph 的区别:从快速构建 Agent 到生产级工作流编排
人工智能·langchain·llm