1. 为什么智能体项目绕不开LLM Evals这道坎
做智能体开发的人都有一个共同的体感:Demo跑通只要一个下午,但要让它在生产环境里稳定干活,可能要折腾三个月。这中间的鸿沟,十有八九卡在评估环节。你搭了一个基于RAG的客服智能体,本地测试问了十个问题都答得挺像样,一上线用户问了个边缘case,它就开始一本正经地胡说八道。你改了一版提示词,感觉好像好了点,但又说不清到底好了多少,更不知道有没有把原来能答对的问题改坏。这种“凭感觉调优”的状态,就是没有评估体系最典型的症状。
LLM Evals说白了就是给大模型和智能体做“体检”的一套方法论和工具链。它要回答的核心问题很朴素:你的智能体到底行不行?行到什么程度?哪一块不行?改了一版之后是变好了还是变差了?这些问题听起来简单,但真正落地一套生产级评估体系,涉及的东西远比想象中多。从评估指标的设计、测试集的构建、评估方法的选择(规则匹配、语义相似度、LLM-as-judge),到评估流程的自动化、结果的追踪与回归,每一个环节都有坑。
这篇文章适合三类人看:一是正在做智能体项目、被效果波动折磨得死去活来的开发者;二是团队里负责搭建AI工程化基础设施的技术负责人;三是对RAGAS、LLM-as-judge这些概念听过但没实际用过、想搞清楚怎么落地的工程师。我会从整体设计思路讲到具体实操,把RAGAS评估、LLM-as-judge、测试集构建、回归测试这些关键环节拆开揉碎,配上可以直接抄的代码和参数配置。读完之后你至少能做到:给自己的智能体项目搭一套能跑起来的评估流水线,知道每个指标背后的含义,遇到评估结果异常时知道往哪个方向排查。
2. 评估体系的整体设计与方案选型
2.1 先搞清楚你要评估什么:智能体的三层评估对象
很多人一上来就问“用什么工具做评估”,这个问题问早了。你得先明确评估对象是什么。智能体和普通LLM应用不一样,它至少涉及三个层面的东西需要分别评估。
第一层是检索层。如果你的智能体用了RAG,那检索出来的文档片段质量直接决定了后续生成的上限。检索层要评估的是:召回率够不够、排序准不准、有没有把不相关的噪声塞进上下文。这一层的评估相对客观,因为你可以拿标准答案去比对。
第二层是生成层。给定上下文和用户问题,模型生成的回答质量如何。这里要看的维度就多了:事实一致性(有没有编造)、相关性(有没有答非所问)、完整性(该说的有没有说全)、格式合规性(输出结构对不对)。这一层是LLM Evals的主战场。
第三层是任务层。智能体最终是要完成任务的,比如帮用户查订单、改地址、发起退款。任务层的评估看的是端到端的成功率:用户的问题有没有被正确理解、工具调用有没有选对、参数有没有填对、多轮对话有没有保持上下文一致。这一层最接近业务指标,但也最难自动化评估。
我见过不少团队只评估生成层,结果上线后发现智能体“话说得漂亮但事没办成”。所以三层要分开评、分开看,才能定位问题到底出在哪。
2.2 为什么选RAGAS + LLM-as-judge这套组合
评估方法大致分三类:基于规则的、基于模型的、基于人工的。规则匹配适合格式检查、关键词命中这类确定性强的场景,但对付开放式生成就力不从心了。人工评估最准,但成本高、速度慢,不可能每次改代码都拉人来评。基于模型的评估(也就是LLM-as-judge)是目前性价比最高的方案,用一个大模型去评判另一个模型的输出。
RAGAS是专门为RAG系统设计的评估框架,它把检索和生成两个环节的评估指标都封装好了,开箱即用。核心指标包括Faithfulness(忠实度)、Answer Relevancy(答案相关性)、Context Precision(上下文精确率)、Context Recall(上下文召回率)。这几个指标的设计逻辑很清晰:Faithfulness看的是回答有没有忠实于检索到的上下文,Answer Relevancy看的是回答和问题是否相关,Context Precision和Recall分别看检索的准和全。
但RAGAS不是万能的。它主要针对RAG场景,对于工具调用、多轮对话这些智能体特有的能力覆盖不够。所以实际项目中,我的做法是RAGAS打底,再叠加自定义的LLM-as-judge评估器来处理任务层的评估。比如工具调用准确性,我会写一个judge prompt,让模型判断“智能体是否选择了正确的工具、参数是否合理”,输出一个0到1的分数。
注意:LLM-as-judge本身也有偏差。模型倾向于给较长的回答打高分,也倾向于给自己的输出打高分。所以judge模型最好和被测模型不是同一个,而且要在prompt里明确评分标准,减少主观性。
2.3 评估体系的分层架构设计
一套能跑的生产级评估体系,我一般会分成四层来搭。
最底层是数据层,包括测试集、标准答案、评估配置。测试集的质量直接决定评估结果的可信度,这部分后面会详细讲怎么构建。
往上是执行层,负责跑评估任务。输入是测试集和被测智能体,输出是每个样本的原始回答和中间过程(检索结果、工具调用记录等)。这一层要支持并发执行,不然几百条测试用例跑起来太慢。
再往上是评分层,把执行层的输出喂给各种评估器,得到每个维度的分数。RAGAS的指标、自定义judge、规则检查都在这一层。
最上面是分析与追踪层,负责汇总分数、对比不同版本的评估结果、生成报告、触发告警。这一层往往被忽视,但实际上非常重要。没有追踪和对比,你根本不知道这次改动是正向还是负向。
3. 核心细节解析与实操要点
3.1 测试集构建:评估体系的地基
测试集是评估体系里最容易被低估的环节。很多人随便找几个问题就开始跑评估,结果分数忽高忽低,根本没法用。一个好的测试集要满足几个条件:覆盖核心场景、包含边缘case、有可靠的标准答案、规模适中。
构建测试集有几种常见做法。第一种是从生产日志里采样,这是最贴近真实分布的方式。把线上用户的真实query捞出来,去掉重复和无效的,人工标注标准答案。第二种是基于知识库合成,用LLM根据文档内容自动生成问答对,再人工审核。这种方式效率高,但要注意合成的问题可能分布不均。第三种是专家设计,针对业务场景手工设计测试用例,覆盖各种边界情况。
我的经验是三种方式结合:生产日志采样占60%,合成占30%,专家设计占10%。生产日志保证分布真实,合成补充覆盖度,专家设计专门针对那些容易出错的边缘场景。
测试集的规模不用追求大。对于大多数智能体项目,200到500条测试用例就足够发现主要问题了。关键是每条用例都要有明确的标准答案或评分标准。如果标准答案本身模棱两可,评估结果就没有意义。
实操心得:测试集要版本化管理,和代码一样提交到git。每次修改测试集都要记录原因,不然过几个月你根本想不起来为什么加了某条用例。
3.2 RAGAS评估的四个核心指标怎么用
RAGAS的四个核心指标各有各的用途,不能混着看。
Faithfulness(忠实度)衡量的是回答中的每个论断是否都能在检索到的上下文中找到依据。这个指标低,说明模型在编造信息,也就是幻觉。计算方式是先把回答拆成若干论断,然后逐条判断是否被上下文支持,最后算支持的比例。Faithfulness低于0.8就要警惕了,说明幻觉问题比较严重。
Answer Relevancy(答案相关性)衡量的是回答和问题的相关程度。注意它不判断回答对不对,只判断相不相关。计算方式是让模型根据回答反推可能的问题,然后算反推问题和原问题的相似度。这个指标低,说明模型答非所问或者回答太泛。
Context Precision(上下文精确率)衡量的是检索到的上下文中,有多少是真正相关的。这个指标低,说明检索噪声大,把不相关的内容也塞进来了。噪声会干扰模型生成,也会浪费token。
Context Recall(上下文召回率)衡量的是标准答案中的信息,有多少能在检索到的上下文中找到。这个指标低,说明检索漏了关键信息,模型再强也答不出来。
这四个指标要结合起来看。比如Faithfulness高但Context Recall低,说明模型很老实,只根据检索到的内容回答,但检索本身漏了信息。这时候要优化的是检索环节,不是生成环节。
from ragas import evaluate from ragas.metrics import ( faithfulness, answer_relevancy, context_precision, context_recall, ) from datasets import Dataset # 准备评估数据,格式要求如下 eval_data = { "question": ["用户的问题1", "用户的问题2"], "answer": ["智能体的回答1", "智能体的回答2"], "contexts": [["检索到的文档片段1", "片段2"], ["片段3", "片段4"]], "ground_truth": ["标准答案1", "标准答案2"] } dataset = Dataset.from_dict(eval_data) # 执行评估 result = evaluate( dataset, metrics=[faithfulness, answer_relevancy, context_precision, context_recall], ) print(result) # 输出每个指标的分数,以及每个样本的详细评分这段代码是RAGAS评估的最小可用示例。实际项目中,contexts要从你的检索系统里实际取出来,不能手工填。ground_truth就是标准答案,需要提前准备好。
3.3 LLM-as-judge的自定义评估器怎么写
RAGAS覆盖不了的维度,就要自己写judge。写judge的核心是设计好评判prompt。一个好的judge prompt要包含:评判任务说明、评分标准(每个分数段对应什么表现)、输出格式要求、以及必要的示例。
以工具调用准确性评估为例,我会这样设计prompt:
TOOL_CALL_JUDGE_PROMPT = """ 你是一个评估专家,负责判断智能体的工具调用是否正确。 用户问题:{question} 智能体选择的工具:{selected_tool} 工具参数:{tool_params} 可用工具列表:{available_tools} 标准答案中的预期工具:{expected_tool} 请从以下维度评分(0-1分): 1. 工具选择是否正确:选择的工具是否是最适合解决用户问题的 2. 参数是否合理:传入的参数是否完整、准确 3. 是否有冗余调用:是否调用了不必要的工具 评分标准: - 1.0:工具选择正确,参数完整准确,无冗余调用 - 0.7:工具选择正确,但参数有小瑕疵 - 0.4:工具选择基本合理,但存在明显问题 - 0.0:工具选择错误或参数严重错误 请以JSON格式输出:{{"score": 分数, "reason": "评分理由"}} """这个prompt的关键点在于:评分标准要具体,每个分数段对应什么表现要说清楚;输出格式要结构化,方便程序解析;要给出评分理由,方便人工复核时理解judge的判断逻辑。
注意:judge模型的选择很重要。实测下来,judge模型的能力至少要和你被测模型相当,否则judge本身判断不准,评估结果就不可信。另外judge的温度参数建议设成0,保证评分稳定。
3.4 评估流程的自动化与回归测试
评估不能是一次性的,要集成到开发流程里。我的做法是搭一条评估流水线:代码提交后自动触发评估,跑完测试集后生成报告,和基线版本对比,如果关键指标下降超过阈值就阻断合并。
这条流水线的核心是回归测试。每次改动(不管是改prompt、换模型、调检索参数)都要跑一遍完整的测试集,对比改动前后的分数。这样才能确保改动是正向的,没有引入回归。
回归测试要注意几点。第一,测试集要固定,不能这次跑用这批、下次跑用那批,否则分数没法对比。第二,评估环境要一致,包括模型版本、温度参数、检索配置等。第三,要区分“统计显著”和“随机波动”。LLM的输出本身有随机性,同一版本跑两次分数也会有波动。所以对比时要看多次运行的平均值,单次差异在5%以内的不要急着下结论。
import json from datetime import datetime def run_regression_test(agent, test_set, baseline_scores, threshold=0.05): """执行回归测试,对比基线分数""" current_scores = evaluate_agent(agent, test_set) report = { "timestamp": datetime.now().isoformat(), "baseline": baseline_scores, "current": current_scores, "diffs": {}, "regressions": [] } for metric in current_scores: diff = current_scores[metric] - baseline_scores[metric] report["diffs"][metric] = diff if diff < -threshold: report["regressions"].append({ "metric": metric, "baseline": baseline_scores[metric], "current": current_scores[metric], "diff": diff }) if report["regressions"]: print("检测到回归,请检查以下指标:") for reg in report["regressions"]: print(f" {reg['metric']}: {reg['baseline']:.3f} -> {reg['current']:.3f}") else: print("所有指标正常,无回归") return report这段代码展示了回归测试的基本逻辑。实际使用时,baseline_scores要存在数据库或文件里,每次评估后更新。
4. 实操过程与核心环节实现
4.1 从零搭建评估环境的完整步骤
假设你手上有一个基于RAG的问答智能体,现在要给它搭一套评估体系。我按实际操作顺序把步骤列出来。
第一步:安装依赖。RAGAS的安装很简单,但要注意版本兼容。我用的组合是ragas 0.1.x + langchain 0.1.x + openai 1.x。版本不匹配是新手最容易踩的坑,建议用虚拟环境隔离。
pip install ragas==0.1.10 pip install langchain==0.1.20 pip install langchain-openai==0.1.6 pip install datasets==2.19.0第二步:准备测试集。从生产日志里导出最近一个月的用户query,去重后随机采样300条。然后人工标注标准答案。标注时要注意:标准答案要基于知识库内容,不能凭标注者的个人知识;对于知识库里没有答案的问题,标注为“无法回答”,这也是重要的测试用例。
第三步:配置评估模型。RAGAS默认用OpenAI的模型做评估,但你可以换成任何兼容OpenAI接口的模型。评估模型和被测模型建议用不同的,避免“自己评自己”的偏差。
from langchain_openai import ChatOpenAI from ragas.llms import LangchainLLMWrapper # 配置评估用的LLM evaluator_llm = ChatOpenAI( model="gpt-4o", # 评估模型建议用能力较强的 temperature=0, # 温度设为0保证评分稳定 max_tokens=2048 ) # 包装成RAGAS可用的格式 ragas_llm = LangchainLLMWrapper(evaluator_llm)第四步:跑评估并分析结果。把测试集喂给智能体,收集回答和检索上下文,然后调用RAGAS评估。跑完后不要只看总分,要逐条看低分样本,分析问题出在哪。
第五步:建立基线并集成到CI。第一次评估的结果作为基线,之后每次改动都跑回归测试。集成到CI的方式可以是用GitHub Actions或者GitLab CI,在PR合并前自动触发。
4.2 评估结果的分析与问题定位
评估跑完出一堆分数,怎么分析?我的方法是先看整体,再看分层,最后看个案。
整体看四个核心指标的分布。如果Faithfulness普遍低于0.8,说明幻觉是主要问题,要检查检索质量或者调整prompt让模型更保守。如果Answer Relevancy低,说明模型容易跑题,要检查prompt里的指令是否清晰。如果Context Recall低,说明检索漏信息,要检查检索策略。
分层看不同类型问题的表现。把测试集按问题类型分组(事实型、推理型、多跳型、无法回答型),看哪类问题得分最低。往往你会发现某类问题特别差,那就是优化的重点方向。
个案看低分样本的具体表现。挑出得分最低的20条,逐条看智能体的回答、检索到的上下文、标准答案,人工判断问题出在哪个环节。这一步最费时间,但收获也最大。我经常在这一步发现一些意想不到的问题,比如检索系统对某些关键词的处理有bug,或者prompt里的某个指令被模型忽略了。
4.3 参数调优与评估迭代的实操记录
评估体系本身也需要调优。我记录了一次典型的调优过程。
初始状态:Faithfulness 0.72,Answer Relevancy 0.85,Context Precision 0.68,Context Recall 0.61。明显Context Recall是短板,检索漏信息严重。
第一轮优化:把检索的top_k从3调到5。Context Recall升到0.74,但Context Precision降到0.59,因为塞了更多噪声进来。Faithfulness也降到0.69,因为噪声干扰了生成。
第二轮优化:加入重排序(rerank)环节,先召回top_20,再用重排序模型选top_5。Context Recall保持0.73,Context Precision回升到0.71,Faithfulness回到0.74。这轮优化效果明显。
第三轮优化:调整prompt,明确要求模型“只根据提供的上下文回答,如果上下文没有相关信息就明确说不知道”。Faithfulness升到0.83,Answer Relevancy略降到0.82(因为有些问题模型选择不回答,但标准答案是有答案的)。
第四轮优化:检查那些模型说“不知道”但实际有答案的case,发现是检索没召回到。调整了检索的query改写策略,Context Recall升到0.79。
这个过程说明评估不是一次性的,而是“评估-定位-优化-再评估”的循环。每轮优化只改一个变量,这样才能归因。
实操心得:优化时不要同时改多个东西,否则分数变了你也不知道是哪个改动起的作用。另外,每次优化后都要跑完整测试集,不能只跑之前失败的case,因为改动可能引入新的回归。
4.4 生产环境的持续评估与监控
上线之后的评估和开发阶段不一样。开发阶段是离线评估,用固定测试集。上线后要做在线评估,用真实流量。
在线评估的做法是:对一部分线上请求进行采样,异步跑评估,不阻塞用户请求。评估结果写入监控系统,设置告警阈值。比如Faithfulness连续一小时低于0.7就告警。
在线评估的挑战在于没有标准答案。用户不会告诉你正确答案是什么。这时候只能用无参考的评估指标,比如Faithfulness(不需要标准答案)、Answer Relevancy(不需要标准答案),以及基于用户反馈的信号(点赞、点踩、追问率)。
我的做法是离线评估保证质量下限,在线评估监控质量波动。两者结合,既能深入分析,又能及时发现线上问题。
5. 常见问题与排查技巧实录
5.1 评估分数忽高忽低怎么办
这是最常见的问题。同一版本的智能体,跑两次评估分数差5个点,根本没法判断改动是否有效。原因通常有三个:LLM输出的随机性、评估器的随机性、测试集样本量不够。
解决办法:第一,把被测模型和评估模型的温度都设成0。第二,增加测试集样本量,样本越多,随机波动的影响越小。第三,多次运行取平均值,至少跑3次。如果条件允许,用bootstrap方法计算置信区间,只有分数差异超出置信区间才认为是真实变化。
5.2 RAGAS评估报错或超时的排查
RAGAS评估过程中常见的报错有几类。一是API限流,评估需要大量调用LLM,很容易触发rate limit。解决办法是加并发控制,用tenacity做重试。二是token超限,长上下文会导致超出模型的最大token限制。解决办法是截断上下文或者换用支持更长上下文的模型。三是解析失败,RAGAS需要模型输出特定格式,模型没按格式输出就会解析失败。解决办法是在prompt里强化格式要求,或者换用指令遵循能力更强的模型。
from tenacity import retry, stop_after_attempt, wait_exponential @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=60)) def safe_evaluate(dataset, metrics): """带重试的评估调用""" return evaluate(dataset, metrics=metrics)5.3 LLM-as-judge评分偏差的校准方法
Judge模型有几种已知偏差:位置偏差(倾向于选第一个选项)、长度偏差(倾向于给长回答高分)、自我偏好(倾向于给自己生成的內容高分)。校准方法包括:随机打乱选项顺序、在prompt里明确要求不考虑长度、用多个judge模型投票。
我常用的做法是用两个不同厂商的模型做judge,取平均分。如果两个模型的评分差异超过0.3,就标记出来人工复核。这样能过滤掉大部分judge偏差导致的问题。
5.4 测试集覆盖度不足的补救
测试集跑了一段时间后,你会发现有些线上问题测试集里根本没有覆盖。补救方法是建立“bad case回流”机制:线上发现的bad case,人工标注后加入测试集。这样测试集会随着时间越来越完善。
另外要定期做测试集的覆盖度分析。把测试集按问题类型、难度、业务场景分类,看哪些类别样本太少。我一般要求每个核心业务场景至少有20条测试用例,每个难度级别至少有30条。
| 常见问题 | 排查方向 | 解决方法 |
|---|---|---|
| 分数波动大 | 温度参数、样本量 | 温度设0,增加样本量,多次运行取平均 |
| API限流 | 并发数、调用频率 | 加并发控制,用重试机制 |
| 解析失败 | 输出格式、模型能力 | 强化格式指令,换更强模型 |
| Judge偏差 | 位置、长度、自我偏好 | 打乱顺序,多模型投票,人工复核 |
| 覆盖不足 | 场景分布、难度分布 | bad case回流,定期覆盖度分析 |
5.5 评估成本控制的实战经验
LLM评估的成本不低。一次完整评估跑300条测试用例,每条要调用多次LLM(生成回答、评估Faithfulness、评估Relevancy等),加起来可能上千次调用。如果每次提交代码都跑全量评估,成本很快就上去了。
我的成本控制策略是分层评估。日常开发用快速评估集,只跑50条核心用例,覆盖主要场景,成本低、速度快。发版前跑全量评估集,300条用例,确保质量。另外,评估模型可以用便宜一些的,比如用GPT-4o-mini做初筛,只有分数异常的case才用GPT-4o复核。
还有一个省钱的技巧是缓存。同样的输入和评估prompt,结果可以缓存起来。测试集里有些用例是重复的,缓存能省不少调用。
6. 智能体评估体系的扩展方向
评估体系搭起来之后,可以往几个方向扩展。一是多模态评估,如果智能体处理图片、音频,评估也要覆盖这些模态。二是多轮对话评估,现在的评估大多是单轮的,但智能体的很多任务是多轮完成的,需要评估对话的连贯性和任务完成度。三是对抗评估,主动构造一些刁钻的输入来测试智能体的鲁棒性,比如prompt注入、边界输入、矛盾指令。
我在实际项目里的体会是,评估体系的价值不在于分数本身,而在于它逼着你去定义“什么叫做得好”。这个定义过程本身就是对业务的深入理解。很多团队做评估做着做着,发现真正的问题不是模型不行,而是业务需求本身就没想清楚。评估体系就像一面镜子,照出的是整个系统的成熟度。
最后分享一个小心得:评估报告不要只给分数,要给具体的失败案例和改进建议。分数是给工程师看的,案例是给产品和业务看的。一份好的评估报告,应该让不看代码的人也能明白智能体哪里不行、为什么不行、该怎么改。