可观测性与链路追踪 Observability & Tracing
所属:01-fundamentals / 06-agent-infra
面试权重:★★
来源:通用领域知识;未做一手考证
相关知识点:01-fundamentals/05-agent-evaluation/agent-eval.md、llm-as-judge.md、06-agent-infra/gateway-routing.md
一句话#
Agent 是多步、非确定性、会传播错误的系统,所以它的可观测性不是"打日志",而是链路追踪 —— 把一次运行拆成带输入输出的 step 树,既能定位"哪一步坏了",又能把这些真实运行变成评测数据与训练数据,形成从线上失败回到模型改进的闭环。
为什么重要(面试角度)#
这是「生产化」的题,也是最容易讲出闭环思维的地方。面试官想听:
- 你能说清为什么日志不够、需要 trace(多步 + 错误传播 + 需要归因)
- 你能列出每一步该记什么(模型、token、成本、延迟、工具参数与返回、错误、重试)
- 你能把 trace 当评测数据用:真实失败 case → 评测集/在线打分
- 你能讲出从生产失败回到训练数据的反馈闭环,并说清这个闭环的难点
你做过网关(日志与链路追踪是它的职责之一)和意图识别的线上误判回流,这条线你有真实素材。能讲闭环,层级就从"会埋点"升到"会运营模型"。
核心内容#
为什么 agent 需要 trace 而不是日志#
| Agent 的特性 | 只打日志的问题 | trace 的解法 |
|---|---|---|
| 多步 | 一次运行产生几十上百行日志,散落在不同服务的日志文件里,时序难对齐 | 一次运行 = 一个 trace,每步 = 一个 span,父子结构天然表达调用关系 |
| 非确定性 | 同一个输入每次路径不同,没法靠复现定位 | 把那一次的完整路径与每步输入输出留档,可回放分析 |
| 错误传播 | 最后报的错往往不是根因(第 1 步就错了,第 7 步才崩) | 顺着 trace 往回找第一个偏离正常的分叉 |
| 成本分布不均 | 总成本无法归因到具体步骤 | 每个 span 记 token 与成本,能算出哪一步最贵 |
| 需要人审 | 没有可读的完整上下文,无法判断过程是否合理 | span 的输入输出就是评审所需的全部材料 |
一句话:日志回答"系统做了什么",trace 回答"这一次为什么失败"。
trace 的数据模型#
概念上分三层(不同工具的命名略有差异,但结构同构):
- Session(会话):跨多轮的容器,承载同一个用户/对话的全部 trace。
- Trace:一次请求/一次任务的完整运行(一次 agent 任务 = 一个 trace)。
- Span / Observation:trace 内的一步,有类型(LLM 调用、工具调用、检索、判断、人工介入)、开始结束时间、输入输出、状态。
每一步该记什么(这是面试要能列出来的清单):
| span 类型 | 必须记录 |
|---|---|
| LLM 调用 | 模型名与版本、prompt(或引用)、输出、输入/输出 token 数、温度等参数、成本、延迟、结束原因(正常/超长/被截断)、错误与重试 |
| 工具调用 | 工具名、完整参数、返回结果(或摘要)、成功/失败、错误类型、耗时、是否重试 |
| 检索(RAG) | 原始 query、改写后的 query、命中的 chunk id 与分数、rerank 前后排序、注入上下文的长度 |
| 路由决策 | 选中的模型、置信度/分数、判定为哪一档、备用路径 |
| 人工介入 / 拒绝 | 触发原因、被拦截的动作、人工选择 |
| 最终结果 | 用户可见输出、是否成功、用户反馈(点赞点踩、是否追问答、是否转人工) |
要主动提出的工程约束:
- PII 与合规:prompt 里常有用户隐私,必须脱敏或做引用式存储,并明确留存策略与访问权限。"全都记下来"和"什么都不记"都是错的。
- 采样:全量记录的存储成本可能很高,可以分级 —— 错误与失败 case 全记,成功 case 按比例采样。
- 大 payload 截断/外链:长文档、大返回值要截断或存到对象存储,trace 里只留引用。
- 归因与关联:trace 要和用户 id、会话 id、版本号(模型版本、prompt 版本、代码版本)关联,否则无法做版本对比。
- 性能开销:埋点本身要异步、不能阻塞请求链路。
trace 当评测数据用#
这是 trace 最有价值的一层 —— 它是评测集与训练数据的原料:
- 生产失败 case → 评测集:从 trace 里筛出失败/低分/被投诉的运行,人工标注后进 golden set。这样评测集天然贴合真实分布,比拍脑袋构造的样本有价值得多。
- 在线打分挂到 trace 上:对采样的线上 trace 跑 LLM-as-a-Judge 或规则校验,把分数作为 score 挂在 trace 上。就能持续监控质量,而不是只在发版时测一次(→ 见
llm-as-judge.md)。 - 用户反馈作为 score:点赞点踩、追问率、转人工率、重试率,直接落在 trace 上 —— 这是最诚实的质量信号(虽然稀疏且有噪声)。
- 回放做回归:用历史 trace 的输入重跑新版本,对比输出与分数,做回归评测,防止改动造成能力回退。
- A/B 与版本对比:trace 上带版本 tag,可以按版本聚合指标(成功率、成本、延迟、质量分),做真实的线上对比。
- 构造偏好数据:同一 prompt 下不同模型的输出、或不同版本的输出,可直接组成
(prompt, chosen, rejected)用于 DPO 之类的偏好对齐(→ 见02-interview/projects/hkgai-llm.md)。
注意:trace 数据是生产数据,用于评测和训练都要过隐私与合规流程;且它带分布偏置(线上表现出来的问题不代表全部问题,长尾样本少)。
从生产失败回到训练数据(反馈闭环)#
闭环的形状:
线上 trace 采集(每步输入输出 + 结果 + 反馈)
↓
失败聚类与归因(是工具选择错?参数错?检索没召回?prompt 没覆盖?)
↓
人工标注 / 构造样本(评测样本 + 训练样本 + 偏好对)
↓
数据进入训练(SFT 补能力 / DPO 补偏好)或 prompt 与工具描述改进
↓
回归评测(新版本在 golden set 上不能退化)
↓
灰度上线 → 继续采集 trace这个闭环的关键工程点:
- 埋点字段要能对上训练需要的字段。如果 trace 里没记"路由判定结果",就没法把路由误判 case 捞出来做训练数据。埋点设计要回头问一句"这些字段将来能用来干什么"。这就是 QueWI 里"误判 case 回灌训练"能落地的前提。
- 失败要能被分类,否则一堆 case 无从下手。至少要能按"系统边界"分:是路由/网关、检索、工具、模型生成、还是用户输入本身的问题。
- 闭环要闭合:只采集不回流,等于存了一堆数据没用;回流了但不做回归评测,等于用线上做实验。
- 注意反馈信号的偏置:点踩的人更有表达欲,沉默的大多数不反馈 —— 不能把反馈率当成质量。
工具与选型#
- Langfuse:开源 LLM 可观测平台,提供 trace/session/observation 的数据模型、以及在 trace 上挂 score 和建 dataset 的能力 —— 正好覆盖上面"追踪 + 评测"两层。
- OpenTelemetry 一类通用追踪标准:生态成熟、可接入既有 APM,但对 LLM 特有字段(token、成本、prompt)需要自定义约定。
- 自建 vs 采购:自建可控、无数据出境问题,但要自己维护存储与查询;采购上线快、UI 好,但要考虑数据合规与成本。评估口径:数据合规(隐私不能出境/不能给第三方)往往是一票否决项,其次才是功能。
常见面试问法#
Q:agent 出错了,只有日志为什么不够? A:agent 是多步、非确定性系统:一次运行产生大量散落在不同服务的日志,时序难对齐;同一个输入每次路径不同,没法靠复现定位;错误会传播 —— 最后报的错往往不是根因(第 1 步就偏了,第 7 步才崩)。trace 把一次运行组织成带父子关系的 span 树,每步的输入输出、耗时、成本、错误都留档,可以顺着树往回找第一个偏离正常的分叉,也可以整段回放给人审。
Q:你的 trace 里会记录什么? A:按 span 类型分:LLM 调用记模型名与版本、prompt/输出、token 数与成本、参数、延迟、结束原因、错误与重试;工具调用记工具名、完整参数、返回值、成败与错误类型、耗时;检索记原始与改写后的 query、命中 chunk 与分数、rerank 前后排序;路由决策记选中模型、置信度与档位;最后记用户可见输出、成败与用户反馈。同时要讲清约束:PII 脱敏、分级采样(失败全记、成功按比例)、大 payload 截断或外链、关联用户/会话/版本号以便对比、埋点异步不阻塞链路。
Q:trace 怎么和评测结合? A:四条主要用法:① 从 trace 里筛失败 case,人工标注后进 golden set —— 评测集因此贴合真实分布;② 对采样的线上 trace 跑 LLM-as-a-Judge 或规则校验,把分数挂在 trace 上做持续质量监控;③ 用户反馈(点赞点踩、追问、转人工、重试)作为 score;④ 用历史 trace 的输入回放新版本做回归评测,并可按版本 tag 做线上 A/B 对比。此外同一 prompt 下不同模型的输出还能组成偏好对用于对齐训练。
Q:从线上失败到模型改进,闭环怎么搭?难点在哪? A:闭环是"采集 trace → 失败聚类归因 → 人工标注/构造样本 → 训练或 prompt/工具改进 → 回归评测 → 灰度上线 → 继续采集"。难点:① 埋点要预先设计,字段必须对得上训练所需(没记路由判定结果就捞不出路由误判 case);② 失败要能按系统边界分类(路由/检索/工具/生成/输入),否则无从下手;③ 反馈信号有偏置(点踩者更有表达欲),不能把反馈率当质量;④ 合规:生产数据用于训练要过脱敏与授权;⑤ 闭环要真的闭合 —— 只采集不回流等于白存,回流不做回归评测等于拿线上做实验。
Q:怎么定位"有时候快有时候慢"这类问题?
A:靠 trace 的分段计时 + 分桶。把一次请求拆成网关、路由、检索、工具、prefill(TTFT)、decode(TPOT)、网络等 span,按阶段看 P50/P90/P99 的分布,找出哪一段的尾部在恶化;再按请求类型、模型版本、缓存命中与否分桶。常见成因是请求长度长尾、突发排队、缓存命中率波动、上游限流触发重试。没有分段 trace,这类问题只能靠猜(→ 见 latency-cost.md)。
易错点#
- ❌ 把可观测性等同于"打日志" —— agent 需要的是结构化的多步 trace(span 树),不是文本行。
- ❌ 只记最终输出,不记每步的输入输出 —— 那样无法归因,也无法回放与评测。
- ❌ 埋点字段与将来用途脱节:上线后才想要"路由误判 case",却发现没记判定结果与置信度。
- ❌ 全量记录且不做 PII 脱敏 —— 合规风险;反过来"为合规什么都不记"则失去可观测性。正确做法是脱敏 + 分级采样。
- ❌ 把用户反馈率直接当质量指标 —— 反馈有严重的选择偏置。
- ❌ 采集了数据但不做闭环(不回流评测与训练),或回流了但不做回归评测。
- ❌ 忽略埋点的性能开销与并发限制(异步、采样、不在关键路径上做重活)。
- ❌ 用 trace 数据训练/评测时不检查它与真实分布的偏差(线上暴露的问题只是子集)。
自测#
1. 为什么 agent 的可观测性必须用 trace 而不是日志?
答案
因为 agent 有三个特性让日志失效:① 多步 —— 一次运行几十上百步,日志散落在不同服务里、时序难对齐;② 非确定性 —— 同一输入每次路径不同,没法靠复现定位,必须留存那一次的完整路径;③ 错误传播 —— 最后报的错通常不是根因(第一步就偏了,第七步才崩),需要顺着调用树往回找第一个异常分叉。trace 把一次运行组织成带父子关系的 span 树,每步的输入输出、耗时、成本、错误都在里面,既支持归因也支持回放。
2. 一次 agent 运行的 trace 里,你会记哪些字段?还要注意什么约束?
答案
字段按 span 类型:LLM 调用记模型名/版本、prompt 与输出、输入输出 token 数、成本、参数(温度等)、延迟、结束原因、错误与重试;工具调用记工具名、完整参数、返回、成败、错误类型、耗时;检索记原始 query、改写 query、命中 chunk 与分数、rerank 前后排序;路由记选中模型、置信度、档位;最后记用户可见输出、成败与用户反馈。约束:PII 脱敏与留存策略、分级采样(失败全记/成功抽样)、大 payload 截断或外链、关联用户/会话/版本号、埋点异步不阻塞链路、存储成本可控。
3. 怎么把 trace 变成评测数据?
答案
① 从 trace 中筛选失败、低分、被投诉的运行,人工标注后加入 golden set —— 评测集因此贴合真实流量分布;② 对采样的线上 trace 跑 LLM-as-a-Judge 或规则校验,把分数作为 score 挂在 trace 上,实现持续的质量监控而非只在发版时测一次;③ 用户反馈(点赞点踩、追问、转人工、重试率)作为 score;④ 用历史 trace 的输入回放新版本,做回归评测;⑤ 按版本 tag 聚合指标做线上 A/B;⑥ 同一 prompt 下不同模型/版本的输出可组成 (prompt, chosen, rejected) 偏好对用于对齐训练。
4. 描述从线上失败回到模型改进的闭环,并指出两个最容易断掉的环节。
答案
闭环:采集 trace → 失败聚类与归因(路由/检索/工具/生成/输入)→ 人工标注或构造样本(评测样本 + 训练样本 + 偏好对)→ 训练(SFT 补能力、DPO 补偏好)或改进 prompt 与工具描述 → 回归评测确保不回退 → 灰度上线 → 继续采集。最容易断掉的两环:① 埋点与训练需求的脱节 —— 上线后才想要某类 case(如路由误判),但 trace 里没记判定结果与置信度,于是捞不出训练数据;② 闭环不闭合 —— 只采集不回流(存了一堆数据没用),或回流了但不做回归评测(等于拿线上当实验、可能引入回退)。另外合规(脱敏与授权)和反馈信号偏置也是常见障碍。
5. 团队想"把所有 prompt 和输出全量存下来,方便以后分析"。你怎么评估这个提议?
答案
要分两面看。价值侧:完整数据确实是最有分析余地的,尤其是失败 case 与难复现问题。风险与成本侧:① 合规 —— prompt 里常有用户 PII,全量原始存储需要脱敏、访问控制、留存期限与使用授权,否则是法律风险而非技术风险;② 存储成本 —— 全量 prompt/输出随流量线性增长,可能远超预期;③ 安全 —— 集中存储的敏感数据是攻击目标。务实做法是分级:失败与异常 case 全量保留(更有分析价值),成功 case 按比例采样;对 PII 做脱敏或引用式存储(正文放受控存储,trace 里只留引用);明确留存策略与访问审计。核心论点:可观测性的目标是"能定位、能回流",不是"存得越多越好"。