LLM 应用没有单元测试——但你需要评估体系传统软件的 bug 是崩溃和异常。LLM 应用的 bug 是看起来对但实际不对——幻觉、答非所问、工具调用错误。这些 bug 不会抛异常只会悄悄拉低用户体验。2026 年一个合格的 LLM 应用评估体系包含四层层级目标频率工具离线评测开发阶段评估模型/方案每次变更RAGAS, DeepEval, BLEUCI 门禁提交前自动检查质量每次 PRPytest LLM断言A/B 测试上线前对比新旧方案每次发布自建框架线上监控实时监控质量指标持续Prometheus 自定义metrics第一层构建评估数据集评估体系的地基是数据集。没有高质量评估集一切指标都是垃圾。# 评估数据集的标准结构 EVAL_DATASET [ { id: eval_001, category: 事实查询, difficulty: easy, query: 公司年假政策是什么, expected_answer: 员工每年享有10天带薪年假工作满3年后增至15天。, must_contain: [10天, 15天, 带薪], # 必须包含的关键信息 must_not_contain: [无薪], # 不能包含的内容 context_docs: [hr_policy_2026.pdf], # 参考文档 }, { id: eval_002, category: 多步推理, difficulty: hard, query: 张三和李四谁的年假更多, expected_answer: 张三有15天(工龄5年)李四有10天(工龄2年)张三更多。, must_contain: [张三, 更多, 15], context_docs: [employee_db, hr_policy_2026.pdf], }, ] # 四类核心测试用例 def build_eval_suite(): return { 事实查询: 30, # 知识库能直接回答的问题 多步推理: 20, # 需要综合多文档 边界情况: 20, # 知识库没有的信息 / 模糊问题 对抗测试: 10, # 故意拼错/歧义/诱导幻觉 }数据集的三个原则 -覆盖真实分布按线上场景的比例采样别全放简单题 -标注一致每道题至少双人标注diff 讨论后统一 -随着线上反馈迭代把线上 bad case 加入评估集保持以战养战第二层RAG 评估 —— RAGAS 实战如果你的应用基于 RAGRAGAS 是 2026 年最成熟的评估框架from ragas import evaluate from ragas.metrics import ( faithfulness, # 忠实度回答是否基于检索到的文档 answer_relevancy, # 答案相关性回答是否切题 context_precision, # 上下文精确度检索结果中相关比例 context_recall, # 上下文召回率相关内容被检索到的比例 ) from datasets import Dataset eval_data Dataset.from_dict({ question: [ 公司的远程办公政策是什么, 如何申请报销 ], answer: [ 公司允许员工每周远程办公2天。, 登录OA系统填写报销单上传发票提交审批。 ], contexts: [ [公司远程办公政策员工每周可选择2天远程办公需提前报备。], [报销流程OA系统→新建报销单→上传发票→部门经理审批→财务打款。] ], ground_truth: [ 员工每周可远程办公2天需提前报备。, 通过OA系统提交报销单附发票经审批后打款。 ] }) result evaluate(eval_data, metrics[ faithfulness, answer_relevancy, context_precision, context_recall ]) print(fFaithfulness: {result[faithfulness]:.2%}) print(fAnswer Relevancy: {result[answer_relevancy]:.2%}) print(fContext Precision: {result[context_precision]:.2%}) print(fContext Recall: {result[context_recall]:.2%})RAGAS 指标解读指标GoodWarningBad问题定位Faithfulness0.900.80-0.900.80模型在编造检查prompt和temperatureAnswer Relevancy0.850.75-0.850.75检索召回不准或模型跟丢问题Context Precision0.800.70-0.800.70检索噪声大需要re-rankerContext Recall0.850.75-0.850.75检索遗漏检查chunking和embedding第三层LLM-as-Judge 的正确用法LLM 自己评自己是危险的——自我偏好偏差会让分数虚高 10-20%。以下是 2026 年业界验证过的做法import json def llm_judge(query: str, answer: str, reference: str, criteria: list[str]) - dict: 用强模型评估带结构化 rubric prompt f你是一个严格的评估专家。请根据以下标准对回答评分1-5分。 评估标准 {chr(10).join(f- {c} for c in criteria)} 用户问题{query} 参考答案{reference} 待评估回答{answer} 请按以下 JSON 格式输出不要输出其他内容 {{ scores: {{标准1: 分数, ...}}, overall: 平均分, strengths: [优点1, 优点2], issues: [问题1, 问题2], hallucination_detected: true/false, hallucination_details: 如有幻觉具体描述 }} response client.chat.completions.create( modelclaude-opus-4-7, # 用最强的模型当 Judge messages[{role: user, content: prompt}], temperature0.0, response_format{type: json_object} ) return json.loads(response.choices[0].message.content) # 减轻自我偏好用 DIFFERENT 模型做 Judge # 如果被测模型是 GPT-5.1用 Claude Opus 4.7 做 Judge反之亦然LLM-as-Judge 三原则 1.Judge 和被测模型必须是不同模型——跨模型评估偏差远低于自评 2.用结构化 rubric 而非给个分数——带具体标准的评分一致性高 40% 3.人工抽检校准——每天抽 20 条人工复评跟踪 LLM Judge 和人工评分的相关性第四层线上监控评估集可以测出 80% 的问题但剩下 20% 只在线上暴露from dataclasses import dataclass, field from datetime import datetime import numpy as np dataclass class LLMMetrics: LLM 应用的实时监控指标 # 质量指标 response_lengths: list[int] field(default_factorylist) user_feedback_scores: list[int] field(default_factorylist) # 安全指标 refusal_count: int 0 hallucination_flags: int 0 tool_call_failures: int 0 # 性能指标 latencies: list[float] field(default_factorylist) token_counts: list[int] field(default_factorylist) def get_summary(self) - dict: return { avg_latency_ms: np.mean(self.latencies[-100:]), p95_latency_ms: np.percentile(self.latencies[-100:], 95), refusal_rate: self.refusal_count / max(len(self.response_lengths), 1), hallucination_rate: self.hallucination_flags / max(len(self.response_lengths), 1), tool_failure_rate: self.tool_call_failures / max(len(self.response_lengths), 1), avg_user_score: np.mean(self.user_feedback_scores[-50:]) if self.user_feedback_scores else 0, } # 线上幻觉检测简单但有效的启发式检查 def detect_potential_hallucination(response: str, retrieved_docs: list[str]) - bool: 检测回答中可能不在检索文档中的关键声明 import re # 提取数字、百分比、金额等容易编造的信息 critical_claims re.findall(r\d%|\$\d|\d万元|\d人, response) for claim in critical_claims: found any(claim in doc for doc in retrieved_docs) if not found: return True return False线上告警阈值参考指标告警阈值严重阈值幻觉率5%10%P95延迟5s10s工具调用失败率3%8%用户负反馈率10%20%小结LLM 评估不是一个一次性做完的事情——它是伴随应用整个生命周期的持续流程。评估数据集要随线上反馈迭代LLM-as-Judge 要定期人工校准监控指标要和业务 SLA 绑定。起步建议先用 RAGAS 50 条评估数据跑通离线评测 → 接入 CI → 上线后加监控 → 每月迭代评估数据集。下一篇预告LLM 评估体系进阶——A/B 测试统计显著性、多模型对比评测框架、自动化回归测试。
LLM 评估体系从零到一:Benchmark、指标与线上监控,2026 实战指南
LLM 应用没有单元测试——但你需要评估体系传统软件的 bug 是崩溃和异常。LLM 应用的 bug 是看起来对但实际不对——幻觉、答非所问、工具调用错误。这些 bug 不会抛异常只会悄悄拉低用户体验。2026 年一个合格的 LLM 应用评估体系包含四层层级目标频率工具离线评测开发阶段评估模型/方案每次变更RAGAS, DeepEval, BLEUCI 门禁提交前自动检查质量每次 PRPytest LLM断言A/B 测试上线前对比新旧方案每次发布自建框架线上监控实时监控质量指标持续Prometheus 自定义metrics第一层构建评估数据集评估体系的地基是数据集。没有高质量评估集一切指标都是垃圾。# 评估数据集的标准结构 EVAL_DATASET [ { id: eval_001, category: 事实查询, difficulty: easy, query: 公司年假政策是什么, expected_answer: 员工每年享有10天带薪年假工作满3年后增至15天。, must_contain: [10天, 15天, 带薪], # 必须包含的关键信息 must_not_contain: [无薪], # 不能包含的内容 context_docs: [hr_policy_2026.pdf], # 参考文档 }, { id: eval_002, category: 多步推理, difficulty: hard, query: 张三和李四谁的年假更多, expected_answer: 张三有15天(工龄5年)李四有10天(工龄2年)张三更多。, must_contain: [张三, 更多, 15], context_docs: [employee_db, hr_policy_2026.pdf], }, ] # 四类核心测试用例 def build_eval_suite(): return { 事实查询: 30, # 知识库能直接回答的问题 多步推理: 20, # 需要综合多文档 边界情况: 20, # 知识库没有的信息 / 模糊问题 对抗测试: 10, # 故意拼错/歧义/诱导幻觉 }数据集的三个原则 -覆盖真实分布按线上场景的比例采样别全放简单题 -标注一致每道题至少双人标注diff 讨论后统一 -随着线上反馈迭代把线上 bad case 加入评估集保持以战养战第二层RAG 评估 —— RAGAS 实战如果你的应用基于 RAGRAGAS 是 2026 年最成熟的评估框架from ragas import evaluate from ragas.metrics import ( faithfulness, # 忠实度回答是否基于检索到的文档 answer_relevancy, # 答案相关性回答是否切题 context_precision, # 上下文精确度检索结果中相关比例 context_recall, # 上下文召回率相关内容被检索到的比例 ) from datasets import Dataset eval_data Dataset.from_dict({ question: [ 公司的远程办公政策是什么, 如何申请报销 ], answer: [ 公司允许员工每周远程办公2天。, 登录OA系统填写报销单上传发票提交审批。 ], contexts: [ [公司远程办公政策员工每周可选择2天远程办公需提前报备。], [报销流程OA系统→新建报销单→上传发票→部门经理审批→财务打款。] ], ground_truth: [ 员工每周可远程办公2天需提前报备。, 通过OA系统提交报销单附发票经审批后打款。 ] }) result evaluate(eval_data, metrics[ faithfulness, answer_relevancy, context_precision, context_recall ]) print(fFaithfulness: {result[faithfulness]:.2%}) print(fAnswer Relevancy: {result[answer_relevancy]:.2%}) print(fContext Precision: {result[context_precision]:.2%}) print(fContext Recall: {result[context_recall]:.2%})RAGAS 指标解读指标GoodWarningBad问题定位Faithfulness0.900.80-0.900.80模型在编造检查prompt和temperatureAnswer Relevancy0.850.75-0.850.75检索召回不准或模型跟丢问题Context Precision0.800.70-0.800.70检索噪声大需要re-rankerContext Recall0.850.75-0.850.75检索遗漏检查chunking和embedding第三层LLM-as-Judge 的正确用法LLM 自己评自己是危险的——自我偏好偏差会让分数虚高 10-20%。以下是 2026 年业界验证过的做法import json def llm_judge(query: str, answer: str, reference: str, criteria: list[str]) - dict: 用强模型评估带结构化 rubric prompt f你是一个严格的评估专家。请根据以下标准对回答评分1-5分。 评估标准 {chr(10).join(f- {c} for c in criteria)} 用户问题{query} 参考答案{reference} 待评估回答{answer} 请按以下 JSON 格式输出不要输出其他内容 {{ scores: {{标准1: 分数, ...}}, overall: 平均分, strengths: [优点1, 优点2], issues: [问题1, 问题2], hallucination_detected: true/false, hallucination_details: 如有幻觉具体描述 }} response client.chat.completions.create( modelclaude-opus-4-7, # 用最强的模型当 Judge messages[{role: user, content: prompt}], temperature0.0, response_format{type: json_object} ) return json.loads(response.choices[0].message.content) # 减轻自我偏好用 DIFFERENT 模型做 Judge # 如果被测模型是 GPT-5.1用 Claude Opus 4.7 做 Judge反之亦然LLM-as-Judge 三原则 1.Judge 和被测模型必须是不同模型——跨模型评估偏差远低于自评 2.用结构化 rubric 而非给个分数——带具体标准的评分一致性高 40% 3.人工抽检校准——每天抽 20 条人工复评跟踪 LLM Judge 和人工评分的相关性第四层线上监控评估集可以测出 80% 的问题但剩下 20% 只在线上暴露from dataclasses import dataclass, field from datetime import datetime import numpy as np dataclass class LLMMetrics: LLM 应用的实时监控指标 # 质量指标 response_lengths: list[int] field(default_factorylist) user_feedback_scores: list[int] field(default_factorylist) # 安全指标 refusal_count: int 0 hallucination_flags: int 0 tool_call_failures: int 0 # 性能指标 latencies: list[float] field(default_factorylist) token_counts: list[int] field(default_factorylist) def get_summary(self) - dict: return { avg_latency_ms: np.mean(self.latencies[-100:]), p95_latency_ms: np.percentile(self.latencies[-100:], 95), refusal_rate: self.refusal_count / max(len(self.response_lengths), 1), hallucination_rate: self.hallucination_flags / max(len(self.response_lengths), 1), tool_failure_rate: self.tool_call_failures / max(len(self.response_lengths), 1), avg_user_score: np.mean(self.user_feedback_scores[-50:]) if self.user_feedback_scores else 0, } # 线上幻觉检测简单但有效的启发式检查 def detect_potential_hallucination(response: str, retrieved_docs: list[str]) - bool: 检测回答中可能不在检索文档中的关键声明 import re # 提取数字、百分比、金额等容易编造的信息 critical_claims re.findall(r\d%|\$\d|\d万元|\d人, response) for claim in critical_claims: found any(claim in doc for doc in retrieved_docs) if not found: return True return False线上告警阈值参考指标告警阈值严重阈值幻觉率5%10%P95延迟5s10s工具调用失败率3%8%用户负反馈率10%20%小结LLM 评估不是一个一次性做完的事情——它是伴随应用整个生命周期的持续流程。评估数据集要随线上反馈迭代LLM-as-Judge 要定期人工校准监控指标要和业务 SLA 绑定。起步建议先用 RAGAS 50 条评估数据跑通离线评测 → 接入 CI → 上线后加监控 → 每月迭代评估数据集。下一篇预告LLM 评估体系进阶——A/B 测试统计显著性、多模型对比评测框架、自动化回归测试。