从黑盒到可量化:基于 Langfuse + RAGAS 构建生产级 RAG 可观测与评测体系
系统拆解 Langfuse 全链路可观测与 RAGAS 量化评测的组合方案,覆盖 RAG 分层埋点、Dataset、Bad Case、回归评测、发布门禁与生产安全。
从黑盒到可量化:基于 Langfuse + RAGAS 构建生产级 RAG 可观测与评测体系
RAG 系统最难处理的问题,往往不是“模型能不能回答”,而是当答案出现错误时,我们无法快速说清:究竟是问题改写偏了、知识没有召回、重排丢掉了关键文档、Prompt 约束不足,还是模型在脱离上下文自由发挥。
Demo 阶段可以靠开发者逐条查看答案,生产阶段却不能继续依赖“感觉不错”。真实流量会带来长尾问题、复杂会话、成本波动和不可重复的偶发故障。如果系统只有接口日志和最终答案,就仍然是一个黑盒。
一套真正可用的 RAG 工程体系,需要同时回答两个问题:
- 发生了什么?——通过 Langfuse 记录完整调用链,定位问题所在环节。
- 回答得怎么样?——通过 RAGAS 将检索与生成质量转化为可比较的指标。
本文围绕这两个问题,给出一套从在线观测、Bad Case 沉淀到离线回归评测的生产级设计。
一、为什么传统监控不够
Prometheus、Grafana 和常规 APM 非常适合观察 QPS、错误率、数据库耗时和 HTTP 延迟,但 RAG 的故障通常具有明显的语义属性。
例如,一次请求返回 200、总耗时 1.8 秒,从传统监控看一切正常,但实际可能发生了以下问题:
- Query 改写改变了用户原意;
- 向量检索没有召回关键资料;
- TopK 中混入大量相似但无关的文档;
- Reranker 把真正有价值的文档排到了后面;
- 上下文超过预算被截断;
- 模型生成了检索材料中不存在的事实;
- Prompt 或模型版本变化导致效果回退;
- Token 消耗突然增加,但无法定位增加在哪一步。
这些问题仅靠 CPU、接口延迟和错误码无法解释。LLM 应用需要额外观测 Prompt、Completion、Context、Token、模型参数、检索结果、语义评分以及每个业务步骤的父子关系。
二、总体设计:可观测与评测分工
Langfuse 与 RAGAS 解决的是两个相互衔接、但并不相同的问题。
| 组件 | 核心职责 | 主要产物 |
|---|---|---|
| Langfuse | 记录和还原一次请求的执行过程 | Trace、Span、Generation、Token、成本、异常和业务标签 |
| RAGAS | 判断检索与生成结果的质量 | Faithfulness、Answer Relevancy、Context Precision、Context Recall 等分数 |
两者组合后的数据流如下:
线上 RAG 请求
→ Langfuse 记录完整 Trace
→ 发现低分、投诉或异常样本
→ 沉淀为 Dataset
→ RAGAS 批量评测候选版本
→ 分数回写并比较
→ 达到门禁后发布
Langfuse 让问题“看得见”,RAGAS 让效果“比得出”。真正的价值不在于两个工具分别部署成功,而在于它们形成同一条数据闭环。
三、RAG 全链路应该怎样埋点
Langfuse 通常使用三层观测模型:
- Trace:一次完整用户请求或 Agent 任务;
- Span:请求中的一个业务步骤,可以继续嵌套;
- Generation:真正调用大模型的叶子节点。
对标准 RAG 流程,可以采用下面的分层方式。

1. 根 Trace:记录完整请求
根 Trace 应当承担全局索引作用,至少包含:
user_id、session_id;- 环境、应用、租户和渠道;
- RAG 版本、Prompt 版本、模型版本;
- 原始问题、最终答案;
- 总耗时、总 Token、总成本;
- 请求状态、异常类型、用户反馈和最终评分。
这些字段决定了后续能否按照用户、会话、版本和环境进行筛选与对比。
2. Query 改写 Span
记录原始问题、改写后问题、改写策略、意图识别结果和耗时。
出现检索偏差时,第一步应确认改写后的 Query 是否仍然忠于用户意图。很多“向量库检索不准”,根因其实发生在检索之前。
3. 向量检索 Span
建议记录:
- 实际检索 Query;
- 知识库和索引版本;
- Embedding 模型版本;
- TopK、相似度阈值;
- 召回文档 ID、标题、片段和分数;
- 检索耗时。
生产环境不要无节制地保存完整敏感文档。可以根据数据等级保存摘要、Hash、文档 ID 或经过脱敏的片段,并配置访问控制与留存周期。
4. 重排与过滤 Span
记录重排模型、过滤规则、重排前后数量、各文档分数,以及最终送入模型的 Context 列表。
这个节点能回答两个关键问题:关键文档是否被错误过滤,以及噪声文档是否占用了上下文窗口。
5. Generation 节点
Generation 专门描述模型调用,应记录:
- Prompt 模板及版本;
- 实际输入的 Context;
- 模型、温度、最大输出长度等参数;
- 模型输出;
- Input、Output Token;
- 首 Token 延迟、总推理耗时;
- 重试、限流和异常信息。
如果使用的模型 SDK 不能自动返回 Token Usage,需要在适配层补充,否则成本分析会出现数据缺口。
四、上下文传播:从 Demo 走向生产
原型项目可以直接在关键函数上增加 @observe 装饰器。嵌套调用时,SDK 会自动建立父子关系,接入成本很低。
生产系统还需要动态注入用户、会话、版本和租户信息。这时应利用 OpenTelemetry Context,在入口处写入 Trace 属性,让下游 Span 自动继承。
@observe(as_type="chain")
def rag_pipeline(question, user_id, session_id):
span = trace.get_current_span()
span.set_attribute("langfuse.user.id", user_id)
span.set_attribute("langfuse.session.id", session_id)
span.set_attribute("app.rag.version", "rag-2026-07")
rewritten = rewrite_query(question)
docs = retrieve(rewritten)
contexts = rerank(docs)
return generate_answer(question, contexts)
进程内通常通过 contextvars 隐式传播;跨服务调用则应使用 W3C Trace Context,通过 traceparent Header 传递 Trace ID 和父 Span ID。这样,网关、RAG 服务、模型网关和工具服务才能串成一条完整链路。
如果系统基于 LangGraph 构建 Agent,可以在 graph.invoke() 外层建立根节点,每个 Node 建立 Span,每次模型调用建立 Generation。条件分支、循环重试和工具调用因此都会呈现在同一棵链路树中。
五、RAGAS 如何量化 RAG 质量
仅仅记录链路还不够。我们还需要将“这次回答好不好”转化为稳定指标。
Faithfulness:是否忠于上下文
用于判断答案中的事实是否能够从检索 Context 中得到支持。分数低通常意味着模型产生了幻觉,或者上下文本身不足以支撑回答。
Answer Relevancy:是否回答了问题
用于判断答案与用户问题是否相关。它可以发现答非所问、过度发散或大量无关内容。
Context Precision:召回内容是否有效
用于观察召回结果中真正有用的信息占比。分数低说明检索噪声过多,可能需要调整 Query、TopK、Chunk、Embedding 或 Reranker。
Context Recall:需要的信息是否被召回
用于判断回答问题所需的关键信息是否出现在 Context 中。分数低通常意味着知识缺失或漏召回。
需要注意:不同 RAGAS 版本对数据字段和指标定义可能存在变化;部分指标可以在没有标准答案时运行,部分指标则需要 Reference 或 Ground Truth。升级版本时应固定依赖、校验输入 Schema,并用一小批已知样本检查评分口径是否变化。
六、Dataset 是整套体系的枢纽
线上 Trace 只是事实记录,Dataset 才能把一次事故转化为可重复验证的资产。
建议从以下渠道持续收集样本:
- 用户明确点踩或投诉;
- 人工审核发现的典型错误;
- RAGAS 自动评分低于阈值;
- 线上异常、超时或高成本请求;
- 新业务场景和高风险问题;
- 历史版本曾经修复过的缺陷。
Dataset 中至少保留 question、answer、contexts,并根据指标需要补充 reference。同时保存业务分类、难度、风险等级、语言、数据来源和脱敏状态。
一个常见误区是直接把模型的实际回答当成 expected_output。实际回答不等于标准答案。如果某项指标依赖参考答案,应由业务专家修正,或者从可信数据源构造 Reference。
七、建立可持续的质量闭环

推荐将整个流程固化为五个阶段。
阶段一:线上观测
Langfuse 实时记录调用链、成本、延迟和异常。监控系统对高错误率、高 Token、低评分和关键字段缺失建立告警。
阶段二:Bad Case 沉淀
将具有代表性的失败样本加入 Dataset,并标注根因:改写、检索、重排、上下文、Prompt、模型或数据问题。
阶段三:离线批量评测
使用同一份 Dataset 对不同候选方案执行 RAGAS:
- Prompt A 与 Prompt B;
- Embedding 模型 A 与模型 B;
- 不同 Chunk Size 和 Chunk Overlap;
- 不同 TopK、相似度阈值和 Reranker;
- 不同生成模型与参数。
阶段四:发布门禁
不要只比较平均分。至少同时观察:
- 各指标均值与 P10 等低分位;
- 严重失败率;
- 核心场景通过率;
- 延迟与成本变化;
- 相对上一版本的回退样本数量。
只有质量、性能和成本共同达标,候选版本才允许进入灰度。
阶段五:灰度验证与回写
线上按版本 Tag 区分流量,将 RAGAS 分数、人工反馈和业务结果回写原始 Trace,比较离线评测与真实用户反馈是否一致。如果偏差明显,需要调整 Dataset 的样本分布和评分标准。
八、生产环境不能忽略的工程细节
1. 异步上报与 Flush
Langfuse SDK 通常使用本地缓冲和异步批量上报。短生命周期脚本退出前应显式 flush();常驻服务应在优雅退出阶段刷新缓冲区。不要在每个请求中无条件执行阻塞式 Flush,否则观测组件可能反过来增加业务延迟。
2. 采样与留存
低风险正常流量可以采样,高风险请求、异常请求和低分样本应尽量全量保存。Prompt、Context 和模型输出体积较大,应分别设置热数据、冷数据和删除周期。
3. 数据安全
在 SDK 或模型网关入口统一进行脱敏,避免身份证号、手机号、密钥和企业机密进入观测平台。生产环境应配置项目隔离、最小权限、审计日志和数据删除能力。
4. 版本可追溯
每条 Trace 都应携带应用、Prompt、模型、知识库、Embedding、Reranker 和配置版本。没有版本信息,即使发现指标下降,也很难确定究竟是哪项变化造成的。
5. 观测系统自身降级
Langfuse 上报失败不能阻断主业务。SDK 应设置合理超时、批量大小、队列上限和失败降级策略,并对“观测数据丢失率”本身进行监控。
九、落地检查清单
上线前可以快速检查以下问题:
- 是否能通过一个 Trace 还原完整 RAG 请求?
- Query、召回文档、重排结果和最终 Context 是否可追溯?
- 是否记录 Prompt、模型、知识库和检索策略版本?
- Token、成本、延迟和异常是否完整?
- 用户、会话、环境和租户维度是否可筛选?
- 敏感字段是否在上报前完成脱敏?
- Bad Case 是否能够一键进入 Dataset?
- RAGAS 输入字段是否与当前版本匹配?
- 候选版本是否使用同一 Dataset 回归测试?
- 发布门禁是否同时考虑质量、成本和延迟?
- 短任务退出、服务重启和上报失败时是否有兜底?
十、总结
生产级 RAG 的关键,不是再增加几个日志,而是建立一套能够解释、衡量和持续改进系统质量的数据机制。
Langfuse 负责保存一次请求“经历了什么”,RAGAS 负责判断结果“做得怎么样”,Dataset 则把线上问题沉淀成长期可复用的回归资产。三者连接起来,RAG 才能从人工抽查和主观判断,升级为可观测、可评测、可比较、可回归的工程系统。
最终应该形成这样的闭环:
监控发现问题 → Trace 定位根因 → Dataset 沉淀样本 → RAGAS 量化评测 → 发布门禁验证 → 线上反馈继续反哺。
Demo 阶段可以靠手感,生产阶段必须靠数据。