用LangSmith做RAG量化评估:告别“感觉还行”的实战指南

发布时间:2026/10/6 6:42:26
用LangSmith做RAG量化评估:告别“感觉还行”的实战指南
做RAG项目最怕什么不是模型不聪明也不是文档没传好而是别人问你“效果怎么样”的时候你只能回一句“感觉还行”。我做过几个RAG落地项目早期基本都是这个状态自己试了十来个问题答上来了七八个就觉得差不多了真上线之后才发现一堆边界情况根本hold不住。后来我把RAG评估这套流程整体接入LangSmith才真正把“感觉还行”变成了“分数、曲线、失败样本”这些可量化、可对比、可追溯的东西。这篇就用我一个实际项目的数据来拆一拆LangSmith做RAG量化评估到底怎么玩。先说这篇文章适合谁。如果你正在用LangChain搭RAG或者已经把RAG跑通了但说不清哪里好哪里差再或者你想对知识库做一次“体检”却不知道从哪下手这篇都是给你写的。我会把评估指标怎么选、数据集怎么造、LangSmith怎么配、结果怎么解读、踩了哪些坑一次性说清楚。不需要你有LangSmith基础但建议你对RAG的基本链路检索-增强-生成有个概念。1. RAG评估的痛点和LangSmith的定位1.1 为什么“感觉还行”会害了项目RAG的上手门槛不高真落地了才知道坑有多深。最典型的场景是你换了一个嵌入模型召回变好了还是变差了你改了prompt里的上下文指令回答是更忠实了还是开始放飞自我了你往知识库里加了一批新文档老问题的答案有没有被“带偏”这些问题靠人工抽几个问题去试根本测不全。更麻烦的是RAG是“检索生成”两级系统如果答案错了你很难一眼看出是检索没召回到对的文档还是召回了但模型没用好或者是模型压根没按上下文答。这不是靠感觉能定位的。还有一个容易被忽略的点人工评测的结果不可复现。你今天觉得这个回答“还行”明天状态不好可能就觉得“不行”换个人来评测标准又不一样。上了生产之后如果用户反馈变差你拿什么数据去复盘没有量化评估一切复盘都是猜。1.2 LangSmith在RAG评估里扮演什么角色LangSmith本身不是专门为RAG设计的它是一个LLM应用的调试、监控和评估平台。但因为它天然跟LangChain是同一家的链路追踪做得特别好所以在RAG这个场景里它的价值被放得很大。我总结下来LangSmith在RAG评估中的核心角色有三个第一是追踪器。RAG的每个调用检索、生成、评分都会自动形成一条trace输入输出、调用了哪些检索器、用了哪些文档片段、token消耗多少全都能看到。出问题的时候直接顺着trace往下看检索结果和答案一对比就知道问题在哪一层。第二是评估框架。它不帮你定义什么是“好”但它让你把这些标准变成可批量执行的评估器evaluator跑在数据集上输出结构化分数。你可以用内置的评估器也可以自己写基于LLM的评分函数。第三是实验对比平台。同一个数据集可以反复跑每次改动你都可以发起一次新的评估然后对比两次实验的分数。这个能力特别适合做RAG优化因为RAG的改动通常不是一个模型那么简单换分块大小、换检索top-k、换prompt模板都会影响最终效果没有实验对比几乎无法收敛。1.3 RAG方案选型和知识库形态的边界讲到知识库就绕不开大家经常讨论的RAG知识库、知识图谱、ontology这些概念到底什么关系。我自己的理解是RAG的核心是“无结构的文本召回”你给它文档它切成块、做向量化、按相似度召回它不关心文档之间的逻辑关系。知识图谱和ontology解决的是“关系”问题比如“A公司的法人是谁”“B产品与C标准是否兼容”这类需要多跳推理的问答。如果你的业务里大量是这种强关系型问题纯RAG会非常吃力而斯坦福的GraphRAG这类方案则试图把两者结合起来。RAG还有很多待解决的瓶颈最典型的几个召回率上不去文档切分不合适、嵌入模型区分度不够、上下文塞太多导致模型“迷失在中间”、答案跟检索内容不一致模型用了参数记忆没有用上下文。这些问题不量化的时候都是玄学量化了之后每个都会变成具体的指标缺口这也是为什么我强烈建议把评估前置。2. 评估指标别只看一个分数2.1 三个核心RAG指标的定义与计算逻辑RAG评估里最常用、也最值得先跑通的是RAGAS提出的三件套忠实度faithfulness、答案相关性answer relevance、上下文相关性context relevance。刚开始做量化评估的团队我建议先把这三个指标搞懂再考虑加别的。忠实度衡量的是“答案有没有忠于检索到的上下文”。它干的事是把答案拆成若干陈述句然后逐一判断每个句子是否能从检索到的文档里找到依据。答案编得再漂亮只要有一半内容知识库没提过忠实度分数直接打折。答案相关性衡量的是“回答到底有没有答到点子上”。实现逻辑通常是拿生成的答案去反向生成若干相似问题再看这些反向问题与原问题的相似度。如果你的答案跟问题根本不相关反向生成的问题就会跑偏如果答案是围绕问题展开的反向问题就跟原问题高度重合。上下文相关性衡量的是“检索回来的文档本身有没有用”。判断方式是把检索到的每个文档块拿去和原问题计算相关性看看有几个文档块确实是问什么答什么。很多RAG系统的问题出在这一层检索器召回了一堆无关内容模型再强也答不对。这三个指标从两个维度锁死了RAG质量检索质量上下文相关性和生成质量忠实度、答案相关性。只看一个指标很容易产生误判比如答案相关性很高但上下文相关性很低说明模型大概率在“闭卷答题”这种系统埋着雷。2.2 评估数据集的构建思路有指标就得有评测题。很多团队卡在“没有评估集”这一步其实没那么玄。我建议建评估集遵循三个原则小型起步、难度分层、持续沉淀。数量上起步阶段20到50条就够跑一轮。核心不是数量而是覆盖度。我通常把题目分成几类简单事实类知识库里直接有答案、推理聚合类需要结合多个文档块才能答出来、否定类知识库里没有对应内容模型应该拒绝回答、模糊类问题有歧义需要模型澄清。这几类覆盖的RAG弱点完全不同事实类测召回推理类测“多跳”能力否定类测模型会不会“硬编答案”模糊类测prompt设计。每条评估样本要设计成三元组输入用户问题、正确答案可选、参考文档可选。LangSmith里创建example的时候可以直接带上这些字段评估时就能做更细的对比分析。2.3 不同业务场景怎么调整指标权重指标不是死的。我做过的项目里有客服问答型、制度检索型、研发文档型各场景侧重点完全不同。制度检索型最怕“一本正经胡说八道”忠实度权重要拉满研发文档型最关键的是“要不要得准”上下文相关性是核心客服问答型要求即时可用答案相关性优先级最高。实操上我一般会先跑一轮完整的三指标评估再做Case分析看丢分集中在哪里然后用那根最明显的短板当主线目标去优化而不是漫无目的地把所有分数都往上拉。3. 实操把LangSmith跑起来3.1 先搭好追踪环境很简单的接入前提是你有一个LangSmith账号free tier就行然后装包pip install langsmith langchain-openai langchain-text-splitters拉环境变量。注意开发阶段我建议先不开采样全部trace进来数据量大再说export LANGCHAIN_TRACING_V2true export LANGCHAIN_PROJECTmy-rag-eval export LANGCHAIN_API_KEYls__xxx小提示项目名尽量语义化一个实验一个项目别把所有实验都堆在default里面否则后面看trace会想骂人。3.2 数据集准备与上传准备好评测集之后上传到LangSmith就两步。用SDK先建数据集再批量传examplefrom langsmith import Client client Client() dataset_name rag_qa_basic_v1 # 已有则可复用否则新建 try: dataset client.create_dataset(dataset_namedataset_name) except Exception: dataset client.get_dataset(dataset_namedataset_name) examples [ { inputs: {question: 公司年假政策是什么}, outputs: {answer: 入职满一年可享5天年假详见制度第3条。}, }, # ... 更多样本 ] client.create_examples( inputs[e[inputs] for e in examples], outputs[e[outputs] for e in examples], dataset_iddataset.id, )这个阶段有一个容易犯的错误example里塞了大量与问题无关的字段。没必要LangSmith的example是给评估器喂数据用的你只要放“问题”“标准答案如果有”“参考文档如果有”就够了。塞多了不仅浪费额度还会影响自定义评估器的解析逻辑。3.3 封装RAG应用为可评估函数LangSmith评估的标准姿势是把RAG链路包成一个函数入参是question出参是answer和中间结果。我推荐把检索到的上下文一并返回因为这是后面诊断“检索层问题”的关键证据from langchain_openai import OpenAIEmbeddings, ChatOpenAI from langchain_community.vectorstores import FAISS from langchain_core.prompts import ChatPromptTemplate embeddings OpenAIEmbeddings(modeltext-embedding-3-small) vectorstore FAISS.load_local(index_dir, embeddings, allow_dangerous_deserializationTrue) retriever vectorstore.as_retriever(search_typesimilarity, search_kwargs{k: 4}) llm ChatOpenAI(modelgpt-4o-mini, temperature0) prompt ChatPromptTemplate.from_messages([ (system, 基于以下检索到的资料回答用户问题。如果资料中没有相关信息明确说明‘未找到’。\n\n资料{context}), (user, {question}) ]) def rag_app(question: str): docs retriever.invoke(question) context_text \n\n.join([d.page_content for d in docs]) response llm.invoke(prompt.format_messages(contextcontext_text, questionquestion)) return { answer: response.content, contexts: context_text, source_docs: [d.metadata.get(source, ) for d in docs], }注意温度设为0。评估阶段任何随机性都会污染分数生成结果不稳定你没法判断一次变好是改对了还是运气好。3.4 配置评估器并运行评估LangSmith支持多种评估器。我只推荐两种起步内置的LLM-as-judge评估器和自己写的Python评估器。RAG三件套可以直接用RAGAS评估器也可以自己用提示词封一个judge。下面是我常用的一个自定义忠实度评估器逻辑简单直接from langsmith.evaluation import evaluate from langsmith.schemas import Run, Example from langchain_openai import ChatOpenAI judge_llm ChatOpenAI(modelgpt-4o, temperature0) def faithfulness_evaluator(run: Run, example: Example) - dict: answer run.outputs.get(answer, ) contexts run.outputs.get(contexts, ) resp judge_llm.invoke( f判断以下答案是否严格基于给定的资料内容而不是模型自己的知识。\n f资料{contexts[:6000]}\n答案{answer}\n f只输出一个数字1代表完全基于资料0代表存在资料以外的信息。 ) score 1 if 1 in resp.content.strip() else 0 return {key: faithfulness, score: score}然后跑评估experiment_results evaluate( rag_app, datadataset_name, evaluators[faithfulness_evaluator], experiment_prefixbaseline, max_concurrency5, )跑完控制台会输出每个example的详细分数LangSmith后台会生成一个完整的实验对比页面。这里我建议配上LangSmith的Project页面去看trace每一次评估运行都是一条完整的trace从question到retriever再到llm每一步耗时、token、输入输出全都在。评估分数低的时候直接点开对应trace立刻能看到是检索结果不对还是生成挂了这个体验很爽。3.5 提交到真实请求评估前先跑通小规模我强烈建议第一次跑别一上来就扔几百条。先拿10条跑通全链路确认数据集能拉取、评估器能正常打分、trace能完美记录。这个问题在LangSmith上尤其容易踩数据集创建和读取的权限、example字段名不匹配、评估器里想的字段和实际run outputs的字段不一致都会导致跑一半报错。小规模验证通过后再上全量。跑完之后直接在实验对比页面看平均分、分布条形图、失败样本列表。第一次跑通常会让你震撼——我第一个项目基线评估跑完上下文相关性平均分只有0.62而我之前一直“感觉”检索效果还不错。4. 数据解读与优化闭环4.1 学会读评估报告而不是只看平均分平均分只能说明整体水位真正值钱的是失败样本。我拿到评估结果后固定的排查顺序是先看上下文相关性再过滤掉上下文相关性差的样本看剩下样本里的答案相关性和忠实度。基本逻辑如果上下文相关性普遍低别白费力气调prompt问题在检索层如果上下文相关性高但忠实度低问题在生成层要么是检索结果位置不对要么是提示词没约束住模型如果前两项都高但答案相关性低那就是问题本身太难或者评估题设计有缺陷。实际项目里我遇到过一种很隐蔽的情况上下文相关性分数忽高忽低平均分看起来还行但点开trace发现每次召回的文档差异很大。这说明不是检索器本身的问题而是文档切分导致同一内容分散在不同窗口里。这种问题藏得深但LangSmith的trace能帮你看到检索结果的具体内容比较容易暴露。4.2 从指标反推根因一张问题定位表我习惯把RAG问题按下面这个表归类症状定位方向常见原因上下文相关性低检索层分块过大/过小、嵌入模型不匹配、top-k设置不当上下文相关但答案错误生成层prompt约束不足、模型优先用了参数记忆忠实度低但答案相关性高提示词模型system prompt没有强制要求基于上下文分数普遍不稳定数据配置评估集过小、temperature未归零、文档有更新这张表是我排查问题的first check。有一次某类问题答案相关性和上下文相关性同时低我顺着trace看了十几个样本发现检索器返回的文档几乎都是同一篇导致答案全是同一段话的不同角度重复。后来一查是分块后文档块数量太少一个核心段落垄断了相似度排名。把分块尺寸调小、加一个MMR的重排序逻辑上下文相关性直接从0.55拉到0.78。4.3 三类典型的RAG瓶颈与针对性优化前面提到RAG瓶颈这里展开讲我实际碰过并修复的三个场景。第一个是召回率瓶颈。现象是上下文相关性分数长期在0.6左右上不去。解决办法是分两步第一步调chunk策略我习惯从经验值出发中文场景256到512个字符一档一档试注意要保证语义完整别把一句话从中间切断第二步换嵌入模型把官方text-embedding-3-small换成更懂领域语义的自训练模型或者更大尺寸的模型这个改动通常能立竿见影。第二个是上下文利用率瓶颈。调完检索之后retrieval分数上去了但忠实度不动甚至往下掉。这是因为检索回来的内容变多了模型“迷失在中间”。对策是重排rerank。早期我自己写了个简单方案让LLM对检索结果做一个相关性打分取top2再进生成。后来换成了专门rerank模型。加了这一步之后忠实度从0.71提升到0.83效果非常直观。第三个是模型“闭卷考试”瓶颈。有些问题模型明明没在检索资料里找到答案它也会用自己的知识硬答。这个在否定类问题上特别常见。LangSmith的trace里能看到模型在资料为空或者资料与问题完全无关时依然给出自信满满的回答。解决办法是检索结果相关性分低于阈值时直接返回“未找到相关内容”或者把prompt改成“资料中没有明确依据时必须拒绝回答”。实测之后否定类问题的合格率从40%拉到85%以上。4.4 建立评估驱动的迭代闭环量化评估最大的价值是让你告别“拍脑袋优化”。我现在每个RAG项目都固定跑“基线评估 - 定位瓶颈 - 假设 - 改动 - 复评 - 对比”这个闭环。每次改动只动一个变量比如只改chunk_size或者只换embedding模型。一次动两个变量评估分数变了你都不知道是谁的功劳。LangSmith的实验对比功能很好地支撑了这个流程每个改动对应一个experiment历史记录全部保留回溯和复盘都非常方便。团队成员拿到同一份数据集和评估配置后提出的优化假设都能被快速验证而不是只靠主观感觉争论。5. 常见问题与避坑实录5.1 评估结果不稳定怎么排查评估结果波动的原因我碰到过几类一是LLM judge本身有随机性temperature没归零是最大的坑judge模型建议固定在gpt-4o级别的能力以上太弱的模型打分靠谱度直接下降二是评估集数量太少十几条样本波动天然大这个靠增加样本量解决三是样本难度分布偏差如果评估集全是简单题分数高得没有区分度建议定期往评估集里注入线上用户真实的问题保持难度曲线。解决之后我通常要求同一配置连跑三轮取中位数避免单次波动影响判断。5.2 图片、表格内容怎么进RAG评估有朋友问“RAG知识库能存储图片吗”。严格来说传统向量检索对图片无能为力图片没法直接切块和向量化。图片放入知识库的前提是用多模态模型提炼文字描述或做OCR把图片变成可检索的文本块。表格也是同理Markdown或Html格式保留结构再切块否则检索出来就是一坨乱码。这部分内容在评估时也要特殊对待我会在评测集里单开一个“多模态文档类”分组评测时单独看它的各项分数因为图片转文本的准确性会直接影响RAG链路的上限如果不分开统计很容易掩盖这类样本的检索问题。5.3 LLM-as-judge的偏差要注意什么用LLM给LLM打分本质上是有偏差的常见的有长度偏好答案写得越长越容易被判好、自夸偏好judge模型觉得自己答得好的就算好、上下文长度敏感性资料太长时judge会“迷失”。我的应对方法一是prompt里强制要求以资料为准而不是以答案质量为准二是对每个评估器输出做抽样人工复核尤其是分数异常高的样本人工看一遍有没有误判三是关键指标最好用双judge交叉验证两个模型都给出高分才算过。5.4 没法用云平台本地有没有替代方案LangSmith是云服务有些团队的数据合规要求不满足。本地替代方案我试过promptfoo它支持本地评测集和LLM评估器EvalPlus和DeepEval也都能落地。但要说明一点本地方案在trace可视化、实验对比、团队协作上都不如LangSmith完善。我的建议是如果条件允许先用LangSmith跑通评估方法和闭环流程后续如果有合规要求再迁移到本地方案评估数据集和评估器逻辑都是可以整体搬走的。结尾的几句大实话我自己的体会是LangSmith本身不是什么魔法真正改变项目节奏的是“量化评估”这个习惯。以前团队开周会聊RAG优化全靠抢功劳现在打开实验对比页谁的改动有效一目了然。最后再分享一个技巧新文档入库之前先挑几条跟新文档相关的评测样本跑一遍基线否则你根本不知道一次文档更新是改善还是恶化了线上效果。坚持做下去你会发现所谓“感觉还行”和“数据说话”之间差的不是工具而是一套连贯的评估习惯。