RAG系统全链路观测实战:LangSmith追踪与调试指南

发布时间:2026/10/12 18:04:49
RAG系统全链路观测实战:LangSmith追踪与调试指南 1. 为什么 RAG 系统需要一台“心电监护仪”做过 RAG 应用的人大概都有过这种体验用户反馈“回答不准”你打开日志一看检索回来的文档片段看起来没问题生成模型也没报错但最终答案就是跑偏了。更让人头疼的是这种问题往往无法稳定复现——同一个问题问两遍一次对一次错。这时候你面对的其实是一个典型的黑盒困境检索、重排、拼接、生成这几个环节串在一起任何一个环节的微小偏差都可能在最终输出上被放大但你手里没有任何工具能告诉你偏差到底发生在哪一步。RAG 的本质是一条流水线链路上至少包含查询改写、向量检索、结果重排、上下文组装、提示词渲染、大模型生成这几个关键节点。传统做法是在每个节点手动打日志但日志是离散的、非结构化的你很难把一次完整的请求链路串起来看。LangSmith 解决的正是这个问题——它给整条链路装上了一台“心电监护仪”每一次请求的输入输出、耗时、token 消耗、中间状态都被完整记录下来并且以可视化的方式呈现。你可以把它理解成给 RAG 系统做了一次全链路的心电图监测哪个环节“心律不齐”一目了然。这篇文章面向的是已经跑通过基础 RAG 流程、但被调试和观测问题困扰的开发者。如果你还在纠结怎么把向量库和模型接起来建议先把基础链路跑通再来看观测部分。观测这件事的价值在于它不会让你的系统从“不能用”变成“能用”但能让你的系统从“勉强能用”变成“稳定可靠、可迭代”。我个人的经验是一个没有接入观测工具的 RAG 项目调试效率至少低三倍因为你大量的时间花在了“猜”上面而不是“看”上面。LangSmith 的核心能力可以拆成三块链路追踪Tracing、数据集与评估Datasets Evaluation、监控与反馈Monitoring Feedback。这三块能力对应了 RAG 开发的不同阶段——开发期你需要追踪来定位问题迭代期你需要评估来量化改进效果上线后你需要监控来发现回归。本文重点讲第一块也就是全链路观测的搭建和实战用法因为这是一切的基础。没有可靠的追踪数据后面的评估和监控都是空中楼阁。在正式开始之前先明确一个认知观测工具本身不会提升你的 RAG 效果它只是让你“看见”问题的工具。真正提升效果的是你看见问题之后做的那些调整——换 embedding 模型、调整 chunk 策略、优化提示词、加 rerank 等等。但“看见”这一步是绕不过去的这也是为什么值得花时间把观测链路搭扎实。2. LangSmith 接入 RAG 链路的三种姿势与选型逻辑LangSmith 的接入方式比很多人想象的要灵活不同项目结构适合不同的接入姿势。选错了姿势后期维护会很别扭选对了几乎零侵入就能拿到完整的链路数据。我按侵入程度从低到高梳理三种方式并说明各自适合什么场景。2.1 环境变量零侵入接入适合快速验证最省事的方式是配置环境变量让 LangChain 或 LangGraph 自动上报追踪数据。你只需要设置几个变量框架层会自动把每次链式调用的输入输出、耗时、token 数上报到 LangSmith。这种方式几乎不需要改代码适合已经用 LangChain 生态搭建好的项目快速验证观测效果。具体来说需要配置的变量包括开启追踪的开关、API 密钥、项目名称、以及服务端点。项目名称这个字段很关键它相当于给数据分了“文件夹”不同环境开发、测试、生产用不同的项目名后期查数据时不会混在一起。我见过不少团队所有环境共用一个项目名结果调试时满屏都是生产流量根本没法看。这种方式的局限在于它只能追踪框架内部自动埋点的部分。如果你在链路中间插了一些自定义的 Python 函数、手写的检索逻辑、或者第三方的 API 调用这些环节默认是“隐身”的不会出现在追踪视图里。所以它适合链路比较标准、自定义逻辑不多的场景。2.2 装饰器手动埋点适合混合链路当你的 RAG 链路里有一部分是自定义代码时就需要用装饰器来手动埋点。LangSmith 提供了traceable装饰器把它加在任意函数上这个函数的输入输出、执行耗时、异常信息就会被自动捕获并且挂到当前追踪链路的正确位置上。这个装饰器的价值在于它解决了“链路断点”问题。举个例子你的检索环节可能是自己写的一个函数里面先做查询改写再调向量库最后做一次业务过滤。如果不埋点这段逻辑在追踪视图里就是一个黑盒加上装饰器之后查询改写的输入输出、向量库返回的原始结果、过滤后的结果全都能看到。排查“为什么检索结果不对”这类问题时这个粒度是必须的。用装饰器时有个细节要注意函数的参数和返回值最好是可序列化的。如果你传了一个自定义对象进去LangSmith 可能无法正确展示。我一般的做法是在埋点函数里只传基础类型和字典复杂对象在函数内部转换。另外装饰器可以嵌套父函数和子函数都加装饰器时追踪视图里会形成清晰的层级关系这对理解链路结构很有帮助。2.3 手动 Run 管理适合需要精细控制的场景最灵活但也最麻烦的方式是手动创建和管理 Run 对象。你可以显式地开始一个 run、记录中间状态、结束 run完全掌控上报的时机和内容。这种方式适合那些链路结构动态变化、或者需要根据运行时条件决定是否上报的场景。手动管理的典型用法是在一个请求的入口处创建一个父 run然后在各个子环节创建子 run最后统一结束。这样做的好处是你可以精确控制每个 run 的元数据比如把用户的原始问题、会话 ID、租户 ID 这些业务字段挂上去后期按这些字段过滤数据会非常方便。缺点就是代码侵入性最强每个环节都要写样板代码。三种方式的选型逻辑其实很简单能用环境变量解决的就别写代码能用装饰器解决的就别手动管理。只有当框架自动埋点覆盖不到、装饰器又不够灵活时才考虑手动管理。我自己的项目通常是混合使用——框架部分靠环境变量自动上报自定义的检索和业务逻辑用装饰器最外层再手动挂一些业务元数据。接入方式侵入程度适用场景主要局限环境变量极低标准 LangChain 链路自定义代码不显示装饰器中等混合链路、自定义函数需注意参数可序列化手动 Run高动态链路、精细控制样板代码多3. 把一次 RAG 请求拆成可观测的节点接入方式确定之后下一个关键问题是到底要观测哪些节点观测粒度太粗定位不到问题太细数据量大到没法看。我的经验是按 RAG 链路的自然边界来切分每个边界对应一个可独立观测的节点。3.1 查询理解与改写节点用户输入的原始问题往往不适合直接拿去检索。口语化的表达、指代不明的代词、省略的上下文都会让检索效果打折扣。所以很多 RAG 系统会在检索前加一个查询改写环节把用户问题转换成更适合检索的形式。这个节点需要观测的核心信息包括原始查询是什么、改写后的查询是什么、改写用了哪个模型、耗时多少。为什么要观测这些因为改写环节是“静默失败”的高发区。改写模型可能把用户的意思理解偏了或者改写后的查询丢失了关键实体但最终答案看起来又“像那么回事”你很难察觉。有了这个节点的追踪数据你就能对比原始查询和改写查询快速判断问题是不是出在改写上。我在实际项目里遇到过一个典型案例用户问“它支持哪些格式”改写模型把“它”直接保留了下来检索时自然找不到相关文档。追踪视图里一眼就能看到改写后的查询里有个孤零零的“它”问题定位只花了十秒钟。如果没有这个节点可能要排查半天。3.2 向量检索与重排节点检索节点是 RAG 的命脉也是最需要观测的环节。这个节点要记录的信息包括检索用的查询向量、召回的文档 ID 列表、每个文档的相似度分数、检索耗时。如果用了重排模型还要记录重排前后的顺序变化和重排分数。这里有个容易被忽略的点相似度分数本身也需要观测。很多人只看召回了哪些文档不看分数分布。但分数分布能告诉你很多信息——如果所有召回文档的分数都集中在很窄的区间说明向量空间里这些文档区分度不高可能需要换 embedding 模型如果最高分和最低分差距很大说明检索结果的质量分层明显可以考虑设一个分数阈值来过滤低质量召回。重排节点的观测重点是“顺序变化”。重排模型把哪些文档往前挪了、哪些往后挪了、挪动的依据是什么分数这些数据能帮你判断重排模型是否在正常工作。我见过重排模型配置错误导致所有文档分数都一样的案例追踪视图里看到重排前后顺序完全没变立刻就发现了问题。3.3 上下文组装与提示词渲染节点检索回来的文档片段不能直接塞给大模型中间要经过组装——去重、截断、排序、加上分隔符和指令。这个环节的观测重点是最终送给模型的上下文长什么样、用了多少 token、有没有超出模型上下文窗口。这个节点最典型的坑是上下文超长导致截断。你可能检索回了十个文档片段但模型上下文窗口只够放五个组装逻辑默默截断了后面五个而后面五个里恰好有正确答案。追踪视图里能看到最终组装的上下文对比检索结果就能发现截断问题。另一个坑是分隔符使用不当导致模型分不清哪些是文档内容、哪些是指令这个也能从渲染后的提示词里看出来。3.4 生成与后处理节点最后一个节点是大模型生成需要观测的信息包括完整的提示词、模型返回的原始输出、token 消耗输入和输出分开统计、生成耗时、以及是否有后处理逻辑对输出做了修改。生成节点的观测价值在于区分“模型能力问题”和“上下文质量问题”。如果上下文里明明有正确答案模型却答错了那是模型能力或提示词的问题如果上下文里根本没有正确答案那问题出在检索环节。没有这个节点的追踪数据你很难做这个区分只能凭感觉猜。后处理节点也值得观测因为有些系统会对模型输出做格式化、敏感词过滤、引用标注等处理。如果后处理逻辑有 bug可能把正确的答案改错了而你在最终输出里看到的是被改错的结果根本想不到问题出在后处理。4. 追踪数据里的“心电图”该怎么读数据采集上来只是第一步真正考验功力的是怎么读这些数据。追踪视图里信息量很大新手容易看花眼。我总结了一套读图的方法按“先看整体、再抓异常、后做对比”的顺序来。4.1 先看整体链路耗时分布打开一次请求的追踪视图第一眼应该看的是耗时分布。整条链路的总耗时是多少、每个节点各占多少、有没有哪个节点明显偏慢。这个“心电图”能快速告诉你系统的性能瓶颈在哪。常见的耗时异常有这么几种检索节点耗时占比过高可能是向量库索引没建好或者查询向量维度太高生成节点耗时占比过高可能是输出 token 太多或者模型本身响应慢某个节点耗时波动极大可能是外部服务不稳定。我一般会先看 P95 和 P99 的耗时而不是平均值因为平均值会被大量正常请求拉低掩盖掉长尾问题。耗时数据还有一个用法是对比不同请求。如果你发现某类问题的检索耗时明显高于其他问题可能这类问题的查询向量在向量空间里处于“稀疏区域”检索时需要扫描更多数据。这个洞察能指导你优化索引结构或者调整查询策略。4.2 抓取分数异常与空召回耗时看完之后重点看检索节点的分数数据。这里要抓两类异常分数异常低和空召回。分数异常低意味着检索回来的文档和查询的相关性很差模型拿着这些文档很难生成正确答案。这时候要往回查是查询改写出了问题还是 embedding 模型不适合这个领域还是文档库里根本没有相关内容。追踪数据能帮你快速排除掉一些可能性——如果改写后的查询看起来没问题文档库里也确实有相关文档那问题大概率在 embedding 模型上。空召回更直接就是检索结果为空。这种情况要么是查询和文档的向量空间完全不匹配要么是过滤条件太严格把结果全过滤掉了。追踪视图里能看到过滤前后的结果数量对比一眼就能判断是哪种情况。我遇到过一次空召回排查后发现是元数据过滤条件里有个字段值写错了导致所有文档都被过滤掉追踪数据里过滤前的召回数量是正常的过滤后变成零问题一目了然。4.3 对比输入输出定位偏差环节当前两步都没发现明显异常但最终答案就是不对时就需要做输入输出对比。具体做法是从最终答案往回推看每个节点的输出是否符合预期。比如最终答案说“不支持某格式”但你知道文档里明确写了支持。那就往回看生成节点的上下文里有没有那段说明支持的文档如果有那是模型没用好上下文问题在提示词或模型如果没有那是检索没召回那段文档问题在检索环节。再往回看检索节点的召回列表如果那段文档在召回列表里但排名很靠后被截断逻辑切掉了那问题在组装环节。这种逐层回溯的方法听起来笨但配合追踪视图其实很快。因为每个节点的输入输出都摆在那里你只需要顺着链路走一遍偏差发生在哪一步是藏不住的。我处理过的最复杂的一个 case回溯了四层才定位到问题——查询改写把用户问题里的一个关键否定词弄丢了导致检索方向完全反了。如果没有全链路追踪这种问题几乎不可能定位。4.4 用元数据做切片分析单次请求的追踪数据能解决个案问题但要发现系统性问题需要把多次请求的数据聚合起来看。这时候元数据就派上用场了。我习惯在追踪数据里挂上这些元数据用户 ID、会话 ID、问题类型、使用的模型版本、检索的索引版本。有了这些字段就可以做切片分析——比如按问题类型分组看平均检索分数按模型版本分组看生成质量按索引版本分组看召回率变化。这种分析能发现一些单次追踪看不出来的趋势性问题。举个例子我曾经通过按问题类型切片发现涉及“对比类”问题的检索分数普遍偏低。进一步分析发现这类问题的查询改写逻辑有问题改写后的查询丢失了对比的两个对象。这个问题在单次追踪里很难发现因为每次看起来都“只是这次没答好”但聚合起来看就暴露了系统性的模式。5. 踩过的坑追踪链路搭建中的真实教训观测链路本身也是代码也会出问题。这一节分享几个我在搭建过程中踩过的坑都是那种“不看不知道、一看吓一跳”的问题。5.1 追踪数据把敏感信息带出去了这是最需要警惕的坑。RAG 系统的输入输出里可能包含用户隐私、业务敏感数据、内部文档内容。如果追踪工具把这些数据原样上报就等于在另一个地方又存了一份敏感数据合规风险很大。我的做法是在上报前做一层脱敏。具体来说对用户输入里的手机号、邮箱、身份证号这类模式化的敏感信息做正则替换对检索回来的文档内容如果涉及内部资料只上报文档 ID 和分数不上报文档正文。LangSmith 支持在上报前对数据进行处理可以在装饰器里包一层脱敏函数。这个坑的隐蔽性在于开发阶段用的都是测试数据感觉不到问题一旦上线接入真实用户数据风险就来了。所以脱敏逻辑最好在搭建观测链路的第一天就加上别等到上线前才补。5.2 采样率设置不当导致数据失真或成本失控全量上报追踪数据在开发阶段没问题但生产环境流量一大数据量和存储成本会快速上升。这时候需要设置采样率只上报一部分请求的追踪数据。采样率设置有讲究。设得太低比如只采 1%那出问题时你很可能没有对应的追踪数据等于白搭设得太高成本又扛不住。我的经验是分层采样正常请求低采样率比如 5%异常请求报错、超时、用户负反馈全量上报。这样既控制了成本又保证了问题请求一定有数据可查。实现分层采样的关键是能在请求结束时判断这次请求是否“异常”。可以在链路最外层包一个判断逻辑如果捕获到异常或者检测到用户负反馈信号就强制上报这次追踪。LangSmith 的 API 支持这种动态采样。5.3 异步链路里的上下文丢失RAG 系统里经常有异步操作比如并发检索多个数据源、异步调用模型。在异步场景下追踪的上下文也就是当前 run 的 ID可能会丢失导致子 run 挂不到父 run 上追踪视图里出现一堆孤立的节点。这个问题的根源是异步任务的执行上下文和创建它的上下文不是同一个。解决办法是在创建异步任务时显式传递追踪上下文或者在异步任务内部重新绑定上下文。不同框架的处理方式不一样LangChain 生态里一般用run_tree或者 context 变量来传递具体要看版本。我踩这个坑的时候追踪视图里检索节点和生成节点是分开的两个独立链路完全看不出它们属于同一次请求。排查了半天才意识到是异步上下文丢失。修复之后整条链路才正确串联起来。5.4 版本升级导致的埋点失效LangChain 和 LangSmith 都在快速迭代版本升级时埋点 API 偶尔会有 breaking change。我遇到过一次升级后装饰器不再自动捕获异常信息导致追踪视图里所有报错的节点都显示“成功”排查问题时被误导了很久。教训是升级依赖版本后要专门验证一遍追踪链路是否还正常工作。验证方法很简单跑一个会故意报错的请求看追踪视图里是否正确标记了错误。这个检查应该加入升级 checklist花不了两分钟但能避免很多误判。6. 从追踪到评估让观测数据产生复利追踪数据本身是“原材料”真正产生价值的是基于这些数据做的评估和迭代。这一节讲怎么把追踪数据用起来形成“观测-评估-改进”的闭环。6.1 把问题请求沉淀成评估数据集每次排查完一个问题请求不要让它就这么过去了。把这次请求的输入、期望输出、实际输出整理一下加到一个评估数据集里。积累到几十上百条之后你就有了一个能反映真实问题的测试集。这个数据集的价值在于每次你调整了检索策略、换了模型、改了提示词都可以拿这个数据集跑一遍看改进是否真的有效、有没有引入回归。没有这个数据集你的改进就是“感觉好像好了一点”无法量化。LangSmith 的数据集功能支持直接从追踪记录里创建样本操作路径很短。我一般会在排查完问题后顺手把样本加进去养成习惯之后数据集自然就丰富起来了。6.2 用评估器量化每个节点的质量有了数据集之后可以针对不同节点设计评估器。检索节点可以用召回率、MRR 这类指标生成节点可以用答案相关性、忠实度这类指标。评估器可以是基于规则的也可以是基于模型的。基于模型的评估器也就是常说的 LLM-as-Judge在 RAG 场景里很实用因为很多质量维度很难用规则描述。比如“答案是否忠实于检索到的文档”这个维度用模型来打分比写规则靠谱得多。但要注意评估模型本身的选择和提示词设计评估器的质量直接决定了评估结果的可信度。我一般会先用人工标注一小批数据然后用这批数据校准评估器看评估器的打分和人工打分是否一致。一致度够高之后才放心用评估器去跑大规模数据。6.3 建立回归监控的基线当系统上线后追踪数据的作用从“调试”转向“监控”。你需要建立一套基线指标比如平均检索分数、平均生成耗时、答案采纳率等然后监控这些指标是否偏离基线。偏离基线往往意味着系统出了问题——可能是上游数据源变了、模型服务降级了、或者用户群体发生了变化。有了监控你能在用户大规模投诉之前发现问题。我一般会设置一个简单的告警规则比如某个指标连续一段时间偏离基线超过阈值就触发告警。监控指标的选择要克制不要什么都监控。选三到五个最能反映系统健康度的核心指标就够了指标太多反而会淹没真正的信号。我的核心指标清单是检索平均分数、空召回率、生成平均耗时、用户负反馈率。这四个指标基本能覆盖大部分问题场景。7. 一些让观测更顺手的实操技巧最后分享几个日常使用中总结的小技巧都是那种“知道了能省不少事”的经验。关于项目命名建议用“环境-用途”的格式比如“prod-rag-main”“dev-rag-experiment”。这样在项目列表里一眼就能找到目标项目不会在几十个项目里翻找。另外实验性的追踪数据建议单独放一个项目不要和主项目混在一起否则主项目的数据会被实验流量污染。关于追踪数据的保留策略开发环境的追踪数据保留时间可以短一些生产环境的保留时间长一些。LangSmith 支持配置数据保留策略合理配置能控制存储成本。我一般开发环境保留两周生产环境保留三个月足够覆盖大部分排查需求。关于标签的使用给追踪数据打标签是个好习惯。比如给所有报错的请求打上“error”标签给用户负反馈的请求打上“negative-feedback”标签。后期按标签过滤数据非常方便比按时间或关键词搜索高效得多。关于团队协作如果多人共用 LangSmith 项目建议约定一套元数据规范比如所有人都用同样的字段名记录用户 ID、会话 ID。字段名不统一的话后期做聚合分析会很痛苦。这个规范最好在项目初期就定下来后期改成本很高。关于性能开销追踪上报本身是有开销的包括序列化数据和网络请求。在高并发场景下建议用异步上报避免阻塞主流程。LangSmith 的 SDK 默认是异步上报的但如果你在装饰器里做了复杂的序列化逻辑可能会拖慢主流程这点要注意。关于调试技巧追踪视图里可以直接看到每个节点的输入输出善用这个功能能省去大量打日志的时间。我现在的习惯是遇到问题先看追踪视图实在看不出来再考虑加日志。大部分问题在追踪视图里都能找到线索。关于数据导出LangSmith 支持把追踪数据导出成常见格式方便做离线分析。如果你需要做复杂的统计分析导出到本地用 pandas 处理会比在界面上看灵活得多。我一般每周导出一次数据做趋势分析看看系统整体健康度的变化。关于成本控制追踪数据的存储和查询都是有成本的尤其是当数据量大了之后。除了前面说的采样策略还可以考虑对历史数据做降采样——比如超过一个月的追踪数据只保留摘要信息不保留完整的输入输出。这样既保留了趋势数据又控制了存储成本。关于版本管理追踪数据里记录模型版本和提示词版本很重要。当你发现某段时间的回答质量下降时能快速定位到是不是某次版本更新导致的。我一般会在元数据里记录模型名称、模型版本、提示词模板的哈希值这样任何一次变更都能在追踪数据里追溯。关于异常处理追踪链路本身也可能出错比如网络问题导致上报失败。要确保上报失败不会影响主流程一般用 try-catch 包住上报逻辑失败时静默处理或者记录到本地日志。我见过因为上报失败导致整个请求失败的案例这是本末倒置了——观测是为了让系统更好不是让系统更脆弱。关于文档沉淀每次排查完一个典型问题建议把排查过程和结论记录下来形成团队的排查手册。追踪数据是“现场”排查手册是“经验”两者结合才能让团队的整体排查效率提升。我自己的团队维护了一份排查手册新成员遇到问题时先查手册能解决大部分常见问题解决不了的再找老人这样知识就沉淀下来了。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询