新闻详情

新闻详情

首页 / 资讯中心 / 详情

Agent可观测性实战:从分布式追踪到Token成本归因

发布时间:2026/10/1 15:10:47来源:尧图网络
Agent可观测性实战:从分布式追踪到Token成本归因
跑 Agent 项目的人大概都经历过这种绝望昨天还能正常跑完的任务今天重新执行Agent 在第三步开始绕圈最后触发超时你以为只是模型抽风打开日志发现它压根没拿到期望的工具返回更糟的是月底看账单发现 Token 花费是上个月的五倍但你完全不知道钱烧在了哪次对话里。这些问题的本质是你把 Agent 当成一个黑盒在调用而不是当成一套分布式系统在运维。Agent 可观测性Observability要解决的就是用分布式追踪、链路诊断和 Token 成本精细化核算把黑盒变成白盒——让你能回答三个问题系统走到哪一步了每一步为什么这么走这一步花了多少钱这篇文章我按自己在多个 Agent 项目里的落地经验从原理、埋点、排查和成本归因四个角度拆开讲。先说一个基本判断传统的 APM 监控思路放在 Agent 场景下基本失灵。原因不是工具不好而是 Agent 的执行模型和传统服务根本不在一个维度上。传统后端是请求-响应模型一次 HTTP 调用从入口到出口链路是确定的超时和错误码是清晰的。Agent 不一样它的核心是一个循环——规划、调用工具、读取结果、再规划。这个循环的次数不固定每一步的分支不固定模型可能根据中间结果临时改主意甚至同一个任务跑两遍路径完全不同。这种不确定性的执行模型决定了你不能再只盯着 QPS、错误率、P99 延迟这些经典指标你得先看清楚它到底在干什么。1.1 本地开发能跑一到线上就变黑盒我在项目里反复遇到的情况是本地调试时Agent 每一步都打印日志看起来一切正常一旦部署成服务日志被大量并发请求淹没出现问题时只能看到某次对话失败了但找不到是哪一步失败、调了哪个工具、模型当时收到了什么上下文。原因很简单——本地调试你面对的是一个进程线上你面对的是一个由 LLM 调用、工具执行、上下文管理、记忆检索组成的复杂流水线。这个流水线往往会横跨多个服务API 网关、Agent 编排服务、工具执行器、向量数据库、模型网关。任何一个环节出问题都可能让整个任务失败但失败的表现却五花八门工具抛异常、模型返回格式不对、上下文被截断、Token 超限、回调超时。1.2 Agent 流水线里到底藏了什么拆开看一个典型的 Agent 执行单元包含五个可观测节点LLM 调用节点模型选择、Prompt 组装、温度等参数、输入输出 Token 数、延迟和限流。工具调用节点工具选择逻辑、入参构造、执行耗时、返回结果大小、异常信息。上下文管理节点历史消息截断策略、重要信息摘要、缓存命中情况。记忆检索节点向量检索的 TopK、相似度阈值、召回内容质量。路由与决策节点Agent 选择哪个子任务、是否结束循环、是否切换模型。这五个节点之间还有强耦合——工具返回的结果会进入下一轮 LLM 调用的上下文记忆检索的内容会影响模型的决策上下文截断策略又决定了模型能不能看到关键信息。传统监控工具孤立地看每个节点的指标但 Agent 问题恰恰是跨节点的因果问题比如工具返回了一个超长 JSON导致下一轮 LLM 调用的上下文超限触发截断模型丢失关键信息最终决策错误。这种因果链条只有靠链路追踪才能完整还原。1.3 Token 成本不只是调一次 API 收费Token 成本核算是 Agent 可观测性里最容易低估的部分。很多人以为 Token 成本和调用次数成正比实际完全不是。同样一个业务操作在不同情况下 Token 消耗可能相差几十倍。比如一个工具返回了 12KB 的原始数据Agent 把它原封不动塞进下一轮 Prompt随后又做一轮摘要再把摘要塞回上下文——这个信息搬运过程会产生大量的输入 Token 重复计费。再比如重试机制模型输出格式不对导致重试一次Token 消耗直接翻倍。还有多 Agent 协同场景每个子 Agent 都要携带系统提示词和任务背景这些都属于每次调用都要付钱的固定开销。成本失控从来不是某一个 API 太贵而是整个链路上看不见的 Token 浪费太多。2.1 先想清楚要追踪什么Trace 是决策链不是调用链做分布式追踪第一件事不是选工具而是定义 Trace 的粒度。传统后端里一个 Trace 对应一次外部请求一个 Span 对应一次 RPC 或数据库访问层级清晰。Agent 场景下如果照搬这套你会发现所有 Span 都挂在同一个 HTTP 入口下根本看不出 Agent 的思考过程。我的做法是把一次完整的 Agent 执行从用户提问到最终回复定义为一个 Trace然后按照 Agent 的决策单元来划分 Span而不是按照系统调用划分。也就是说一个 Span 应该代表Agent 做了一次决策并执行了一个动作的完整闭环包括接收输入、调用模型、解析结果、执行工具、返回观察结果。这个闭环内部的子过程具体的 LLM HTTP 调用、工具 HTTP 请求作为 Span 的属性和事件记录而不是另起一层 Span。原因很简单排错时你最需要回答的是这一步为什么这么做而不是这一步调用了几次 HTTP。2.2 一个最小可落地的 Span 模型我在生产环境里用的 Span 结构大概是这样的核心字段用代码表示{ name: agent.step.execute, trace_id: 0a1b2c3d4e5f60718293a4b5c6d7e8f9, span_id: 1a2b3c4d5e6f7080, parent_span_id: 0a1b2c3d4e5f6000, agent_run_id: run_20250607_093012_abc123, start_time: 2025-06-07T09:30:12.123Z, end_time: 2025-06-07T09:30:15.456Z, attributes: { agent.id: customer_service_bot, agent.version: 2.1.0, step.index: 7, step.type: tool_call, step.name: query_order_status, llm.model: gpt-4o-mini, llm.input_tokens: 4820, llm.output_tokens: 156, llm.prompt_hash: sha256:9f2c8e6d..., tool.name: order_service.query, tool.input: {\order_id\:\SO-20240607-001\}, tool.result_size_bytes: 12480, tool.result_summary: 订单状态:已发货,物流单号:SF123456, context.window_tokens: 28100, context.max_tokens: 32000 }, events: [ {time: 2025-06-07T09:30:13.010Z, name: llm.response.received, attributes: {finish_reason: tool_calls}}, {time: 2025-06-07T09:30:14.220Z, name: tool.execution.started, attributes: {timeout_ms: 5000}} ] }这里有几个我特别想强调的设计agent_run_id 必须贯穿整个 Trace。一次用户会话可能包含多轮 Agent 执行如果只靠 trace_id你很难把同一会话里的多次执行关联起来看趋势。prompt_hash 是隐藏的排障利器。它可以帮助你快速判断这次奇怪的行为是不是因为 Prompt 变了两个 Trace 的 prompt_hash 不同优先怀疑 Prompt 版本问题。工具结果要双轨记录既要记录原始大小定位数据膨胀问题也要记录一个截断后的摘要方便人眼快速浏览。摘要字段控制在 200 字以内既直观又省存储。context.window_tokens 必填。定位上下文超限和截断导致模型变蠢时这个字段比什么都管用。2.3 用 run_id 把子 Agent 和多轮循环串成树实际项目中很少只有一个 Agent 单打独斗。常见的是编排 AgentOrchestrator调度多个子 Agent子 Agent 再调用工具形成一棵调用树。这里有个容易踩的坑子 Agent 可能是异步执行的也可能是独立进程/微服务如果不在链路上下文里显式传递标识Trace 就会在子 Agent 的边界断开。我的方案是依赖 W3C Trace Context 标准把 trace_id、parent_span_id 以及自定义的 agent_run_id 塞进子 Agent 调用的 Headers 或者消息队列的消息属性里。子 Agent 启动时接收这些参数作为自己 Trace 的根上下文。这样整个编排过程在 Jaeger 或者 Grafana Tempo 里就能呈现为一棵完整的树根节点是编排 Agent 的决策子节点是各个子 Agent 的执行叶子节点是工具调用和模型调用。排查哪个子 Agent 拖慢了整体或者哪个子 Agent 烧了最多 Token时直接从树上聚合就行。3.1 症状一Agent 在循环里出不来这是我遇到最多的问题也是最难靠打印日志定位的。现象是Agent 反复调用同一个工具输入参数几乎一致模型输出的内容也高度相似直到触发步数上限。光看业务日志你只能看到几十条调用工具 X的记录但不知道模型在每一步给自己传达了什么样的想法。正确的排查链路是打开该次执行的 Trace按时间排序发现step.type在llm_call和tool_call之间反复横跳且tool.name基本不变。对比相邻两个 Span 的llm.prompt_hash发现 hash 只差最后一段——因为工具返回结果每次都一样模型在下一轮看到的新信息其实没有变化。点开中间某个 Span 的events查看llm.response.received事件里的finish_reason和模型完整输出发现模型的 reasoning 里出现用户可能想知道更多细节我继续调用这类自洽话术。最终结论不是工具出错而是模型的停止条件失效——它认为每次获取一次新数据都算进展但数据根本没变化。这类问题的修复通常在业务层给循环加上严格的收敛判断比如连续两次工具返回的数据哈希相同就终止或者把判断是否继续的逻辑从纯模型决策改为模型建议 代码校验混合模式。但如果没有 Trace 数据你可能要花一整天抓日志去猜。3.2 症状二工具调用边说边做数据对不上另一种常见故障是Agent 在回复里声称自己调用了某个工具但实际没有调用或者调用了工具但入参和它声称的不一致。这类问题的隐蔽性很高因为单看 LLM 的回复文本一切正常单看工具日志也一切正常两者割裂后就找不到关系了。我曾经排查过一个典型案例客户反馈Agent 查天气时说室外温度 46 度明显不对。打开 Trace 后发现Agent 在步骤 3 调用了天气工具但tool.input里的城市参数被模型从北京改成了武汉——模型在生成工具入参时自行脑补了一个城市。更蹊跷的是步骤 2 的 LLM 调用里模型输出明明包含我要查询北京的天气的文本但紧接着的tool_call入参却是武汉。这属于典型的模型生成工具参数与自身表述脱节问题。如果没有把 LLM 的输出内容和工具的实际入参放在同一个 Span 里对比这个问题几乎没法定位。这类问题的经验是必须在 Span 里同时记录模型选择工具的决定包括原始文本和实际执行的入参包括 JSON 序列化后的完整值。两者不一致时不要怀疑是数据链路丢了大概率是模型本身的问题需要在 Prompt 工程或工具参数约束上解决。3.3 症状三Token 用量暴涨但找不到是哪一步现象是同一个功能昨天每次调用平均消耗 5 万 Token今天突然变成 20 万。业务上没有任何变更代码也没有发布新版本。用我下面会讲到的 Token 归因方法按agent_run_id聚合每个 Span 的llm.input_tokens很快发现暴涨集中在某个工具返回后。进一步查看tool.result_size_bytes和context.window_tokens发现该工具返回的数据量从昨天的 2KB 涨到了今天的 15KB——原因是上游服务有个字段从开关量变成了全量历史明细。数据被吞进 Agent 上下文后每一轮后续决策都要带着这 15KB 反复计费。一次 8 步的任务这 15KB 被重复计算了 8 次Token 消耗自然爆炸。这种问题如果你只看某次调用的 Token 数永远找不到根因因为单次调用并没有异常异常在跨步骤的重复计费上。4.1 成本的四个隐藏黑洞在讲归因方法之前先盘一下 Agent Token 成本为什么这么难核算。除了最直观的模型单价 x 调用次数还有四个隐藏因素上下文重放Context Replay每次 LLM 调用都要携带历史消息。一个步数为 N 的 Agent 执行总输入 Token 约等于历史消息长度与步数的乘积在常数级别上的增长。步骤越多重放开销越大呈二次增长趋势。工具返回吞没Tool Result Swallowing工具接口返回一个 10KB 的 JSONAgent 原样塞进上下文下一轮再用再下一轮还用直到被截断或摘要。这个反复搬运是输入 Token 的头号元凶。System Prompt 的隐性放大System Prompt 本身不大但它随每次调用都要带上。多 Agent 场景下每个子 Agent 都有一份几十上百行的系统提示词乘以调用次数就是一笔不小的固定成本。重试与幂等缺失模型输出格式不合法触发重试、外部工具失败后整步重来、网络超时导致重复提交。每一次重试都是完整 Token 消耗的翻倍。4.2 建立按 Trace 归因的成本模型传统的成本核算以API 调用为单位——每个接口记录 input/output token再乘以单价。这在单轮 Chat 场景够用但 Agent 场景必须把成本归因到业务操作路径上。否则你只知道某模型花了多少钱但不知道哪个功能、哪类用户、哪种任务模式在烧钱。我的做法分三步在每个 LLM Span 上记录 token 明细model、prompt_tokens、completion_tokens、cache_read_tokens、cache_creation_tokens如果厂商支持提示词缓存。把 Span 成本归属到 Trace 和业务路径。一个 Trace 代表一次端到端的业务操作Trace 上打上业务属性比如business_typeorder_query、user_tiervip、entry_pointapp。在报表层聚合按 Trace 聚合得到单次操作的全链路成本按业务类型聚合得到每类功能的成本占比按步骤聚合得到成本分布在哪一步。成本计算公式很简单我直接给出参考单位统一为美元汇率按账单结算折算Span 成本 (prompt_tokens * 输入单价 / 1M) (completion_tokens * 输出单价 / 1M) Trace 成本 sum(所有 LLM Span 的 Span 成本)注意如果厂商提供了提示词缓存Prompt Cachingcache_read_tokens一般按输入单价的约 1/10 计费prompt_tokens字段里要区分开未命中缓存的部分否则成本会被高估。不同厂商的缓存计费规则不一样建议在代码里用独立字段存放而不是在计算时猜。4.3 一个可执行的 Token 账单示例我整理过一份真实场景下的 Trace 级成本账单数值做过脱敏处理用来和团队对齐钱到底花在哪业务路径模型输入 Token输出 Token估算成本人民币占比用户提问 - 检索知识库 - 生成回复4 步主力模型 A128,4003,200约 2.68 元41%工具返回异常 - 重试 2 次主力模型 A45,6001,100约 0.94 元14%多 Agent 编排分析 - 计划 - 执行子任务主力模型 A 轻量模型 B220,3009,800约 4.12 元63%系统提示词 零散验证请求轻量模型 B18,9002,400约 0.19 元3%从这份账单能直接看出多 Agent 编排是成本大头工具重试次之而用户提问直接回答反而占比不高。如果你只按模型维度看账单你会得出主力模型 A 花了很多钱这个正确但毫无指导意义的结论。按业务路径归因后你才敢拍板说我们的多 Agent 编排设计过度了需要裁剪。5.1 方案矩阵链路采集与存储怎么选Agent 可观测性的基础设施本质上还是埋点 - 采集 - 存储 - 展示 - 告警这条链路。区别在于 Agent 场景的 Trace 具有三个特点单条 Trace 的 Span 数量多、Span 属性携带的文本和 JSON 体积大、Token 成本类属性需要单独索引。所以在选型时要围绕这三点来做。环节可选方案适用场景需要注意的问题埋点 SDKOpenTelemetry SDKPython/Node/Go 等标准场景语言覆盖广Agent 框架的自定义 Span 需要手动封装采集器OpenTelemetry Collector标准场景推荐注意 Payload 截断策略不要原样上报工具返回全文存储Jaeger / Grafana Tempo / ClickHouse开发或中小规模用 Jaeger/Tempo需要长周期成本分析的选 ClickHouseTempo 对 Trace 内嵌关键属性的查询支持需要额外配置展示Grafana / Jaeger UI可视化分析用 Trace 视图排查单次执行用表格聚合做成本趋势告警Prometheus Alertmanager指标类告警Token 成本告警要基于 Trace 聚合不是 Span 聚合我的建议是不要一开始就上全套大而全的平台。先用 OpenTelemetry SDK 把 Span 埋好采集到 Jaeger 或 Tempo够你肉眼排错了。当你开始频繁回答上周每种业务操作的平均成本是多少这类问题再考虑把 trace 数据同步到 ClickHouse 做 OLAP 分析。我之前就吃过亏一开始就建了 ClickHouse 数仓结果埋点数据质量太差花了大把时间清洗还是不如先把埋点做扎实。5.2 日志先行结构化的观测层兜底方案不是所有团队都有条件快速上全链路追踪。如果资源有限我的建议是先做一套结构化的观测层日志格式固定、字段完整后续接 Trace 时能无缝迁移。这套日志的 JSON Schema 我贴在下面已经按 Agent 场景踩过一遍坑{ timestamp: 2025-06-07T09:30:12.123Z, level: INFO, agent_run_id: run_20250607_093012_abc123, session_id: sess_8888, step_index: 7, step_type: tool_call, event: tool.execution.completed, llm_model: gpt-4o-mini, llm_input_tokens: 4820, llm_output_tokens: 156, tool_name: order_service.query, tool_duration_ms: 1200, tool_input_summary: order_idSO-20240607-001, tool_result_size: 12480, tool_result_status: success, context_tokens: 28100, error: null, metadata: { env: prod, agent_version: 2.1.0 } }这套日志的关键在于把模型层信息和工具层信息放在一条日志里而不是拆成两条。Agent 的因果链条是模型决定调工具 - 工具执行结束 - 结果回到模型如果你拆成两条日志中间会夹杂其他并发请求的日志排错时要把两条日志从一堆数据里配对痛苦不堪。合为一条后直接按agent_run_id和step_index排序就能完整复原每一步的决策和执行结果。这套日志我建议所有字段保持扁平避免嵌套层级过深。Elasticsearch 或 Loki 对扁平字段的索引和过滤都更友好。嵌套 JSON 在排错时写查询条件很别扭。5.3 让开发生效的最后一公里从 Trace 到告警埋点做好了Trace 也能查了但如果不配告警可观测性就只停留在出事能查层面。我个人认为Agent 项目上线后最该配的五类告警是单次执行步数超阈值比如正常任务最多 15 步配一个单次执行超过 25 步的告警大概率是循环失控。单次执行 Token 成本超阈值按业务路径分别设阈值防止某个功能悄悄变成烧钱黑洞。工具失败率突变Agent 对工具的结果信任度很高工具一旦开始失败Agent 行为会跟着螺旋变差。上下文窗口使用率过高比如context.window_tokens / max_tokens超过 85%说明截断风险极高模型可能在失忆状态下决策。模型返回格式异常率finish_reason不是预期的调用行为或 JSON 解析失败次数上升通常是底层模型升级或 Prompt 结构改动导致。告警渠道用常见的值班群就行关键是告警里要带上agent_run_id和 Trace 链接。这样收到告警的人点进去就能看到完整链路不需要再去日志系统里搜。我见过太多团队告警文案里只有Agent 异常四个字点开不知道查什么最后告警沦为背景噪音。真到了这一步我觉得 Agent 可观测性最值得记住的一句话是先解决可见性再谈优化和成本。我见过很多团队一上来就想着怎么把 Token 成本降一半结果连每个业务路径花了多少都不知道谈何优化。反过来把 Trace 埋点、成本归因、告警阈值这三件事踩实成本优化方案会自动浮现——因为数据会告诉你该裁哪个 Agent、该摘哪段工具返回、该给哪类重试加熔断。最后分享一个我个人很受益的小技巧给每条 Agent Trace 打上prompt_template_version和agent_framework_version两个 tag。Prompt 调优和框架升级是 Agent 项目里最频繁的变更这两个 tag 能让你快速回答一个灵魂拷问——这个行为变化是模型的问题还是我改了什么导致的 我自己靠这两个 tag 至少避免过十次无效争论。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

一种云端服务器与内网电脑之间实现磁盘映射的方法 2026/10/1 15:47:18

一种云端服务器与内网电脑之间实现磁盘映射的方法

WireGuard云端Ubuntu与本地Win11内网互通实战搭建文档 文章目录 WireGuard云端Ubuntu与本地Win11内网互通实战搭建文档 前言 一、实战目标 二、项目整体说明 三、云端Ubuntu服务端部署(最终成功版) 1. 安装WireGuard核心组件 2. 生成服务端公私钥(无报错干净密钥) 3. 开启内…

阅读更多 →
新能源车新车发布和车型信息去哪里看 2026/10/1 15:47:18

新能源车新车发布和车型信息去哪里看

新能源车新车发布和车型信息去哪里看? 新能源车的新车信息要拆成两件事:「发布动态」看报道层——哪天发布、预售价多少、官方怎么说;「车型信息」看核对层——续航、电池、智驾硬件的准确规格。前者可以用每日电车(https://carda…

阅读更多 →
2032全球高温滤料28.77亿美元,特种过滤耗材赛道平稳扩容 2026/10/1 15:47:18

2032全球高温滤料28.77亿美元,特种过滤耗材赛道平稳扩容

高温滤料是相较常规常温滤料具备更高耐温性能的特种过滤耗材,主流基材包含 PPS 聚苯硫醚、Nomex 芳香族聚酰胺、P84 聚酰亚胺、PTFE 聚四氟乙烯、玻璃纤维、PSA 芳砜纶等纤维材料,广泛应用于烟气除尘、工业尾气净化等工况场景。 根据调研数据测算&#x…

阅读更多 →
Everything 下载安装教程:装完先确认索引了什么 2026/10/1 15:47:17

Everything 下载安装教程:装完先确认索引了什么

Everything 是一个 Windows 上的文件名搜索工具。它的特点只有一个字:快——打开软件就能在输入框里搜,边打边出结果,几万个文件的筛选几乎是瞬时的。 快的原因在它的做法上:它不去一个个翻文件夹,而是直接读 NTFS 文…

阅读更多 →
企业微信SCRM收费标准:2026主流SCRM服务商价格对比全公开 2026/10/1 15:47:16

企业微信SCRM收费标准:2026主流SCRM服务商价格对比全公开

企业微信自带的基础客户管理功能可以免费使用,但仅能完成简单的客户添加、基础标签、内部沟通,无法满足私域精细化运营、销售过程管控、合规聊天存档等业务需求。企业想要做规模化私域运营,就要采购第三方SCRM服务商产品。市面上服务商报价参…

阅读更多 →
为什么 MR 头显必须把合成放在 GPU 最后一级:TimeWarp 与 late-latch 的工程取舍 2026/10/1 15:47:04

为什么 MR 头显必须把合成放在 GPU 最后一级:TimeWarp 与 late-latch 的工程取舍

为什么 MR 头显必须把合成放在 GPU 最后一级:TimeWarp 与 late-latch 的工程取舍 摘要:在 90Hz 的 MR 一体机上,从应用提交一帧到光子出屏还要走 ~16ms,这段时间里头部仍在转动。如果合成发生在应用渲染的同一帧,屏幕上…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉