跳到主要内容

Agent 流水线的分布式追踪:为什么你的 APM 工具形同虚设

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的 Datadog 仪表盘一片绿色。Jaeger 链路看起来干净整洁。P99 延迟符合 SLA。而你的 Agent 流水线正在悄无声息地因重试死循环每天烧掉 4000 美元,却没有触发任何一条报错。

传统 APM 工具是为微服务设计的——确定性路径、有界载荷、可预测的扇出。Agent 流水线打破了所有这些假设。执行路径在运行时才能确定。工具调用深度变化剧烈。一次"请求"可能跨数分钟产生数十次 LLM 调用。而当出了问题,失败模式通常不是异常——而是一个悄然膨胀成本和延迟、却返回看似正常输出的静默重试级联。

结果是一代工程师在盲目飞行,信任着那些衡量错误事物的仪表盘。

为什么标准 Trace/Span 模型会失效

经典分布式追踪之所以有效,是因为服务具有稳定的契约。一个 POST /api/orders 请求总是经过相同的三个服务,顺序不变。你预先定义 schema,对偏差设置告警,然后万事大吉。

Agent 流水线不是这样运作的。一次用户查询会触发一个计划-执行-观察循环,其中迭代次数、调用的工具集、分支决策全部由模型在运行时自主决定。你无法对一个静态调用图进行插桩,因为根本不存在静态调用图。

Agent 工作负载的若干特性会击穿 Span 构建时的假设:

非确定性控制流。 相同的输入在不同的运行中会产生不同的执行链路。周二成功的工具调用可能在周三超时,触发三次重试和一条在预生产测试中从未存在过的降级分支。

无界载荷大小。 在多轮工作流中,上下文会不断累积。一个有 10 步、系统提示 4000 个 token、平均工具输出 500 个 token 的 Agent,仅仅因为上下文传递,在最后一次 LLM 调用时就已携带超过 40000 个输入 token——这还不算任何输出生成。传统 Span 假设载荷有界。

无错误传播的嵌套重试。 这是最危险的失败模式。工具返回一个瞬态错误。Agent 以相同方式重试。同样的错误,同样的重试,再来三次。没有任何异常抛给调用方。用户看到的是 45 秒延迟而不是 15 秒,LLM 账单增加了三倍——但你的错误率仪表盘依然是零。

循环检测盲区。 当 Agent 进入循环——反复以相同参数调用同一工具——标准链路只会显示莫名其妙的延迟增长。经典追踪里没有"此 Span 是同一操作第 N 次重试"的内置概念。

专用 Agent 可观测性真正需要什么

缺失的原语分为四类。

Token 预算追踪作为一等指标。 Token 数量对 Agent 的意义,就像内存使用量对传统服务的意义——一种有限资源,其耗尽会导致静默劣化。正确的可观测性栈应实时追踪输入 Token、输出 Token、缓存 Token 和每条链路的成本。更重要的是,它追踪每次成功的成本,而不是每次请求的成本。一个重试三次才成功的流水线,其每次成功成本与一次就能成功的流水线截然不同,即便两者在简陋的仪表盘里都显示为单次"请求"。

工具调用延迟作为有类型的 Span。 每次工具调用都应该被捕获为一个结构化 Span,包含:输入参数、输出数据(或错误)、耗时,以及重试次数。这让你能够区分"LLM 本身慢"和"工具调用的外部 API 慢"——这两种情况在优化时至关重要。它还能让你将工具错误率与下游成本峰值关联起来。

模型版本作为高基数维度。 大多数生产 Agent 流水线同时运行多个模型——一个廉价模型用于路由和分类,一个能力更强的用于推理,可能还有第三个用于综合。每一个延迟指标、错误率和成本计算都需要按模型版本拆分。当一次模型升级发布后 P99 延迟翻倍,你需要立即知道劣化是在路由层还是推理层。

重试次数和循环计数作为显式字段。 这些不应该从重复 Span 中推断,而应作为每条链路的一等数值字段浮出水面,让你可以直接查询:"显示所有 retry_count > 2 的链路。"这个查询是排查成本峰值时最有用的单一操作。

三个预判 Agent 劣化的指标

长期运营生产 Agent 的团队最终都会收敛到相同的三个早期预警信号。这三个信号都会在用户察觉之前变得可见。

Token 膨胀率。 追踪每条链路的中位数和 P95 输入 Token 数量随时间的变化。Token 膨胀几乎总是提示词漂移、上下文累积 bug 或意外重试循环的第一个可观测症状。如果你的中位数输入 Token 在没有对应功能变更的情况下周增 20%,那就是出问题了。这在质量劣化触达用户前数天就可以测量到。

工具错误率峰值,而非整体错误率。 Agent 流水线会在内部吸收工具错误——这正是重试逻辑的意义所在。但工具错误率(重试前的错误,而非重试后)是下游 API 不稳定的领先指标。当某个依赖开始抖动,工具错误率会立即飙升。成本和延迟随后跟上。用户可见的失败最后到来。监控重试前的工具错误率,让你有窗口期提前干预。

每次成功成本与每次请求成本的背离。 如果每次请求成本平稳,但每次成功成本在上涨,说明你的重试和降级逻辑正在悄然消耗 token 处理那些被悄悄解决、没有浮出水面的失败。这个差距是静默重试级联最清晰的信号。每次成功成本上涨 10%,通常对应着重试率悄然翻了三倍。

工具链全景

专用可观测性平台已经涌现,专门填补这些空白。截至 2026 年部署最广泛的几个:

LangSmith 与 LangChain 和 LangGraph 深度集成,为基于 LangChain 的工作流提供自动链路捕获。如果你已经在这个技术栈上,集成几乎零配置,但它是专有的,在 LangChain 生态之外难以使用。

Langfuse 是开源的、基于 SDK 的,对复杂工作流有良好支持。对于希望自托管且不绑定特定框架的团队,这是默认选择。

Arize Phoenix 以 OpenTelemetry 原生基础平衡了监控与评估。更适合有数据科学参与、希望在生产监控旁边运行评估的团队。

OpenLLMetry(由 Traceloop 出品)采用不同路径:它是一个开源插桩 SDK,发出标准 OpenTelemetry Span,让你路由到任何兼容 OTel 的后端。它自动插桩 OpenAI、Anthropic、LangChain 和主流向量数据库。

Weights & Biases Weave 记录保留了 Agent 运行间父子关系的结构化执行链路,原生支持 OTel 导出。

它们之间的选择,不如尽早开始插桩这个决定重要。所有等到上线后才添加 Agent 可观测性的团队,都有相同的经历:他们在最关键的增长期盲目调试。

OpenTelemetry GenAI 标准:有什么,缺什么

OpenTelemetry 的 GenAI 语义约定为 Agent 追踪提供了厂商中立的基础。标准化属性涵盖:模型名称和版本、Token 数量(输入/输出/缓存)、工具调用输入和输出、结束原因,以及提供商元数据。Datadog、Splunk 和其他主流 APM 厂商现已原生摄取 OTel GenAI Span,这意味着你可以一次插桩,随处导出。

还处于实验阶段或缺失的内容:重试和循环模式没有标准表示。跨嵌套调用的成本归因缺乏收敛语义。多 Agent 协调——一个 Agent 孵化另一个——对于切换没有标准 Span 类型。静默失败检测根本没有标准化方案。

这意味着即便你今天采用了 OTel GenAI 约定,你仍然需要为最重要的指标添加自定义 Span 属性:重试次数、循环迭代、每条链路成本和每次成功成本。标准给了你基础;Agent 专用插桩仍然是你自己的责任。

优先插桩什么

如果你的 Agent 流水线从零可观测性开始,优先顺序很重要。按顺序添加以下内容:

第一,为每条消息、工具调用和决策分支添加关联 ID。没有关联,跨日志调试多步骤失败几乎不可能。这是成本几乎为零、回报立竿见影的唯一一件事。

第二,为每次工具调用发出一个结构化 Span,将重试次数作为显式字段。不是推断的——是显式的。这一个改动让重试级联检测成为可能。

第三,追踪每次 LLM 调用和每条链路的 Token 数量。实时计算成本。如果每条链路成本连续超过五分钟超过阈值,设置告警。

第四,将模型版本作为每个指标的一个维度来追踪。这在你第一次做模型升级、需要理解什么发生了变化时变得至关重要。

第五,添加循环检测。最简单的版本:如果同一工具在单条链路中以相同参数被调用超过 N 次,发出一个警告事件并考虑终止运行。静默循环是最昂贵的失败模式,也是最容易预防的一种。

运营现实

40% 的 Agentic AI 项目在上线前就失败了,成本失控是主要驱动因素之一。那些能够交付并维持生产 Agent 的团队有一个共同特质:他们把可观测性视为功能,而非事后补丁。他们在规模扩展之前就插桩。他们对工具错误率告警,而不仅仅是用户可见错误。他们同时追踪每次成功成本和每次请求成本。他们把 Token 膨胀当作它本来的样子——煤矿里的金丝雀。

你的 APM 工具是为执行路径在部署时就已知的世界打造的。Agent 流水线活在另一个世界,那些为微服务服务得很好的仪表盘,不会告诉你 Agent 什么时候开始劣化。现在就为这个现实做好建设,在静默重试循环把某个周二下午变成一张意外的账单之前。

Let's stay in touch and Follow me for more thoughts and updates