1. 从跑通Demo到敢上生产AgentOps到底卡在哪大模型应用这两年最魔幻的地方在于Demo阶段惊艳全场上线之后一地鸡毛。我自己带过几个AI Agent项目从最开始的单轮问答到后来的多工具编排、多智能体协作几乎每一个都经历过同一个阶段本地跑得好好的一放到真实流量里就开始出各种玄学问题——回答突然变慢、工具调用莫名其妙失败、同一个问题两次回答完全不一样、Token消耗像脱缰的野马。这些问题的共同点是传统监控体系根本看不见它们。你拿APM去看一个Agent服务CPU、内存、QPS、错误率全都正常但用户就是在骂街。因为Agent的健康不在系统层而在推理链路层——Prompt怎么拼的、检索召回了什么、工具调了几次、模型返回了什么、Token烧了多少、这一步为什么走了这条分支。这就是AgentOps要解决的问题。AgentOps可以理解为面向AI Agent的运维体系它把LLM调用、工具执行、检索增强、多智能体协作这些环节全部纳入可观测范围让一个Agent的每一次决策过程都能被追踪、被回放、被量化。而观测云这类平台恰好提供了承载这套体系的底座统一的指标、日志、链路追踪、事件告警再加上对LLM语义数据的原生支持。这篇文章不讲概念科普我想把从0到1搭一套AgentOps体系的完整思路拆开讲——包括埋什么点、怎么埋、数据怎么组织、告警怎么设、踩过哪些坑。适合已经跑通过Agent Demo、准备往生产推的开发者也适合正在做企业级AI应用平台、需要给上层业务提供可观测能力的平台团队。2. 先想清楚Agent的可观测对象和传统服务完全不是一回事2.1 传统APM的三个盲区在动手埋点之前必须先把认知掰过来。传统APM监控的是请求-响应这个黑盒它关心的是延迟、错误、吞吐。但Agent的执行过程是一个有状态的、多步的、带决策的链路传统APM至少有三个盲区第一个盲区是语义盲区。一个HTTP 200的响应在APM里是成功的但内容可能是模型胡编的、答非所问的、或者触发了安全策略被截断的。系统层看不到回答质量。第二个盲区是链路盲区。一次用户提问背后可能是意图识别 → 检索知识库 → 重排 → 拼Prompt → 调LLM → 解析工具调用 → 执行工具 → 再调LLM → 生成最终答案。这中间任何一步出问题APM只会告诉你这个请求耗时3秒但不会告诉你3秒里哪一步占了2.8秒。第三个盲区是成本盲区。LLM调用是按Token计费的一个Agent如果陷入工具调用循环可能一次请求烧掉几万Token。传统监控里这只是一次普通的函数调用账单出来才知道疼。2.2 AgentOps要观测的四类数据想清楚盲区之后AgentOps的观测对象就清晰了。我一般把它分成四类数据类型具体内容用途Trace链路一次Agent执行的完整Span树含每步输入输出问题定位、回放Metric指标延迟、Token数、工具调用次数、成功率趋势监控、容量规划Log日志Prompt原文、模型原始返回、异常堆栈深度排查Event事件工具失败、超时、内容拦截、成本超阈值实时告警这四类数据在观测云里对应不同的数据类型但关键是它们要能通过同一个Trace ID串起来。否则你看到指标异常却找不到对应的日志排查效率会大打折扣。2.3 一个反直觉的结论不是埋得越多越好新手容易犯的错是全埋。Prompt全文、模型完整返回、每一次检索的Top100文档全都塞进可观测平台。结果就是存储成本爆炸、查询慢如蜗牛、真正有用的信号被淹没。我的经验是分层埋点核心链路LLM调用、工具执行全量埋中间数据检索结果、重排分数采样埋原始大文本完整Prompt、完整文档只在异常时落盘。这个策略后面会详细讲怎么落地。3. 埋点设计把一次Agent执行拆成可追踪的Span树3.1 Span的粒度怎么定埋点的第一步是确定Span的粒度。Span太粗定位不到问题Span太细链路图变成毛线团。我一般按一次有意义的决策或一次外部调用来切分用户请求入口一个Root Span意图识别/路由一个Span每次检索向量检索、关键词检索各一个Span重排一个Span每次LLM调用一个Span这是最关键的每次工具调用一个Span多智能体之间的消息传递一个Span这样一次典型的RAG Agent执行大概会产生8-15个Span。这个粒度既能看清全貌又不会太碎。3.2 每个Span必须带的属性Span光有名字没用必须带足够的属性才能支撑后续分析。以LLM调用Span为例我固定会带这些字段span.set_attribute(llm.provider, openai) # 或 anthropic / 本地模型 span.set_attribute(llm.model, gpt-4o) span.set_attribute(llm.request.type, chat) span.set_attribute(llm.prompt.tokens, prompt_tokens) span.set_attribute(llm.completion.tokens, completion_tokens) span.set_attribute(llm.total.tokens, total_tokens) span.set_attribute(llm.latency.ms, latency) span.set_attribute(llm.finish_reason, finish_reason) # stop / length / tool_calls span.set_attribute(llm.temperature, temperature) span.set_attribute(llm.stream, is_stream) span.set_attribute(agent.step, step_index) # 第几步 span.set_attribute(agent.session_id, session_id)工具调用Span则带span.set_attribute(tool.name, search_knowledge_base) span.set_attribute(tool.input.size, len(json.dumps(tool_input))) span.set_attribute(tool.success, success) span.set_attribute(tool.retry.count, retry_count) span.set_attribute(tool.latency.ms, latency)这些字段看起来琐碎但它们是后面做聚合分析的基础。比如你想知道哪个工具最容易失败直接按tool.name分组统计tool.successfalse就行。3.3 Trace ID的透传是生命线这里有个特别容易踩的坑Trace ID在异步和流式场景下会断。Agent大量使用异步调用和流式输出如果不在每个异步任务、每个回调里显式传递上下文Span就会变成孤儿链路图直接断掉。我的做法是在请求入口生成一个session_id和trace_id然后通过上下文变量Python里用contextvarsJava里用ThreadLocal或Reactor的Context一路透传。流式场景下每个chunk的处理都要带上这个上下文。观测云的SDK支持OpenTelemetry标准用标准的Context传播机制就能解决。提示如果你的Agent用了消息队列做异步编排记得把Trace上下文塞进消息头里消费端再还原出来。否则跨服务的链路会断成两截。3.4 采样策略别让可观测拖垮生产全量埋点的成本在流量上来之后会非常吓人。我的采样策略是分层的错误全采任何Span标记为error100%上报慢请求全采超过P95延迟的请求100%上报正常请求采样按5%-10%采样大文本按需Prompt全文、检索文档只在错误或慢请求时落盘这个策略在观测云里可以通过SDK的采样器配置也可以在后端用处理规则实现。实测下来存储成本能降70%以上但排查问题时该有的数据一个不少。4. 指标体系建设从Token账单到Agent健康度4.1 四层指标体系埋点数据上来之后要把它组织成有意义的指标。我一般分四层第一层资源层。LLM调用的QPS、延迟分布、错误率、Token消耗速率。这层最接近传统监控用来判断系统是否健康。第二层链路层。单次Agent执行的平均Span数、平均步数、工具调用次数分布、检索命中率。这层用来判断Agent的执行效率。第三层质量层。回答采纳率、用户追问率、工具调用成功率、内容拦截率。这层需要业务侧配合埋点但价值最高。第四层成本层。单次请求平均Token成本、单用户日均成本、按模型/按工具的成本拆分。这层直接关系到能不能活下去。4.2 几个必须盯的核心指标指标不用多但有几个是必须盯死的指标计算方式告警阈值建议LLM调用P99延迟按model分组统计 10s 告警单请求Token数total_tokens的P95 阈值 告警工具调用失败率fail/total 5% 告警Agent步数异常单请求Span数P99 20步 告警空回答率回答长度为0的占比 2% 告警循环检测同一工具连续调用3次立即告警其中循环检测这个指标特别重要。Agent陷入工具调用死循环是生产环境最常见的故障之一一次循环可能烧掉几十万Token。我的做法是在Agent执行器里加一个计数器同一个工具连续调用超过3次就强制中断并上报事件。4.3 Token成本的可视化拆分Token成本这块光看总数没用必须能拆。我一般按三个维度拆按模型拆GPT-4o和本地小模型的成本差几十倍要能看出各自占比按Agent拆哪个Agent最烧钱按用户/租户拆如果是SaaS要能定位到具体客户观测云的自定义指标能力可以支持这种多维拆分。关键是在埋点时就把这些维度作为Tag打进去后面聚合才方便。4.4 用仪表盘把Agent健康度讲清楚指标最终要落到仪表盘上。我给团队做的Agent健康度大盘固定包含这几块顶部是总览卡片今日请求数、成功率、平均延迟、总Token消耗、预估成本。中间是趋势图延迟P50/P95/P99、Token消耗趋势、错误率趋势。下面是明细表Top10慢请求、Top10高Token请求、工具失败排行。这个大盘每天早上团队站会看一眼基本能判断昨天Agent跑得怎么样。有异常直接点进去看Trace效率比翻日志高太多。5. 告警与根因定位让问题在用户投诉前暴露5.1 告警规则怎么设才不扰民告警设得太松天天响团队会麻木设得太紧真出事了没反应。我的经验是分级告警P0立即处理LLM调用失败率10%、Agent循环检测触发、成本突增300%P11小时内处理P99延迟10s、工具失败率5%、空回答率2%P2当天处理Token消耗环比增长50%、检索命中率下降P0告警直接打电话P1发群消息P2进日报。这样既不会漏掉严重问题也不会被噪音淹没。5.2 从告警到根因的排查链路告警响了之后排查路径要清晰。我总结的链路是告警 → 指标下钻 → Trace定位 → 日志确认 → 修复验证。举个例子告警说LLM调用P99延迟突增。第一步在仪表盘上按model分组看发现是某个特定模型的问题。第二步点进慢请求的Trace发现是Prompt特别长检索召回了太多文档。第三步看检索Span的日志发现是某个查询触发了全量扫描。第四步修复检索逻辑加过滤条件。第五步观察指标恢复。这条链路能跑通的前提是前面埋点和指标都做到位了。所以AgentOps是个系统工程不能指望某一个环节解决所有问题。5.3 一个真实的排查案例说个我印象最深的。有段时间用户反馈Agent有时候答非所问但监控指标全都正常。后来我们在质量层加了一个回答与问题相关性的采样评估才发现问题出在检索环节某些查询的向量检索返回了完全不相关的文档但重排分数却很高导致模型基于错误上下文生成答案。这个问题的根因是重排模型的输入格式和训练时不一致。如果没有链路级的可观测这种问题几乎不可能定位——因为从系统层看一切正常。注意Agent的很多问题不是错误而是错误的内容。所以质量层的可观测不能省哪怕它需要额外的评估成本。5.4 告警的降噪与聚合生产环境告警多了之后必须做聚合。比如一次模型服务抖动可能瞬间产生几百条告警。观测云支持告警聚合和抑制规则我的配置是同一根因的告警5分钟内合并为一条关联告警如延迟高和超时多合并展示。这样团队收到的告警数量能降一个数量级但关键信息不丢。6. 落地过程中的坑我踩过的五个真实教训6.1 坑一Prompt里带了敏感信息早期我们图省事把完整Prompt直接上报到可观测平台。结果有一次排查问题时发现Prompt里包含了用户的手机号、订单号甚至有一次带上了内部API的鉴权头。这是严重的安全隐患。修复方案是上报前脱敏在SDK层加一个过滤器对Prompt和模型返回做正则替换把手机号、身份证、邮箱、密钥模式全部打码。观测云支持在数据接入时配置处理规则但更稳妥的做法是在客户端就脱敏避免敏感数据出网。6.2 坑二流式响应的Span收尾时机流式输出场景下Span什么时候结束是个问题。如果等第一个chunk就结束那延迟数据完全不准如果等最后一个chunk那中间如果连接断了Span可能永远不结束。我的做法是Span在收到第一个chunk时记录first_token_latency在流结束时记录total_latency并设置一个超时兜底比如60秒无数据就强制结束Span并标记异常。这样两个延迟指标都能拿到也不会出现悬挂Span。6.3 坑三多智能体协作的链路爆炸多智能体场景下Agent之间互相调用Span树会变得非常深。如果不加控制一次请求可能产生上百个Span链路图根本没法看。我的处理方式是分层聚合单个Agent内部的Span保持细粒度Agent之间的调用用一个协作Span包起来只记录关键信息发起方、接收方、消息摘要、耗时。这样链路图保持在可读的层级。6.4 坑四指标基数爆炸给Span打Tag的时候如果不小心把高基数的字段比如用户ID、请求ID打成Tag指标基数会爆炸查询直接卡死。我踩过一次把session_id打成了指标Tag结果一天产生了几百万个时间序列。教训是高基数维度只放在Trace里不要放进Metric。指标Tag只保留低基数的枚举值比如model、tool_name、status。6.5 坑五可观测本身的性能开销埋点是有成本的。SDK的序列化、网络上报、上下文切换都会占用资源。我们早期用同步上报结果Agent的延迟被拉高了15%。后来改成异步批量上报Span先在内存缓冲攒够一批或到时间窗口再统一发送。同时把上报线程和业务线程隔离避免互相影响。改完之后开销降到3%以内基本可以接受。7. 从单Agent到多智能体可观测体系的扩展思路7.1 单Agent时代的观测重点单Agent场景相对简单观测重点在LLM调用质量和工具执行可靠性。这时候指标体系可以轻一点Trace粒度可以细一点因为Span总数不多。7.2 多智能体带来的新挑战多智能体一上来问题就复杂了。首先是链路变长一次任务可能经过五六个Agent接力其次是状态难追踪每个Agent有自己的上下文出问题时不知道是哪个环节传错了最后是成本难归因一个任务烧的钱要分摊到多个Agent上。我的应对策略是引入任务级Trace在任务入口生成一个task_id所有参与的Agent的Span都挂在这个task下。同时给每个Agent的输入输出做摘要记录这样即使链路很长也能快速看出信息在哪一步失真了。7.3 协作质量的可观测多智能体最怕的是互相甩锅——A说B给的信息不对B说A的指令不清。要解决这个需要在Agent之间的消息传递上加观测记录消息的原始内容、接收方的解析结果、是否触发重试。我一般会统计几个协作指标消息传递成功率、消息解析失败率、协作轮次分布、任务完成率。这些指标能反映多智能体系统的整体健康度。7.4 面向未来的扩展评估与反馈闭环AgentOps的终极形态不只是看还要能评和改。我现在在做的方向是把可观测数据和评估体系打通线上采样的Trace自动进入评估队列用LLM-as-Judge或人工标注打分评估结果反哺到Prompt优化和模型选型。这个闭环一旦跑通Agent的迭代速度会快很多——因为你知道改哪里、改完有没有效果而不是凭感觉调Prompt。8. 一些实操层面的经验补充8.1 工具选型的取舍可观测平台的选择上我倾向于用统一平台而不是拼凑多个工具。原因是Agent的数据关联性太强Trace、Metric、Log、Event必须能互相跳转。如果分散在四个系统里排查一次问题要开四个页面效率极低。观测云这类一体化平台的优势就在这里。SDK层面优先选支持OpenTelemetry标准的这样将来换平台成本低。LLM调用这块Langfuse、Phoenix这类专用工具也可以作为补充但核心链路还是建议走统一的可观测体系。8.2 团队协作的约定AgentOps落地不只是技术问题还是协作问题。我们团队有几个约定所有新增Agent必须接入埋点SDK才能上线所有P0告警必须有明确的on-call负责人每周复盘一次告警和慢请求把共性问题沉淀成规则。这些约定看起来琐碎但能保证可观测体系不会随着项目推进而荒废。8.3 成本控制的几个小技巧最后分享几个控制可观测成本的小技巧一是用列式存储存Trace压缩率高二是对历史数据做分级存储7天内热存30天后转冷三是定期清理无用的Tag和指标避免基数膨胀四是采样策略动态调整流量高峰期降采样率。这些技巧单独看都是小优化但叠加起来能把可观测成本压到总成本的5%以内对于要长期跑的Agent系统来说很关键。我在实际项目里最深的一个体会是AgentOps不是上线之后才考虑的事而是从设计Agent架构时就要一起想。埋点、Trace透传、指标定义这些东西后期补的代价远大于前期设计。所以如果你现在正在从0到1搭Agent建议把可观测当成一等公民来对待而不是等出问题了再回头补。
