主题
第 9 章 · 打分的边界
pixiu 锚点:
docs/lab/E2-scoring-decision-table.md、scripts/eval_e2_judge_probe.py
开篇:给定一个指标,该用哪种打分手段?
做 eval 时你会反复遇到一个问题:这个指标,我该用什么来打分?
pixiu 用三种打分手段:
- 代码断言——判硬指标(字段对不对、条数够不够、逻辑一致不一致)。快、客观、可复现。
- LLM 裁判——判软指标(回复好不好、语气对不对、有没有风险提示)。灵活,但自身不稳定(第 7 章)。
- 人工抽查——校准基准。最准,但最慢。
旧手记把这三种并列介绍,但没给一个判据:面对一个具体指标,你到底该选哪种? 这一章就是来补这个判据的——pixiu 的课题 E2 把它做成了一张决策表。
E2 决策表(这一章的核心)
| 指标类型 | 打分手段 | pixiu 的例子 | 可信度 | 实证 |
|---|---|---|---|---|
| 结构化字段 | 代码断言 | scene_type、signal、action_level、投票一致性 | 高(确定性) | E1 抓退化 |
| 叙事质量 | LLM 裁判 | 不瞎编数据、建议与 action_level 一致、含风险提示 | 中(概率性) | E2 极端+轻微都抓 |
| 裁判可信度 | 人工抽查 | 定期校准裁判有没有飘 | 高(但慢) | 理论,未跑 |
怎么用这张表?拿到一个指标,先问:它能用代码量化吗? 能 → 代码断言(首选,确定性最高)。不能,需要判断"好不好"→ LLM 裁判。裁判本身可不可信 → 定期间隙人工抽查校准。
这个优先级很重要:代码断言永远优先。能确定的别交给概率。只有必须判断的,才请裁判出场。
裁判比想象的好
很多人对 LLM 裁判存疑——它自己都是概率模型,能公正打分吗?pixiu 的 E2 实验给出一个意外的正面结论:裁判比想象的好用。
实验拿 signal_basic 用例,给裁判看三档叙事(同一个 mock 信号:BUY、action_level=watch、close=28.50):
| 叙事 | 打分 | 通过 | 裁判理由 |
|---|---|---|---|
| 好(数据+观望+风险提示) | 1.00 | ✓ | 准确基于信号/action_level,建议观望,含风险提示 |
| 中(建议对,漏风险提示) | 0.50 | ✗ | 信号/建议用对了,但缺风险提示 |
| 坏(强烈买入+编造目标价+无提示) | 0.00 | ✗ | 虚构数据,无提示,违背 watch |
三个发现:
- 极端区分完美——好 1.00、坏 0.00,没有误判。
- 对轻微违规灵敏——中等叙事只是"漏了风险提示",裁判照样抓到,打 0.50(低于 0.8 阈值),精确判否。这是最让我意外的——它不是只能区分天壤之别,细微的合规缺失也逃不过。
- 打分有分寸——部分正确给部分分(中等 0.50),不是非黑即白的二元判断。这支持了第 7 章用"通过率阈值"而非二元判断的做法。
裁判也有坑:同模型自评偏差
但别急着把裁判吹上天。E2 实验里有个故意的"坑"值得讲:裁判用的模型和 agent 用的是同一个(都是 deepseek-v4-flash)。
为什么要故意同模型?是为了实证旧手记第 7 章的一个原则:"裁判应不同于 Agent 模型"。如果裁判和 agent 是同一个模型,会有"自评偏差"——模型倾向于认可自己的风格。
E2 的发现是:在手写叙事(人写的三档样例)上,同模型裁判依然准确(1.00/0.50/0.00)。但这个实验有个局限——真正的自评偏差,要"agent 生成叙事 + 不同模型裁判"对比才能暴露。pixiu 当时没配第二个模型(zhipu 没配),所以这个边界 E2 老老实实标注了"未充分验证"。
这里的教训是:知道你的裁判在哪里可信、在哪里不可信。 同模型裁判在手写样例上准,不代表在 agent 真实输出上没偏差。E2 的诚实之处在于——它没把"手写样例准"夸大成"裁判完全可靠",而是明确指出了未验证的边界。
结合第 7 章:裁判在哪飘、在哪稳
把 E2 和 E3(第 7 章)合起来看,你对裁判会有一个更完整的认识:
- 极端情况(极好/极差):裁判稳,可信(E3 std 0)
- 边界情况(好但可挑刺):裁判飘,要多跑(E3 std 0.31)
- 轻微违规:裁判灵敏,抓得住(E2 的 0.50)
- 同模型自评:手写样例准,真实输出可能有偏差(E2 未充分验证)
这就是"打分的边界"——不是笼统地说"信裁判"或"不信裁判",而是精确到"在什么类型的输入上、测什么类型的指标、该信到什么程度"。
两套裁判的坑
E2 还发现一个工程层面的坑,登记在 findings 的 E2-1:
pixiu 有两套独立的 LLM 裁判——报告质检的
report_qc.evaluate_report和 eval 的 E2judge_fn。它们各写各的,没有统一抽象。
这是个常见的工程债务:同一个能力(LLM 裁判)在不同地方各实现一遍。 短期能跑,但长期维护两套裁判逻辑、两套 prompt、两套阈值,迟早会不一致。E2 把它标成"未来应抽象通用裁判"。
你自己的项目里,如果也在多处用 LLM 裁判,值得早点抽象出统一的裁判层——别等有了三套才发现痛。
这一章的工具:打分手段自检
- [ ] 面对一个指标,你有没有清晰的"该用哪种打分手段"的判据?(还是拍脑袋)
- [ ] 能用代码断言的,你是不是优先用了代码断言?(别把确定性的活交给概率裁判)
- [ ] 用 LLM 裁判时,你知道它在哪类输入上飘吗?(跑个稳定性探针)
- [ ] 你的裁判和 agent 是同一个模型吗?(是的话,留意自评偏差)
- [ ] 你有没有多处各写一遍裁判逻辑?(该抽象统一了)
小结
打分的核心智慧是边界感:代码断言判结构化、LLM 裁判判叙事、人工校准裁判本身,三者各司其职。而 LLM 裁判——既不是不可靠的玄学,也不是万能的银弹,它在极端情况稳、在边界情况飘、对轻微违规灵敏、但在自评时可能偏。
知道这些边界,你才能在正确的场景、用正确的手段、信到正确的程度。
第三部分(验证)到这里讲完了。你已经知道怎么对付非确定性(第 7 章)、怎么用 eval 驱动开发(第 8 章)、怎么选择打分手段(第 9 章)。下一部分,我们换一个视角——agent 不只是"回答问题",它还要和调度系统协作、和会话记忆协作。
下一章
第 10 章 · 编排 vs 自决:5 管线替代 12 任务 —— 定时任务和对话,怎么共享同一套工具。