
传统后端出了Bug,你看日志就能定位。LLM应用出了问题,你看日志只能看到一行"200 OK"——请求成功了,但回答是胡说八道的。 HTTP 200,但用户体验 404。
先做一个小测试。
你的LLM应用上线了,用户投诉"回答不对"。你能在5分钟内回答以下问题吗?
1 □ 最终发给模型的完整Prompt是什么?(不是模板,是拼好的最终版)
2 □ 检索环节召回了哪些文档?相关性得分是多少?
3 □ 模型输出了什么原始内容?后处理改了什么?
4 □ 这次请求消耗了多少Token?延迟多少毫秒?
5 □ 中间调了哪些工具?每个工具的输入输出是什么?如果你一个都答不上来——你的系统在裸奔。
如果你能答上来但需要翻三个系统拼凑信息——你的系统穿了件破衣服,聊胜于无。
如果你用一个trace ID就能把上面所有信息串起来看——恭喜,你是少数派。
今天聊的这个话题,可能是AI工程化里最不性感但最救命的一环——LLM可观测性与链路追踪。
用人话说:传统后端的监控是"体检",LLM系统的可观测性是"ICU的心电监护仪"——你不盯着,它随时可能出事,而且出事的方式你根本猜不到。
维度 | 传统后端 | LLM系统 |
|---|---|---|
故障是否显性 | 是——报错、崩溃、超时 | 否——"自信地胡说八道" |
HTTP状态码有用吗 | 有用——500就是出错了 | 无用——200但回答是错的 |
输出是否确定 | 是——同样输入同样输出 | 否——同样输入可能不同输出 |
根因是否单一 | 通常是——某行代码出错 | 通常不是——检索/Prompt/模型任何一环都可能 |
日志能定位问题吗 | 通常能 | 通常不能——你需要看完整链路 |
传统后端的故障是"崩了",你知道出事了。LLM系统的故障是"答错了",你可能根本不知道出事了。
这就是LLM可观测性权重更高的根本原因:系统本身是非确定的半黑盒,你不主动观测,就永远不知道它在干什么。
用户反馈:"你们的AI助手说我的订单已经发货了,但实际上还没发。"
没有可观测性的调试过程:
1 Step 1: 看日志 → "200 OK",无有用信息
2 Step 2: 猜测是检索的问题 → 手动跑检索 → 召回的文档看起来没问题
3 Step 3: 猜测是Prompt的问题 → 手动拼Prompt → 回答正确
4 Step 4: 猜测是模型的问题 → 但当时用的什么模型版本?不知道
5 Step 5: 猜测是上下文窗口太长截断了 → 但当时的Token数是多少?不知道
6 Step 6: 放弃猜测 → 回复用户"已修复" → 实际上什么都没修耗时:2小时。结果:什么都没定位到。
有可观测性的调试过程:
1 Step 1: 拿到用户请求的trace ID
2 Step 2: 打开追踪面板,看到完整链路:
3 → 检索环节:召回了3篇文档,第1篇是另一个订单的发货通知(相关性0.82)
4 → Prompt:包含了错误文档的内容
5 → 模型输出:基于错误文档给出了错误回答
6 Step 3: 根因明确:检索环节的相似度阈值太低,召回了不相关文档
7 Step 4: 调高阈值,加一条精确匹配订单号的前置过滤耗时:8分钟。根因定位:精确。
这就是"祈祷它能工作"和"知道它在怎么工作"的差距。
一个LLM请求的完整生命周期,远比你以为的复杂。

1 用户请求
2 │
3 ├─ [Span 1] 输入预处理
4 │ 输入文本、意图分类结果、参数解析
5 │
6 ├─ [Span 2] 检索(Retrieval)
7 │ 查询向量、召回文档列表、相关性得分、耗时
8 │
9 ├─ [Span 3] Prompt组装
10 │ 系统Prompt + 检索结果 + 用户输入 = 最终Prompt
11 │ Token数量、是否触发截断
12 │
13 ├─ [Span 4] LLM调用
14 │ 模型名称/版本、完整输入、完整输出
15 │ Token消耗(input/output)、延迟、温度参数
16 │
17 ├─ [Span 5] 工具调用(可能多轮)
18 │ ├─ [Span 5.1] 调用工具A:输入、输出、耗时
19 │ ├─ [Span 5.2] 调用工具B:输入、输出、耗时
20 │ └─ [Span 5.3] 再次LLM调用:整合工具结果
21 │
22 ├─ [Span 6] 输出后处理
23 │ 格式化、敏感信息过滤、回答质量检查
24 │
25 └─ [Span 7] 最终输出
26 返回给用户的内容、总延迟、总Token消耗每一个Span都需要记录,用同一个trace ID串起来。
维度 | 记录内容 | 为什么重要 |
|---|---|---|
完整Prompt | 拼好的最终Prompt,不是模板 | 模板+变量可能拼出意想不到的东西 |
模型输出 | 原始输出,后处理前 | 后处理可能改掉了关键信息 |
检索结果 | 召回的文档+相关性得分 | 最常见的错误来源 |
Token消耗 | input tokens + output tokens | 成本控制+异常检测 |
延迟 | 每个Span的耗时 | 性能优化+SLA保障 |
工具调用 | 每次调用的输入/输出 | Agent调试的核心 |
元数据 | 模型版本、温度、用户ID | 根因分析必备 |
少记一个维度,就多一类你无法定位的问题。
整个可观测性架构的核心是一个看似简单的东西——trace ID。
1 trace_id = "tr-a3f8b2c1-2026-05-31-user42"
2
3 这一个ID就能串起:
4 用户请求 → 意图分类 → 检索召回 → Prompt拼装
5 → 模型调用 → 工具调用 → 后处理 → 最终输出没有trace ID,你的日志就是一堆散落的拼图碎片。有了trace ID,每一片都自动归位。
设计要点:
用人话说:trace ID就是你给每个请求发的一张"身份证"。不管它在系统里跑了多少个服务、调了多少个模型,凭这张身份证就能查到它的全部"行程记录"。
链路追踪解决的是单个请求的问题——某次回答错了,能定位根因。
但还有一类问题是群体性的——整体质量在缓慢下降,你一条一条看看不出来。

信号 | 怎么监控 | 告警阈值示例 |
|---|---|---|
质量漂移 | 对线上输出采样评测,追踪均分趋势 | 7日滑动均分下降 > 0.3 |
幻觉率 | 采样检测输出与检索文档的一致性 | 幻觉率 > 5% |
Token异常 | 监控每次请求的Token消耗分布 | P99 Token突增 > 50% |
延迟飙升 | 监控端到端延迟的P50/P95/P99 | P95 > 10秒 |
质量漂移是什么?系统没人改过,但回答质量悄悄变差了。
原因可能是:
漂移原因 | 为什么会发生 | 怎么发现 |
|---|---|---|
模型更新 | 模型提供商偷偷更新了模型版本 | 监控模型输出的评测分数趋势 |
数据变化 | 检索的知识库内容更新了,但Prompt没适配 | 监控检索命中率和相关性分数 |
用户分布变化 | 用户的提问方式/话题发生了迁移 | 监控意图分类的分布变化 |
上下文膨胀 | 对话越来越长,关键信息被挤出窗口 | 监控Token消耗的P95趋势 |
质量漂移的可怕之处在于它是渐变的。 不是某一天突然变差,而是每天差一点点,一个月后回头看才发现已经面目全非。
这就好比温水煮青蛙——你不监控水温,就永远不知道什么时候该跳出来。
除了趋势性的漂移,还有突发性的异常模式:
异常模式 | 可能原因 | 告警方式 |
|---|---|---|
Token消耗突然飙升 | Agent陷入循环 / Prompt注入 | Token P99超出基线2倍 |
某类请求成功率骤降 | 上游API挂了 / 数据源变更 | 按意图分类监控成功率 |
幻觉率突然上升 | 检索质量下降 / 模型版本变更 | 幻觉率超出基线3个标准差 |
延迟分布出现双峰 | 某个Span间歇性超时 | P99/P50比值异常 |
用户反馈负面率上升 | 多种可能 | 用户评分滑动均值下降 |
每一个异常模式背后都有一个具体的根因,但你得先看到异常,才能去找根因。
把上面的内容组织成一个分层架构:
层级 | 关注点 | 工具/手段 | 回答的问题 |
|---|---|---|---|
L1: 链路追踪 | 单个请求 | Trace + Span + 结构化日志 | 这一次回答为什么错了? |
L2: 指标聚合 | 统计分布 | 时序指标 + 仪表盘 | 整体质量在变好还是变差? |
L3: 质量评测 | 内容质量 | 采样评测 + LLM-as-Judge | 输出的内容质量到底怎么样? |
三层缺一不可:
1 用户请求
2 │
3 ├──→ 链路追踪(L1)
4 │ 记录每个Span的详细信息
5 │ trace ID串联完整链路
6 │
7 ├──→ 指标采集(L2)
8 │ Token消耗 → 时序数据库
9 │ 延迟 → 时序数据库
10 │ 工具调用次数 → 时序数据库
11 │ → 仪表盘可视化 → 阈值告警
12 │
13 └──→ 质量采样(L3)
14 每N个请求采样1个
15 → 自动评测(规则 + LLM-as-Judge)
16 → 质量分数 → 趋势监控 → 漂移告警工具 | 定位 | 核心特点 |
|---|---|---|
Langfuse | 开源LLM可观测性平台 | 追踪+评测+Prompt管理一体化,可私有部署 |
Langsmith | LangChain官方 | 与LangChain深度集成,可视化追踪 |
Braintrust | 企业级平台 | 追踪+评测+数据集管理,全链路 |
Arize Phoenix | 开源LLM追踪 | 基于OpenTelemetry,与现有监控集成好 |
OpenLLMetry | 开源标准化 | 基于OpenTelemetry的LLM专用扩展 |
Helicone | 代理式接入 | 改一行代码就能用,零侵入 |
选择建议:
但工具永远是次要的。最重要的是你知道要记录什么、监控什么、在什么情况下告警。 搞清楚这三个问题,用什么工具都能做好。
按优先级排序,一步一步来:
1 □ 为每个请求生成trace ID
2 □ 记录最终Prompt(完整拼装后的版本)
3 □ 记录模型原始输出
4 □ 记录Token消耗和延迟
5 □ trace ID在API响应头中返回这一步做完,你就从"裸奔"变成了"穿上了衣服"。
1 □ 检索环节:查询、召回文档、相关性得分
2 □ 工具调用:每次调用的输入、输出、耗时
3 □ Prompt拼装:模板+变量+最终结果
4 □ 后处理:过滤/格式化改了什么这一步做完,你能在8分钟内定位任何一次错误回答的根因。
1 □ Token消耗分布(P50/P95/P99)
2 □ 端到端延迟分布
3 □ 按意图分类的请求量和成功率
4 □ 工具调用频率和失败率
5 □ 基础告警规则这一步做完,你能看到系统的整体健康状况。
1 □ 线上请求采样(5%-10%)
2 □ 自动质量评测(规则 + LLM-as-Judge)
3 □ 质量分数趋势图
4 □ 漂移告警
5 □ Bad Case自动收集 → 补充到离线评测集这一步做完,你的系统从"祈祷它能工作"正式升级为"知道它在怎么工作"。
可观测性不性感。
没有人会因为"我们的链路追踪做得好"而上热搜。没有用户会因为"你们的监控仪表盘很漂亮"而多付钱。
但每一个在凌晨被叫醒处理线上事故的工程师都知道:可观测性做得好不好,决定了你是8分钟修好问题回去睡觉,还是通宵翻日志到天亮。
LLM系统让这件事变得更极端——因为传统系统至少会"报错",LLM系统的故障模式是"自信地给你一个错误的答案,还带着完美的语法和流畅的逻辑"。
HTTP 200,但答案是错的。这种故障你不主动观测,永远发现不了。
所以这篇文章的核心只有一句话:
不要祈祷你的AI系统能工作。要知道它在怎么工作。
给每个请求发一张"身份证",记录它的每一步"行程",监控整个系统的"体温",在"发烧"之前收到告警。
这不是过度工程。这是LLM应用从"Demo"走向"生产级"的最低要求。
你的AI系统还在裸奔吗?今天是个穿衣服的好日子。
— 完 —