没有指标的代价
Skill 变差了,你怎么知道?
- 等到用户投诉,已经发生了多少次糟糕体验
- 等到有人抱怨"AI 最近感觉变差了",无法定位是哪个 Skill、哪个维度
- 等到业务指标下降,追溯成本极高
有了指标,质量下降可以在用户感知之前被发现。
L1/L2/L3 分层框架
csharp
L3 --- 系统健康(System Health)
↳ 可用率、时延、Token 消耗、错误率
↳ 采集:每次调用自动记录
L2 --- 输出质量(Output Quality)
↳ 格式合规率、LLM-as-Judge 质量分
↳ 采集:定期抽样评测(高频 Skill 每天,低频每周)
L1 --- 业务价值(Business Outcome)
↳ 任务完成率、输出采纳率、用户评分
↳ 采集:用户反馈 + 行为追踪
三层依赖关系:
L3 健康 → L2 质量 → L1 价值
L3 频繁超时 → L2 输出被截断 → L1 任务失败
L3 健康但 L2 质量差 → L1 用户不采纳
三层正常 → Skill 真正有价值
L3 是基础,L2 是中间层,L1 是最终目标。报警时从 L3 往上排查,比从 L1 往下倒推快得多。
Demo 设计
测试对象:rnd-technical-writer,给定主题写 Markdown 技术文章。
6 次调用覆盖中英文混合:
| ID | 输入(截断) | 语言 |
|---|---|---|
| T01 | Python asyncio event loop internals | EN |
| T02 | Redis 缓存穿透、击穿、雪崩 | CN |
| T03 | Docker multi-stage builds | EN |
| T04 | LangGraph 状态管理入门教程 | CN |
| T05 | HTTP/2 multiplexing | EN |
| T06 | Rust 所有权模型(面向 Python 读者) | CN |
L2 格式检查规则(代码检查,不依赖 LLM):
python
def check_format(article: str) -> tuple[bool, list[str]]:
issues = []
if "---" not in article[:300]:
issues.append("missing frontmatter")
h2_count = len(re.findall(r"^## ", article, re.MULTILINE))
if h2_count < 3:
issues.append(f"only {h2_count} H2 sections (need ≥3)")
if "```" not in article:
issues.append("no code block")
if len(article.split()) < 200:
issues.append(f"too short: {len(article.split())} words")
return len(issues) == 0, issues
L2 质量评分(LLM-as-Judge,4 维加权):
technical_accuracy × 0.35
depth × 0.25
clarity × 0.20
practical_value × 0.20
运行结果
Step 1:L3 采集
csharp
[T01] Python asyncio... ✓ 52.9s ~1515 tokens
[T02] Redis 缓存穿透... ✓ 40.2s ~470 tokens
[T03] Docker multi-stage... ✓ 33.5s ~1312 tokens
[T04] LangGraph 状态管理... ✓ 50.6s ~996 tokens
[T05] HTTP/2 multiplexing.. ✓ 39.9s ~1264 tokens
[T06] Rust 所有权模型... ✓ 39.4s ~541 tokens
Step 2:L2 评分
ini
[T01] ✓ format ok | acc=4 dep=4 cla=5 pra=4 → 4.20/5
[T02] ✗ missing frontmatter; no code block; too short: 71 words
acc=4 dep=3 cla=4 pra=3 → 3.55/5
[T03] ✓ format ok | acc=4 dep=4 cla=5 pra=4 → 4.20/5
[T04] ✓ format ok | acc=4 dep=3 cla=4 pra=4 → 3.75/5
[T05] ✓ format ok | acc=4 dep=3 cla=5 pra=3 → 3.75/5
[T06] ✗ missing frontmatter; too short: 149 words
acc=4 dep=3 cla=4 pra=3 → 3.55/5
健康看板
ini
══════════════════════════════════════════════════════════════════════
Skill Health Dashboard: rnd-technical-writer
══════════════════════════════════════════════════════════════════════
── L3: System Health ──
Metric Value Threshold Status
──────────────────────────── ───────── ────────── ──────
Availability 100.0% >99% ✓
P90 Latency 50.6s <30s ✗
P99 Latency 50.6s <60s ✓
Avg Tokens/call 1016 (budget)
── L2: Output Quality ──
Format Compliance 66.7% >95% ✗
Quality Score (L-J) 3.83 >3.8/5 ✓
── L1: Business Value ──
Task Completion Rate 83.3% >75% ✓
Adoption Rate 66.7% >60% ✓
Avg User Rating 3.50 >4.0/5 ✗
── Alerts ──
🟡 [WARNING] P90 latency > 30s current=50.6s threshold=30s
🟡 [WARNING] Format compliance < 95% current=66.7% threshold=95%
🟡 [WARNING] Avg rating < 4.0 current=3.50 threshold=4.0
三个发现
发现 1:P90 时延 50.6s,6 次调用全部超阈值
6 次调用全部超过了 30s 阈值,最快的是 T03(33.5s)。glm-4-flash 生成一篇完整技术文章需要 30-50s,这对用户是可感知的等待。
告警把"用户觉得慢"变成了精确的数字:P90=50.6s,超出 30s 目标 67%,可以直接讨论是切模型还是加 streaming。
后续行动:
- 评估更快的模型(更高 RPM 或更低延迟的 endpoint)
- 对长文章任务加入流式输出(streaming),减少用户感知等待
- 或将阈值调整为 60s,承认当前模型的特性
发现 2:中文请求格式合规率 0%,英文 100%
T02、T06 是两个失败的格式检查。T01、T03、T05(英文请求)全部通过,T04(中文请求)例外通过,T02、T06 失败。
失败原因:
- T02:无 frontmatter、无代码块、71 words(用
split()计数,中文文本几乎全部被截到少量词) - T06:无 frontmatter、149 words(同样是中文字数问题)
两个问题叠加:
split()字数检查对中文失效(第 01 篇也发现了这个问题)- 模型对中文请求有时跳过 frontmatter,英文请求几乎总是生成
Skill Prompt 用英文写,格式要求对中文输出没有做等价声明,所以模型自行省略了格式要求。修复方向:
markdown
## 输出要求
无论请求语言是中文还是英文,均必须包含:
- YAML frontmatter(title, description, tags)
- 至少 3 个 H2 章节
- 至少 1 个代码块
发现 3:质量分 3.83,刚好越过阈值
平均质量分 3.83/5,阈值是 3.8,通过了,但仅勉强通过。如果没有设置这个阈值,这个数字会被当作"正常"接受。
质量分的组成:T02(3.55)和 T06(3.55)拉低了均值。两个 fail 用例的 depth 和 practical_value 只有 3 分,说明 Skill 在中文请求上不仅格式差,内容深度也不足。
L2 的两个子指标互相补充:格式检查找到了"无 frontmatter、无代码块",质量评分找到了"depth=3、practical_value=3",两个指标指向同一根因------Skill Prompt 对中文场景的格式要求没有覆盖。
指标告警规则参考
yaml
alerts:
# L3
- availability_7d < 99% → CRITICAL:立即排查
- p90_latency > 30s → WARNING:检查模型/接口状态
- p90_latency > 60s → CRITICAL:服务不可用级别
# L2
- format_compliance_7d < 95% → WARNING:抽样查看问题输出
- quality_score_7d < 3.5 → CRITICAL:考虑回滚 Skill 版本
- quality_score_7d < 3.8 → WARNING:排查低分调用
# L1
- task_completion_delta < -10% (单周) → CRITICAL:立即用户访谈
- adoption_rate < 60% → WARNING:调查采纳障碍
- avg_rating < 4.0 → WARNING:结合 L2 定位原因
落地路线图
css
第一步(不需要工具,立即可做):
□ 整理现有 Skill 台账
□ 手动估计每个 Skill 的调用频率和主观满意度
→ 这是最原始的 L1 基线
第二步(1-2 周):
□ 在每次 Skill 调用前后打印时延和 Token 数
□ 得到真实 L3 基线数字
第三步(2-4 周):
□ 对 Top 3 业务 Skill 建立 L2 评测集
□ 每周跑一次抽样,记录质量分趋势
第四步(月度运营):
□ 加入 👍/👎 用户反馈入口,得到真实 L1 数据
□ 将三层汇总,出月度 Skill 健康报告
总结
- P90 告警把模糊的"感觉慢"变成精确的数字:50.6s vs 30s 阈值,可以直接指导优化方向
- 格式合规率揭示了 Prompt 的语言盲区:英文 100% 通过,中文有格式缺失,根因是 Prompt 没有对中文输出做等价声明
- 质量分 3.83 勉强过关,L2 双指标相互印证:格式检查发现结构问题,质量评分发现内容深度不足,两者指向同一根因
参考资料
- Langfuse 文档------Skill 调用追踪
- 本系列完整 Demo 代码:skill-04-metrics
欢迎访问 PrimeSkills ------ 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。
更多实用知识和有趣产品,欢迎访问我的个人主页