taxonomy → eval 映射 —— 每条失败该交给哪种评测
taxonomy → eval 映射 —— 每条失败该交给哪种评测
日期: 2026-06-27 阶段: Phase 1 - 产品定义×评测×可观测底座 标签: #eval-types #llm-as-judge #taxonomy #cost-coverage
核心问题
Day 9-12 我们做完了错误分析全链路:采样 → open coding → axial coding → 一棵失败 taxonomy(v1.0)→ 定向补难例。现在站在一个尴尬的中间地带:taxonomy 告诉了我"系统会在哪些地方犯错",但没告诉我"每种错该用什么去抓"。
这正是 eval 工程最容易出错的一步。新手的两种典型死法:
- 死法一:什么都上 LLM-judge。 连"输出是不是合法 JSON""SAR 草稿有没有引用 CTR 门槛金额"这种确定性检查也喂给一个判官 LLM——慢、贵、每周要维护、还可能判错。
- 死法二:什么都想用代码断言。 把"SAR 叙述读起来专不专业""调查结论与证据是否自洽"硬塞进正则——根本测不了主观质量。
正确做法是 Hamel & Shreya 和 Aman Khan 都反复强调的:先错误分析定义"测什么",再为每个失败类匹配"用什么测"。本篇就是建立这个映射:taxonomy 的每个叶子 → 一种 eval 类型 + 数据来源 + 阈值 + 是否可自动化。这张映射表,就是把 W1-W2 的方法论沉淀成可执行的评测套件的"路由表"。
关键内容
A. 三类 eval 的能力边界——各自能抓什么、抓不到什么
不是三个并列选项,而是三层能力梯度。逐类讲透"它的判别机制 + 它的天花板"。
A.1 代码型 eval(code-based assertion / reference-based check)——确定可回归
机制:把"对错"写成一个布尔函数。output is valid JSON、SAR draft cites tx T0007、recall == 1.0。判定是确定性的,同一输入永远同一结果。
- 成本:Hamel 原话"a simple regex or assertion costs almost nothing"(2026-01)——分钟级编写、近零维护。
- 能抓:结构校验、PII 泄漏、必填字段、引用匹配、与已知正确答案的逐字/结构比对。
- 抓不到:语气是否得体、novel 语境下的事实准确性、推理质量。这些没有"一行能写出的规则"。
- 本项目现状:
evalRuleBaseline(evalBaseline.ts)就是纯代码型 eval——它拿assessCase的topTypology和金标label做精确比对算 recall/FPR。零模型调用、确定、可进 CI。
A.2 LLM-as-judge——主观可扩展
机制:用一个 LLM 当裁判,给它角色 + 上下文 + 评判目标 + 输出标签。Aman Khan 的四段式 judge prompt(2026-04 更新版):① 设角色("你是资深 AML 合规审查员");② 给上下文(要评的 SAR 草稿);③ 给目标("判断叙述是否完整覆盖 5W1H");④ 要标签——用文本标签("完整 / 缺失要素")而非 1-5 数字打分,因为 LLM 理解语言优于数字刻度(Aman Khan 2026-04)。
- 成本:高。Hamel 给的硬数字——判官上线前至少 100 个人工标注样本对齐,之后每周维护监控漂移,且需要开发/PM/领域专家协同(2026-01)。
- 能抓:幻觉、语气-人设错配、完整性、对上下文的忠实度、恰当的不确定性表达。
- 抓不到:结构/语法错误(这类反而该用代码断言,用 judge 是杀鸡用牛刀且不稳)。
- 致命前提:judge 本身必须先被评测。Aman Khan 称之为"用 eval 检查你的 eval"——当 judge 标"友好"而人工标"机械",那个 0% 一致率精确告诉你判官哪里要修。
A.3 人工评审(human review)——金标但贵
机制:领域专家直读 raw trace,open coding 记失败、axial coding 归类、为 judge 提供 ground truth 标注。
- 成本:最贵。Hamel 引述团队把 60-80% 开发时间花在错误分析与评测上(2026-01)。
- 不可替代之处:① 初始错误分析("Always read through the raw traces yourself"——这是发现新失败模式的唯一途径);② 校准/验证自动判官;③ 高风险、需要隐性专业判断的决策。
- 抓不到:规模。一个人一天读不完几千条 trace——这正是要把"测什么"沉淀成前两类自动 eval 的原因。
反直觉洞察①:判官 LLM 不是"省掉人工",而是"放大人工"。 直觉以为 LLM-judge 让人类退场,实际相反——judge 上线前要 100+ 人工标注对齐,上线后每周人工抽检校准漂移。人工标注的总量没减少,只是从"逐条判每个输出"变成"判 100 条 + 持续抽检"。 把 judge 当成"无须人工"的自动化,等于跳过校准直接信一个没测过的测量仪。
B. 每类失败 → eval 类型的决策框架
不是凭感觉分配,而是按两个正交维度决策:失败是客观还是主观(决定 judge 还是代码)× 是否会反复迭代(决定值不值得上贵 eval)。
决策树(每个 taxonomy 叶子跑一遍):
if 失败可由确定性规则判定(结构/引用/数值/精确匹配):
→ 代码型 eval # 首选,Hamel: "catch with assertion if you can"
elif 失败是主观质量(语气/完整性/推理/忠实度):
if 这个失败会被反复迭代(持续泛化失败):
→ LLM-as-judge # 值得付 100+ 标注 + 每周维护的代价
else:
→ 人工抽检 # 一次性/低频失败,不值得建判官
else: # 既非确定规则、又不宜自动化(高风险终判)
→ 人工评审(不可自动化项,见 C)
这个框架直接对应 Hamel 的层级建议:"Start with cheap code-based checks where possible. Only build expensive evaluators for problems you'll iterate on repeatedly."(2026-01)——先穷尽代码能抓的,再把 LLM-judge 留给"修了 prompt 还反复犯"的持久泛化失败。
把它落到本项目 AML taxonomy 上:
| taxonomy 失败叶 | 客观/主观 | eval 类型 | 数据来源 | 阈值 | 可自动化? |
|---|---|---|---|---|---|
| 漏报已知 structuring | 客观 | 代码型(recall) | 金标 label | recall ≥ 0.95 | ✅ |
| normal 误报为类型学 | 客观 | 代码型(FPR) | 金标 normal 子集 | FPR ≤ 8% | ✅ |
| SAR 未引用关键证据 tx | 客观 | 代码型(引用比对) | citedTxIds vs evidenceTxIds | 覆盖率 = 100% | ✅ |
| SAR 金额/门槛数值写错 | 客观 | 代码型(数值断言) | fmtUsd 输出比对 | 精确相等 | ✅ |
| SAR 叙述遗漏 5W1H 要素 | 主观 | LLM-judge | 人工标 100 草稿 | TPR/TNR ≥ 0.9 | ⚠️ 校准后 |
| 叙述语气不专业/口语化 | 主观 | LLM-judge | 同上 | 文本标签一致率 | ⚠️ 校准后 |
| 调查结论与证据不自洽 | 主观+高风险 | 人工评审 | 专家直读 | 逐案 | ❌ |
| 误把合法现金商户判成洗钱 | 客观(数值边界) | 代码型(难例集) | Day 12 难例批 | 失败模式稳定 | ✅ |
C. "不可自动化项"的识别与处理
不是所有失败都该被自动化——有些故意保留人工,识别它们和分配自动 eval 同样重要。
识别准则(满足任一即归为不可自动化):
- 高风险终判:SAR 是否真的上报、是否冻结账户——监管后果严重,必须人在环(HITL)。
- 判定本身依赖隐性专业判断:例如"这串交易在该客户的历史语境下是否反常",连人类专家也要调档案,无法压成一句 prompt。
- 金标标注本身需要人:judge 的 ground truth、taxonomy 的验证——这是自动化的前置输入,逻辑上不能被它要服务的自动化替代。
反直觉洞察②:"能不能自动化"和"该不该自动化"是两回事。 "SAR 草稿语气是否专业"技术上能用 LLM-judge 自动化,但若这个失败一年只出现两三次(非持久泛化失败),建一个要 100+ 标注 + 每周维护的判官是负 ROI——该留给人工抽检。反过来,"是否提交 SAR"也许技术上能让模型给建议,但监管风险决定它永远不该全自动。自动化决策的轴是"成本 × 频率 × 风险",不是"技术上行不行"。
反直觉洞察③:用 LLM-judge 之前必须先用代码 eval 测这个 judge。 这是个递归——judge 是一个 LLM 系统,它也会犯错(判错主观质量)。所以判官的"对错"要用人工标注的 held-out 集,以 TPR/TNR 量化(Hamel 2026-01)。跳过这一步,等于拿一把没校准的尺子去量产品,量出来的好坏全是它自己的偏差。 本项目纪律:任何 LLM-judge 进套件前,先有一个代码型 meta-eval 比对它与 100 条人工标注的一致率,达不到 TPR/TNR ≥ 0.9 不上线。
成本-覆盖率权衡(决定套件构成的核心账):
| eval 类型 | 建设成本 | 单次运行成本 | 维护负担 | 覆盖的失败类型 | 进 CI? |
|---|---|---|---|---|---|
| 代码型断言 | 分钟级 | 近零(无模型调用) | 近零 | 客观(结构/数值/引用/匹配) | ✅ 默认 |
| 参考型比对 | 小时级 | 低 | 低 | 客观(与金标比对) | ✅ |
| LLM-judge | 周-月级(需 100+ 标注) | 中(每条一次模型调用) | 高(每周校准漂移) | 主观(语气/完整/推理) | ⚠️ 校准后、可异步 |
| 人工评审 | —(持续投入) | 高(专家工时) | —(60-80% 开发时间) | 高风险/隐性判断 | ❌(抽样离线) |
读这张表的方式:覆盖率自上而下递增,成本也自上而下递增——套件设计就是在这条曲线上找一个"用最便宜的 eval 抓尽可能多失败"的拐点。AML 套件的实际拐点是:~70% 失败用代码型(数值/引用/recall 这些 AML 天然客观),~25% 留 LLM-judge(SAR 叙述质量),~5% 锁死人工(提交决策)。
设计要点
| 决策 | 选择 | 理由 |
|---|---|---|
| 分配顺序 | 先穷尽代码型,再考虑 judge | Hamel:"catch with assertion if you can",成本最低 |
| judge 触发门槛 | 仅"持久泛化失败" | judge 有 100+ 标注 + 每周维护的高 overhead |
| judge 输出格式 | 文本标签非数字打分 | LLM 理解语言优于数字刻度(Aman Khan) |
| judge 上线前提 | 代码型 meta-eval 比对人工,TPR/TNR ≥ 0.9 | 没校准的判官 = 没校准的尺子 |
| 不可自动化项 | 高风险终判 + 隐性专业判断 + 金标标注 | 自动化轴是成本×频率×风险,非技术可行性 |
| CI 准入 | 代码型进 CI;judge 异步/校准后进 | 确定性才能当质量门 |
对本项目的落地
-
新增
src/aml/evalMap.ts——映射即代码:把上面的"失败叶 → eval 类型"表写成一个结构化常量EVAL_MAP,每条记录{ failureClass, evalType: 'code' | 'judge' | 'human', dataSource, threshold, automatable }。这张表既是文档也是 eval runner 的路由配置——runner 读它决定每个失败类调哪个评测函数。 -
代码型 eval 直接复用现有资产:表里所有
evalType: 'code'的客观项,已有或易加:recall/FPR 走现有evalRuleBaseline(evalBaseline.ts);"SAR 引用覆盖"走一个新断言,比对SarDraft.citedTxIds(types.ts)⊇ 该案assessCase的evidenceTxIds;"金额数值正确"走fmtUsd输出的精确比对。零新增模型依赖,全部可进 CI。 -
LLM-judge 标记为"P3 接入、当前留桩":
SarDraft.generatedBy现在是'rule-template'(types.ts已诚实标注 W1 为规则模板)。判官评 SAR 叙述质量要等 P3 LLM 版 SAR 上线后才有意义——现在在evalMap.ts里把这几条标evalType: 'judge', automatable: 'after-calibration',用计划语气写设计、不谎称已实现。 -
写 meta-eval 骨架(
src/aml/judgeMetaEval.ts,设计稿):约定 judge 上线前必须跑的校准——拿 100 条人工标注的 SAR 草稿,算 judge 与人工的 TPR/TNR,低于 0.9 阻断上线。先把接口和阈值常量定下来(JUDGE_MIN_TPR = 0.9),实现待 P3。 -
automatable: 'human'的项进 HITL 流程而非 eval 套件:types.ts已有ReviewAction = 'approve' | 'return' | 'edit'和AuditEvent——"是否提交 SAR"这类不可自动化终判,归到这条人工复核链路,eval 套件不给它打自动分,只在报告里标"需人工"。这条边界让套件诚实:它不假装能测它测不了的东西。
参考资料
| 资源 | 类型 | 发布日期 | 链接 |
|---|---|---|---|
| Hamel Husain LLM Evals FAQ(三类 evaluator 成本/TPR-TNR/100+ 标注/60-80% 时间) | 工程博客原文 | 2026-01(PDF 标 2026-01-15) | https://hamel.dev/blog/posts/evals-faq/ |
| Aakash G. Aman Khan AI PM Crash Course: Prototyping→Observability→Evals(四段式 judge prompt、文本标签、用 eval 测 eval) | 课程纪要 | 2026-04 更新 | https://www.news.aakashg.com/p/aman-khan-podcast |
| Aakash G. AI Evals Masterclass with Hamel & Shreya(可二元判定失败类) | 课程纪要 | 2025-09 | https://www.aakashg.com/ai-evals-masterclass-with-hamel-shreya/ |
| Braintrust Evals are the new PRD | 工程博客 | 2025 | https://www.braintrust.dev/blog/evals-are-the-new-prd |
项目 src/aml/evalBaseline.ts / typology.ts / types.ts | 代码 | 本仓库 | — |
SOTA 检查 (2026-06-11)
- 本主题当前 SOTA:"先错误分析定义测什么,再按客观/主观 + 迭代频率把失败路由到代码型 / LLM-judge / 人工"是 2025-2026 AI eval 的主流分配框架,Hamel & Shreya(Maven 课已训 2000+ 人)和 Aman Khan(Prototyping→Observability→Evals)双线收敛到同一套。
- 是否仍是 SOTA:✅ 是。三类 eval 的分工边界稳定;"judge 需人工校准(TPR/TNR)才可信"已是共识纪律。
- 2026 进展 / 替代:
- LLM-judge 的可靠性边界被进一步压实——"LLM 模拟用户是不可靠代理"(2026-01) 直接背书"关键评分保留人工抽检",与本篇"高风险项锁死人工"一致。
- judge 输出从数字打分转向文本标签 + 结构化 rubric(Aman Khan 2026-04),降低刻度漂移。
- τ²-bench 的 pass^k(2025-06,2026-04 更新 38 模型)提示部分"失败"是稳定性维度,单次 judge 判定不够,需多次重试统计——这会让"该用哪种 eval"多出一个时间维度。
- 本项目对齐:
evalMap.ts把 ~70% 客观失败留给确定性代码型 eval(进 CI),LLM-judge 仅留给 SAR 叙述质量且必须先过 TPR/TNR ≥ 0.9 的 meta-eval,提交 SAR 这类高风险终判锁死人工——正是上述 SOTA 在一个可进 CI、诚实标注来源的 AML 套件上的落地。