模块四 · 质量与生产
可观测:一次请求五步,怎么定位到哪一步坏了
传统日志是散的,Agent 的链路是多步的。这一节给出 trace/span 的记录方式、三个高频故障的定位路径,以及把线上问题转成评估样本的闭环。
读完这一节,你能做到
- 说清 Agent 的排查为什么比普通服务难。
- 用 trace + span 记录一次完整链路。
- 按"答非所问、变贵、卡住"三类现象快速定位。
- 把线上问题沉淀成评估样本,形成闭环。
一、为什么难排查
一次普通的 HTTP 请求,日志是一条线。一次 Agent 请求,是
用户输入 → 意图判断 → 检索 → 拼装 → 模型决策 → 工具调用 → 结果回填 → 再决策 → 输出
每一步都可能出问题,而且每一步的输出都是下一步的输入。只看最终答案,你无法判断是"检索没给对"还是"模型没用好"。
更麻烦的是:它是有状态的。同一个用户第二次问同样的问题,可能因为历史不同而走完全不同的路径。
二、trace 与 span
基本模型
- 一次会话/一次请求 = 一个 trace,有唯一 id。
- 每次模型调用、工具调用、检索 = 一个 span,挂在 trace 下。
- span 之间有父子关系,能还原执行顺序与嵌套。
trace: conv_9f3a
├─ span 1: intent_classify 12ms
├─ span 2: retrieval 86ms 命中 5 条
├─ span 3: llm_decision 1.2s tool_call: query_order
├─ span 4: tool_query_order 45ms ok
├─ span 5: llm_final 900ms 输出 210 token
└─ total: 2.3s / 4.1k input tokens
要记的字段
| 字段 | 为什么 |
|---|---|
| 类型(模型/工具/检索) | 分类统计与定位 |
| 输入摘要、输出摘要 | 判断这一步干了什么 |
| token 数 | 成本归因 |
| 耗时 | 延迟归因 |
| 模型名与版本 | 换模型后对比 |
| prompt 版本 | 改 prompt 后对比 |
| 错误码与重试次数 | 区分是失败还是慢 |
最小可用埋点
一开始不要追求全套。先把这五个字段打全,就能回答 80% 的问题:
会话 id、步骤序号、span 类型、耗时、是否重试
再按需要加:输入摘要(前 100 字)、token 数、模型名与 prompt 版本。
为什么先要“步骤序号”
没有它,你只能看到“这次会话调了 7 次模型”,但说不清哪一次是多余的。有了序号与耗时,一条时间线就能看出“第 3 步重试了两次”这类异常。
三、三类高频现象的定位路径
1. 答非所问
先看检索 span:召回的片段里有没有答案?
- 没有 → 检索/切分问题,别去改 prompt。
- 有 → 看拼装与决策 span:片段是否排在前面、指令是否明确、是否被历史干扰。
2. 成本突然翻倍
按三个方向查:
- 上下文变长:检索片段数量、历史是否没裁剪。
- 步数变多:工具失败率是否上升导致重试。
- 缓存失效:prompt 前缀是否被改动。
3. 卡住不出结果
看工具 span:
- 哪个调用超时、在重试。
- 是否有工具返回空导致循环。
- 是否触发了步数上限。
四、线上问题 → 评估样本的闭环
四步
- 从用户反馈或告警里拿到 trace id。
- 还原链路,定位到具体 span。
- 修复(检索、prompt、工具错误信息)。
- 把这条输入加入评估集,标注期望行为。
第 4 步最容易漏,也最重要。没有它,同一个问题会在下个版本再来一次。
一个纪律
每次只修一类问题,修完跑一遍完整评估集,确认没有把别的场景弄坏。
五、日志里的两个红线
- 不要存完整敏感数据。手机号、证件号、卡号要脱敏;prompt 里如果有用户隐私,日志也要处理。
- prompt 版本要可追溯。改 prompt 是最高频的变更,版本号与变更人必须能对上 trace。
六、三个必看的看板
| 看板 | 看什么 | 异常信号 |
|---|---|---|
| 效果 | 兜底率、转人工率、负反馈率 | 兜底率突然上升,通常是检索或工具集体失败 |
| 成本 | 单次 token、平均步数、大模型占比 | 单次 token 涨三成,多半是上下文没裁剪 |
| 稳定性 | 超时率、重试率、工具失败率 | 重试率上升会放大上游压力 |
三个看板按天看就够,不需要实时大屏。关键是有阈值告警:没有告警的看板,出问题时没人会主动打开。
还有一条容易被忽略:按会话看长尾。多数成本与体验问题集中在少数超长会话上,只看平均值会被摊平。列出“最贵的 20 个会话”,往往一眼就能看出设计缺陷:历史没裁剪、步数没上限,或者某个工具一直在重试。
保留策略:明细 trace 保留 30 天,聚合指标保留一年。排查通常发生在一周内,但成本与效果趋势需要长期对比。
七、常见坑
- 只记录最终答案。 出问题时无从下手。
- 日志分散在各服务,没有 trace id。 拼不起来。
- 不记 token 与模型版本。 成本和效果变化都无法归因。
- 把用户隐私原样写日志。 合规风险。
- 修完不入评估集。 同一个 bug 反复出现。
- 只盯成功率不看步数。 步数上升意味着成本与延迟在恶化。
八、动手任务:自写 → AI 写 → 对比 → 取舍
四步不跳:① 自己写(限时,关掉补全)→ ② 让 AI 写同一题 → ③ 逐条比对 → ④ 说出保留谁的写法。
① 自己写
- 画一张你系统的 trace 结构图:有哪些 span、父子关系怎么连、每个 span 记哪些字段。
- 写一份"三类现象 → 先看哪个 span"的排查清单。
② 让 AI 写同一题
把第 1 题交给 AI,补一句 按“span 名称 / 类型 / 必记字段 / 用途”表格输出,并指出哪些字段涉及隐私需要脱敏。
③ 对比要盯的点
- 它有没有遗漏"prompt 版本"这类归因字段?
- 脱敏它有没有主动提?
- 排查清单是不是只写了"看日志"?
④ 一句话取舍
它的方案里,哪一项记录成本最高?你愿意为它付这个成本吗?
九、自测
- Agent 的排查为什么比普通服务难?
- trace 与 span 分别是什么?
- 至少要记哪几类字段?
- "答非所问"应该先看哪个 span?为什么?
- 成本翻倍先查哪三处?
- 线上问题转成评估样本的闭环有哪四步?
参考答案要点:多步、每步输出是下一步输入、有状态;一次请求 / 每个子调用;类型、输入输出、token、耗时、模型与 prompt 版本、错误与重试;检索,先确认片段里有没有答案;上下文、步数、缓存;取 trace、定位 span、修复、入评估集。
配套题目
★ 越多越该先背;点题目可看完整答案与深入版。
- ★★★★★ Agent 线上出问题,怎么从日志定位到具体是哪一步?
- ★★★★☆ 流式输出中途失败,或者首字特别慢,怎么处理?
- ★★★★☆ Agent 的成本怎么监控?突然翻倍先查什么?
- ★★★☆☆ 流量上来之后,Agent 怎么限流和降级?
提示:读完可以顺手做几道对应题目,检验是否真的理解