跳转至

第 4 章:Skill 质量评估体系

本章目标: 建立完整的 Skill 评估框架,掌握测试方法和正确率追踪
预计阅读时间: 30 分钟
难度等级: ⭐⭐⭐☆☆(进阶)


📖 目录

  1. 评估维度概览
  2. 触发准确性评估
  3. 任务完成率评估
  4. 上下文效率评估
  5. 用户满意度评估
  6. 维护成本评估
  7. 自动化测试框架
  8. 正确率追踪机制
  9. A/B 测试设计
  10. 本章实践

评估维度概览

五维评估框架

                    ┌─────────────────┐
                    │   Skill 质量    │
                    └────────┬────────┘
           ┌─────────────────┼─────────────────┐
           │                 │                 │
           ↓                 ↓                 ↓
    ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
    │ 触发准确性   │ │ 任务完成率   │ │ 上下文效率   │
    │  (Trigger)   │ │ (Completion) │ │  (Context)   │
    └──────────────┘ └──────────────┘ └──────────────┘
           │                 │                 │
           └─────────────────┼─────────────────┘
           ┌─────────────────┼─────────────────┐
           ↓                 ↓                 ↓
    ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
    │ 用户满意度   │ │ 维护成本     │ │ 综合评分     │
    │ (Satisfaction)│ │  (Cost)      │ │   (Score)    │
    └──────────────┘ └──────────────┘ └──────────────┘

评估指标总览

维度 核心指标 测量方法 目标值
触发准确性 误触发率、漏触发率 日志分析 <5% / <5%
任务完成率 成功率、一次通过率 用户反馈 >90% / >80%
上下文效率 Token 使用量、加载文件数 会话分析 <5KB / <3 文件
用户满意度 NPS、重复使用率 调查问卷 >8 / >60%
维护成本 更新频率、问题报告数 版本追踪 <1 次/月 / <5%

触发准确性评估

指标定义

误触发率(False Positive Rate):

1
2
3
4
误触发率 = 误触发次数 / 总触发次数 × 100%

误触发:Skill 在不应该触发时触发
例:用户说"我会用 PDF",pdf-tools 错误触发

漏触发率(False Negative Rate):

1
2
3
4
漏触发率 = 漏触发次数 / 应触发次数 × 100%

漏触发:Skill 在应该触发时未触发
例:用户说"分析这个 PDF",pdf-tools 未触发

触发准确率(Accuracy):

准确率 = (正确触发次数) / (总触发机会) × 100%
       = 100% - 误触发率 - 漏触发率

数据收集方法

方法 1:会话日志分析

# 分析会话日志
def analyze_triggers(session_logs):
    results = {
        'correct_triggers': 0,
        'false_positives': 0,
        'false_negatives': 0
    }

    for log in session_logs:
        # 检查 Skill 是否触发
        triggered = check_skill_triggered(log)
        # 检查是否应该触发
        should_trigger = check_should_trigger(log)

        if triggered and should_trigger:
            results['correct_triggers'] += 1
        elif triggered and not should_trigger:
            results['false_positives'] += 1
        elif not triggered and should_trigger:
            results['false_negatives'] += 1

    return results

方法 2:用户反馈收集

1
2
3
4
5
6
7
8
在 Skill 使用后询问(可选):

"这个 Skill 的触发是否符合您的预期?"
- ✅ 是,正是我需要的
- ❌ 否,不应该触发
- ❌ 否,应该触发但没有

记录反馈用于计算准确率

方法 3:测试用例

# 测试用例集
test_cases = [
    # (用户输入,应该触发,说明)
    ("分析这个 PDF", True, "明确触发"),
    ("我会用 PDF 工作", False, "提及但不需要处理"),
    ("提取 PDF 文本", True, "明确功能"),
    ("PDF 是什么", False, "知识问题"),
    ("帮我看看这个文档", True, "隐式触发"),
    # ... 更多用例
]

def evaluate_trigger_accuracy(test_cases):
    correct = 0
    for user_input, should_trigger, description in test_cases:
        triggered = test_skill_trigger(user_input)
        if triggered == should_trigger:
            correct += 1

    return correct / len(test_cases) * 100

目标值

指标 优秀 良好 需改进
误触发率 <3% <5% >10%
漏触发率 <3% <5% >10%
触发准确率 >95% >90% <85%

改进策略

误触发高 → 收紧触发条件:

1
2
3
4
5
6
# 修改前(太宽泛)
description: 处理文档

# 修改后(更精确)
description: PDF 文件处理:提取文本、编辑、分析。
             当用户需要处理 PDF 文件内容时使用

漏触发高 → 扩展触发词:

1
2
3
4
5
6
# 添加更多触发场景
description: |
  PDF 处理。当用户需要:
  (1) 提取文本,(2) 编辑 PDF,(3) 分析内容,
  (4) 转换格式,(5) 合并拆分,
  或说"这个文档"、"这个文件"(上下文中是 PDF)时使用


任务完成率评估

指标定义

成功率(Success Rate):

1
2
3
成功率 = 成功完成的任务数 / 总任务数 × 100%

成功:用户目标达成,无需人工干预

一次通过率(First Pass Yield):

1
2
3
一次通过率 = 一次成功的任务数 / 总任务数 × 100%

一次成功:无需重试、无需纠正

平均重试次数(Average Retries):

1
2
3
平均重试 = 总重试次数 / 总任务数

重试:用户需要重复指令或纠正

数据收集方法

方法 1:任务完成标记

# 在 Skill 中标记任务完成
def mark_task_completion(task_id, success, retries=0):
    log_entry = {
        'task_id': task_id,
        'success': success,
        'retries': retries,
        'timestamp': datetime.now().isoformat()
    }
    save_to_log(log_entry)

# 使用时
if task_completed_successfully():
    mark_task_completion(task_id, True)
elif task_failed():
    mark_task_completion(task_id, False)

方法 2:用户确认

1
2
3
4
5
6
7
8
任务完成后询问:

"任务完成!结果是否符合预期?"
- ✅ 是,完全符合
- ⚠️ 部分符合,需要调整
- ❌ 否,需要重做

记录用户确认

方法 3:会话分析

# 分析会话中的纠正模式
def analyze_correction_patterns(session):
    corrections = 0
    for message in session.messages:
        if contains_correction(message):
            # "不对"、"错了"、"应该是"等
            corrections += 1

    return corrections

# 纠正次数多 = 任务完成率低

目标值

指标 优秀 良好 需改进
成功率 >95% >90% <80%
一次通过率 >85% >75% <60%
平均重试 <0.3 <0.5 >1.0

改进策略

成功率低 → 分析失败原因:

1
2
3
4
5
失败原因分类:
1. 理解错误 → 改进触发条件
2. 执行错误 → 修复脚本/逻辑
3. 输出错误 → 调整输出格式
4. 边界情况 → 添加异常处理

一次通过率低 → 优化工作流:

1
2
3
4
常见问题:
- 步骤遗漏 → 添加检查清单
- 参数错误 → 添加验证
- 格式不对 → 提供模板


上下文效率评估

指标定义

平均 Token 使用量:

1
2
3
平均 Token = 总 Token 数 / 会话数

包括:元数据 + SKILL.md + 加载的参考文档

加载文件数:

1
2
3
平均加载文件数 = 总加载文件数 / 会话数

包括:SKILL.md + references 文件

上下文密度:

1
2
3
上下文密度 = 有用信息量 / 总 Token 数

有用信息:直接用于任务的内容

测量方法

方法 1:会话分析工具

def analyze_context_usage(session_id):
    session = get_session(session_id)

    # 统计加载的文件
    loaded_files = session.loaded_files
    total_tokens = session.total_tokens

    # 统计有用内容
    useful_tokens = count_useful_tokens(session)

    return {
        'files_loaded': len(loaded_files),
        'total_tokens': total_tokens,
        'useful_tokens': useful_tokens,
        'density': useful_tokens / total_tokens
    }

方法 2:Skill 自检

在 Skill 中添加自检(定期):

"检查上下文使用:
- 当前加载文件数:X
- 估计 Token 数:Y
- 是否超过阈值:是/否

如果超过,考虑:
1. 能否精简 SKILL.md?
2. 能否延迟加载某些文件?
3. 能否移到 scripts/执行?"

目标值

指标 优秀 良好 需改进
平均 Token <3KB <5KB >10KB
加载文件数 <2 <3 >5
上下文密度 >70% >50% <30%

改进策略

Token 过多 → 精简内容:

1
2
3
4
1. 删除冗余解释
2. 缩短示例
3. 移到 references/
4. 使用更简洁的表达

加载文件多 → 优化结构:

1
2
3
4
1. 合并相关文件
2. 使用渐进式披露
3. 延迟非必要加载
4. 脚本执行代替加载


用户满意度评估

指标定义

净推荐值(NPS):

1
2
3
4
5
6
7
NPS = 推荐者比例 - 贬损者比例

推荐者:评分 9-10
被动者:评分 7-8
贬损者:评分 0-6

目标:NPS > 50

重复使用率:

1
2
3
重复使用率 = 重复使用的用户数 / 总用户数 × 100%

重复使用:7 天内使用 2+ 次

用户留存率:

7 日留存 = 7 天后仍使用的用户数 / 初始用户数 × 100%
30 日留存 = 30 天后仍使用的用户数 / 初始用户数 × 100%

数据收集方法

方法 1:满意度调查

定期询问(每 10 次使用后):

"请评价这个 Skill:
⭐⭐⭐⭐⭐ 非常满意
⭐⭐⭐⭐  满意
⭐⭐⭐   一般
⭐⭐    不满意
⭐     非常不满意

改进建议:[开放文本]"

方法 2:使用频率分析

def analyze_usage_frequency(user_id):
    usage = get_user_usage(user_id)

    # 计算使用频率
    days_with_usage = len(set(u.date for u in usage))
    total_days = (usage[-1].date - usage[0].date).days + 1

    return {
        'frequency': days_with_usage / total_days,
        'total_uses': len(usage),
        'avg_per_day': len(usage) / total_days
    }

方法 3:反馈分析

def analyze_feedback(feedbacks):
    sentiments = {
        'positive': 0,
        'neutral': 0,
        'negative': 0
    }

    for feedback in feedbacks:
        sentiment = classify_sentiment(feedback.text)
        sentiments[sentiment] += 1

    return sentiments

目标值

指标 优秀 良好 需改进
NPS >50 >30 <0
重复使用率 >70% >50% <30%
7 日留存 >60% >40% <20%

维护成本评估

指标定义

更新频率:

1
2
3
更新频率 = 更新次数 / 时间(月)

包括:Bug 修复、功能更新、文档更新

问题报告率:

1
2
3
问题报告率 = 问题报告数 / 使用次数 × 100%

问题:Bug、错误、困惑

平均修复时间(MTTR):

1
2
3
MTTR = 总修复时间 / 问题数

修复时间:从报告到解决

目标值

指标 优秀 良好 需改进
更新频率 <1/月 <2/月 >4/月
问题报告率 <2% <5% >10%
MTTR <24h <48h >1 周

自动化测试框架

测试类型

1. 单元测试:

1
2
3
4
5
# 测试单个函数
def test_extract_text():
    result = extract_text('fixtures/sample.pdf')
    assert len(result) > 0
    assert isinstance(result, str)

2. 集成测试:

1
2
3
4
5
6
7
8
# 测试完整工作流
def test_full_workflow():
    # 1. 触发 Skill
    # 2. 执行任务
    # 3. 验证输出
    output = run_skill('pdf-tools', 'extract', 'sample.pdf')
    assert output.success
    assert output.text is not None

3. 回归测试:

1
2
3
4
5
# 确保更新不破坏现有功能
def test_regression():
    for test_case in regression_suite:
        result = run_skill(test_case.input)
        assert result == test_case.expected

测试框架示例

# tests/test_skill.py
import pytest
from skill_runner import SkillRunner

class TestSkillTrigger:
    @pytest.mark.parametrize("input,should_trigger", [
        ("分析 PDF", True),
        ("我会 PDF", False),
        ("提取文本", True),
        ("PDF 是什么", False),
    ])
    def test_trigger(self, input, should_trigger):
        runner = SkillRunner('pdf-tools')
        triggered = runner.check_trigger(input)
        assert triggered == should_trigger

class SkillTaskCompletion:
    def test_extract_text(self):
        runner = SkillRunner('pdf-tools')
        result = runner.run('extract', 'fixtures/sample.pdf')
        assert result.success
        assert len(result.text) > 0

    def test_rotate(self):
        runner = SkillRunner('pdf-tools')
        result = runner.run('rotate', 'fixtures/sample.pdf', 90)
        assert result.success
        assert result.output_file.exists()

if __name__ == '__main__':
    pytest.main()

持续集成

# .github/workflows/skill-test.yml
name: Skill Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Run Tests
        run: |
          pip install -r requirements.txt
          pytest tests/

      - name: Validate Skill
        run: |
          python scripts/package_skill.py skills/my-skill

正确率追踪机制

日志格式

{
  "timestamp": "2026-03-26T10:30:00Z",
  "skill": "pdf-tools",
  "task": "extract_text",
  "input": "sample.pdf",
  "success": true,
  "duration_ms": 1500,
  "tokens_used": 3500,
  "user_feedback": "positive",
  "retries": 0
}

追踪仪表板

# Skill 性能仪表板

## 触发准确性
- 误触发率:2.3% ✅
- 漏触发率:1.8% ✅
- 准确率:95.9% ✅

## 任务完成率
- 成功率:94.2% ✅
- 一次通过率:87.5% ✅
- 平均重试:0.18 ✅

## 上下文效率
- 平均 Token:3.2KB ✅
- 加载文件:2.1 ✅
- 上下文密度:68% ⚠️

## 用户满意度
- NPS: 52 ✅
- 重复使用率:65% ✅
- 7 日留存:58% ✅

告警机制

def check_alerts(metrics):
    alerts = []

    if metrics['false_positive_rate'] > 0.10:
        alerts.append("误触发率过高")

    if metrics['success_rate'] < 0.80:
        alerts.append("成功率过低")

    if metrics['avg_tokens'] > 10000:
        alerts.append("Token 使用过多")

    if metrics['nps'] < 0:
        alerts.append("NPS 为负")

    return alerts

A/B 测试设计

测试场景

场景 1:触发词优化

1
2
3
4
A 组:当前 description
B 组:优化后 description

测量:触发准确率、漏触发率

场景 2:工作流优化

1
2
3
4
A 组:当前工作流
B 组:优化后工作流

测量:成功率、一次通过率、用户满意度

场景 3:输出格式优化

1
2
3
4
A 组:当前输出格式
B 组:新输出格式

测量:用户满意度、重复使用率

实施方法

def run_ab_test(skill_name, variant_a, variant_b, duration_days=7):
    # 随机分配用户
    users = get_all_users()
    group_a = random_sample(users, 0.5)
    group_b = [u for u in users if u not in group_a]

    # 部署变体
    deploy_variant(skill_name, 'A', variant_a, group_a)
    deploy_variant(skill_name, 'B', variant_b, group_b)

    # 收集数据
    metrics_a = collect_metrics(group_a, duration_days)
    metrics_b = collect_metrics(group_b, duration_days)

    # 统计分析
    result = statistical_test(metrics_a, metrics_b)

    return {
        'winner': 'A' if result.a_better else 'B',
        'confidence': result.confidence,
        'improvement': result.improvement_pct
    }

本章实践

练习 1:设计评估框架

任务: 为你的 Skill 设计完整的评估框架

输出:

## Skill 评估框架

### 评估维度
| 维度 | 指标 | 目标值 | 测量方法 |
|------|------|-------|---------|
| 触发准确性 | ... | ... | ... |
| 任务完成率 | ... | ... | ... |
| ... | ... | ... | ... |

### 数据收集计划
1. ...
2. ...
3. ...

### 改进循环
[描述如何根据评估结果改进]

练习 2:编写测试用例

任务: 为你的 Skill 编写 10+ 个测试用例

输出:

# tests/test_my_skill.py
import pytest

class TestTrigger:
    @pytest.mark.parametrize("input,should_trigger", [
        # 至少 5 个用例
        ("...", True),
        ("...", False),
        # ...
    ])
    def test_trigger(self, input, should_trigger):
        ...

class TaskCompletion:
    def test_task_1(self):
        ...

    def test_task_2(self):
        ...


本章总结

核心要点

  1. 五维评估框架:
  2. 触发准确性
  3. 任务完成率
  4. 上下文效率
  5. 用户满意度
  6. 维护成本

  7. 关键指标:

  8. 触发准确率 >90%
  9. 成功率 >90%
  10. Token <5KB
  11. NPS >30

  12. 自动化测试:

  13. 单元测试
  14. 集成测试
  15. 回归测试
  16. CI/CD

  17. 持续追踪:

  18. 日志记录
  19. 仪表板
  20. 告警机制
  21. A/B 测试

检查清单

评估 Skill 时检查:

1
2
3
4
5
6
7
□ 触发准确率 >90%
□ 成功率 >90%
□ Token 使用 <5KB
□ NPS >30
□ 有自动化测试
□ 有日志追踪
□ 有改进循环


第 4 章完
下一章:第 5 章:Skill 进化与持续优化