第十二章 评估与可观测性:如何知道系统是否正常工作

核心命题:在确定性软件中,测试通过 = 正确。在概率性 Agent 系统中,度量本身是核心工程挑战——输出是分布而非确定值,正确性是程度而非是非,问题在复杂的非线性因果链中静默发展,直到某个阈值被穿越才以告警的形式显现。如果不能有效测量 Harness 的效果,就无法可靠地改进它:每一次”感觉应该更好了”的优化,都可能只是在解释噪声。本章建立可操作的评估框架和可观测性基础设施,将 Agent 系统的行为从”不透明的概率黑盒”转变为”可度量、可诊断、可持续改进”的工程对象。

12.1 Agent 系统的评估挑战

传统软件的测试逻辑建立在确定性假设之上:给定输入 xx,系统总是产生相同输出 f(x)f(x),“通过”意味着 f(x)=yexpectedf(x) = y_{\text{expected}}。Agent 系统打破了这一假设的每一个环节——同一输入可以产生不同输出,“正确”是一个程度问题而非二值问题,评估本身也是概率性的。这不是实现缺陷,而是概率性系统的结构性特征。

三个核心评估难点

难点一:输出的概率性。将”通过/失败”的二值标准应用于概率性输出,会产生大量噪声:同一个设计良好的 Agent 在 10 次运行中可能有 8 次”通过”、2 次”失败”——这是随机性而非系统缺陷。直接用单次运行结果来判断 Harness 质量,等价于用单次硬币投掷来判断硬币是否公平。正确的评估框架需要分布视角:度量的对象是在典型任务分布上的期望质量(以及方差),而非单次运行的结果。

评估样本量的选择是一个统计功效(statistical power)问题。对二项准确率指标,要在显著性水平 α=0.05\alpha=0.05、统计功效 1β=0.801-\beta=0.80 下检测两个比例 p1,p2p_1, p_2 间的差异,每组所需样本量近似为:

n(z1α/22pˉ(1pˉ)+z1βp1(1p1)+p2(1p2))2(p1p2)2n \approx \frac{(z_{1-\alpha/2}\sqrt{2\bar p (1-\bar p)} + z_{1-\beta}\sqrt{p_1(1-p_1)+p_2(1-p_2)})^2}{(p_1-p_2)^2}

代入 p1=0.90,p2=0.85p_1=0.90, p_2=0.85n686n\approx 686;要识别 3 个百分点的下降则需 n1900n\approx 1900 以上——这是 Agent 系统评估实践中最容易被低估的成本。**黄金集(Golden Set)**策略:维护一个人工标注的、覆盖典型场景和边界情况的任务集,规模需按上述功效公式反推(而非凭直觉取一个”看起来够”的数字);每次系统变更后在这个固定集合上运行评估,用统计检验(而非直觉判断)确认是否存在显著质量变化。

难点二:评估成本。确定性测试的成本是廉价的计算资源;语义质量的评估需要人工标注(最可靠但极贵)或 LLM-as-judge(更便宜但有系统偏差)。这产生了一个张力:评估越频繁、越全面,成本越高,但覆盖率越低意味着质量退化可能在被发现之前扩散。

评估成本的帕累托前沿:计算型断言(测试通过率、格式合规率)成本极低(每次评估 < 1ms),可以 100% 覆盖;语义型评估(LLM-as-judge)成本较高,应作用于计算型断言通过之后的高置信度候选,以及需要语义判断的边界案例。这是 §11.2 计算型/语义型传感器分工原则在评估层的复现。

难点三:分布偏移。在测试集上表现良好,不等于在生产环境中表现良好。生产输入的分布随时间变化——用户输入模式改变、代码库演化、外部 API 行为更新——都可能使在过时测试集上设计的 Harness 产生静默的质量退化。**在线评估(Online Evaluation)**是对抗分布偏移的关键机制:在生产流量中抽样一定比例进行实时质量评估,使测量对象始终对准当前的真实分布,而非历史快照。

决策理论视角:评估是在不确定性下的统计决策问题

上述三个难点共同指向一个统一框架。评估行为本身可以被重新表述为决策问题——“这个输出够不够好”等价于”我应不应该接受这个结果”——一个在不确定性下最小化期望损失的标准 Wald 型决策问题。这个视角不只是修辞重构,它直接决定了样本量、阈值、judge 校准三者必须一起设计而非分开拍板。

Wald 的统计决策框架由损失函数、先验、后验更新三件套构成,对应到评估场景:

  • 损失函数 L(d^,y)L(\hat d, y):定义”错误接受”(将低质量输出标为通过,FP)与”错误拒绝”(将高质量输出标为失败,FN)的代价。对高风险输出(如不可逆写、对外发送),LFPLFNL_{FP}\gg L_{FN},最优阈值 τ\tau^* 应满足 τ=LFP/(LFP+LFN)\tau^* = L_{FP}/(L_{FP}+L_{FN}),向严格方向偏移
  • 先验 π(θ)\pi(\theta):LLM-as-judge 对特定模式的系统性偏差(如倾向于接受较长输出、倾向于接受与自身输出风格相似的结果)构成有偏先验——需要通过标定数据集(calibration set)量化为偏差矩阵
  • 贝叶斯更新:随着人工标注样本积累,持续更新 judge 偏差估计 P(θ标注样本)P(\theta\mid \text{标注样本}),实现评估机制的持续校准

这个框架使”LLM-as-judge 存在偏差”从定性警告升级为可量化、可校准的工程问题——judge 自身的可靠性可用 P/R 曲线、AUC、与人工标注的一致性指标(Cohen’s κ ≥ 0.6 通常视为可接受)来度量。“评估本身的评估”由此获得统一的理论语言。

LLM-as-judge 的偏差类型与校正方法

实践中已知的主要偏差:

位置偏差(Position Bias):Judge 倾向于偏好排在前面的选项。校正方法:对每个评估样本执行两次 judge,交换候选答案的顺序,取一致结论;若两次结论相反,标记为”争议样本”,触发人工复核。

冗长偏差(Verbosity Bias):Judge 倾向于给更长、看起来更”详尽”的输出更高分,即使冗余内容降低了实际质量。校正方法:在 judge 的 System Prompt 中显式要求”以简洁性和准确性为评分标准,不以输出长度为标准”,并通过标定集(包含故意冗长但低质量的样本对)验证 judge 是否真的执行了这个标准。

自我优势偏差(Self-Enhancement Bias):用 GPT-4 评估 GPT-4 生成的输出,存在高估。校正方法:使用与生成模型不同的模型族作为 judge,或对同一输出用多个不同 judge 评估取众数。

12.2 Q/T/C 的可测量指标体系

从第三章引入的三轴约束出发,建立可操作的度量框架。指标的选择不只是枚举维度,更重要的是建立指标层级——每一层的指标回答不同的问题,触发不同级别的响应。

指标的四个层级

层级一:基础设施指标(Infrastructure Metrics)——系统能否运行?

  • API 调用成功率(应 > 99.5%)
  • 平均请求延迟 P50/P95/P99
  • Token 消耗速率(每分钟总 token)
  • Hook 管道执行时间

这一层的异常意味着系统不可用或严重受损,触发即时告警。

层级二:组件行为指标(Component Metrics)——各构件是否按预期工作?

  • Plan 生成成功率 + 平均步骤数
  • 每工具类型的调用频率分布
  • Hook 触发率与升级率(升级率 = 触发人工确认的 Hook 比例)
  • Compaction 触发频率(高频 Compaction 是主动管理不足的信号)

这一层的异常指向特定构件的设计问题,触发工程师调查(不一定是即时告警)。

层级三:任务质量指标(Task Quality Metrics)——任务是否被正确完成?

  • 计算型质量:测试通过率、格式合规率、约束满足率
  • 语义型质量:LLM-as-judge 评分均值与方差(评分分布宽泛是不确定性信号)
  • 一致性:相同任务多次运行的输出分布方差(高方差 = 不稳定)
  • 人工复核通过率(抽样评估中人类接受的比例)

层级四:业务结果指标(Business Outcome Metrics)——系统是否产生了预期的业务价值?

  • 每任务成本(含 API + 人工注意力)
  • 人工介入率趋势(期望随信任积累而降低)
  • 任务完成时间(端到端,含等待时间)

各轴度量的关键实践

质量轴(Q)度量

  • 功能正确性:以 success_criteria(§9.1 Plan Schema 的字段)为计算型测试门槛,覆盖”可形式化验证的目标”(§4.5);对”可语义评估但不可形式化的目标”,使用标定过偏差的 LLM-as-judge
  • 质量方差:方差本身是独立的质量维度。低均值高方差(平均 60 分,标准差 25 分)和低均值低方差(平均 60 分,标准差 5 分)代表根本不同的问题:前者是 Harness 对任务类型覆盖不均,后者是系统性设计问题
  • 退化检测:在黄金集上维护质量基线。对每次 Harness 变更,用 Mann-Whitney U 检验(非参数,不假设正态分布)检测质量分布是否显著变化,p 值阈值设为 0.05;当样本量较小时(n<30n<30),同时报告效应量(如 Cliff’s δ)以避免”无显著差异”被误读为”无变化”——前者可能仅是功效不足

时间轴(T)度量

  • 每任务步骤数:间接度量搜索效率——若步骤数突然增加但质量未提升,说明 Agent 在做无效探索,是 Plan 设计问题或 Context 质量退化的信号
  • 超时率:超时 = T 轴约束被违反;若超时率上升,首先检查是否有步骤陷入无收敛循环(§5.3 发散特征)
  • 等待时间:任务排队时间 + 人工审批等待时间。人工审批等待时间是人类注意力成本的代理指标(§3.1 C 轴的第三子维度)

成本轴(C)度量

  • 按构件分解 token 消耗:System Prompt token 是固定成本,工具调用 token 是变量成本,Hook 调用 token 是监督成本。若 Hook token 占比突然上升(如超过总消耗 30%),可能是 Hook 设计过重或 Hook 风暴的早期信号
  • 成本方差:成本均值超出预算固然危险,成本方差过大同样是问题——高方差意味着成本不可预测,对于批量任务系统可能导致预算不确定性
  • 人工介入频率趋势:若人工介入率随时间上升(而非下降),说明 Harness 未在积累信任——可能是任务分布漂移、或 Agent 行为退化

红旗指标(需要即时响应)

以下指标的异常代表系统级问题,不应等待定期复盘:

红旗指标阈值建议可能根因
成本/任务突增超过基线 3×Hook 风暴、Context 膨胀、Plan 循环
Hook 触发率骤升同比增加 50%+新的错误模式触发、Hook 配置变更
任务失败率连续上升连续 3 轮 > 10%模型行为变化、工具 API 异常、Context Rot
升级率(人工确认比例)突增超过基线 2×输入分布偏移、Hook 阈值设计问题
P99 延迟倍增超过 SLA 150%工具调用超时、模型响应慢、循环触发

12.3 可观测性的三层设计

可观测性不是事后添加的调试工具,而是 Harness 架构的一等公民——它决定了当系统出现问题时,工程师能以多快的速度定位根因。可观测性的基础设施应当在系统设计阶段就确定,而非在第一次生产事故之后紧急补充。

三层可观测性架构

层一:结构化日志(Structured Logs)——事实记录层

结构化日志是可观测性的基础。每一个可能引起行为差异的事件,都应产生一条结构化日志记录——不是自由文本,而是具有固定 Schema 的 JSON 对象,以支持后续的查询和聚合。

事件日志的标准 Schema

{
  "timestamp": "2025-03-15T09:23:41.123Z",
  "trace_id": "tr_8f2a...(关联同一任务的所有事件)",
  "span_id": "sp_4c1b...(当前步骤的标识)",
  "parent_span_id": "sp_2a9e...(上层步骤)",
  "component": "PostToolUse/code_quality_check",
  "event_type": "hook_triggered",
  "input_hash": "sha256:...",
  "output_hash": "sha256:...",
  "token_cost": { "input": 1240, "output": 380 },
  "duration_ms": 2340,
  "success": true,
  "escalated": false,
  "metadata": { "tool": "write_file", "path": "src/main.py" }
}

Schema 的关键字段:trace_id 将同一任务的所有事件串联(支持端到端追踪);span_idparent_span_id 构建事件的因果树(支持 Hook 调用链的重建);token_cost 支持成本按组件分解;escalated 标记是否触发了人工确认(支持升级率统计)。

日志什么,不日志什么:日志记录完整的事件元数据,但不记录模型的原始输入输出内容(PII 风险 + 存储成本)。用 input_hashoutput_hash 代替原始内容——在需要调试时,通过任务 ID 在安全隔离的存储中重放,而非将敏感内容写入通用日志系统。

层二:指标(Metrics)——聚合监控层

指标是对日志的时间序列聚合,回答”系统整体上是否健康”的问题。与日志不同,指标丢弃了个别事件的细节,保留了跨事件的统计规律。

指标类型选择

  • 计数器(Counter):只增不减的累计值,适用于事件次数(任务数、Hook 触发次数、token 消耗总量)
  • 仪表盘(Gauge):当前值,适用于资源使用(活跃任务数、Context 当前大小)
  • 直方图(Histogram):值的分布,适用于延迟和成本——用直方图而非均值,因为 Agent 系统的延迟分布通常是多峰的(快速成功路径 vs. 需要重试的慢路径)

告警规则设计:告警应建立在”相对于基线的变化”而非”绝对值超过阈值”上,因为不同任务类型的绝对成本差异很大:

# 告警条件示例(伪代码)
if cost_per_task.rolling_1h > cost_per_task.baseline_7d * 3:
    alert("成本突增:当前 {cost_per_task.rolling_1h},基线 {cost_per_task.baseline_7d}")

if hook_escalation_rate.rolling_30m > hook_escalation_rate.baseline_24h * 2:
    alert("升级率异常:可能存在输入分布偏移或 Hook 设计问题")

层三:追踪(Tracing)——因果链重建层

追踪是三层中最昂贵但最具诊断价值的层。它记录完整的因果链——从任务起点到最终输出(或失败),经过的每一个组件和每一次工具调用,按时间顺序形成一棵有向树。

追踪的核心价值:当某个任务失败或成本异常时,追踪使”死后诊断”成为可能——工程师可以重放完整的执行路径,在任意步骤暂停检查,精确定位问题发生的位置和上下文。这在 Agent 系统中尤为重要,因为 Agent 的状态是隐式的(存在于 Context 中),传统的堆栈追踪无法重建推理过程。

Trace 结构示例(简化)

Task tr_8f2a [总耗时 47s, 总成本 12,340 tokens]
├── Step 1: 分析失败测试 [2.1s, 1,800 tokens]
│   ├── Tool: read_file("tests/test_api.py") [0.1s, 320 tokens]
│   └── PostToolUse Hook: format_check [0.02s, 0 tokens, 通过]
├── Step 2: 定位根因 [3.4s, 2,200 tokens]
│   └── Tool: db_query("SELECT ...") [0.8s, 850 tokens]
└── Step 3: 修复代码 [41.5s, ⚠ 8,340 tokens — 异常]
    ├── Tool: write_file("src/main.py") [0.2s, 1,100 tokens]
    ├── PostToolUse Hook: quality_check [12.3s, 3,800 tokens]
    │   └── PostToolUse Hook: quality_check [12.1s, 3,400 tokens]  ← 递归触发!
    │       └── PostToolUse Hook: quality_check [未完成,成本熔断]
    └── [成本熔断触发,任务中止]

在这个 Trace 中,Step 3 的异常成本一眼可见,且递归触发的 Hook 链路清晰呈现——这是 §11.5 描述的 Hook 风暴在追踪层的具体表现。没有追踪,这个问题可能需要数小时甚至数天才能从日志中拼凑出来;有了追踪,定位时间可以缩短到分钟级别。

可观测性的预算与权衡:可观测性不是免费的。完整的结构化日志会增加存储成本,细粒度追踪会增加 API 延迟(每个 span 的创建有开销),大量指标的实时计算消耗计算资源。可观测性预算的分配原则:高风险操作(不可逆写、外部 API 调用、Compaction)和高异常率组件(历史上频繁失败的步骤),应获得最详细的可观测性覆盖;低风险的只读操作,可以以较低粒度记录。

12.4 调试 Agent 系统的方法论

Agent 系统的调试难度远超传统软件——概率性行为意味着问题无法精确重现;长链推理意味着错误可能在多步之后才显现(因果距离远);涌现行为意味着组件层面的正常不保证系统层面的正常。经典调试方法(断点、堆栈追踪、变量检查)都不直接适用。需要一套针对 Agent 系统特性设计的调试方法论。

四步调试法

第一步:异常定位(成本与时间异常入手)

生产问题通常首先从指标层被发现——成本突增、延迟倍增、失败率上升。不要从源代码开始(找不到具体入口);不要从单次日志开始(看不到统计规律)。

正确的起点是指标层:

  1. 确认异常的时间起点:问题从什么时候开始?(与 Harness 变更时间、模型版本更新时间、输入分布变化时间对比)
  2. 确认异常的组件归属:哪个组件的指标在异常时间点显著变化?(按组件分解 token 消耗,找到占比突增的组件)
  3. 确认异常的任务特征:所有任务都受影响,还是只有特定类型的任务?(按任务类型分组统计异常率)

第二步:追踪复放(Trace Replay)

从异常任务中选取若干代表性样本,通过追踪系统重放完整的执行路径。选取代表性样本的原则

  • 选取”异常最明显”的样本(成本最高、失败最确定),而非边界样本——边界样本的信息密度低
  • 同时选取”同类任务中正常的样本”作为对照——差异往往比绝对值更有诊断价值

在追踪中寻找:哪个步骤的成本 / 延迟 / 失败率与正常样本有显著差异?是单次异常(工具偶尔超时)还是系统性异常(某类 Hook 在每个任务中都触发了 2 倍以上的成本)?

第三步:最小化复现(Minimal Reproduction)

找到可疑组件后,构造一个最小的复现场景:保留触发问题所必需的 Context 和 Plan,移除其他内容。如果可以在没有生产数据的情况下(用合成输入)稳定复现问题,说明定位是准确的。

Agent 系统中”最小化复现”的特殊挑战:由于输出的概率性,单次运行不能确认复现成功——需要在相同输入下运行多次,确认问题稳定出现(不是噪声)。重复次数应由所要区分的失败率差异决定:若想以 80% 功效区分”5% 偶发”与”30% 系统性失败”,至少需要 7–10 次重复;区分更细微的差异(如 10% vs. 20%)则需 30+ 次。

最小化的方向

  • 移除 Context 中与问题无关的部分(哪些信息被移除后问题不再出现?保留那些信息)
  • 缩短 Plan(哪些步骤可以被跳过而问题仍然出现?保留那些步骤)
  • 替换工具(用最简单的工具替换复杂工具,验证问题是否在工具交互层)

第四步:对比分析(Diff Analysis)

将复现出问题的最小场景,与一个同类任务中正常运行的场景进行系统性对比。关注的差异维度:

  • Context 差异:问题场景和正常场景的 Context 在哪里不同?(任务描述、工具描述、历史摘要)
  • Plan 差异:步骤数量、步骤粒度、fallback 设计是否有差异?
  • 工具调用差异:同一步骤触发了不同的工具调用序列?工具返回的结果格式或内容有差异?
  • Hook 触发链差异:正常路径和异常路径的 Hook 触发顺序和结果是否不同?

常见失败模式及其可观测特征

失败模式指标特征追踪特征根因方向
Hook 风暴成本骤增,P99 延迟倍增某 Hook 在同一步骤递归出现Hook 输出格式触发了新的工具调用
Context 膨胀成本线性增长,Compaction 频率上升每步工具结果 token 占比递增工具返回结果未在注入前压缩
发散搜索步骤数增加但质量不提升类似错误信号重复出现多轮失败信号信息密度低(§5.3)
分布偏移黄金集质量稳定,在线质量下降异常任务的输入特征分布与训练集不同新输入类型未被 Harness 覆盖
Plan 循环步骤数超出预期,abort_conditions 未触发Trace 中相同步骤重复出现abort_conditions 设计不完备

影子模式测试(Shadow Mode Testing)

在生产环境中,对实时流量运行新版 Harness 的”影子副本”——新版本与生产版本并行处理同一输入,但新版本的输出不影响实际用户。这使 Harness 变更可以在真实分布上评估,同时没有生产风险。影子模式是对抗分布偏移和发现回归的最强评估手段,代价是约 2 倍的计算成本(仅在验证期间)。


章末案例剖析

案例中的数据(准确率、工单量、token 消耗、修复前后对比等)均为基于作者工程实践的说明性示例,旨在量化呈现分布偏移在三层可观测性基础设施中的诊断路径,非实测基准。

这个案例没有告警声,没有成本暴增,没有任何组件出错——系统以正常的成本和延迟平稳运行,黄金集上的评估分数始终维持在基线附近。但在这层平静之下,三周内路由准确率从 94% 悄悄滑落到 82%,直到一次定期复盘才被发现。这是 §12.1 描述的第三类评估难点——分布偏移——的典型形态:没有组件故障,没有代码变更,问题的根源在于现实世界改变了,而 Harness 没有跟上。这个案例完整展示了三层可观测性基础设施(指标 → 日志 → 追踪)如何将一次静默退化转化为可定位、可修复的工程问题,以及 §12.4 四步调试法在非突发失效场景中的实际运用。

系统背景:一家 SaaS 公司部署了一个用户工单自动分类路由 Agent,负责将客户提交的支持工单分类到三个类别并路由到相应团队:

工单类型路由目标典型工单内容
bug_report工程团队功能异常、报错、数据不一致
feature_request产品团队新功能建议、使用场景扩展
billing_issue财务团队账单疑问、退款申请、套餐变更

Harness 基于 2 万条历史标注工单构建,在前 8 周的生产运行中路由准确率稳定在 94%,黄金集(320 条样本)评估分数 93.8%,误路由工单的人工修正量约每天 6 条。系统运行稳定,团队未做任何 Harness 变更。


阶段一:指标层——渐进退化的发现(第 11 周定期复盘)

每两周一次的系统质量复盘通常是例行走查。这一次,工程师在打开周度指标仪表盘时发现了一条不寻常的趋势线:

在线路由准确率(周均值)

周次在线准确率黄金集准确率产品团队工单量人工修正量(条/日)
第 8 周(基线)94.1%93.8%基准 × 1.06
第 9 周91.3%93.9%基准 × 1.2114
第 10 周87.4%94.1%基准 × 1.3827
第 11 周82.1%93.6%基准 × 1.5741

这张表呈现了分布偏移的典型指纹:在线准确率持续下降,黄金集准确率纹丝不动。这立即排除了 Harness 退化(Harness 变更会同时影响两者)和随机噪声(三周连续单向下滑的概率极低),将根因范围锁定在生产输入分布与黄金集分布之间出现了系统性偏差

第二个关键信号:产品团队的工单量在这三周持续异常增加,比基准高出 57%,而其他两个团队(工程、财务)的工单量无明显变化。产品团队反映:越来越多的工单”看起来不像功能请求,但我们找不到更合适的归类,只能接收后手动转发给 CS 团队”。

指标层分析的局限:指标层能告诉我们”发生了什么”——准确率在下降,产品团队工单量在增加——但无法告诉我们”为什么”。要回答”什么类型的工单被错误路由”,需要进入日志层。


阶段二:日志层——根因方向锁定(第 12 周一上午)

从结构化日志中提取第 9–11 周所有被人工修正的工单(共 448 条),按工单来源账户的套餐类型进行分组:

-- 结构化日志查询(伪代码)
SELECT
  account_tier,
  COUNT(*) as total_tickets,
  SUM(manually_rerouted) as misrouted,
  AVG(manually_rerouted::float) as error_rate
FROM ticket_routing_events
WHERE event_date BETWEEN '2025-week9' AND '2025-week11'
GROUP BY account_tier
ORDER BY error_rate DESC
账户套餐类型工单总量误路由工单误路由率
Enterprise(第 9 周起新增)31222170.8%(← 异常)
Pro1,840713.9%
Starter2,210884.0%
Free890364.0%

根因方向清晰:误路由几乎完全集中在 Enterprise 账户(第 9 周随企业版产品上线新增的套餐类型),普通套餐账户的误路由率在 4% 上下,与历史基线吻合。

进一步细化——对 Enterprise 账户的误路由工单按工单内容关键词聚类:

内容聚类样本量被错误路由到实际应路由到
API 认证 / token / webhook 配置89产品团队(feature_request)CS 团队
Onboarding / 账户初始化 / 权限配置78产品团队(feature_request)CS 团队
SSO / LDAP / 企业目录集成54产品团队(feature_request)CS 团队

三个聚类(API 集成、Onboarding、企业身份认证)均被错误分类为 feature_request。这些工单类型在 Enterprise 产品上线前从未出现过,原始 Harness 中没有任何对应的训练样本。

日志层的工程价值:从”准确率在下滑”到”Enterprise 账户的三类工单被错误路由到产品团队”,日志层将一个抽象的指标趋势转化为了具体的、可操作的根因方向。下一步是用追踪层确认机制——Agent 是在不确定的情况下猜测分类,还是以高置信度做出了错误决策?


阶段三:追踪层——机制确认(第 12 周一下午)

从误路由的 Enterprise 工单中随机抽取 5 条,与 5 条同期被正确路由的普通工单配对,拉取完整追踪记录进行对比分析。

正确路由样本(普通 Pro 账户工单)

Task tr_a2f1 ["导出功能在 Safari 浏览器下报错"] [2.1s, 正确: bug_report]

Step 1: 工单内容解析
  └── Tool: parse_ticket(ticket_id="t_9821") [0.1s]

Step 2: 分类推理
  └── 分类决策: bug_report(置信度 0.97)
  └── 路由依据: "用户描述了明确的功能异常现象(报错),与 bug_report 类别的
               核心特征高度匹配;不涉及功能扩展请求或账单问题"

Step 3: 路由执行
  └── Tool: route_ticket(category="bug_report", team="engineering") [0.1s]
  └── Stop Hook: routing_audit [通过,置信度 0.97 > 阈值 0.80]

误路由样本(Enterprise 账户工单)

Task tr_b8c3 ["无法通过 SAML 2.0 完成 SSO 配置,IdP metadata 导入后
              断言验证失败,错误代码 ERR_ASSERTION_MISMATCH"] [2.3s, 错误: feature_request]

Step 1: 工单内容解析
  └── Tool: parse_ticket(ticket_id="t_10483") [0.1s]

Step 2: 分类推理
  └── 分类决策: feature_request(置信度 0.89)  ← ⚠ 高置信度错误分类
  └── 路由依据: "工单涉及 SAML/SSO 配置,这属于企业身份认证集成需求。
               现有分类中 feature_request 与'集成需求'最为接近;
               bug_report 通常指已有功能异常,此处是配置场景;
               billing_issue 明显不符"

Step 3: 路由执行
  └── Tool: route_ticket(category="feature_request", team="product") [0.1s]
  └── Stop Hook: routing_audit [通过,置信度 0.89 > 阈值 0.80]

追踪记录揭示了问题的精确机制:Agent 的推理逻辑是完全正确的局部推理,但建立在错误的全集假设之上

“现有分类中 feature_request 与’集成需求’最为接近”——这句话是对的,在三选一的约束下确实如此。问题在于:正确答案根本不在这三个选项里。Agent 没有做出不确定的、低置信度的猜测;它做出了一个高置信度的、在有限选项内的最优决策,但”有限选项”本身是残缺的。

这是 §1.2 描述的分布外填充在分类任务中的具体形态:当查询超出训练分布,模型不会拒绝回答,而是将输出向最近的已知模式靠拢。SSO 配置问题在 Harness 的认知世界里不存在对应类别,它被引力拉向了”集成需求” → feature_request,以 89% 的置信度。Stop Hook 的路由审计阈值(0.80)是为正常工单设计的,对这种高置信度的结构性错误没有区分能力。

对比分析总结:正常工单和 Enterprise 工单的追踪结构完全相同,推理步骤数量相同,延迟和成本相近——没有任何”系统异常”的特征。差异唯一发生在分类决策的语义层:一个在分布内,一个在分布外。这正是分布偏移最难察觉的原因:从可观测性的基础设施指标看,系统始终”正常”。


阶段四:根因确认与系统修复

根因定性:Enterprise 产品于第 9 周上线,引入了三类此前从未出现的工单类型(API 集成、Onboarding、企业身份认证),这些类型需要路由到 CS 团队,但 Harness 的分类体系中没有这个类别。这是 §12.1 难点三(分布偏移)的教科书案例:

  • 黄金集准确率稳定(93.6%–94.1%):因为黄金集是在 Enterprise 上线前构建的,不含这三类工单,对这一偏移完全不敏感
  • 在线准确率持续下降:因为新类型工单在总工单中的占比随 Enterprise 用户增长而增加(第 9 周 8% → 第 11 周 21%)
  • 成本和延迟无异常:分布偏移不触发基础设施指标,只触发质量指标

为什么前 3 周没有被更早发现:在线评估采用周维度汇总,第 9 周 91.3% 的准确率仍在”可接受波动”的直觉范围内(团队心理阈值约 90%),未触发调查。设第 8 周基线 p0=0.94p_0=0.94、日工单量约 1100 条,按二项分布单日 95% CI 半宽约为 1.96p0(1p0)/n1.41.96\sqrt{p_0(1-p_0)/n}\approx 1.4pp——即”3pp 持续 3 天”的阈值在统计上对应 p<0.001p<0.001 的低误报率。如果部署了 §12.1 建议的在线评估并设置了相对基线的变化告警(如”连续 3 天在线准确率低于基线 3pp 触发告警”),最早可在第 9 周中期发现,将修复窗口缩短约 2 周。

修复方案

修复一:Harness 扩容——添加新分类

将工单分类从 3 类扩展为 5 类,新增 onboarding_help(路由至 CS 团队)和 api_integration_help(路由至技术支持团队):

# System Prompt 分类定义更新(新增段落)

## 新增工单类别(第 9 周 Enterprise 上线后引入)

onboarding_help:企业账户初始化、权限配置、用户目录导入、
  管理员设置等 onboarding 阶段的操作性问题。
  → 路由至:客户成功团队(CS)

api_integration_help:API 认证(OAuth、API key、SAML/SSO)、
  Webhook 配置、第三方系统集成、企业身份认证(LDAP、SCIM)相关问题。
  → 路由至:技术支持团队

修复二:黄金集扩充

从第 9–11 周的人工修正工单中随机抽取 80 条(覆盖三个新聚类),人工标注正确类别后加入黄金集(原 320 条 → 400 条)。重新在扩充后的黄金集上运行评估,确认准确率:

黄金集版本样本量准确率
原版(无 Enterprise 样本)32093.8%(对偏移不敏感)
扩充版(含 80 条 Enterprise 样本)40067.2%(Harness 修复前)
扩充版 + Harness 5 类更新后40091.4%

扩充前后黄金集准确率的对比(93.8% vs. 67.2%)量化了”黄金集对当前生产分布的覆盖盲区”:旧黄金集的 93.8% 是一个虚高的数字,它没有测量系统在真实分布上的性能。

修复三:在线评估告警

部署 §12.1 建议的在线质量评估,对每日生产流量随机抽取 5% 进行 LLM-as-judge 评估,设置基于相对变化的告警规则:

# 在线评估告警规则(伪代码)
if online_accuracy.rolling_3d < baseline_accuracy - 0.03:
    alert("在线准确率较基线下降超过 3pp,持续 3 天,请检查分布偏移")

修复效果(第 12 周末验证)

指标修复前(第 11 周)修复后(第 12 周末)
在线路由准确率82.1%91.8%
Enterprise 账户误路由率70.8%6.2%
产品团队工单量(相对基准)基准 × 1.57基准 × 1.03
人工修正量(条/日)417

复盘与工程结论

问题环节根因修复
分类失败(高置信度误分类)新工单类型在 Harness 分类体系之外,Agent 做出分布外填充扩容分类体系,添加 onboarding_help / api_integration_help
发现延迟(3 周)黄金集不含 Enterprise 工单,对分布偏移不敏感;在线评估仅做周汇总,缺乏实时告警扩充黄金集 + 部署在线评估相对基线告警
产品上线触发偏移但未预警产品发布流程未包含”Harness 覆盖范围是否跟上新功能”的检查项在发布 Checklist 中增加:新功能是否产生现有 Harness 未覆盖的输入类型

本案例的核心工程结论:黄金集准确率稳定,不等于系统在生产环境中准确率稳定——这是 §12.1 难点三(分布偏移)的工程含义,也是本章最重要的实践教训之一。三层可观测性在此案例中的分工清晰体现:指标层发现了”某个维度的质量在下滑”(路由准确率趋势);日志层定位了”哪类输入受到影响”(Enterprise 账户的三类新工单);追踪层确认了”失败的具体机制”(高置信度的分布外填充,而非低置信度的不确定推断)。没有日志层,调查可能在”为什么产品团队工单量增加”的假设上绕行数天;没有追踪层,“Agent 是否在不确定的情况下猜测”这个关键问题就无法被精确回答。可观测性三层架构的价值,恰恰在这种没有爆炸、只有静默漂移的失效模式中最为显著。