附录 D. 阈值校准
这是一个参考性附录。第一遍阅读时不需要它:每章的教学最低要求基于 AgentClinic-production 的默认阈值。本文件汇总了所有「低 / 默认 / 高」表格、阈值平移练习以及需要重新审视阈值的信号。当标准值不再适用时,可在将流程迁移到自己的项目时使用它。
所有表格的通用原则:阈值只有在成对存在时才有意义。只平移一个值而不重新计算与之关联的值,这不是校准,而是拆除回路。每个章节都明确列出了此类平移的风险。
D.1 突变测试(第 5 章)
第 5 章中的数值是 AgentClinic-production 在平均事件流和成熟 SDD 流程下的默认值。在你的项目中,阈值取决于 P0 漏报代价、路由图复杂度、CI 的 SLA 窗口以及输入流的稳定性。任何一行的平移都必须在 validation.md 中附带理由说明。
| 项目参数 | 低 | 默认(AgentClinic) | 高 |
|---|
| P0 漏报代价 | strict_reject_rate ≥ 0.92 | **≥ 0.98** | ≥ 0.995(支付、医疗) | | 路由图复杂度 | depth_of_diagnostics ≥ 2(≤10 条边) | **≥ 3**(10–50 条边) | ≥ 5(>100 条边,多租户) | | CI 的 SLA 窗口 | recovery_time_p95_ms ≤ 800 | **≤ 1200** | ≤ 1500(>500 PR/天) | | 事件流稳定性 | 每个类 1 个突变 | 每个类 2 个突变 | 每个类 5+ 个突变并轮换随机种子 |
练习
cd book2/examples/stress-mutator
mkdir -p out
cp expected/expected_failures.json out/expected_failures_depth5.json
sed -i 's/"depth_of_diagnostics_min": 3/"depth_of_diagnostics_min": 5/' out/expected_failures_depth5.json
python3 scripts/immunity_score.py \
--validator-results out/validator_results.json \
--expected expected/expected_failures.json \
--out out/immunity_default.json
python3 scripts/immunity_score.py \
--validator-results out/validator_results.json \
--expected out/expected_failures_depth5.json \
--out out/immunity_depth5.json
第一次运行应当通过:平均诊断深度为 4,超过了阈值 3。第二次运行应当以退出码 1 结束:同一个验证器已无法通过人为收紧后的阈值 depth_of_diagnostics_min = 5。其差值展示的不是突变中出现的新缺陷,而是收紧阈值所付出的代价。
何时重新审视阈值
- 一个季度内没有任何合并被阈值阻断 —— 阈值过低。
- 一周内超过 10 次具有相同
mutation_id的回归 ——depth_of_diagnostics不足,需要增大。 recovery_time_p95在strict_reject_rate上升时趋近于零 —— 古德哈特定律的征兆。- 出现了新类别的事件 —— 需重新计算全部三个阈值。
- 同一个随机种子(
seed)连续五个 sprint 重复出现相同的mutation_id集合 —— 需要轮换种子。
风险:如果 strict_reject_rate 上升而 depth_of_diagnostics 同时下降,这是古德哈特定律的症状。两个参数必须成对调整。
D.2 影子规范选择(第 6 章)
权重 0.5*mttr_gain + 0.3*early_signal + 0.2*coverage - 0.4*false_escalation 以及 keep/reject 阈值是 AgentClinic-production 的默认值。在你的项目中,它们取决于误升级代价、早期信号的重要性、历史库的规模以及可用的提示样本预算。
| 参数 | 低 | 默认(AgentClinic) | 高 |
|---|---|---|---|
| 误升级代价 | 罚分 false_escalation: 0.2–0.3 | **0.4** | 0.6–0.8(医疗、支付) |
| 早期信号的重要性 | 权重 early_signal: 0.2 | **0.3** | 0.4–0.5(影响半径 >5 个服务) |
| 历史库规模 | 20–50 个案例(冒烟测试) | 50+ 个案例 | 200+ 个案例并轮换窗口 |
| 提示样本预算 | keep-threshold 0.80,4 个槽位 | **0.70,8 个槽位 / 2000 token** | 0.60,12 个槽位 / 4000 token |
练习
使用保守的风险配置运行拍卖(对误升级施加更高罚分):
cd book2/examples/shadow-auction
python3 scripts/score.py --candidates candidates/candidates.yaml --incidents data/incidents.jsonl --weights "0.3,0.4,0.2,0.8" --out out/scorebook.json
python3 scripts/decide.py --scorebook out/scorebook.json --budget-tokens 2000 --keep-threshold 0.70 --reject-threshold 0.40 --out-auction out/auction.json --out-quarantine out/quarantine.json
在这样的配置下,shadow.p0.voice_handoff 从 winner 移动到 disputed,而 shadow.alert.red_color_urgency 仍保持在 rejected。这体现了新配置的影响:团队对 MTTR 缩减的奖励更少,而对误升级的罚分更重。
何时重新审视阈值
- 一个月内没有
winner在事后复盘中表现出正面效果 ——keep-threshold过低。 disputed的占比稳定高于 40% —— 公式未能有效区分案例。- 单一阶段中选出了 8 个以上的胜出者 ——
budget-tokens的设定未考虑QWEN.md的大小。 - 出现了历史数据之外的新事件类别。
mttr_gain与false_escalation同时增长 —— 古德哈特定律的症状。
风险:罚分 false_escalation 和权重 mttr_gain 必须成对调整。只调整其一而不审视另一个会破坏「有用信号 ↔ 虚假噪声」之间的关系。
D.3 分层预算(第 9 章)
10M token 的预算并按 9M/1M(本地/前沿)划分,是 AgentClinic-production 在平均事件流下的默认值。在你的项目中,预算规模和比例取决于事件流、阶段平均成本、争议性审查的占比以及对 local-coder 故障的敏感度。
| 项目参数 | 低 | 默认(AgentClinic) | 高 |
|---|---|---|---|
| 每日事件流 | ≤50/天 → 2–3M token,90/10 | 200/天 → 10M,9M/1M(90/10) | ≥500/天 → 25–40M,80/20 |
| 阶段成本(token) | ~20K | ~50K | 100K+(多步回放) |
| 争议性审查的占比 | ≤5% → 前沿层 5–7% | ~10% → 1M(10%) | 15–25% → 15–20% 前沿层 |
对 local-coder 故障的敏感度 | ≤1 次/月 → 预留 5% | 2–4 次/月 → 7% | 每周发生 → 15% + 冗余提供商 |
练习
cd book2/examples/budget-keeper
python3 scripts/compile.py --budget-spec specs/budget_network_5m.yaml --out out/budget_plan_5m.json
python3 scripts/simulate.py --plan out/budget_plan_5m.json --scenario scenarios/fail_local_45m.json --out out/fail_result_5m.json
python3 scripts/inspect.py --result out/fail_result_5m.json --query "failover_to_frontier==2 && degraded_queue==18 && token_health_min>=0.5"
请检查在预算减半的情况下 token_health_min 是否仍保持在 0.5 以上。在 5M 的现成变体中,比例保持不变:本地层获得 4.5M,前沿层获得 0.5M。如果只修改 daily_budget_tokens 而不调整阶段配额,compile.py 必须因总额校验失败而报错。
何时重新审视阈值
- 一个月内未发生
degraded_mode触发 —— 预算过剩,或实际流量低于预期。 token_health_min低于 0.5 的频率高于每周一次 —— 本地层不足。- 在本地层发生故障时,
failover_to_frontier持续为 0 —— 网关过于严格,前沿层未能起到保险作用。 - 人工超时后的
manual_queue占比连续两个月上升 ——manual_timeout_sec过短。 - 每天的 token 消耗低于
daily_budget_tokens的 60% —— 是时候压缩预算了。
风险:9M/1M 的划分与阶段的 SLA 紧密相关。不得在不更新规范中 budget_plan_phases 的情况下调整该比例 —— 否则前沿层将无法容纳「争议性」案例。
D.4 防止指标的古德哈特化(第 10 章)
阈值 silent_p0 ≤ 5%、manual_review_rate ≥ 15%、edge_drift ≤ 0.12、audit_trace_coverage = 1.0 是 AgentClinic-production 的默认值。在你的项目中,它们取决于 P0 漏报代价、人工复核者的可用性、输入流的动态性以及审计方面的合规要求。
| 项目参数 | 低 | 默认(AgentClinic) | 高 |
|---|---|---|---|
| P0 漏报代价 | silent_p0 ≤ 8% | **≤ 5%** | ≤ 1–2%(支付) |
| 人工复核者的可用性 | manual_review_rate ≥ 8% | **≥ 15%** | ≥ 25%(合规要求) |
| 输入动态性 | edge_drift ≤ 0.20 | **≤ 0.12** | ≤ 0.05(季节性高峰) |
| 审计合规 | audit_trace_coverage ≥ 0.95 | **= 1.00** | = 1.00 + 已签名的追踪记录 |
练习
cd book2/examples/goodhart-validator
mkdir -p out
# 将规范复制到本地的 out/ 目录,并将 silent_p0_cap 放宽至 0.08
cp specs/validation.yaml out/validation_loose.yaml
sed -i 's/threshold: 0.05/threshold: 0.08/' out/validation_loose.yaml
python3 scripts/run_validation.py \
--validation out/validation_loose.yaml \
--metrics fixtures/new_metrics_bad.json
# 危险的变体:同时放宽两项独立防护
cp specs/validation.yaml out/validation_unsafe.yaml
sed -i 's/threshold: 0.15/threshold: 0.10/' out/validation_unsafe.yaml
sed -i 's/threshold: 0.05/threshold: 0.20/' out/validation_unsafe.yaml
python3 scripts/run_validation.py \
--validation out/validation_unsafe.yaml \
--metrics fixtures/new_metrics_bad.json
第一次运行应当仍然为红色:具有 silent_p0=0.18 的坏版本仍违反 silent_p0_cap。第二次(危险的)变体之所以通过,只是因为同时放宽了两项独立防护。这说明了为何 guard 指标不能仅依据 YAML 中的某一行来校准。
何时重新审视阈值
- 一个季度内没有任何版本被
silent_p0_cap阻断 —— 要么团队没有进行高风险变更,要么阈值过于宽松。 manual_review_rate在mttr_gain上升时连续三个 sprint 下降 —— 古德哈特定律的症状,人工复核者已不再是安全网。edge_drift稳定在 0.10–0.11 附近波动 —— 实际输入动态接近阈值。audit_trace_coverage在任意一次运行中降至 1.0 以下 —— 违反合规不变量,应紧急修复而非校准。
- 出现了未涵盖在
silent_p0中的新事件类别 —— 需要新增不变量,而非调整旧的不变量。
风险:silent_p0 和 manual_review_rate 必须成对调整。edge_drift 只有在 audit_trace_coverage=1.0 时才有意义,否则漂移是基于部分样本计算的。所有四个阈值共同构成一个风险契约:孤立放宽其中之一即是破坏它,而非调整它。
完整的指标网络
章节正文中使用了一个包含三个指标和一个看门人的简化版 mermaid 图。完整的依赖网络如下:
flowchart LR
MTTR[MTTR]
silent_p0[silent_p0]
manual_review_rate[manual_review_rate]
escalation_rate[escalation_rate]
postmortem_regression[postmortem_regression]
audit_trace_coverage[audit_trace_coverage]
silent_p0 -->|正相关| MTTR
escalation_rate -->|正相关| MTTR
manual_review_rate -->|负相关| MTTR
manual_review_rate -->|负相关| escalation_rate
audit_trace_coverage -->|负相关| escalation_rate
audit_trace_coverage -->|负相关| silent_p0
postmortem_regression -->|正相关| audit_trace_coverage
postmortem_regression -->|负相关| manual_review_rate逻辑与简化版相同:红色区域是 MTTR 和 silent_p0;削弱它们的路径在于减少人工复核并丢失审计追踪。
D.5 生产就绪度(第 11 章)
23/25 的阈值是 AgentClinic-production 在 SDD 流程中等成熟度、混合操作类型下的默认值。在你的项目中,阈值取决于切换(cutover)错误的代价、流程成熟度、人工审查的负载以及操作的性质(无状态 / 有状态)。
| 项目参数 | 低 | 默认(AgentClinic) | 高 |
|---|---|---|---|
| 切换错误的代价 | 内部工具:21–22/25 仅半自动 | 混合生产:auto ≥23/25 | 支付/医疗:auto ≥24/25 |
| SDD 流程成熟度 | 3 个月 → 仅半自动 20–22 | 6+ 个月 → 半自动 20–22,auto 23+ | 12+ 个月 + 50+ 次回放 → auto 23+,更少的人工停机 |
| 人工审查负载 | 每个 PR(~5/周)→ 可保持 21–22 半自动 | 20–30% 的 PR → auto 23+ | 罕见 → auto 24/25 | | 操作类型 | 无状态 → 22/25 仅 canary/半自动,auto 23+ | 混合 → auto 23+ | 有状态 → auto 24+ 且 backup_verified |
练习
脚本 check_readiness.py 硬编码 THRESHOLD = 23。通过副本来以不同的值运行:
cd book2/examples/real-api && mkdir -p out
cp scripts/check_readiness.py out/check_readiness_t22.py
sed -i 's/THRESHOLD = 23/THRESHOLD = 22/' out/check_readiness_t22.py
python3 out/check_readiness_t22.py --readiness fixtures/readiness_block_audit.json
在 THRESHOLD = 22 下,readiness_block_audit.json 仍因 audit_trace_coverage=0.7 < 1.0 被阻断,尽管总分 22/25 已通过。这表明 audit_trace_coverage 是一个独立的阻断性不变量,而非总分的一部分。本练习旨在体现对阈值的敏感性,而非推荐降低 auto 准入。
何时重新审视阈值
- 一个季度内没有任何就绪度被阈值阻断 —— 对团队当前成熟度而言阈值过低。
- 半自动事件占比连续三个 sprint 上升 —— 23/25 的阈值未达成,源于 Verification 或 Process 维度的系统性缺口。
- 出现了
stateful=true的操作类别 —— 应要求backup_verified,并将此类别的阈值提升至 24/25。 - 一个月内所有就绪度失败都集中在同一维度 —— 这是 SDD 模板的缺陷;应修复模板而非调整阈值。
- 就绪度产物的构建时间超过了切换的 SLA —— 应审视哪些得分可以自动化,而非降低阈值。
风险:在任何总分下,Security 维度为零分与 23/25 阈值不兼容 —— 此类失败无论总分如何都会阻断合并。低于 23/25 的阈值会改变运行模式:这已不再是 auto 准入,而是半自动或 canary 模式。即便是「低」(21/25),也意味着在每个 implement 步骤后都需暂停并由操作员明确确认,而非允许 agent 自主执行修复。