Skip to main content

可观测性与链路追踪

Written: 2026.06
第 19 章跟敲代码:codealong/chapters/ch19_observability_tracing。 这部分代码是本章跟敲版,用来先跑通核心闭环;完整项目源码仍以本讲后文标注的 qa_core/scripts/ 等路径为准。
上一讲测试与接口验收

1. 本讲目标

  • 理解 RAG 系统为什么必须具备可观测性
  • 掌握 LangSmith Trace 的核心字段和业务 metadata 设计
  • 理解 Bad Case 如何通过 LangSmith annotation/dataset 沉淀
  • 了解项目如何通过轻量 adapter 接入 LangSmith,而非自建 LLMOps 平台
  • 掌握生产部署、容量评估、压测和监控告警的面试表达
本讲边界 第 19 讲是全课的生产化收口:第 17 讲证明“质量好不好”,第 18 讲证明“代码坏没坏”,本讲回答“上线后怎么观察问题、定位瓶颈、压测扩容、对外解释生产部署方案”。

2. 前置知识 — 可观测性的三个支柱

2.1 什么是可观测性

在 RAG 系统中,用户说”答案不对”,单看最终回答无法判断问题出在哪里:
没有可观测数据,你只能猜测。有了可观测数据,你可以定位

2.2 本项目的可观测架构

本项目采用 LangSmith 委托 架构——业务代码只负责写入领域 metadata,存储、查询、可视化、评测和标注全部由 LangSmith 平台完成。
核心原则:项目不复刻 LLMOps 平台。自研追踪存储、状态页 Dashboard 和评测 UI 属于平台级工程,超出当前 RAG 项目的范围。企业路线下,LangSmith 提供成熟的 tracing、dataset、evaluation 和 annotation 能力,项目只负责写入业务 metadata。

3. langsmith_adapter.py — 核心代码

项目中与 LangSmith 交互的唯一模块是 qa_core/observability/langsmith_adapter.py(147 行)。它包含四个函数:

3.1 环境配置:configure_langsmith_environment()

app.py 启动时调用一次,将 Pydantic Settings 中的 LangSmith 配置写入环境变量,使 LangChain 集成能自动感知。

3.2 开关检测:langsmith_enabled()

所有 trace 写入操作的守卫。LangSmith 未启用时直接跳过,不影响请求主链路。

3.3 状态查询:langsmith_status()

返回轻量状态字典供状态页使用,包含 providerenabledprojectendpoint 和项目 URL。

3.4 核心函数:record_query_trace()

执行流程
  1. configure_langsmith_environment() — 确保环境变量已注入
  2. langsmith_enabled() 检查 → 未启用直接返回
  3. 构建 metadata 字典(18 个业务字段,见下方)
  4. 构建 inputs(question / scenario_id / source_filter / kb_version)
  5. 构建 outputs(answer_preview[:800] / hit_type / sources / error)
  6. 通过 langsmith.run_helpers.trace() 上下文管理器写入 LangSmith
  7. 异常只记日志不抛出——trace 写入失败不影响用户请求

3.5 写入 LangSmith 的业务 metadata

设计要点
  • metadata 不存完整 prompt/上下文——敏感资料(合同条款、薪酬信息)不应进入外部平台
  • trace_id 使用项目 UUID——可在 LangSmith UI 中搜索 trace_id 直接定位
  • tags 自动包含 scenario_idhit_type,支持在 LangSmith 中按场景和命中路径过滤

4. Bad Case 沉淀

4.1 LangSmith 闭环流程

  1. Trace 发现:在 LangSmith 中按 hit_type=insufficient_contextsources_count=0 过滤失败案例
  2. Annotation 标注:为失败案例标注 expected_outputis_correct,加入 Dataset
  3. Dataset 管理:每个场景维护一个回归评估集,新增标注后自动触发 Evaluation
  4. Gate 验收:在 CI 或发版前跑 Evaluation,对比基线分数判断是否退化

4.2 Trace、Annotation、Dataset、Evaluation 分别是什么

这四个词很容易混在一起,先把它们的职责区分清楚: 可以用一句话串起来:

4.3 从一次 bad case 到一次 Evaluation

下面用一个跨境贸易问题举例:
复核人员会在 Annotation 中补充:
然后把这个 Trace 加入 cross_border_risk_bad_cases Dataset。下次改 query rewrite、Milvus schema、Prompt Profile 或知识库版本时,LangSmith Evaluation 会重新跑这些样本,检查这类问题是否被修复。

4.4 Evaluation 和本地 Gate 的边界

LangSmith Evaluation 偏平台能力,本地 Gate 偏工程约束。两者分工如下: 因此本项目推荐的企业路线是:

4.5 与自建闭环的对比

本项目的教学定位:讲 LangSmith 企业闭环为主线,JSonL 底层原理只作为概念类比。

5. RAGQueryContext 中的 trace 调用

trace 不只是在问答结束时写一次,而是在整个 Pipeline 生命周期中逐步累积数据。调用链:
RAGQueryContext.run_stage() 是阶段自动计时的关键:它执行回调并记录 time.perf_counter() 差值,最终汇总为 stage_timings_ms

6. 面试收口 — 生产部署、容量评估与监控

面试中只说“项目用了 LangChain + Milvus + FastAPI”是不够的。更好的表达是:这个系统不仅能回答问题,还考虑了上线后的容量、压测、扩容、监控和故障定位。

6.1 生产部署拓扑

本项目当前适合中小规模知识库和教学/企业内部门户场景,推荐的最小生产拓扑如下: 组件分工:

6.2 并发访问量怎么估算

RAG 系统的并发不能只看 HTTP QPS,因为一次请求通常会经历多阶段:
如果平均一次完整问答耗时 6 秒,系统同时有 30 个请求在处理,那么粗略吞吐是:
但是 WebSocket 流式请求会长时间占用连接,面试时要区分:

6.3 容量分档和硬件选型

下面是面试表达用的经验分档,真实项目必须以压测结果为准。表里的并发、chunk 数和机器配置不是官方标准,也不是本项目承诺的容量,只是帮助你说明“如何估算、如何验证、如何扩容”的起点。 扩容优先级建议:
  1. 先看 LLM 延迟和限流:如果慢在云端 LLM,本地加 CPU 没用。
  2. 再看 Reranker:CrossEncoder 最容易成为本地推理瓶颈,候选数越多越慢。
  3. 再看 Milvus:检索 P95 高时,检查索引、collection 是否 load、segment 是否过碎、内存是否不足。
  4. 最后看 API worker:API 本身通常不是最重的计算点,但会受 WebSocket 长连接影响。

6.4 什么时候需要升级硬件

不要用“访问量大了就加机器”这种笼统说法。更专业的判断方式是看指标阈值:

6.5 压测方式

RAG 压测要分层做,不能只压健康检查,也不能只看单次人工提问。 第一层:健康检查和普通 HTTP 接口。
第二层:HTTP 检索诊断接口,用来测不含最终 LLM 生成的检索半链路。
第三层:WebSocket 流式问答主链路。hey 不适合测 WebSocket,可以用 Python 脚本模拟多用户连接:
压测报告至少要给出:
  • 成功率 / 错误率
  • P50 / P95 / P99 首 token 延迟
  • P50 / P95 / P99 完整回答耗时
  • 每阶段耗时:intent、embedding、milvus、rerank、llm
  • CPU、内存、磁盘 IO、网络
  • Milvus collection 是否 load、查询 P95、segment 数
  • LLM API 错误、限流、超时次数

6.6 监控与告警

生产环境建议把监控分成四层: 告警建议: 下面的阈值是示例起点,不是通用生产标准。真正上线时应先压测得到本项目的正常基线,再按“明显偏离基线 + 持续一段时间”设置告警。

6.7 生产发布流程

推荐把上线流程讲成一条稳定流水线:
如果只是 .env.compose 变化,例如更换模型地址、LangSmith 配置、DashScope Key:
如果 Milvus schema 或入库逻辑变化,必须先重建知识库。已有知识库只更新资料内容时不加 --reset-collections;只有旧 collection schema 不兼容时才删除 collection 重建:

6.8 生产事故排查案例

生产环境排查要从“现象”走到“证据”,不要只看最后的错误消息。下面这些案例可以作为常见问题排查模板。 一个通用排查顺序:

6.9 二期规划边界

一期目标是把企业级多场景 RAG 主链路做稳。二期不要把所有热门能力一次性塞进主线,建议采用“主线必做 + 亮点选做”的边界。 二期边界可以这样理解:
二期不是把系统改成“多个 Agent 自由聊天”,而是把当前可靠的 RAG Pipeline 封装成可调用工具,由主控 Agent 按意图选择 RAG、SQL、GraphRAG 或运维工具。GraphRAG 可以作为独立专家 Agent 存在,但不强依赖 Neo4j;基础版可以先用 MySQL 存实体和关系,Neo4j 作为增强方案。多模态也不做任意图片聊天,而是作为 OCR/VLM 文档入库增强。

6.10 面试表达模板

可以这样回答“你的项目生产环境怎么部署、能扛多少并发”:
我不会直接说一个固定 QPS,因为 RAG 的瓶颈取决于 LLM 首 token、Embedding/Reranker 推理、Milvus 检索和 WebSocket 长连接。我的做法是先定义指标:并发连接数、请求 QPS、首 token P95、完整回答 P95、Milvus P95、Reranker P95 和错误率。小规模可以用单机 Docker Compose,8C32G 起步;部门级会把 API、Milvus/MySQL、模型推理拆开,Reranker 尽量放 GPU;更大规模再上 Milvus Cluster 和多 API 实例。上线前分别压 HTTP 诊断接口和 WebSocket 在线问答主链路,线上用 LangSmith Trace 记录阶段耗时和命中质量,再配合主机/容器监控和质量告警判断是否扩容。

7. 本讲实践闭环

通过标准:能把项目从“本地能跑”讲到“生产可观测、可压测、可扩容、可排查”。

7.1 本讲从 0 到 1 实现闭环

这一讲把项目从“能跑”收束到“可观测、可部署、可压测、可排查”。实现顺序如下:
  1. 先配置 LangSmith 环境变量,让 LangChain/项目代码能把 trace 发出去。
  2. 再封装 record_query_trace(),统一记录场景、版本、命中路径、耗时、错误信息。
  3. 然后把阶段耗时写入 RAGQueryContext,定位慢在检索、重排、LLM 还是历史。
  4. 最后补生产部署、压测、监控和事故排查流程。
实现完成后,相关代码结构应该是下面这张图: 来源:真实代码节选,见 qa_core/observability/langsmith_adapter.py::configure_langsmith_environment()
Trace 的价值不只是“看到一次调用”,而是把业务维度记录进去。排查时可以按场景、版本、意图、source、命中路径过滤。 来源:真实代码逻辑压缩版,对应 qa_core/observability/langsmith_adapter.py::record_query_trace()
Trace 失败不能影响用户请求。真实代码会捕获异常并记录 warning,保证 LangSmith 网络波动不会把问答链路拖挂。 阶段耗时要在 Pipeline 内部记录。只有总耗时没有意义,因为你不知道慢在 Milvus、Reranker、LLM 还是 MySQL 历史。 来源:真实代码调用点,见 qa_core/pipeline/context.py::RAGQueryContext.run_stage()
生产部署和压测验收要关注并发连接数、首 token P95、完整回答 P95、错误率和各阶段耗时,而不是只报一个模糊 QPS。 来源:命令行验收,对应 docker-compose.yml.env.compose 和生产部署章节命令。
闭环验证重点: 验收重点:线上问题能从 trace、日志、健康检查、active 版本和质量报告中定位,而不是靠猜。

8. 重点掌握


9. 本讲小结

  • 项目不复刻 LLMOps 平台:trace 存储、过滤、可视化、标注和评估全部委托给 LangSmith
  • 147 行 adapter 是项目中与 LangSmith 交互的唯一代码
  • 18 个 metadata 字段 覆盖了场景、数据隔离、检索策略、耗时和错误信息
  • LangSmith 闭环:Trace 发现 → Annotation 标注 → Dataset 沉淀 → Evaluation 回归 → Gate 验收
  • 生产化表达:用并发连接数、首 token P95、阶段耗时、Milvus/Reranker/LLM 瓶颈、压测结果和监控告警来回答容量问题,而不是拍脑袋报 QPS
  • 事故排查:先看服务健康和 preflight,再看 active 版本、trace 阶段耗时、依赖状态和入库数据
  • 二期规划:主线建议是受控 Agentic RAG,GraphRAG 和 OCR/VLM 作为可插拔增强,不把自由多智能体作为生产主方案