1. 为什么 LLM 应用上线后反而更让人睡不着觉做过传统后端服务的同学大概都有个共识接口上线之后只要 CPU、内存、QPS、错误率这几条曲线不飘晚上基本能睡个安稳觉。但换成 LLM 应用和 AI Agent这套经验基本失效。我身边不少团队都遇到过类似场景——服务监控面板一片绿用户却在群里反馈“答非所问”“卡住不动”“同一个问题昨天能答今天不行”。你去翻日志只有一条孤零零的 HTTP 200耗时 8 秒看不出任何异常。这就是 LLM 与 AI Agent 可观测性要解决的核心问题。传统 APM 关注的是“请求是否成功、耗时多少”而 AgentOps 关注的是“这次推理到底经历了什么、模型为什么这么答、工具调用有没有跑偏、Token 花在哪了”。观测云这类平台之所以被拿来做 AgentOps 底座是因为它本身具备指标、日志、链路、事件一体化的能力能把 LLM 调用这种“黑盒”拆成可追踪的链路。这篇文章面向的是已经在做或准备做 AI Agent 落地的工程师包括后端、算法、SRE 和平台团队。我会从整体设计思路讲到具体埋点、指标设计、链路追踪、告警配置再到踩过的坑尽量给出一套可以直接抄作业的 AgentOps 运维体系。文中涉及观测云的具体配置我会说明是基于常见实践的合理方案实际字段名以你所用版本为准。2. AgentOps 体系整体设计与选型思路2.1 先搞清楚 AgentOps 和传统 APM 的边界很多人一上来就想把 LLM 调用塞进现有的 APM 里结果发现数据模型根本对不上。传统 APM 的 Trace 是“服务 A 调服务 B 调数据库”层级浅、语义明确。而一个 AI Agent 的一次任务可能是这样的结构用户输入 → 意图识别 → 规划Planner→ 多次工具调用 → 多次 LLM 推理 → 结果聚合 → 输出。中间还可能嵌套子 Agent形成树状甚至图状结构。所以 AgentOps 的数据模型至少要覆盖四层会话层Session一次完整的人机交互可能包含多轮对话。任务层Task/RunAgent 为完成某个目标执行的一次完整流程。步骤层Step规划、推理、工具调用、反思等单个动作。调用层Call具体的一次 LLM 请求或一次工具 API 请求。这四层如果用传统 APM 的父子 Span 硬套会非常别扭。观测云支持自定义 Trace 结构和 Span 属性这是它能做 AgentOps 底座的关键。我的建议是会话和任务用 Trace 表示步骤和调用用 Span 表示LLM 特有的字段模型名、Token 数、温度、Prompt 版本作为 Span 属性挂上去。2.2 为什么选观测云而不是自己搭一套自己搭一套可观测体系不是不行但成本主要在三个地方数据存储、查询性能和告警联动。LLM 调用产生的数据量比普通接口大得多一次推理的 Prompt 加 Completion 动辄几千 Token如果全量存日志存储成本会迅速失控。观测云的优势在于它把指标、日志、链路、用户访问、事件放在同一个数据平台里可以用同一套查询语言做关联分析。比如你想查“某个 Prompt 版本上线后Token 消耗和错误率的变化”在割裂的系统里要跨三个平台导数据在观测云里就是一条查询的事。另外它的告警支持多条件组合这对 AgentOps 很关键——单纯“错误率超过 5%”没意义因为 LLM 的“错误”很多时候是语义层面的需要结合业务指标判断。选型时我建议重点看三个能力是否支持自定义 Span 属性、是否支持高基数标签查询、是否能做基于日志内容的告警。这三点决定了你能不能把 Agent 的行为观测清楚。2.3 数据采集的三种方式与取舍采集 LLM 调用数据常见有三种方式各有适用场景采集方式实现位置优点缺点适用场景SDK 埋点应用代码内字段最全、可控性高侵入代码、需维护核心业务链路网关代理API 网关层无侵入、统一拿不到业务语义统一计量、限流日志解析日志采集器零侵入字段缺失、延迟高兜底、历史数据我的实践经验是组合使用核心 Agent 链路用 SDK 埋点保证字段完整所有 LLM 出口流量在网关层再做一层代理采集用于计量和成本核算日志解析作为兜底。这样即使某个服务忘了埋点网关层也能兜住基础数据。2.4 指标体系的分层设计AgentOps 的指标不能只有技术指标必须技术、成本、质量三条线并行。我通常分成四层基础设施层CPU、内存、GPU 利用率、显存占用。服务层QPS、P95/P99 延迟、错误率、超时率。LLM 调用层Token 消耗输入/输出分开、首 Token 延迟TTFT、生成速度Tokens/s、模型调用成功率。业务质量层任务完成率、工具调用成功率、用户反馈评分、重试率、幻觉率人工标注或模型评估。这四层里首 Token 延迟和 Token 消耗是最容易被忽视但最该盯的两个指标。TTFT 直接决定用户体感Token 消耗直接决定账单。很多团队上线后第一个月账单超预算就是因为没把 Token 按模型、按业务线拆开看。3. 核心埋点与数据模型实操要点3.1 Trace 与 Span 的字段设计埋点做得好不好直接决定后面能不能查得动。我踩过的最大坑是一开始只记了模型名和耗时结果出问题时根本定位不到是哪段 Prompt 导致的。后来重新设计了一套字段分享给大家。Trace 级别建议至少包含session_id会话标识用于串联多轮对话。user_id用户标识注意脱敏。agent_nameAgent 名称或版本。task_type任务类型如问答、检索、代码生成。total_tokens本次任务总 Token。total_cost本次任务估算成本。status成功、失败、超时、中断。Span 级别按类型区分。LLM 调用 Span 建议包含llm.model模型名称与版本。llm.prompt_versionPrompt 模板版本号这个极其重要。llm.input_tokens/llm.output_tokens分开记录。llm.temperature/llm.top_p采样参数。llm.ttft_ms首 Token 延迟。llm.finish_reason结束原因如 stop、length、tool_calls。工具调用 Span 建议包含tool.name工具名称。tool.input_size/tool.output_size输入输出大小。tool.status成功、失败、超时。tool.retry_count重试次数。提示llm.prompt_version这个字段一定要加。我遇到过线上回答质量突然下降排查半天发现是有人改了 Prompt 模板没走发布流程。有了版本号直接按版本对比指标就能秒定位。3.2 Prompt 与 Completion 的脱敏处理把完整 Prompt 和 Completion 存进可观测平台风险和收益并存。收益是排查方便风险是可能泄露用户隐私、密钥、内部数据。我的做法是分级存储默认只存 Prompt 的哈希值和长度不存原文。对确需排查的链路开启采样存储采样率控制在 1% 以内。存储前做正则脱敏过滤手机号、身份证、邮箱、API Key 等模式。敏感业务线直接关闭原文存储只保留结构化字段。脱敏正则建议至少覆盖这几类\d{11}手机号、\d{17}[\dXx]身份证、[A-Za-z0-9]{32,}长串密钥、邮箱格式。这些规则在采集端做不要等到存储端否则数据已经落盘了。3.3 上下文与多轮对话的关联多轮对话的可观测性难点在于每一轮看起来是独立请求但实际共享上下文。如果不做关联你看到的是几十条孤立的 LLM 调用根本不知道哪几条属于同一次对话。解决方案是引入session_id和turn_index。session_id标识整个会话turn_index标识第几轮。这样在观测云里可以按session_id聚合还原出完整的对话链路。更进一步可以把每轮的context_tokens也记下来观察上下文膨胀情况——很多 Agent 跑着跑着变慢变贵就是因为上下文越滚越大没做裁剪。3.4 工具调用的可观测性AI Agent 和普通 LLM 应用最大的区别就是会调工具。工具调用出问题往往比模型本身出问题更隐蔽。我建议对每次工具调用都记录完整的输入输出摘要注意脱敏并单独统计工具的成功率和延迟。有个容易被忽略的点工具调用的参数是模型生成的可能格式错误。比如模型生成了一个不存在的参数名或者参数类型不对。这类错误在传统监控里看不出来因为 HTTP 请求可能根本没发出去。所以要在工具执行前做参数校验并把校验失败单独记为一种错误类型。4. 基于观测云的完整落地流程4.1 环境准备与数据接入假设你已经有一个跑起来的 AI Agent 服务接下来要把它接入观测云。整体流程分四步安装采集器、配置数据源、埋点上报、验证数据。采集器方面观测云提供 DataKit 作为统一采集入口。部署方式根据你的环境选容器环境用 DaemonSet物理机用主机安装。安装完成后重点配置两个采集器dk-trace用于接收链路数据dk-log用于接收日志。如果你的 Agent 是 Python 写的直接用 OpenTelemetry 的 Python SDK 上报到 DataKit 的 OTLP 端口即可。配置示例以 OTLP HTTP 为例# datakit.conf 片段 otlp: http: enable: true addr: 0.0.0.0:4318应用侧配置环境变量export OTEL_EXPORTER_OTLP_ENDPOINThttp://localhost:4318 export OTEL_SERVICE_NAMEai-agent-service export OTEL_TRACES_EXPORTERotlp注意DataKit 的 OTLP 端口默认可能未开启需要手动在配置文件里打开。我第一次接入时折腾了半小时最后发现是端口没开。4.2 埋点代码的编写以 Python 为例用 OpenTelemetry 手动埋点。核心思路是会话开始建 Trace每个步骤建 SpanLLM 调用和工具调用作为子 Span。from opentelemetry import trace from opentelemetry.trace import Status, StatusCode tracer trace.get_tracer(agent.ops) def run_agent_task(session_id, user_input): with tracer.start_as_current_span(agent.task) as task_span: task_span.set_attribute(session_id, session_id) task_span.set_attribute(task_type, qa) # 规划阶段 with tracer.start_as_current_span(agent.plan) as plan_span: plan planner(user_input) plan_span.set_attribute(plan.steps, len(plan)) # LLM 调用 with tracer.start_as_current_span(llm.call) as llm_span: llm_span.set_attribute(llm.model, your-model) llm_span.set_attribute(llm.prompt_version, v1.2.3) resp call_llm(user_input) llm_span.set_attribute(llm.input_tokens, resp.usage.input) llm_span.set_attribute(llm.output_tokens, resp.usage.output) llm_span.set_attribute(llm.ttft_ms, resp.ttft) # 工具调用 with tracer.start_as_current_span(tool.call) as tool_span: tool_span.set_attribute(tool.name, search) result call_tool(plan) tool_span.set_attribute(tool.status, success) return result这段代码的关键在于 Span 的嵌套关系。agent.task是父 Spanagent.plan、llm.call、tool.call是子 Span。这样在观测云的链路视图里你能看到一棵完整的执行树每个节点的耗时、属性一目了然。4.3 指标计算与上报除了链路指标也要单独上报。Token 消耗、TTFT、任务完成率这些适合做成指标方便做趋势分析和告警。from opentelemetry import metrics meter metrics.get_meter(agent.ops) token_counter meter.create_counter( llm.tokens.total, descriptionTotal tokens consumed ) ttft_histogram meter.create_histogram( llm.ttft.ms, descriptionTime to first token ) def record_llm_metrics(model, input_tokens, output_tokens, ttft): token_counter.add(input_tokens, {model: model, type: input}) token_counter.add(output_tokens, {model: model, type: output}) ttft_histogram.record(ttft, {model: model})这里有个细节Token 计数要按输入和输出分开打标签。因为输入和输出的单价不一样混在一起算成本会失真。另外模型名作为标签方便按模型维度做成本分摊。4.4 观测云上的仪表盘搭建数据上报之后在观测云上建仪表盘。我一般建三个视图第一个是总览视图放核心指标QPS、P95 延迟、错误率、Token 消耗速率、成本速率。这个视图给值班同学看一眼判断系统是否健康。第二个是 LLM 专项视图放 TTFT 分布、Token 消耗按模型拆分、Prompt 版本对比、finish_reason 分布。这个视图给算法和业务同学看用于优化 Prompt 和模型选型。第三个是 Agent 行为视图放工具调用成功率、平均步骤数、任务完成率、重试率。这个视图给 Agent 开发者看用于优化规划逻辑。仪表盘的查询语句以观测云的 DQL 为例统计某模型 Token 消耗L::llm.tokens.total {model your-model} [:: 1h] by type具体语法以你所用版本为准核心思路是按标签聚合、按时间窗口统计。4.5 告警规则配置告警是 AgentOps 体系里最容易配错的部分。配太松没意义配太紧天天误报。我的经验是分三级P0 告警服务不可用、错误率突增、Token 消耗异常飙升。这类直接电话通知。P1 告警TTFT 超过阈值、工具调用失败率上升、任务完成率下降。这类走群通知。P2 告警成本接近预算、Prompt 版本变更、模型切换。这类走日报。Token 消耗告警特别值得说。不要用绝对值要用同比和环比。比如“过去 1 小时 Token 消耗比过去 7 天同期均值高 50%”这种规则能捕捉到异常又不会因为业务自然增长而误报。5. 常见问题与排查技巧实录5.1 链路断链为什么 Span 串不起来这是接入初期最常见的问题。表现是观测云上看到一堆孤立的 Span没有父子关系。原因通常有三个一是跨服务调用时没有传递 Trace Context二是异步任务没有正确继承上下文三是 SDK 版本不兼容。排查方法先看单个服务内的 Span 是否正常嵌套如果正常问题就在跨服务传递。检查 HTTP 请求头里有没有traceparent消息队列的消息属性里有没有带上下文。异步场景比如 Agent 用线程池或协程并发调工具要特别注意OpenTelemetry 的上下文默认不跨线程传播需要手动 attach。5.2 数据量爆炸如何控制成本LLM 应用的数据量很容易失控。我见过一个团队上线一周日志量涨了 20 倍存储费用直接爆表。控制成本的核心是采样和分级。链路数据核心链路 100% 采集非核心链路 10% 采样。日志数据结构化字段全量原文按需采样。指标数据全量但注意控制标签基数。标签基数是隐形杀手。比如你把user_id作为指标标签用户一多时间线数量就爆炸。正确做法是user_id只放在链路和日志里指标里用user_type这种低基数标签。5.3 排查速查表现象可能原因排查方向回答质量下降Prompt 变更、模型切换查 prompt_version、model 标签响应变慢上下文膨胀、工具超时查 context_tokens、tool 耗时成本突增重试过多、上下文过长查 retry_count、input_tokens任务中断工具失败、超时查 tool.status、finish_reason链路断链上下文未传递查 traceparent、异步传播数据缺失采集器异常、采样查 DataKit 状态、采样率5.4 几个独家避坑技巧技巧一给 Prompt 加版本号并纳入发布流程。Prompt 变更和代码变更一样要走 review 和灰度。我见过太多因为改了一个词导致线上大面积翻车的案例。技巧二对模型输出做结构化校验。如果 Agent 依赖模型输出 JSON一定要做 schema 校验校验失败单独计数。这类错误在传统监控里完全不可见。技巧三建立成本预算告警。按业务线、按模型设置日预算和周预算接近阈值就告警。LLM 的成本是线性的不设预算很容易失控。技巧四保留最近 N 轮的原始数据用于复盘。采样可以但最近 24 小时的原始数据建议全量保留方便出问题时快速定位。技巧五把用户反馈接入可观测体系。点赞点踩、重新生成这些行为都是质量信号。把它们和 Trace 关联起来才能形成“技术指标 业务质量”的闭环。6. 从能观测到能优化AgentOps 的进阶方向6.1 用可观测数据驱动 Prompt 优化有了 Prompt 版本和质量的关联数据优化就有了依据。比如你可以对比 v1.2 和 v1.3 两个版本的完成率、平均 Token 消耗、用户反馈评分用数据决定哪个版本更好。这比拍脑袋改 Prompt 靠谱得多。更进一步可以把失败案例自动收集起来形成评估集。每次 Prompt 变更前先在这个评估集上跑一遍看指标有没有退化。这套流程跑顺了Prompt 迭代的效率会大幅提升。6.2 多 Agent 协作的观测当系统从单 Agent 演进到多 Agent观测复杂度会指数级上升。这时候需要引入parent_agent和child_agent字段把 Agent 之间的调用关系也画进链路里。观测云的链路视图支持这种树状结构关键是埋点时要正确设置父子关系。多 Agent 场景下我建议额外关注两个指标Agent 间通信延迟和任务分发均衡度。前者影响整体响应时间后者影响资源利用率。6.3 把可观测性左移到开发阶段最好的 AgentOps 不是上线后才观测而是开发阶段就埋好。我现在的做法是本地开发时就把 Trace 打到本地 collector开发同学自己就能看到每次调用的完整链路。这样问题在开发阶段就暴露了不用等到线上。本地 collector 可以用观测云的 DataKit 单机版配置简单资源占用低。开发同学改完代码跑一次任务直接在本地看链路效率比翻日志高得多。6.4 关于模型评估与可观测的结合LLM 的“错误”很多时候不是技术错误而是语义错误。比如回答虽然格式正确但内容是错的。这类问题靠传统监控抓不到需要引入模型评估。可以把评估结果作为一个指标上报和 Trace 关联。这样你就能看到“哪些链路更容易产生低质量回答”从而针对性优化。评估可以是人工的也可以是模型自动评估。自动评估成本低、覆盖广但准确性有限人工评估准确但成本高。我的建议是自动评估做全量监控人工评估做抽样校准两者结合。7. 一些实际落地后的体会这套 AgentOps 体系我在几个项目里落地过最大的体会是可观测性不是上线后补的而是设计时就要考虑的。如果 Agent 的代码结构本身就不清晰埋点会非常痛苦。反过来如果一开始就把规划、推理、工具调用拆成独立的模块埋点就是顺手的事。另一个体会是不要追求一步到位。我见过团队想一次性把所有指标都做全结果拖了两个月还没上线。正确的做法是先接入链路和基础指标跑起来之后再逐步补充。先有数据再谈优化。最后分享一个我觉得特别有用的小习惯每次线上出问题排查完之后把排查过程用到的查询语句存下来形成自己的“排查手册”。下次遇到类似问题直接套用效率翻倍。这套手册积累到一定程度就是团队最宝贵的运维资产。