评估 · Eval / Hallucination / 质量度量
Agent 轨迹评测、CI gate、幻觉四层防御 → 02-Agent工程实践-生产落地Playbook.md §7、§11
风格说明 :本篇以 机制深度 + 量化方法 为主轴------从 LLM 评估的统计基础到 hallucination 的物理根因。不重复"评测库速查",而是讲为什么这些方法有效、何时失效、怎样组合。覆盖"是什么 → 怎么算 → 为什么这么算 → 工程含义"四段。前置阅读 :
01-Transformer与Attention.md(理解 exposure bias / sampling 是 hallucination 机制根因);02-Prompt-工程(prompt 评估是基础)。 后续展开 :07-部署(线上观测 + §10 Token FinOps);08-架构(业务级 KPI);AgentOps 四支柱见本篇 §10、§99。
1. 本质:为什么 LLM 评估比传统 ML 难
1.1 一句话定义
LLM 评估 :用一组指标 + 数据集衡量模型在特定任务上的"好坏"------比传统分类 / 回归任务难得多,因为 LLM 输出是 自由文本 + 多种正确答案 + 主观维度。
1.2 LLM 评估 vs 传统 ML 评估
| 维度 | 传统 ML(分类 / 回归) | LLM |
|---|---|---|
| 输出空间 | 离散 / 数值 | 任意文本 |
| 正确答案 | 唯一 | 可能多种正确答案 |
| 评估方式 | accuracy / RMSE 等明确 | 多维度组合(正确 / 流畅 / 安全 / 风格) |
| 样本量 | 万级到亿级 | 千级到万级(人工标注贵) |
| 可解释性 | 容易 | 难(为什么这个答案好?) |
| 自动化 | 完全自动 | 需要 LLM-judge 或人工 |
| 过拟合风险 | 中 | 极高(benchmark 污染) |
1.3 三个易混概念
| 概念 | 准确含义 | 常见误解 |
|---|---|---|
| Benchmark | 通用基准(MMLU、HumanEval 等) | 当成"模型整体能力",但常被训练污染 |
| Eval | 业务场景的具体评估 | 当成 benchmark 的复制 |
| Online Metrics | 线上真实指标(CTR、留存) | 当成 eval 的延伸(实际差异巨大) |
1.4 评估"金三角"
核心:
- Benchmark:行业通用,对比模型;
- Eval:业务场景,决定是否上线;
- Online:线上 A/B,决定是否推全;
- 金三角必须打通------只看 benchmark 上线大概率翻车。
2. Benchmark:通用基准的"是与非"
2.1 主流 Benchmark 速查
| 类别 | Benchmark | 测什么 | 典型分数 |
|---|---|---|---|
| 通用知识 | MMLU | 57 学科多选 | Llama 3.1 405B: 88.6 |
| 推理 | BBH | 23 项 hard reasoning | GPT-4: 81.5 |
| 数学 | GSM8K(小学) | 7000 数学题 | GPT-4: 92 |
| 数学 | MATH | 12.5k 中学竞赛 | GPT-4: 50, o1: 94 |
| 代码 | HumanEval | 164 Python 编程 | GPT-4: 87, Claude 3.5: 92 |
| 代码 | MBPP | 974 编程 | Llama 3 70B: 76 |
| 代码 | SWE-bench | 真实 GitHub issue | Claude 3.5 Sonnet: 49 |
| 常识 | HellaSwag | 完型填空 | GPT-4: 95 |
| 代码(中级) | LiveCodeBench | 时刻更新(防污染) | 接近真实编程 |
| 中文 | C-Eval | 中文多学科 | Qwen 2.5 72B: 82 |
| 中文 | CMMLU | 中文知识 | Qwen 2.5 72B: 84 |
| Agent | AgentBench | 8 个 Agent 任务 | 多模型差异大 |
| 长上下文 | LongBench | 21 个长上下文任务 | 模型差异显著 |
| 多模态 | MMMU | 多模态推理 | GPT-4o: 70 |
2.2 Benchmark 的"4 大陷阱"
陷阱 1:训练污染
问题:模型可能在训练集里见过 benchmark 题目------分数虚高。
实证:研究显示,GSM8K 的题目改写后(数字 / 名字变了),有些模型分数掉 30%------说明模型在死记答案而非推理。
应对:
- 看 dynamic benchmark(如 LiveCodeBench,每月更新);
- 看 私有 eval(公司内部的,模型没见过);
- 看 答案分布(如果模型对 benchmark 答案分布很集中,可疑)。
陷阱 2:Benchmark 与业务脱节
问题:MMLU 高不代表客服 AI 好。
例子:
- Llama 3.1 70B:MMLU 86 → 客服任务可能不如 finetune 后的 Qwen 7B;
- GPT-4:MMLU 88 → 在某 RAG 任务上不如 BGE + 小模型组合。
应对:自建业务 eval(详见 §3)。
陷阱 3:评分主观
问题:很多 benchmark(如生成质量)需要主观打分。
例子:
- HumanEval:自动判定(跑测试)------客观;
- MT-Bench:用 GPT-4 judge------主观(GPT-4 可能偏好自己风格)。
应对 :用 多个 judge(GPT-4 + Claude + 人工抽样)。
陷阱 4:单点指标
问题:MMLU 87 ≠ 模型整体好。
- 可能某子领域 95,某子领域 60;
- 整体平均掩盖了致命弱点。
应对 :看 细分领域分(如 MMLU-Pro 的 STEM / 人文 / 法律细分)。
2.3 Staff 视角:怎么读 benchmark 报表
| 看什么 | 不要看什么 |
|---|---|
| 细分领域分 | 仅总分 |
| 与你业务相关的子集 | 总平均 |
| 数据集发布时间 vs 模型 cutoff | 仅当前分 |
| 同模型在 dynamic benchmark 的衰减 | 仅 static benchmark |
| 方差 / 置信区间 | 单点估计 |
3. 自建 Eval:业务场景评估
3.1 自建 Eval 的"5 个必备"
| 维度 | 内容 |
|---|---|
| Dataset | 100-1000 个真实业务 case |
| Labels | 每 case 的 ground truth 或评分标准 |
| Metric | 衡量好坏的具体公式 |
| Scorer | 自动 / LLM-judge / 人工 |
| Versioning | dataset 版本管理 |
3.2 Dataset 构建
数据来源:
- 线上真实数据:脱敏 + 抽样;
- 历史客服 / 工单:人工筛选;
- 合成数据:LLM 生成 + 人工 review;
- 对抗样本:故意构造的难例 / 边界。
配比建议(电商客服为例):
| 类别 | 占比 | 来源 |
|---|---|---|
| Happy path | 60% | 真实数据采样 |
| 边界 case | 20% | 人工设计(极端 / 罕见) |
| 对抗样本 | 10% | 故意 jailbreak / 注入 |
| 长尾 | 10% | P99 的真实 case |
3.3 Metric 设计
示例任务:客服 AI 分类(4 类)。
| Metric | 公式 | 健康线 |
|---|---|---|
| Accuracy | 正确数 / 总数 | > 0.90 |
| F1(per class) | 2·P·R/(P+R) | 每类 > 0.85 |
| Macro F1 | 各类 F1 平均 | > 0.85 |
| 延迟 P99 | 99% 请求延迟 | < 1s |
| 成本(avg token) | input + output tokens | 业务约定 |
生成类任务 metric:
| Metric | 含义 |
|---|---|
| BLEU / ROUGE | 字面重合度(已过时但简单) |
| BERTScore | 语义相似度(用 BERT embedding) |
| LLM-Judge Score | 用 GPT-4 / Claude 打分 |
| Human Eval | 人工评分(金标准但贵) |
3.4 LLM-as-a-Judge
思路:用 GPT-4 等强模型评估其他模型的输出。
python
JUDGE_PROMPT = """
你是 LLM 输出评估员。给定问题和回答,按以下维度打 1-5 分:
1. Correctness(准确性):信息正确无错
2. Completeness(完整性):回答完整覆盖
3. Clarity(清晰度):表达清晰
4. Style(风格):符合任务要求
问题:{question}
回答:{answer}
(参考答案:{reference})
输出 JSON:
{
"correctness": <1-5>,
"completeness": <1-5>,
"clarity": <1-5>,
"style": <1-5>,
"reasoning": "<简要解释>"
}
"""
def llm_judge(question, answer, reference, model="gpt-4o"):
response = openai.chat.completions.create(
model=model,
messages=[{"role": "user", "content": JUDGE_PROMPT.format(...)}],
response_format={"type": "json_object"},
temperature=0.0,
)
return json.loads(response.choices[0].message.content)
3.5 LLM-Judge 的 4 大坑
| 坑 | 含义 | 缓解 |
|---|---|---|
| Self-bias | 模型偏好自己风格 | 用多个 judge(GPT + Claude) |
| Position bias | 偏好 A/B 测试中先出现的 | 随机交换顺序 |
| Length bias | 偏好长答案 | 加约束"长度不影响评分" |
| Anchor bias | 第一个例子定调 | shuffle test order |
3.6 双 Judge 评估流水线
python
def double_judge_eval(question, answer_a, answer_b, reference):
# Judge 1: GPT-4
score_a_gpt = llm_judge(question, answer_a, reference, model="gpt-4o")
score_b_gpt = llm_judge(question, answer_b, reference, model="gpt-4o")
# Judge 2: Claude
score_a_claude = llm_judge(question, answer_a, reference, model="claude-3-5-sonnet")
score_b_claude = llm_judge(question, answer_b, reference, model="claude-3-5-sonnet")
# 综合
a_total = (score_a_gpt['correctness'] + score_a_claude['correctness']) / 2
b_total = (score_b_gpt['correctness'] + score_b_claude['correctness']) / 2
return {"a": a_total, "b": b_total, "winner": "a" if a_total > b_total else "b"}
3.7 人工评估(HITL)
何时需要:
- LLM-judge 不可靠的场景(专业领域 / 高风险);
- 校准 LLM-judge(先让人评 100 个,再训 judge);
- 上线前最终把关。
人工评估流程:
- 选 100-300 case(占总数 5-10%);
- 多人独立标(每 case 至少 3 人);
- 计算 inter-annotator agreement(Cohen's kappa > 0.6 健康);
- 异常 case 重审。
4. Hallucination:LLM 的"幻觉"机制
4.1 一句话定义
Hallucination(幻觉) :LLM 生成看似合理但事实错误 或编造的内容。是 LLM 最棘手的失效模式。
4.2 Hallucination 的 4 大类
| 类型 | 含义 | 例子 |
|---|---|---|
| Factual | 事实错误 | "爱因斯坦获 1942 年诺奖"(实际 1921) |
| Logical | 推理错误 | "A > B, B > C, 所以 A < C" |
| Citation | 编造引用 | 编不存在的论文 |
| Source | 误用上下文 | 答案与给的文档不符 |
4.3 Hallucination 的物理根因
根因 1:训练分布
- 训练时见的事实有错(互联网数据自带错误);
- 训练后无机制 "知道自己不知道"。
根因 2:Sampling
- 推理时按概率 sampling,不一定选最准 token;
- temperature > 0 会引入随机性。
根因 3:Exposure Bias
- 训练 teacher forcing:每步看真实历史;
- 推理时看自己输出:错误可能复合。
根因 4:Memorization vs Reasoning
- 训练时见过相似 case → 记住答案;
- 没见过 → 根据"模式"生成(可能错)。
4.4 如何检测 Hallucination
方法 1:与外部知识对比
python
def check_factual(answer, knowledge_base):
# 抽取 claim
claims = extract_claims(answer) # 用另一个 LLM
# 每个 claim 在 KB 里验证
for claim in claims:
evidence = knowledge_base.search(claim)
if not supports(claim, evidence):
return "HALLUCINATION", claim
return "OK", None
方法 2:Self-Consistency
python
def detect_via_consistency(question, n=5):
answers = [llm(question, temperature=0.7) for _ in range(n)]
# 如果 N 个 sampling 答案严重不一致 → 模型在"猜"
consistency = calculate_consistency(answers)
if consistency < 0.5:
return "POSSIBLE_HALLUCINATION"
return "OK"
方法 3:Verifier 模型
python
def verifier(question, answer):
response = strong_model(f"""
问题:{question}
回答:{answer}
这个回答的关键事实是否正确?回答 yes/no/uncertain,并解释。
""")
return parse(response)
方法 4:Citation 校验
python
def check_citations(answer, source_docs):
citations = extract_citations(answer) # "[doc_id_1]"
for cite in citations:
if cite not in source_docs:
return "FAKE_CITATION", cite
# 检查引文内容是否真实存在
if not text_in_doc(answer.related_text, source_docs[cite]):
return "MISCITATION", cite
return "OK"
4.5 Hallucination 量化指标
| 指标 | 计算方式 |
|---|---|
| Factuality Rate | 事实正确 / 总输出 |
| Citation Accuracy | 引用真实存在 / 总引用 |
| Contradiction Rate | 与给定上下文矛盾 / 总输出 |
| Confidence Calibration | 模型自信度 vs 实际准确率(ECE) |
4.6 缓解 Hallucination 的工程方法
| 方法 | 含义 | 适用 |
|---|---|---|
| RAG | 给 LLM 真实文档作为上下文 | 知识密集场景 |
| Temperature=0 | greedy sampling 减少随机 | 准确性优先 |
| CoT + Verifier | 推理过程 + 校验 | 多步推理 |
| Refusal Training | 训模型说"不知道" | 通用场景 |
| Tool Use | 用 calculator / SQL 代替 LLM "算" | 数学 / 查询 |
| HITL | 高风险场景人审 | 资金 / 医疗 |
4.7 RAG 中的 Hallucination
问题:即使有 RAG 上下文,LLM 仍可能 hallucinate("忽略文档自己编")。
实测(某 RAG 系统,1000 query):
- 上下文相关时:96% 准确,4% hallucination;
- 上下文不相关时:65% 准确,35% hallucination(模型"猜");
- 没有相关文档时:20% 准确,80% hallucination;
解法:
- 强 prompt:"仅根据提供的文档回答,不在文档中的信息回答'未找到'";
- Verifier:检查答案是否能在文档中找到 evidence;
- Refusal:训练 / prompt 让模型拒答。
5. Online Eval:线上真实指标
5.1 线上 vs 离线指标
| 维度 | 离线 Eval | 线上指标 |
|---|---|---|
| 能测什么 | accuracy / F1 / safety | CTR / 留存 / 满意度 |
| 数据 | 标注的固定数据集 | 真实用户行为 |
| 延迟 | 几小时跑完 | 实时 |
| 统计 | 单点对比 | A/B + p-value |
| 风险 | 低 | 高(用户真在用) |
5.2 线上指标设计
核心三角(任何 LLM 应用都该有):
| 指标族 | 例子 |
|---|---|
| 质量 | 任务完成率、用户满意度、bounce rate |
| 效率 | P50/P99 延迟、cost per session |
| 安全 | 错误率、违规率、HITL 触发率 |
5.3 用户反馈信号
显式信号:
- 👍/👎(用户点赞 / 点踩);
- 评分(1-5 星);
- 文字反馈。
隐式信号:
- 重新提问率(用户没满意,再问);
- 会话长度(5 轮以内完成 vs 10 轮以上);
- 跳出率(用户中途离开);
- 转人工率(客服场景关键指标)。
5.4 A/B 测试 LLM
流程:
- 设计:明确假设("v4 比 v3 满意度高 5%");
- 流量:10% → 50% → 100%(灰度);
- 观察:7-14 天最少(看周期性);
- 统计:p < 0.05 + effect size 合理;
- 决策:胜出版本上全量。
5.5 A/B 测试的坑
| 坑 | 含义 |
|---|---|
| Network effect | 用户 A 影响用户 B(社区 / 推荐) |
| Seasonality | 周末 vs 工作日差异 |
| Long-term effect | 短期好长期坏(如增点击牺牲留存) |
| Cohort variation | 不同用户群差异大 |
应对:
- 用 stratified random(按用户群分层);
- 跑长时间(至少 1 个完整周期);
- 看 multiple metrics(不只单指标)。
6. Eval 工具链
Harness 全栈(Staff) :06-Harness全栈-Eval-Agent-RL-Test.md §2 Evaluation + §5 Test · 可跑 demo:demos/harness-staff-kit
6.1 主流框架
| 工具 | 类别 | 强项 |
|---|---|---|
| OpenAI Evals | 开源 | 标准化、与 OpenAI 模型集成 |
| LangSmith | LangChain 系列 | end-to-end trace + eval |
| LangFuse | 开源 | 自部署友好 |
| Weights & Biases | 通用 ML | 实验管理 + 可视化 |
| DeepEval | Python 库 | LLM 专项指标多 |
| Promptfoo | YAML-based | 简单 + CI 友好 |
| Helicone | Observability | LLM API 调用监控 |
| Phoenix(Arize) | 开源 | trace + eval + drift detection |
| Datadog LLM Obs | 商业 | APM + LLM 集成 |
6.2 Promptfoo 实战
yaml
# promptfoo.yaml
prompts:
- id: classify_v3
template: |
请把以下文本分类到 物流/售后/商品/其他 之一:
{{input}}
- id: classify_v4
template: |
你是电商客服分类专家。根据下文分类到 物流/售后/商品/其他:
...
{{input}}
providers:
- openai:gpt-4o-mini
- anthropic:claude-3-5-sonnet
tests:
- vars: { input: "什么时候发货" }
assert:
- type: equals
value: "物流"
- vars: { input: "想退货" }
assert:
- type: equals
value: "售后"
# 100+ cases ...
scoring:
- accuracy: 0.5
- cost: 0.3
- latency: 0.2
bash
# 跑 eval
promptfoo eval --output results.json
# 看结果
promptfoo view
6.3 LangSmith / LangFuse 实战
python
from langsmith import Client
from langchain.smith import RunEvalConfig
client = Client()
eval_config = RunEvalConfig(
evaluators=[
"qa", # 内置 QA 评估
"criteria",
"embedding_distance",
],
custom_evaluators=[my_custom_evaluator],
)
results = client.run_on_dataset(
dataset_name="my_eval_set",
llm_or_chain_factory=my_chain,
evaluation=eval_config,
)
6.4 CI 集成
yaml
# .github/workflows/llm-eval.yml
name: LLM Eval
on: [pull_request]
jobs:
eval:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run promptfoo eval
run: |
npm install -g promptfoo
promptfoo eval --output results.json
- name: Check threshold
run: |
python check_eval.py results.json --min-accuracy 0.85
7. 数字账本(生产环境经验值)
7.1 评估流水线时间 / 成本
| 任务 | 时间 | 成本 |
|---|---|---|
| 100 case promptfoo eval(GPT-4o-mini) | 5 min | $0.05 |
| 1000 case eval(GPT-4o) | 20 min | $2 |
| 10000 case eval(GPT-4o + Claude judge) | 2 h | $20 |
| 人工标 100 case | 2-4 h | $200-500 |
| A/B 测试 7 天 | 7 天 | 看流量 |
7.2 模型质量阈值(电商客服)
| 阶段 | 准确率 | 满意度 | 转人工率 |
|---|---|---|---|
| MVP 起步 | > 0.75 | > 70% | < 30% |
| 稳定运营 | > 0.88 | > 85% | < 15% |
| 优秀 | > 0.93 | > 92% | < 8% |
| 顶尖 | > 0.96 | > 95% | < 5% |
7.3 模型对比经验值(同一业务 eval)
| 模型 | 业务 accuracy | 相对成本 |
|---|---|---|
| GPT-4o | 0.92 | 1.0× |
| GPT-4o-mini | 0.87 | 0.06× |
| Claude 3.5 Sonnet | 0.93 | 1.2× |
| Claude 3.5 Haiku | 0.85 | 0.10× |
| Llama 3.3 70B (自部署) | 0.88 | 0.20× |
| Qwen 2.5 72B (自部署) | 0.89 | 0.20× |
→ 大多数业务用 GPT-4o-mini / Claude Haiku 已够,复杂场景用 GPT-4o / Claude Sonnet。
8. 追问链:从"怎么评估"到 Staff+ 讨论
| 层 | 追问 | 子知识点 | 难度 |
|---|---|---|---|
| L1 | 怎么测一个 LLM 的能力? | benchmark | ⭐ |
| L2 | benchmark 的缺陷是什么? | 训练污染 + 业务脱节 | ⭐⭐ |
| L3 | 怎么自建 eval? | dataset + metric + scorer + versioning | ⭐⭐⭐ |
| L4 | LLM-Judge 的坑? | self-bias / position-bias 等 | ⭐⭐⭐ |
| L5 | Hallucination 的物理根因? | 训练分布 + sampling + exposure bias | ⭐⭐⭐⭐ |
| L6 | 离线 eval 高但线上效果差,怎么定位? | eval 与业务分布 mismatch | ⭐⭐⭐⭐ |
| L7(Staff+) | 怎么设计一个组织级 LLM eval 平台? | eval as a service + governance | ⭐⭐⭐⭐⭐ |
Staff+ 答 L7:
"组织级 eval 平台 4 个核心:
- 数据治理:eval dataset 入库、版本化、权限管理;
- 多源 scoring:自动 metric + LLM-judge + 人工,统一接口;
- CI 集成:PR 必跑 eval,准入门禁;
- 观测对齐:离线 + 线上指标统一看板,发现 drift。
关键挑战:1) eval 数据集污染防控;2) 跨 team 复用与定制;3) judge 模型的版本管理(升级 judge 会影响所有历史评分)。
实际落地:内部 fork LangSmith / LangFuse,加自家治理逻辑。"
9. 生产事故复盘 STAR-M-P:Eval 高但线上崩溃
S
- 业务:电商搜索 RAG
- eval:1000 case 离线准确率 0.92
- 线上:上线后 CTR 暴跌 30%
T
- 2025-09-05 上线
- 2025-09-06 09:00:业务方反馈"用户搜不到"
- 10:00:on-call 介入
A
第 1 步:复现
- 跑回 eval set → 仍 0.92
- 抓线上失败 case → 多是"短查询"("iPhone"、"手机")
- eval set 多是长查询("iPhone 15 Pro 128GB 蓝色")
第 2 步:定位
- eval 数据来自历史精确搜索(用户已知具体型号);
- 线上用户大多模糊搜索(短关键词);
- 模型对短查询的召回质量是 0.65(不在 eval set 测过);
- eval 与线上分布严重 mismatch。
R
止血 :回滚到旧版本 修复:
- eval 数据 重新采样:按线上 query length 分布抽 1000;
- eval 加入 短查询 类别(占 40%);
- 模型升级 + RAG 改写 query。
M
| 指标 | eval(旧) | eval(新) | 线上 |
|---|---|---|---|
| 准确率 | 0.92 | 0.84 | 0.85 |
| 短查询准确率 | (未测) | 0.78 | 0.80 |
| CTR | --- | --- | 恢复 |
P
核心教训:
"Eval 数据分布必须匹配线上数据分布 。0.92 vs 0.65 的差异不是模型问题,是 eval 集错了。生产红线:1) eval 集每月更新(按真实分布);2) eval 分布与线上分布对齐审计;3) eval 准入只是必要非充分条件,仍需 canary 上线。"
10. 紧急止血 Cheat Sheet
10.1 线上质量突然下降
python
# 步骤 1: 确认是不是模型问题
recent_responses = sample_recent_responses(n=100)
quality_score = llm_judge_batch(recent_responses)
# 如果分数明显低 → 是模型问题
# 步骤 2: 检查数据漂移
input_distribution_now = analyze_recent_inputs()
input_distribution_baseline = load_baseline_distribution()
drift = kl_divergence(now, baseline)
if drift > 0.5:
# 输入分布变了 → 模型不适应
# 步骤 3: 检查 prompt 版本
prompt_version = get_current_prompt()
last_change = git_log_for(prompt_version)
# 看是不是最近 prompt 改坏了
10.2 快速回滚
bash
# Prompt 版本回滚
kubectl set image deployment/llm-app llm-app=llm-app:v3.2.0
# 或 ConfigMap 改 prompt
kubectl edit configmap llm-prompts
kubectl rollout restart deployment/llm-app
10.3 应急降级
python
# 主模型质量差 → 降级到 fallback
def smart_route(query):
primary_score = quick_quality_check(query, primary_model)
if primary_score < THRESHOLD:
return fallback_model(query)
return primary_model(query)
11. 90 秒口述脚本
"LLM 评估 = Benchmark + Eval + Online,三角必须打通。Benchmark 看通用能力,但训练污染、业务脱节、单点指标 4 大陷阱,看细分领域 + dynamic 才靠谱。自建 Eval 5 必备:dataset / labels / metric / scorer / versioning,LLM-Judge 是甜区但有 self-bias / position-bias 4 坑,必须双 judge。Hallucination 4 类(factual / logical / citation / source),物理根因是训练分布 + sampling + exposure bias + 模式匹配 ≠ 推理,缓解靠 RAG + temperature=0 + Verifier + HITL。Online 是金标准------CTR / 留存 / 满意度,A/B 灰度 + 长时间 + 多指标。最大坑:eval 分布与线上分布 mismatch。"
12. 关联章节
01-Transformer与Attention.md------ Hallucination 的物理根因(exposure bias、sampling、tokenization)01-Prompt工程-Few-Shot-CoT与Tool-Use.md------ Prompt 评估的具体方法02-RAG检索增强-向量库与Chunking.md------ RAG 评估的特殊场景(召回 + 生成两段)03-部署-模型Serving-Caching与Cost.md------ 线上 observability 与 metrics
13. 速记卡
text
Benchmark = MMLU / HumanEval / GSM8K / SWE-bench / C-Eval
4 陷阱 = 训练污染 / 业务脱节 / 评分主观 / 单点指标
自建 Eval = Dataset / Metric / Scorer / Versioning
LLM-Judge = Self / Position / Length / Anchor 4 bias
Hallucination = Factual / Logical / Citation / Source
根因 = 训练分布 + sampling + exposure bias + 模式
缓解 = RAG / temp=0 / CoT+Verifier / Tool / HITL
Online = CTR / 留存 / 满意度 / A/B
工具 = OpenAI Evals / LangSmith / LangFuse / Promptfoo / DeepEval
14. 写给读者的几句话
学到这里,你应该能回答:
- Benchmark 怎么读?陷阱在哪? ------ §2
- 怎么自建一个业务 eval? ------ §3
- LLM-Judge 是什么?怎么用? ------ §3.4-3.7
- Hallucination 的物理根因? ------ §4
- 怎么检测和缓解 Hallucination? ------ §4.4-4.7
- 线上指标与离线 eval 怎么打通? ------ §5
- eval 工具链怎么选? ------ §6
- eval 高但线上崩,怎么定位? ------ §9
- Staff+ 怎么治理组织级 eval? ------ §8
10 题口述 5+ 分钟 = Staff+ 水平。
15. 一句话速记
LLM 评估 = Benchmark(通用)+ Eval(业务)+ Online(真实) ,三角打通才能上线。LLM-Judge 是甜区但要双 judge 防 bias,Hallucination 物理根因是训练分布 + sampling 错误累积,缓解靠 RAG + Verifier + HITL。最大风险 :eval 分布与线上分布 mismatch------0.92 离线可能对应 0.65 线上。生产红线:eval 集按真实分布抽样 + 月度更新 + canary 上线。
16. 深度专题:Sampling 参数对 Hallucination 的影响(机制层)
16.1 Temperature 的统计意义
核心:temperature 控制 softmax 输出的"锐度"。
r
softmax(z_i / T) = exp(z_i / T) / Σ exp(z_j / T)
T → 0: 分布尖锐(greedy)
T = 1: 原始分布
T → ∞: 分布平均(uniform)
16.2 Top-p (Nucleus) Sampling
思路:累计概率 ≤ p 的 token 才参与 sampling。
python
def nucleus_sample(logits, p=0.9):
probs = softmax(logits)
sorted_probs, indices = sorted(probs, reverse=True), argsort(-probs)
cum_probs = cumsum(sorted_probs)
cutoff = where(cum_probs >= p)[0][0]
valid_indices = indices[:cutoff+1]
valid_probs = sorted_probs[:cutoff+1]
valid_probs = valid_probs / sum(valid_probs) # 重新归一
return random_choice(valid_indices, p=valid_probs)
优势 :动态截断(不像 top-k 固定数量)。 实践 :temperature=0.7 + top_p=0.9 是甜区。
16.3 不同任务的 Sampling 配置
| 任务 | temperature | top_p | 理由 |
|---|---|---|---|
| 代码生成 | 0.0-0.3 | 1.0 | 准确性优先 |
| 分类 / 抽取 | 0.0 | 1.0 | deterministic |
| 客服回答 | 0.3-0.5 | 0.9 | 准确 + 自然 |
| 创意写作 | 0.7-1.0 | 0.95 | 多样性 |
| brainstorm | 0.9-1.2 | 0.95 | 创意 |
16.4 Sampling 与 Hallucination 关系
实测(某 QA 任务,1000 query):
| temperature | accuracy | hallucination rate |
|---|---|---|
| 0.0 | 0.91 | 5% |
| 0.3 | 0.89 | 7% |
| 0.7 | 0.84 | 12% |
| 1.0 | 0.79 | 18% |
结论 :高 temperature 几乎线性增加 hallucination------准确性优先就 temperature=0。
17. 深度专题:模型自校准(Calibration)
17.1 Calibration 是什么
核心:模型说"我有 80% 把握"时,实际正确率应该接近 80%。
例子:
- 模型说 80% 把握 → 实际正确 80% ✓ Well-calibrated
- 模型说 80% 把握 → 实际正确 60% ✗ Overconfident(过度自信)
- 模型说 80% 把握 → 实际正确 90% ✗ Underconfident
17.2 ECE(Expected Calibration Error)
python
def calculate_ece(predictions, n_bins=10):
"""
predictions: [(predicted_prob, actual_correct), ...]
返回 0~1 的 calibration error,越低越好
"""
bins = [(i/n_bins, (i+1)/n_bins) for i in range(n_bins)]
ece = 0
n = len(predictions)
for low, high in bins:
bin_preds = [p for p in predictions if low <= p[0] < high]
if not bin_preds:
continue
avg_pred = mean([p[0] for p in bin_preds])
avg_actual = mean([p[1] for p in bin_preds])
ece += abs(avg_pred - avg_actual) * len(bin_preds) / n
return ece
17.3 LLM 的 Calibration 现状
实证:
- GPT-3.5:ECE ≈ 0.15(中等)
- GPT-4:ECE ≈ 0.10(较好)
- RLHF 后通常 overconfident(说很自信但答错)
工程含义:
- 不能直接信 LLM 的"我很确定";
- 必须用外部 verifier 校验;
- 高风险场景必须 HITL。
17.4 改善 Calibration 的方法
| 方法 | 含义 |
|---|---|
| Temperature Scaling | 在 softmax 上加 1 个参数 T,重新校准 |
| Self-Consistency | sample N 次,agreement 越高越确定 |
| Verbalized Confidence | 让 LLM 显式说"我有 X% 把握",比 logit 更可信 |
| Tool Use | 用 calculator / DB 校验事实 |
python
# 让 LLM 显式表达 confidence
prompt = """
回答以下问题,并明确给出你的 confidence (0-100)。
问题:{question}
输出格式:
{
"answer": "...",
"confidence": <0-100>,
"uncertainty_reason": "..."
}
"""
18. 深度专题:RAG Eval 的特殊性
18.1 RAG 评估的"两段"
RAG = Retrieval + Generation,每段都要测。
18.2 Retrieval 指标
| 指标 | 公式 | 含义 |
|---|---|---|
| Recall@K | 真实相关 doc 在 top-K / 总相关 doc | 找到相关的比例 |
| Precision@K | 真实相关 doc 在 top-K / K | top-K 中相关的比例 |
| MRR | 平均 1 / 第一个相关 doc 的 rank | 排序质量 |
| nDCG@K | 折扣累积增益 | 综合排序质量 |
18.3 Generation 指标(RAG 特有)
| 指标 | 含义 | 计算 |
|---|---|---|
| Faithfulness | 答案是否忠于检索的文档 | LLM-judge |
| Answer Relevance | 答案是否回答了问题 | LLM-judge |
| Context Relevance | 检索的文档是否相关 | LLM-judge |
| Citation Accuracy | 引用是否真实存在于文档 | 字面校对 |
18.4 RAGAS 框架
python
from ragas import evaluate
from ragas.metrics import (
faithfulness,
answer_relevancy,
context_recall,
context_precision,
)
dataset = {
"question": [...],
"answer": [...],
"contexts": [...], # 检索的文档
"ground_truth": [...],
}
results = evaluate(
dataset,
metrics=[faithfulness, answer_relevancy, context_recall, context_precision],
)
18.5 RAG 失败模式分类
| 失败 | 根因 | 解决 |
|---|---|---|
| 检索召回低 | embedding 差 / chunking 错 | 换模型 / 调 chunking |
| 检索召回高但 LLM 没用 | prompt 不强 | 强 prompt"必须基于文档" |
| LLM 编造(hallucinate) | 模型自由发挥 | Verifier + refusal training |
| Citation 假 | LLM 不真引用 | 后处理校验 + prompt 强制格式 |
19. 深度专题:Agent Eval 的特殊性
19.1 Agent 评估的难度
为什么 Agent 难评估:
- 多步任务,每步可能错;
- 路径不唯一(A 能 B 也能完成);
- 成功 = 任务完成 + 不犯错 + 不重复 + 不浪费。
19.2 Agent 评估指标
| 指标 | 含义 |
|---|---|
| Task Success Rate | 任务完成率(最关键) |
| Steps to Completion | 完成步数(少越好) |
| Tool Call Accuracy | 工具调用是否正确 |
| Cost per Task | 单任务 token 成本 |
| Loop Rate | 死循环率 |
| Hallucination in Tools | 调用不存在工具 / 编参数 |
19.3 Agent Benchmark
| Benchmark | 测什么 |
|---|---|
| AgentBench | 8 个 Agent 任务(OS / DB / 游戏等) |
| WebArena | Web 操作 Agent |
| SWE-bench | 真实 GitHub issue 修复 |
| TauBench | 客服 / 零售 Agent |
19.4 Agent eval 流水线
python
def eval_agent_task(task_definition, agent):
initial_state = task_definition.setup()
trace = []
success = False
for step in range(MAX_STEPS):
action = agent.act(state)
observation = environment.step(action)
trace.append((action, observation))
if environment.done():
success = environment.task_completed()
break
return {
"success": success,
"steps": len(trace),
"trace": trace,
"cost": agent.total_cost,
}
20. 深度专题:人工评估的统计学
20.1 Inter-Annotator Agreement
Cohen's Kappa:衡量两个标注者一致性。
python
def cohens_kappa(annotator_a, annotator_b):
# Observed agreement
p_o = sum(1 for a, b in zip(annotator_a, annotator_b) if a == b) / len(annotator_a)
# Expected agreement (by chance)
categories = set(annotator_a + annotator_b)
p_e = sum(
(annotator_a.count(c) / len(annotator_a)) *
(annotator_b.count(c) / len(annotator_b))
for c in categories
)
return (p_o - p_e) / (1 - p_e)
# < 0.4: 差
# 0.4-0.6: 一般
# 0.6-0.8: 好
# > 0.8: 极好
20.2 Fleiss' Kappa(多个标注者)
类似 Cohen's,但支持 N 个标注者。常用于 N=3-5 的众包。
20.3 怎么提升标注一致性
- 明确 guideline:写详细标注手册("什么算 correct");
- 训练:先让标注者标 20-50 个,看 disagreement 在哪;
- 校准:定期 cross-check,修正理解偏差;
- 多人 + 多数票:每 case 至少 3 人标,取多数。
21. 评估治理:组织级实践
21.1 Eval-as-a-Service 平台
核心组件:
功能:
- Dataset 版本管理 + 权限;
- 多 model / prompt 对比;
- 自动 + LLM-judge + 人工评分集成;
- CI 集成(PR 准入);
- 趋势看板(model / prompt drift)。
21.2 Eval Governance Checklist
- Dataset 版本:每次评估明确数据集版本(git commit / hash)
- Model 版本:API model 锁版本(OpenAI 等会静默更新)
- Judge 版本:LLM-judge 模型也锁版本
- 结果可追溯:每次 eval 结果入库,含完整 metadata
- 离线 + 线上对齐:每月对比离线 eval 与线上 metrics
- 回归检测:模型 / prompt 改动后必跑回归 eval
- 公平比较:对比模型时 prompt / 配置完全相同
- 失败分析:每次 eval 后看失败 case 分布
21.3 评估的"反模式"
反模式 1:Goodhart's Law
- "成为指标的衡量标准就不再是好指标"------团队优化 benchmark 指标牺牲实际质量;
- 解决:多指标 + 业务指标 + 用户调研。
反模式 2:单 judge 决定一切
- LLM-judge 自身有 bias;
- 解决:多 judge + 人工抽样校准。
反模式 3:eval 数据集污染
- eval set 不小心进了训练 → 分数虚高;
- 解决:eval 集严格隔离,公开 vs 私有分开。
反模式 4:忽视长尾
- 整体 0.92 但长尾 case 灾难;
- 解决:分桶 eval(按 query 难度 / 长度 / 类别)。
22. 评估的未来:自动化与持续评估
22.1 Trends(2026)
趋势 1:Dynamic Benchmark
- 静态 benchmark 易污染,业界转向动态生成 / 实时更新;
- 例:LiveCodeBench、Dynabench。
趋势 2:LLM-Judge 标准化
- 业界趋同用 GPT-4o / Claude 3.5 作 judge;
- 工具支持自动化(如 OpenAI Evals 内置)。
趋势 3:Online + Offline 一体化
- 线上 trace 自动入 eval 数据库;
- 失败 case 自动转人工标注 → 改进数据集。
趋势 4:Multi-modal Eval
- 文本 + 图 + 音 + 视频统一评估;
- 工具刚成型(VHELM、HELM-Multimodal)。
22.2 持续评估 Pipeline
23. 评估常见陷阱总结表
| 陷阱 | 表现 | 解决 |
|---|---|---|
| Benchmark 污染 | 分数飙升异常 | 看 dynamic benchmark |
| Eval-Online mismatch | 离线高线上崩 | 数据分布对齐 |
| Judge self-bias | 评分偏向某模型 | 多 judge |
| Position bias | A/B 顺序影响 | 随机交换 |
| Length bias | 偏好长答案 | 加约束 |
| 数据集太小 | 方差大 | ≥ 500 case |
| 标注者不一致 | kappa < 0.6 | 培训 + 校准 |
| 单指标主导 | 整体好但长尾差 | 分桶 + 多指标 |
| 忽视成本 | 准确率高但贵 | 综合 ROI |
| Goodhart 效应 | 指标好但实际不好 | 用户调研兜底 |
§10 AgentOps 观测栈(Langfuse / Helicone / Phoenix / OpenLLMetry)
AgentOps = 把 LLM 应用当 分布式系统 运维:每次调用是可追溯 span,每次发布有 eval gate,每分钱有 attribution,每次劣化有 alert。与 07-部署 §10 Token FinOps、05-AI辅助开发 DevEx 成本 共用 $/successful task 口径 ,但 数据面分离。
Golden Set 组织流程(RACI、回流、PR Gate) → 专篇 10-Eval集治理;四维版本发布 → 11-Registry。
Buy-Team 交易 Agent 端到端样例(trace JSON + golden YAML + CI gate) → 08 §10.15。
§10.1 四支柱(Trace · Eval · Cost · Alert)
| 支柱 | 回答的问题 | 核心信号 | 典型消费者 |
|---|---|---|---|
| Trace | 哪一步错了? | trace_id、span、tool I/O、prompt 版本 | Oncall、调试 |
| Eval | 能不能上线? | faithfulness、cite rate、judge score | ML / 产品 |
| Cost | 谁花了多少钱? | /req、/successful task、token 分桶 | FinOps、租户账单 |
| Alert | 何时止血? | 错误率↑、P99↑、幻觉率↑、日预算熔断 | PagerDuty |
打通原则 :同一 trace_id 贯穿 Gateway → ChatClient → Tool → VectorStore ;eval 结果与 cost 按 tenant_id + feature 标签 join。
§10.2 观测栈选型(2026)
| 工具 | 类型 | 强项 | 弱项 | 典型组合 |
|---|---|---|---|---|
| Langfuse | 开源 + 云 | LLM trace、prompt 版本、eval 数据集、成本看板 | 重度 APM 需自建 | Spring AI 首选 |
| Helicone | 代理 / SDK | 极快接入、成本缓存统计 | 深度 Agent 图较弱 | 小团队 / 原型 |
| Phoenix(Arize) | 开源 | Embedding 漂移、RAG 检索可视化 | 企业 SSO 需企业版 | RAG 重场景 |
| OpenLLMetry | OTel 语义约定 | 与 Jaeger/Datadog/Grafana 统一 | 需自己搭 UI | 已有 K8s 观测栈 |
决策口诀:
- 已全套 Grafana + Tempo → OpenLLMetry + 自建面板;
- Java/Spring AI 为主 → Langfuse(Observation API 一等公民);
- RAG 幻觉 / 召回 → Phoenix 补检索层;
- 快速验证成本 → Helicone 代理一层,成熟后迁 Langfuse。
§10.3 Spring AI Observation API 集成
Spring AI 2.x 基于 Micrometer Observation,与 Actuator / OTel 导出对齐。
xml
<!-- pom.xml 片段 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>
yaml
# application.yml
management:
tracing:
sampling:
probability: 1.0 # 生产按流量调 0.1--0.3
otlp:
tracing:
endpoint: http://otel-collector:4318/v1/traces
spring:
ai:
chat:
observations:
include-prompt: false # 合规:默认不落全文
include-completion: false
vectorstore:
observations:
log-query-response: false
java
@Configuration
public class AgentObservabilityConfig {
@Bean
ChatClient customerAgent(ChatClient.Builder builder,
VectorStore vectorStore) {
return builder
.defaultAdvisors(
QuestionAnswerAdvisor.builder(vectorStore).build(),
new SimpleLoggerAdvisor() // 开发环境
)
.build();
}
@Bean
ObservationFilter tenantTagFilter() {
return context -> {
String tenant = TenantContext.get();
if (tenant != null) {
context.addLowCardinalityKeyValue(
KeyValue.of("tenant.id", tenant));
}
context.addLowCardinalityKeyValue(
KeyValue.of("feature", "customer-support"));
return context;
};
}
}
导出到 Langfuse(Collector 侧路由示例):
yaml
# otel-collector-config.yaml
exporters:
otlp/langfuse:
endpoint: https://cloud.langfuse.com/api/public/otel
headers:
Authorization: "Bearer ${LANGFUSE_PUBLIC_KEY}"
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlp/langfuse, otlp/tempo]
| Observation 字段 | 用途 |
|---|---|
gen_ai.request.model |
成本分模型 |
gen_ai.usage.input_tokens |
FinOps 输入侧 |
gen_ai.usage.output_tokens |
FinOps 输出侧 |
tenant.id / feature |
多租户归因 |
rag.document.id |
幻觉溯源到 chunk |
§10.4 四支柱落地清单
Trace
- 每个
ChatClient调用有 trace_id;tool 调用为 child span - prompt/completion 默认脱敏;需要排障时按 trace 临时开全量(审计)
- 与业务
order_id/session_id关联(高基数字段用 log 侧车,不进 metric label)
Eval
- 离线集版本 pin;PR 改 prompt → 自动跑 regression(§3)
- 线上 1--5% shadow judge;坏 case 入标注队列(§22.2)
- RAG 专评:context precision / faithfulness(Phoenix 或 Langfuse eval)
Cost
- LiteLLM
metadata带tenant+feature(见 07 §10) - 日报: /successfultask、/1k sessions
- 租户日预算熔断(HTTP 429 + 降级文案)
Alert
- P99 latency、5xx、幻觉关键词命中率
- Eval 分数周环比跌 >5% 告警
- 单租户 cost > 3× 7 日均值
§10.5 与 Eval 本篇其他章节的关系
| 本篇章节 | AgentOps 落点 |
|---|---|
| §3 自建 Eval | Langfuse Dataset + CI webhook |
| §4 Hallucination | Trace 定位错误 chunk;Alert 关键词 |
| §5 Online Eval | Trace 采样 → 标注 → 数据集回流 |
| §21 Eval-as-a-Service | 与 Langfuse 项目/环境对齐 |
§99 6 Q&A + 15 checklist
考前 30 分钟 :6 题 + 15 项。与 13-Agent工程实践 §7、§11 互补。
§99.1 高频 Q&A(6 道)
E01 · AgentOps 和传统 APM 有什么区别?
答 :结论 ------APM 看 服务延迟/错误 ;AgentOps 还要 prompt 版本、tool 轨迹、检索证据、judge 分、token 成本 。工程 ------OTel gen_ai 语义 + Langfuse eval。风险------只接 APM 看不见「答错但 200 OK」。
E02 · Langfuse 和 LangSmith 怎么选?
答 :结论 ------LangChain 深度用 LangSmith ;Spring AI / 多语言 / 自托管 用 Langfuse 。原理 ------二者都覆盖 Trace+Eval;看生态与合规部署。验证------OTel 导出能否进现有 Grafana。
E03 · Spring AI 如何不把 prompt 打进日志?
答 :结论 ------include-prompt: false + ObservationFilter 脱敏;排障开 按 trace 临时采样 。合规------PCI/PII 字段进 Advisor 前 redact。
E04 · 四支柱哪个最先建?
答 :结论 ------Trace → Cost → Alert → Eval 。原理 ------没 trace 无法归因成本与幻觉;eval 可后补数据集。工程------第一周 OTel+Langfuse;第二周 LiteLLM metadata。
E05 · 线上幻觉怎么和 Trace 联动?
答 :结论 ------Output Verifier fail → 打 hallucination.flag span tag → 抽样进 eval 集。RAG------Phoenix 看 retrieval→generation 链;cite 缺失告警。
E06 · $/successful task 在 Eval 域怎么定义?
答 :结论 ------任务成功 = 业务规则通过(如退款单创建成功)且 judge≥阈值。分母 ------非仅 HTTP 200。成本------trace 汇总 input+output token × 单价。
§99.2 考前 Checklist(15 项)
- 四支柱:Trace / Eval / Cost / Alert 各举 1 个指标
- Langfuse vs Helicone vs Phoenix vs OpenLLMetry 选型
- Spring AI
observations.include-prompt: false - ObservationFilter 打
tenant.id/feature - OTel Collector 双写 Langfuse + Tempo
- trace_id 关联
session_id(高基数不进 metric) - 离线 eval PR gate;模型/prompt 版本 pin
- 线上 shadow judge + 坏 case 回流
- RAG:faithfulness + context precision
- LiteLLM metadata 成本归因(链 07 §10)
- $/successful task 定义口述
- 租户日预算熔断
- Alert:P99、5xx、eval 跌、cost 异常
- 与 §4 幻觉四层防御不矛盾
- §99.1 任选 3 题录音 ≤90s
🧭 章节导航(再放)
| # | 文件 | 风格 |
|---|---|---|
| 00 | 00-README.md | 索引 |
| 01 | 01-Transformer与Attention.md | 机制 |
| 02 | 01-Prompt工程-Few-Shot-CoT与Tool-Use.md | 操作 |
| 03 | 02-RAG检索增强-向量库与Chunking.md | 设计 |
| 04 | 01-Agent框架-LangChain-LangGraph与AutoGen.md | 设计 |
| 05 | 01-AI辅助开发-Cursor-Copilot与Claude-Code.md | 操作 |
| 06 | 本篇 · 评估-Eval / Hallucination / 质量度量 | 机制 |
| 07 | 03-部署-模型Serving-Caching与Cost.md | 操作 |
| 08 | 01-电商AI辅助交易场景.md | 设计 |
🧭 章节导航
| # | 文件 | 风格 |
|---|---|---|
| 00 | 00-README.md | 索引 |
| 01 | 01-Transformer与Attention.md | 机制 |
| 02 | 01-Prompt工程-Few-Shot-CoT与Tool-Use.md | 操作 |
| 03 | 02-RAG检索增强-向量库与Chunking.md | 设计 |
| 04 | 01-Agent框架-LangChain-LangGraph与AutoGen.md | 设计 |
| 05 | 01-AI辅助开发-Cursor-Copilot与Claude-Code.md | 操作 |
| 06 | 本篇 · 评估-Eval / Hallucination / 质量度量 | 机制 |
| 07 | 03-部署-模型Serving-Caching与Cost.md | 操作 |
| 08 | 01-电商AI辅助交易场景.md | 设计 |
v2.4 增补 · 长上下文 Eval 与 RAG CI Gate
NIAH/RULER 、RAGAS/DeepEval/Giskard 进 PR 流水线的门禁设计。
B1. 长上下文评估 · 为何单独成类
| 基准 | 测什么 | 面试要点 |
|---|---|---|
| NIAH (Needle In A Haystack) | 深堆噪声中检索插入针 | 随上下文长度准确率曲线 |
| RULER | 多针、变长、推理型任务 | 比 NIAH 更贴近「假长上下文」 |
| InfiniteBench / BABILong | 极长+多跳 | 成本与采样策略 |
Staff 结论 :长上下文 不是「窗口越大越好」 ------要看 有效注意力 与 RAG 是否已覆盖 ;生产优先 RAG+合理窗口,全上下文仅用于审计/法律场景。
B2. NIAH 实验设计模板
yaml
niah_suite:
context_lengths: [4k, 32k, 128k, 200k]
needle_depths: [0.1, 0.5, 0.9] # 在上下文中的相对位置
needles_per_doc: [1, 4]
metric: exact_match_on_secret_token
pass_criteria: acc@128k >= 0.95 for prod_candidate
常见失败 :中间 lost-in-the-middle;缓解:UIC/RAG、摘要链、换模型。
B3. RULER 与生产映射
| RULER 任务族 | 生产类比 |
|---|---|
| 多针检索 | 长合同多条款引用 |
| 变量追踪 | 订单全链路状态追问 |
| 聚合 | 周报跨段落汇总 |
B4. RAGAS · RAG 质量四维
| 指标 | 含义 | CI 阈值示例 |
|---|---|---|
| faithfulness | 答案是否被 context 支撑 | ≥ 0.85 |
| answer_relevancy | 答非所问程度 | ≥ 0.80 |
| context_precision | 检索噪声 | ≥ 0.75 |
| context_recall | 漏检索 | ≥ 0.70 |
B5. DeepEval · 单元测试化 LLM
- GEval:自定义 criteria(礼貌、合规)
- DAG metric:多步判定
- 集成 :
pytest+deepeval test run
python
# 示意:CI 中一条 case
from deepeval import assert_test
from deepeval.test_case import LLMTestCase
from deepeval.metrics import FaithfulnessMetric
def test_refund_faithfulness():
assert_test(
LLMTestCase(input="退款多少", actual_output=out, retrieval_context=ctx),
[FaithfulnessMetric(threshold=0.85)],
)
B6. Giskard · 脆弱性与偏见扫描
| 扫描类型 | 发现 |
|---|---|
| Prompt injection | 越狱模板成功率 |
| Stereotypes | 保护属性切片 |
| Performance bias | 语种/方言差异 |
适合 ** nightly** 全量;PR 上跑 smoke 子集(<10min)。
B7. CI Gate 流水线(推荐)
| Gate 层级 | 触发 | 时长预算 |
|---|---|---|
| L1 PR | prompt/检索变更 | 10 min |
| L2 nightly | 全量+Giskard | 2 h |
| L3 发布前 | NIAH@128k + 业务集 | 4 h |
B8. 与 Langfuse/Trace 联动
- 失败 case 自动带
trace_id回流数据集 - $/eval run 纳入 FinOps(见 06 Staff v2.4)
B9. 口播题(5 题)
B-Q1 · NIAH 过了但线上 RAG 仍胡编?
NIAH 测 裸上下文 ;线上失败在 检索------加 RAGAS context_recall。
B-Q2 · RAGAS faithfulness 低怎么办?
收紧 chunk、加 citation 约束、换 reranker;勿先换 70B。
B-Q3 · DeepEval 与 promptfoo 分工?
DeepEval 指标+pytest ;promptfoo 多模型 diff+A/B prompt------可并用。
B-Q4 · Giskard 误报太多?
调阈值、分 risk_tier;P0 注入保留 fail-closed。
B-Q5 · 长上下文还要不要做 RAG?
要 ;长窗口降延迟与简化架构,但 成本与幻觉 仍靠 RAG+Eval 兜底。
B11. NIAH 变体与工程陷阱
| 变体 | 描述 | 为何重要 |
|---|---|---|
| Multi-needle | 多段 secret | 测聚合记忆 |
| Haystack 真实文档 | 非随机 token | 更接近 RAG |
| Adversarial needle | 与主题相似干扰 | 测鲁棒检索 |
| Dynamic position | 滑动插入点 | 画 U 型准确率曲线 |
陷阱 1 :用 相同模板 过拟合 judge。
陷阱 2 :只测 4k/8k,prod 用 128k 未覆盖 。
陷阱 3 :忽略 tokenizer 差异------字符长度 ≠ token 长度。
B12. RULER 任务详解与采样预算
| 任务 | 输入规模 | 建议采样数/发布 |
|---|---|---|
| Single-NIAH | 32k--128k | 200 |
| Multi-NIAH | 64k+ | 150 |
| Variable tracking | 32k | 100 |
| Aggregation | 128k | 80 |
text
成本估算: 200 cases × 128k tokens × $3/1M ≈ $77/模型/次(仅输入粗算)
→ 发布前抽样 + nightly 全量
B13. RAGAS 失败诊断树
B14. DeepEval × Giskard 组合门禁
| 工具 | PR Gate | Nightly | 阻断条件 |
|---|---|---|---|
| DeepEval | 50 cases | 2k cases | faithfulness < 0.85 |
| Giskard | 10 injection | 全库 | P0 注入成功率 > 0 |
| RAGAS | 30 RAG pairs | 500 | Δrecall < -3% |
| NIAH@32k | 20 | 100@128k | acc < 0.92 |
B15. 长上下文 × RAG 联合策略
| 策略 | 适用 | 代价 |
|---|---|---|
| 长窗口直塞 | 法律单文档 | 高 $、高延迟 |
| RAG+8k | 客服/电商 | 需检索质量 |
| 层次摘要 | 周报类 | 摘要链误差累积 |
| Hybrid | Staff 推荐 | 检索 top-k + 局部窗口 |
B16. CI 配置示例(GitHub Actions 片段)
yaml
name: llm-eval-gate
on: [pull_request]
jobs:
eval-smoke:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pip install ragas deepeval giskard
- run: python scripts/run_ragas_smoke.py --threshold 0.85
- run: python scripts/run_niah_sample.py --length 32768 --n 20
- run: deepeval test run tests/test_faithfulness.py
B17. STAR-M-P · NIAH 通过但 RAG faithfulness 崩盘
Situation:换 128k 模型后 NIAH@128k 0.97,上线 RAG 客服 faithfulness 0.62。
Action :Phoenix 显示 检索漏政策段落;修 chunk 512→256 + hybrid search;faithfulness 0.86。
Metrics:MTTR 1 天;误答率 -40%。
B18. 口播题扩展(8 题)
B-Q6 · 如何选 needle 内容?
与业务 关键字段同分布(订单号、条款号),避免 OOV token。
B-Q7 · RAGAS context_precision 低?
reranker 或减小 k;检查 重复 chunk 稀释。
B-Q8 · DeepEval threshold 如何定?
历史 prod P10 加安全边际;分 risk_tier 两档阈值。
B-Q9 · Giskard 在 CI 太慢?
smoke 子集 + 缓存 embedding;全量仅 nightly。
B-Q10 · 128k 模型是否取消 RAG?
不取消;长窗口作 审计/上诉 通道,日常仍 RAG。
B-Q11 · 多语言 NIAH?
分语言基准;勿用英语 needle 测中文文档。
B-Q12 · Eval 数据集谁维护?
平台+业务 共管;坏 case 自动回流。
B-Q13 · 相对基线 Δ 如何算?
(candidate - baseline) / baseline;主指标 + 护栏分别算。
B19. 大厂题(Eval 向 8 题)
| ID | 题 | 要点 |
|---|---|---|
| E11 | 设计 LLM 质量 CI | 三层 Gate + 相对基线 |
| E12 | 长文档法务助手 eval | NIAH+RAGAS+citation |
| E13 | 幻觉 KPI 怎么定 | faithfulness+业务 verifier |
| E14 | judge 模型漂移 | 人审校准集每月刷新 |
| E15 | eval 成本失控 | 抽样+缓存+SLM judge |
| E16 | 多模型对比发布 | promptfoo matrix |
| E17 | 线上抽检比例 | 高风险 10%,低风险 1% |
| E18 | A/B 与 offline eval 不一致 | 分布偏移+position bias |
B20. v2.4 Checklist 扩展
- NIAH 四变体
- RULER 采样预算口算
- RAGAS 诊断树
- B14 四门禁表
- Hybrid 长上下文策略
- §B17 STAR
- §B18 八题任选 3
B10. v2.4 Checklist
- NIAH vs RULER 区别
- RAGAS 四维各一句
- DeepEval faithfulness pytest 示例
- Giskard PR vs nightly 分工
- CI Gate 三层与相对基线
- 与 §4 幻觉防御一致
官方文档与源码(一级依据)
AI Engineering · 正文机制应来自下方 官方文档(L1) 与 官方源码仓库(L2) ; 禁止用教程站/博客充当机制依据。本章 QPS/延迟/STAR 为面试示意。 写作规范:docs/official-sources-registry.md §0
L1 · 官方文档
L2 · 官方源码
L3 · 论文 / 开放规范