系统学习 AI 学习路径:从 GPU 运行时到推理、微调与 RAG 评估

版本信息最后核对:2026-10-25

agent-runtime-observability

Agent 运行时观测:用 trace、工具 span、会话状态和成本指标,区分“模型没回答”与“工具失败”。

现象

Agent 上线后常见三类抱怨:不回复、答非所问、反复执行同一动作。用户侧通常只看到“服务繁忙”或一句笼统道歉,真正的失败点埋在多次模型调用和工具调用之间。监控上可能表现为成功率下降、P95 延迟升高、token 成本上升、工具错误率升高,也可能所有聚合指标正常,只有特定会话失败。

典型日志包括工具超时、上游 5xx、鉴权过期、限流 429、上下文超长、结构化输出解析失败、达到最大步数。它们对应完全不同的责任方:模型供应商、工具提供方、编排代码、会话存储或客户端。

运行时观测的目标不是“有日志”,而是能回答:这次运行在哪个 span 失败、失败前模型看到了什么、工具返回了什么、重试了几次、花了多少成本、是否影响其他会话。

快速判断

先拿到 trace_id 或 session_id,还原一次失败运行的时间线。不要从最终回答倒推。

# Langfuse 公共 API:取单条 trace 及其 observations
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
  "$LANGFUSE_HOST/api/public/traces/<trace-id>" \
  | jq '{name, latency, totalCost, observations: [.observations[] |
        {name, type, startTime, endTime, level, statusMessage}]}'

不同版本的字段和鉴权方式可能不同,以实例的 API 文档为准。重点看每个 span 的类型、状态、耗时和错误信息,以及模型调用与工具调用之间的先后关系。

线索 更可能的方向
没有 generation span,或模型调用直接报错 模型网关、限流、鉴权、上下文超长
有 tool span 且状态为错误或超时 工具或上游依赖失败
工具成功但回答没用结果 prompt、结果格式、上下文截断
同一工具被连续调用多次 返回不满足预期、循环控制缺失
会话中途丢失历史 会话存储、TTL、多副本一致性
只有部分用户失败 租户配额、权限、地域或版本
成本突然上升但请求量不变 上下文膨胀、重复调用、重试放大
日志里完全没有这次请求 采样、异步上报丢失或入口未埋点

再回答四个问题:

  1. 失败发生在模型、工具、编排还是会话状态?先定位层,再看具体错误。
  2. 是稳定复现还是偶发?固定输入复现偏向逻辑,随机出现偏向超时、并发或上游抖动。
  3. 影响面是单用户、单租户、单工具还是全局?范围决定先止损还是先定位。
  4. 是“没有产生回答”还是“产生了但用户没收到”?后者要查流式转发、连接中断和客户端。

区分“模型没回答”和“工具失败”,最有效的方法是看 span 的完整性:模型 span 是否存在、是否返回、finish reason 是什么;工具 span 的入参、出参、状态码和耗时是什么。模型没有发起工具调用,和工具调用失败,是两类完全不同的修复。

常见原因

模型调用失败

限流、额度耗尽、鉴权过期、上下文超过模型上限、内容安全拦截、结构化输出不合法,都会让 generation 失败。重试可能成功,也可能因为上下文没有裁剪而持续失败。

工具调用失败

工具超时、上游 5xx、参数校验失败、鉴权或权限不足、返回结构变化,都会让 Agent 拿不到结果。没有幂等键的重试还可能造成重复下单、重复发消息等副作用。

编排逻辑

最大步数设置过低会让复杂任务提前终止,过高则可能无限循环;缺少循环检测时,模型会反复调用同一工具;并行工具调用的竞态、状态机缺少终止条件,也会表现为“卡住”。

会话状态

历史消息丢失、重复写入、摘要截断过早、多副本没有共享存储、并发写覆盖,都会让模型“忘记”刚说过的话。长会话没有上限时,上下文会持续膨胀,最终触发超长错误或成本失控。

超时与重试

单步超时、总超时和重试次数没有统一预算时,层层重试会把一次失败放大成多次调用。退避缺失会加剧限流;重试不区分错误类型,会把不可恢复的错误反复重放。

观测缺口

异步上报没有 flush、采样率过低、错误没有标记、工具 span 缺失、敏感信息脱敏过度,都会让排障缺少关键证据。只记录最终输入输出,无法判断中间哪一步出错。

排查步骤

第一步:固定现场

记录 trace_id、session_id、用户或租户、请求时间、模型与 prompt 版本、工具版本、部署版本。把原始请求、最终响应和错误码一起保存,避免只留一张截图。

第二步:还原 span 时间线

按开始时间排序,列出每一步的类型、输入摘要、输出摘要、耗时、状态、重试次数和 token。确认失败点是模型、工具、编排还是存储;确认失败前是否有重试,重试是否改变了结果。

第三步:分层最小复现

用同一组消息直接调用模型,确认模型与网关是否正常;用同一组参数直接调用工具,确认上游与鉴权是否正常;最后再跑完整编排。三层分别复现,能快速排除无关组件。

第四步:检查超时与重试预算

列出入口总超时、单步超时、模型超时、工具超时和重试次数,计算最坏情况下的总耗时与调用次数。确认重试是否只针对可恢复错误,是否有退避和抖动,是否带幂等键。

第五步:检查会话状态

核对读写路径、TTL、并发锁和多副本共享存储;抽查同一会话的历史消息是否重复、缺失或被摘要错误替换。长会话要统计 token 增长曲线,确认是否有裁剪策略。

第六步:做成本归因

按模型、工具、租户、会话和版本聚合 token 与调用次数,找出成本异常的来源。成本上升可能来自上下文膨胀、重试放大、工具返回过大或缓存失效,不一定是请求量增加。

第七步:验证观测本身

确认采样率、flush 时机、异步队列和错误标记是否正常。用一条已知失败的请求检查是否被完整记录;如果日志里没有,先修观测,再谈定位。

修复与验证

验证时回放失败 trace,确认同一输入不再失败;再做故障注入,分别模拟模型限流、工具超时和存储不可用,观察降级是否符合预期。观察成功率、P95、重试次数、单次成本和人工接管率,确认修复没有把问题转移到其他层。

重放生产 trace 可能触发真实副作用,必须在沙箱、幂等环境或只读模式下进行。重试策略、熔断阈值和最大步数的调整要先在预发验证,保留旧配置,并确认可以快速回滚。

预防

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. 只有工具 span 报错,但模型 span 正常,说明问题更可能在哪一层?
  2. 为什么“工具调用成功”不代表 Agent 一定能给出正确回答?
  3. 回放生产 trace 排障时,最大的风险是什么?
答案
  1. 说明模型已经做出决策并调用了工具,失败发生在工具或上游依赖。应查工具超时、鉴权、参数校验、上游 5xx 和返回结构;模型 span 正常也说明不是限流或上下文超长导致的主失败,但仍要确认工具错误是否由模型给出的参数引起。
  2. 工具成功只代表拿到了结果,模型还可能因为结果格式不符合预期、上下文被截断、prompt 指令冲突或模型自身幻觉而不用结果。需要继续看工具输出是否进入下一轮上下文、是否被裁剪,以及模型最终生成时引用了什么。
  3. 重放可能再次触发真实副作用,例如下单、发消息、修改数据或调用计费接口。应在沙箱、幂等环境或只读模式下回放,并对写操作工具做拦截或模拟,避免排障本身造成二次事故。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令