
1. 为什么 LLM 应用上线后运维反而更难了做过传统后端服务的同学应该都有体会服务上线之后看 CPU、内存、QPS、P99 延迟、错误率这几条曲线基本就能判断系统健不健康。但换成 LLM 应用或者 AI Agent这套经验会突然失灵——CPU 很平稳内存也没爆接口成功率 100%可用户就是在骂“答非所问”“胡编乱造”“上一轮说的话下一轮就忘了”。你盯着监控大盘什么都看不出来。这就是我最近半年做 AgentOps 相关工作时最深的感受。LLM 与 AI Agent 的可观测性和传统微服务的可观测性根本不是一个东西。传统服务是确定性的同样的输入走同样的代码路径得到同样的输出。而 LLM 应用是概率性的同一个 prompt温度参数稍微一动输出就飘了Agent 更麻烦它会在一次任务里连续调用多个工具、多轮推理中间任何一步跑偏最终结果就崩了但每一步单独看又都是“成功”的。所以这篇文章想聊的是我基于观测云搭建一套AgentOps 运维体系的完整实践。核心目标很明确把 LLM 调用和 Agent 执行链路里那些“看不见的东西”变成可观测的指标、日志和链路数据让“答得不好”这件事也能被量化、被定位、被复盘。适合正在做 AI Agent 开发、LLM 应用落地、或者被线上效果问题折磨的工程师和运维同学参考。哪怕你只是用大模型 API 做了个小工具这套思路也能帮你少踩很多坑。在展开之前先把几个概念对齐一下避免后面混淆。LLM就是大语言模型负责“理解和生成”AI Agent是在 LLM 之上加了一层“规划 工具调用 记忆”的调度逻辑让它能自主完成多步任务AgentOps则是把 DevOps 那套“开发—部署—监控—迭代”的闭环搬到 Agent 的生命周期管理上。而可观测在这里的含义比传统监控更宽——不只是“系统有没有挂”而是“模型答得好不好、Agent 决策对不对、成本花在哪、有没有泄露风险”。2. AgentOps 可观测体系到底要观测什么2.1 传统监控和 LLM 可观测的本质差异我一开始也想过偷懒直接把 LLM 服务当成普通 HTTP 服务接进现有的 APM 里。结果发现完全不够用。传统 APM 关心的是“请求—响应”这条链路而 LLM 应用真正要关心的是“语义链路”。举个具体的例子用户问“帮我查一下上个月的订单并生成报表”Agent 会先做意图识别再调用订单查询工具拿到数据后调用报表生成工具最后用 LLM 组织语言返回。这条链路里工具调用是确定性的但意图识别和最终生成是概率性的。如果只看接口成功率工具调用全成功接口也返回 200但用户拿到的报表可能是错的——因为意图识别把“上个月”理解成了“上季度”。这种问题在传统监控里是隐形的。所以 LLM 可观测必须额外采集几类数据prompt 和 completion 的原文脱敏后、token 消耗、模型版本、温度等采样参数、工具调用的入参出参、以及每一轮的推理耗时。只有把这些都串起来你才能回答“这次回答为什么不对”这种问题。2.2 AgentOps 的四层观测模型踩了不少坑之后我总结出一套四层观测模型从下往上分别是基础设施层容器、节点、网络、GPU 利用率。这层和传统运维一样用观测云的主机监控和容器监控就能覆盖。模型调用层每次 LLM 请求的延迟、token 数、成本、错误码、限流情况。这是 LLM 应用最烧钱也最容易出问题的地方。Agent 编排层一次任务里有多少轮推理、调用了哪些工具、每步的耗时和结果、有没有死循环或超步数。业务效果层回答质量评分、用户反馈、任务完成率、幻觉率。这层最难量化但价值最高。这四层不是孤立的而是通过一个统一的trace_id串起来。用户发起一次请求从网关进来就生成一个 trace_id一路透传到 LLM 调用和工具调用最后在观测云里能按这个 id 把整条链路还原出来。这个设计是整个体系的地基后面所有分析都依赖它。2.3 为什么选观测云而不是自己拼开源栈市面上可观测方案很多自己用开源组件拼一套也能做。我评估过几种路线最后选观测云主要基于几个现实考量。第一是接入成本观测云对 OpenTelemetry 协议支持比较完整LLM 应用里常用的 Python、Java 生态都能直接对接不用自己写一堆 exporter。第二是数据关联能力它能把指标、日志、链路三种数据在同一个平台里关联查询这对排查 Agent 这种跨多组件的链路特别关键。第三是成本和运维负担自建 ELK Prometheus Jaeger 这套光是维护存储和查询性能就够喝一壶的团队小的话不划算。当然这不是说自建不行。如果你的数据合规要求极高、必须全内网闭环那自建是唯一选择。但对大多数中小团队来说用成熟平台把精力省下来做业务是更务实的决定。下面讲的实践思路是通用的你换成其他支持 OpenTelemetry 的平台也能落地。3. 基于观测云搭建 AgentOps 的实操落地3.1 数据采集从埋点到统一 trace落地第一步是数据采集。我的做法是在 Agent 框架的关键节点埋点统一走 OpenTelemetry SDK。具体来说一次完整的 Agent 执行会生成一个根 span下面挂若干子 spanLLM 调用一个 span每次工具调用一个 span记忆检索一个 span。每个 span 上打上关键属性比如模型名、token 数、工具名、耗时。这里有个实操细节值得强调LLM 的 prompt 和 completion 内容默认不要全量上报。一是数据量大二是可能包含敏感信息。我的做法是只上报长度、hash 值和脱敏后的摘要原文按需采样上报比如只对报错的请求或者被标记为“低质量”的请求保留原文。这样既控制了成本又保证了排查时能拿到关键样本。from opentelemetry import trace tracer trace.get_tracer(agent.ops) def call_llm(prompt, model, temperature): with tracer.start_as_current_span(llm.call) as span: span.set_attribute(llm.model, model) span.set_attribute(llm.temperature, temperature) span.set_attribute(llm.prompt_length, len(prompt)) span.set_attribute(llm.prompt_hash, hash_prompt(prompt)) resp llm_client.invoke(prompt) span.set_attribute(llm.completion_length, len(resp.text)) span.set_attribute(llm.token_usage, resp.usage.total_tokens) return resp上面这段是简化后的埋点示例核心思想是每个关键操作都包一个 span并把能反映“这次调用特征”的属性打上去。这些属性后面就是你在观测云里做筛选、聚合、告警的依据。3.2 关键指标设计别只盯着延迟和错误率埋点做完接下来是设计指标。我列一下实际在用的核心指标分几类指标类别具体指标观测目的性能LLM 首 token 延迟、总延迟、工具调用耗时定位慢在哪一步成本单次请求 token 数、按模型/租户的 token 消耗控制成本、发现异常调用质量重试率、截断率、空回复率、格式错误率间接反映回答质量稳定性限流次数、超时次数、工具失败率发现依赖问题Agent 特征平均推理轮数、工具调用次数、超步数终止率发现 Agent 逻辑异常这里面我特别想说的是**“平均推理轮数”和“超步数终止率”**。这两个指标是 Agent 特有的。正常情况下一个任务可能 3 到 5 轮推理就完成了如果某天平均轮数突然涨到 15那大概率是 Agent 陷入了某种循环或者某个工具返回的结果让它一直重试。这种问题在传统指标里完全看不出来但会直接导致成本飙升和响应变慢。3.3 链路追踪把一次 Agent 任务完整还原指标告诉你“哪里不对”链路追踪告诉你“为什么不对”。观测云的链路查询能把一次 Agent 任务的完整调用树展示出来。我实际排查过一个案例用户反馈“生成报告很慢”。看指标P99 延迟确实高。点进链路一看发现一次任务里 LLM 被调用了 11 次其中 8 次是在反复调用同一个“数据校验”工具。原因是工具返回的格式和 Agent 预期的不一致Agent 就一直重试。这个问题的根因不在 LLM而在工具契约设计。如果没有链路追踪你只会看到“慢”根本不知道慢在反复重试上。所以我的经验是Agent 的每一次工具调用都必须有独立的 span并且把工具的入参出参摘要打上去。这样链路一展开哪一步在空转一目了然。3.4 告警策略从“系统挂了”到“效果变差了”告警这块传统做法是配阈值比如错误率超过 5% 就报警。但 LLM 应用里很多问题不是“挂”而是“悄悄变差”。我配了几类特色告警成本突增告警单位时间 token 消耗环比涨 50% 就触发防止死循环烧钱。质量下滑告警重试率或格式错误率连续 10 分钟高于基线就触发。模型切换告警当模型版本发生变化时通知因为换模型往往会导致效果波动。超步数告警Agent 因达到最大步数而终止的比例升高时触发。提示告警阈值不要拍脑袋定先跑一周收集基线数据再基于 P95 或 P99 来设。我一开始把重试率阈值设成 3%结果天天误报后来改成基于历史基线的动态阈值才稳定下来。4. 踩过的坑与常见问题排查4.1 数据量爆炸全量上报 prompt 的代价最开始我图省事把所有 prompt 和 completion 原文都上报了。结果一周不到日志存储就告急查询也变慢。后来改成分层采样正常请求只上报元数据异常请求和随机 1% 的样本上报原文。这样既保住了排查能力又把数据量压下来 90% 以上。这个坑很典型凡是做 LLM 可观测的几乎都会遇到。4.2 敏感信息泄露密钥和用户数据混进日志这是最危险的一类问题。LLM 应用的 prompt 里经常夹带 API key、用户手机号、内部文档内容。如果原样上报等于把敏感信息写进了日志系统。我的做法是在埋点层加一道脱敏过滤器用正则匹配常见的密钥格式、手机号、身份证号命中就替换成占位符。同时工具调用的鉴权信息绝对不能进 span 属性。这件事必须在采集端做不能指望事后清理。4.3 排查速查表下面这张表是我实际排查时最常用的对照表遇到问题先按这个思路走现象可能原因排查入口响应突然变慢LLM 限流、工具超时、Agent 循环看链路里哪个 span 耗时最长成本突然升高死循环、prompt 变长、模型被换看 token 消耗趋势和推理轮数回答质量下降模型版本变化、prompt 被改、上下文截断对比模型版本和 prompt hash工具频繁失败工具契约变更、鉴权过期看工具 span 的错误率和错误码部分用户报错租户级限流、特定输入触发按租户维度筛选链路4.4 几个容易被忽略的实操心得第一trace_id 一定要透传到工具侧。很多工具是独立服务如果不在调用时把 trace_id 传过去工具内部的日志就没法和主链路关联排查时会断链。第二给 Agent 设最大步数和最大 token 预算并在达到上限时上报一个明确的终止原因否则你永远不知道任务是被“正常完成”还是“被迫中断”。第三定期做效果回归把线上采样的问题样本沉淀成测试集每次改 prompt 或换模型都跑一遍这比事后救火有用得多。5. 从可观测到可运营让数据反哺迭代5.1 用观测数据驱动 prompt 和工具优化可观测体系搭好之后最大的价值不是“出事能查”而是“平时能优化”。我现在的习惯是每周看一次观测数据重点看三类高频失败的工具调用、重试率高的 prompt、token 消耗异常的租户。这些数据直接指导下一轮的 prompt 调整和工具重构。比如发现某个工具的错误率一直偏高就去检查它的返回格式是不是和 Agent 的预期不匹配改完之后重试率立刻降下来。5.2 建立 Agent 的效果基线没有基线就没法判断“变好还是变坏”。我的做法是给每个 Agent 建立一套基线指标平均推理轮数、平均 token 消耗、任务完成率、重试率。每次发版前后对比这些基线波动超过阈值就回滚。这套机制让 Agent 的迭代从“凭感觉”变成了“看数据”团队协作时也少了很多扯皮。5.3 后续可以扩展的方向这套体系目前覆盖了单 Agent 的观测接下来我打算往两个方向扩展。一是多 Agent 协作场景多个 Agent 互相调用时链路会更复杂需要把 trace 的父子关系设计得更清晰。二是把效果评估自动化用另一个 LLM 做裁判对采样样本自动打分把“质量”这个最难量化的指标也纳入监控。这两块我还在摸索等跑通了再单独写一篇。最后分享一个我踩坑踩出来的小经验可观测体系不要一次做全先解决“能看见”的问题再解决“看得懂”的问题。我一开始想一步到位把所有指标和告警都配齐结果埋点写了一堆真正用上的没几个。后来改成先埋最核心的 LLM 调用和工具调用跑起来之后再根据实际排查需求逐步补充反而效率高得多。AgentOps 这件事本质上和做业务一样先跑通闭环再谈精细化。