跳到主要内容

AI 应用评估与可观测性

问题

如何判断一次 Prompt、模型、RAG 或 Agent 改动真的变好了?如何建设离线评测、线上指标、LLM-as-a-Judge、轨迹评估、Tracing 和发布门禁?

面试速答版

AI 应用不能只测“接口成功”和“JSON 能解析”,要建立三层质量闭环:

  1. 离线 Evals:固定代表性数据集,每次改 Prompt、模型、检索或工具都跑回归。
  2. 线上观测:任务完成率、用户反馈、转人工、延迟、成本、工具错误与安全事件。
  3. 失败回流:把线上失败脱敏、去重、标注后加入评测集。

评分优先级通常是:确定性断言 > 人工标注 > 经过校准的 Judge。Agent 还要评估轨迹、工具选择、参数、权限、步骤和最终结果,不能只看最后一句话。

一、为什么传统测试不够

同一个输入可能有多种正确表达,模型和检索又具有概率性。传统单元测试仍然必要,但只覆盖确定性部分:

  • Schema、权限、金额、URL、SQL、工具参数。
  • 流协议、取消、重试、幂等和状态机。
  • 引用资源是否存在、用户是否有权访问。

语义质量则需要任务特定评测:答案是否正确、证据是否充分、风格是否合适、工具路径是否安全。

二、从业务目标定义 Eval

不要从“模型准确率”开始,要从用户任务开始:

产品业务目标离线指标线上指标
客服正确解决问题答案正确、政策遵循、引用支持一次解决率、转人工率、复开率
RAG找到并使用正确资料Recall@K、NDCG、忠实度、引用覆盖来源点击、纠错、无结果率
代码 Agent完成变更且不破坏系统测试通过、Diff 约束、工具轨迹PR 接受率、回滚、缺陷逃逸
数据分析查询正确且解释可信SQL 结果、数值、图表 Schema保存/分享率、人工修正率
不要用一个“总分”掩盖风险

一个平均 90 分的系统,可能在普通问题上 99 分、权限问题上 0 分。安全、隐私和高风险业务约束应作为硬门槛或单独切片,而不是被平均值稀释。

三、评测集设计

数据来源

  • 产品需求和验收用例。
  • 真实线上请求的脱敏、聚类与抽样。
  • 历史事故和人工转接记录。
  • 专家构造的边界、对抗和拒答样本。
  • 合成数据,用于扩充表达方式;必须人工抽查。

切片维度

types/eval-case.ts
interface EvalCase {
id: string;
input: unknown;
expected?: unknown;
rubric?: string[];
tags: Array<
| 'happy-path'
| 'long-context'
| 'multilingual'
| 'prompt-injection'
| 'permission'
| 'tool-use'
| 'no-answer'
>;
source: 'product' | 'production' | 'incident' | 'synthetic';
dataPolicy: 'public' | 'internal' | 'restricted';
}

评测集必须版本化,训练/调参集与最终留出集分开,避免团队反复针对同一批样本“刷题”。

四、评分器的选择顺序

1. 确定性评分

最可信、便宜、可解释:

evals/order-eval.ts
function gradeOrderAnswer(output: OrderAnswer, expected: ExpectedOrder) {
return {
orderIdCorrect: output.orderId === expected.orderId,
amountCorrect: Math.abs(output.amount - expected.amount) < 0.01,
sourceAllowed: output.sources.every(source => expected.allowedSources.includes(source)),
noSecret: !containsSecret(output.text),
};
}

能用数据库、测试、编译器、计算器、JSON Schema 或规则判定的部分,不要交给另一个 LLM 猜。

2. 人工评分

适合建立金标准、评估主观体验和校准 Judge。要提供清晰 Rubric、示例和冲突处理流程,并记录评分者一致性。

3. LLM-as-a-Judge

适合大规模比较开放式答案,但存在位置偏差、长度偏差、自我偏好、知识错误和 Prompt Injection 风险。

推荐:

  • 优先 pairwise 比较,而不是让 Judge 随意打 1–10 分。
  • 随机交换候选答案顺序,检测位置偏差。
  • 只提供评分必要内容,外部文档当作不可信数据。
  • 用人工金标准计算一致率、召回和误判切片。
  • Judge 模型、Prompt、Rubric 和版本都要入库。
evals/pairwise.ts
interface PairwiseJudgment {
winner: 'A' | 'B' | 'tie';
criteria: {
correctness: 'A' | 'B' | 'tie';
completeness: 'A' | 'B' | 'tie';
citationSupport: 'A' | 'B' | 'tie';
};
evidence: string[];
}

五、RAG 评估拆层

RAG 失败时要先判断哪一层坏了:

指标典型问题
解析内容覆盖、结构保留表格、页码、代码块丢失
召回Recall@K、MRR、NDCG正确证据没进候选集
重排Top-K 命中、排序增益候选有正确文档但排得太后
上下文证据覆盖、token、权限截断、重复、越权片段
生成忠实度、引用精度、拒答有证据却答错或无证据硬答

端到端“答案好不好”不能告诉你应该调 chunk、Embedding、Reranker 还是 Prompt。

六、Agent 评估

Agent 评测至少包含四层:

  1. 最终结果:文件、工单、订单或测试是否达到目标。
  2. 轨迹:是否选择正确工具、参数和顺序。
  3. 效率:步骤、token、工具时间、重试和费用。
  4. 安全:是否越权、是否在副作用前确认、是否泄漏数据。
types/agent-trace.ts
interface AgentStep {
index: number;
toolName?: string;
inputHash?: string;
outcome: 'success' | 'error' | 'denied' | 'approval-required';
durationMs: number;
inputTokens?: number;
outputTokens?: number;
}

interface AgentEval {
taskSuccess: boolean;
invalidToolCalls: number;
unauthorizedAttempts: number;
duplicateWrites: number;
totalSteps: number;
totalCostUsd?: number;
}

不要要求 Agent 复制一条“标准轨迹”:不同安全路径都可能正确。应定义允许条件、禁止动作和最终不变量。

七、线上可观测性

Trace 结构

Span 建议包含低基数、可聚合字段:

  • request/workflow ID、功能、环境、租户散列。
  • Provider、能力角色、模型版本。
  • operation、结束原因、错误类型。
  • 输入/输出/缓存/推理 token。
  • 首块延迟、总耗时、工具和检索耗时。
  • Prompt、策略、检索器和评测版本。
内容默认不进 Trace

Prompt、工具参数、工具结果和系统指令可能含敏感数据。OpenTelemetry 的 GenAI 语义约定也明确提示相关字段可能敏感。默认记录摘要、哈希、长度和分类;原文采样必须经过脱敏、权限和短期保留。

前端指标

  • 提交到首个可见内容的时间。
  • 流中断、取消、重新生成和恢复成功率。
  • 引用展开/点击、复制、采纳和纠错。
  • 工具审批接受/拒绝和用户等待时间。
  • 错误提示是否给出可执行的下一步。

八、发布门禁与灰度

evals/release-gate.ts
interface EvalReport {
taskSuccess: number;
safetyPass: number;
p95LatencyMs: number;
meanCostUsd: number;
slices: Record<string, { passRate: number; count: number }>;
}

function canRelease(candidate: EvalReport, baseline: EvalReport): boolean {
return (
candidate.safetyPass === 1 &&
candidate.taskSuccess >= baseline.taskSuccess - 0.005 &&
candidate.p95LatencyMs <= baseline.p95LatencyMs * 1.1 &&
candidate.slices.permission?.passRate === 1
);
}

阈值只是示例。真实门禁要根据风险和样本置信度制定,并查看分布和切片。上线先做 shadow/canary,预先定义回滚指标,避免看到波动后临时解释。

九、常见反模式

  • 只看点赞率,不看任务是否真正完成。
  • 用同一个模型生成答案又给自己打分。
  • 每次换模型都更换评测集,无法与基线比较。
  • 只报告平均分,不看权限、语言、长上下文等切片。
  • 把线上完整 Prompt 全量记录到 Trace。
  • 只评最终答案,不评 Agent 的越权尝试和重复写入。
  • Judge Prompt 被候选答案中的恶意指令劫持。
  • 在没有统计意义的小样本上宣布提升。

常见面试问题

Q1: AI Eval 和普通单元测试有什么区别?

答案:单元测试适合确定性规则;Eval 衡量开放式、概率性语义质量。成熟系统同时需要两者,能确定性判断的部分优先用普通测试。

Q2: 评测集从哪里来?

答案:需求验收、真实线上失败、历史事故、专家边界用例和经过审查的合成数据。需要脱敏、去重、切片、版本化,并保留独立测试集。

Q3: LLM-as-a-Judge 有哪些偏差?

答案:位置、长度、风格、自我偏好、知识错误和注入。通过顺序随机化、pairwise Rubric、多 Judge、人工金标准和切片校准降低风险。

Q4: RAG 为什么要拆层评估?

答案:答案错误可能来自解析、召回、重排、上下文或生成。拆层指标才能定位应该改模型、分块、过滤还是 Prompt。

Q5: Agent 评测为什么不能只看最终答案?

答案:Agent 可能通过越权、重复写入或高成本路径得到正确结果。需要同时评轨迹、工具参数、授权、步骤、成本和不变量。

Q6: 什么是评测切片?

答案:按语言、长度、用户类型、风险、工具、文档类型等维度分组。它能防止平均分掩盖关键场景退化。

Q7: 如何做模型升级门禁?

答案:固定数据集和 Prompt,比较质量、安全、延迟与成本;关键切片设硬门槛;灰度观察线上指标并预设回滚。

Q8: 线上反馈能直接当标签吗?

答案:不能。点赞受 UI、用户预期和选择偏差影响。需要结合任务结果、后续行为和人工标注,并过滤滥用与重复数据。

Q9: 为什么 Trace 不应默认记录完整 Prompt?

答案:Prompt 和工具结果可能包含 PII、密钥和商业数据。默认记录元数据和哈希,需要内容时受控采样、脱敏和短期保留。

Q10: 如何评估流式 UI?

答案:测提交到首块、流畅度、中断率、取消传播、恢复、最终一致性和可访问性,而不只是后端总耗时。

Q11: 如何防止团队对评测集过拟合?

答案:训练/开发/留出集分离,定期从新线上样本扩充,保留隐藏集,并关注真实业务指标是否同步改善。

Q12: 最有价值的 Eval 指标是什么?

答案:没有通用单一指标。首选与业务结果直接相关的任务成功率,再用安全、质量、延迟和成本切片解释结果。

相关链接