1什么是 Agent 可观测性:为什么传统方法不够用
可观测性(Observability)源于控制论,指通过系统的外部输出推断其内部状态的能力。在软件工程中,可观测性由三大支柱构成:Tracing(追踪)、Metrics(度量)和Logging(日志)。这三个维度共同回答了「系统在做什么」「系统表现如何」和「系统发生了什么」三个核心问题。
AI Agent 的可观测性与传统软件有本质区别。传统软件的行为是确定性的:给定相同的输入和代码,输出必然相同。你可以用断点调试、单元测试和日志追踪完全覆盖所有路径。但 Agent 的核心是大语言模型,而 LLM 的本质是概率模型——相同的提示词在不同时间可能产生不同的推理路径和工具调用序列。
更复杂的是,Agent 通常包含多个嵌套环节:规划(Planning)决定要做什么,推理(Reasoning)决定怎么做,工具调用(Tool Use)与外部世界交互,记忆(Memory)维护上下文状态,反思(Reflection)评估和修正自己的输出。每一个环节都可能出错,且错误可能级联放大。
传统 APM(如 New Relic、Datadog APM)能告诉你「HTTP 请求花了 200ms」,但无法告诉你「Agent 为什么选择了工具 A 而非工具 B」「推理链在哪一步偏离了正确方向」「记忆检索返回了不相关上下文」。这些问题的答案需要专门的 Agent 可观测性方案。
一个关键概念是LLM 的不可观测性悖论:LLM 内部的数十亿参数和注意力权重在理论上是可读取的,但实际上没有任何人类能直接理解这些内部状态的含义。因此,Agent 可观测性不是「打开黑盒看里面」,而是「从外部设计足够多的探测点,让黑盒的行为可以被推断和理解」。这要求我们在 Agent 的关键决策点、工具调用边界和状态转换处植入观测探针。
核心理解:Agent 可观测性不是「看模型在想什么」,而是「在关键决策点植入探针,让推理过程可追溯」。设计观测体系时,优先覆盖规划、工具调用和记忆三个最容易出错的环节。
常见误区:把 LLM 的 prompt 和 response 简单存为日志 ≠ 可观测性。真正的可观测性需要结构化数据(token 用量、延迟、工具调用序列、置信度分数),而非纯文本记录。没有结构化的日志在出问题时几乎没有调试价值。
2Agent 可观测性的三大支柱
Agent 可观测性体系由三个互补的维度构成,每个维度覆盖不同的观测需求和故障场景。理解三者的区别和协作关系是构建完整体系的前提。
Tracing(追踪)是 Agent 可观测性的核心支柱。一个 Tracing 记录了一条请求在 Agent 内部的完整执行路径,包括每一步的输入、输出、耗时、token 消耗和元数据。对于 Agent 来说,Tracing 的关键特征是嵌套结构:一个用户请求可能触发多个 LLM 调用、多个工具调用和多次记忆检索,这些操作之间存在因果关系,需要以树状结构(Span Tree)记录。每个 Span(跨度)代表一个原子操作,Span 之间通过父子关系关联。根 Span 是用户请求,子 Span 是 Agent 内部的各个步骤。
Metrics(度量)提供 Agent 系统的宏观健康视图。与 Tracing 关注单次请求不同,Metrics 关注聚合统计:平均响应延迟、P99 延迟、Token 消耗率、工具调用成功率、错误率、成本/请求等。Metrics 的价值在于趋势分析和告警——当 P99 延迟从 3 秒飙升到 15 秒时,你需要一个 Metric 告警来第一时间发现问题,而不等用户投诉。常用的 Metrics 类型包括计数器(Counter,如请求总数)、规约器(Gauge,如当前并发数)和直方图(Histogram,如延迟分布)。
Logging(日志)记录 Agent 运行过程中的离散事件。在 Agent 场景中,最有价值的日志类型包括:工具调用日志(调用参数、返回值、异常信息)、模型调用日志(prompt、response、token 用量、温度参数)、状态变更日志(Agent 状态机转换、记忆更新)和安全日志(敏感数据访问、权限拒绝、异常行为检测)。日志的关键要求是结构化——每条日志应包含时间戳、级别、Agent ID、Session ID、Span ID 等关联字段,使得日志可以与 Tracing 和 Metrics 交叉引用。
三支柱的协作关系可以概括为:Metrics 告诉你出了问题,Tracing 告诉你问题在哪一步,Logging 告诉你为什么出问题。这是一个从宏观到微观的诊断流程。
实践建议:在项目中同时实现三支柱,但不要追求一步到位。建议的实施顺序是:先做 Tracing(最高 ROI),再做 Metrics(告警需求),最后完善 Logging(调试细节)。每个阶段都要确保数据可以关联。
注意陷阱:Tracing 数据量可能非常大——一个复杂的 Agent 请求可能产生 50+ 个 Span。如果不对 Tracing 数据进行采样(Sampling)或聚合(Aggregation),存储成本会快速失控。生产环境建议对 90%+ 的请求做降采样,只保留 100% 的失败请求和慢请求。
3Agent 特有的可观测性挑战
Agent 系统引入了传统软件中不存在的五类独特挑战,这些挑战决定了你不能用现成的 APM 方案直接套用,而需要专门设计观测体系。
挑战一:非确定性执行路径。同一用户请求,Agent 可能走完全不同的执行路径。例如用户问「帮我查一下明天上海的天气」,Agent 可能调用天气 API 直接回答,也可能先搜索「上海明天」确认日期,再调用天气 API,甚至在搜索过程中发现用户指的是「上海浦东机场」而调用机场天气 API。这种路径分支意味着你无法用传统的路由覆盖测试来保证质量——每次执行都可能是新路径。解决方案是建立执行路径聚类(Execution Path Clustering),将相似路径归为一组,分析每个聚类中的成功率和失败模式。
挑战二:级联错误放大。Agent 的多步推理意味着早期的小错误可能在后续步骤中被指数级放大。例如,Agent 在第一步错误理解了用户的意图(偏差 10%),在第二步基于错误意图选择了错误的工具(偏差扩大到 40%),在第三步基于错误工具的返回做了错误的总结(偏差达到 80%)。这种蝴蝶效应使得单步监控不足以发现问题——每一步单独看都「正常」,但组合起来完全错误。解决方案是实施端到端质量评估(End-to-End Evaluation),在关键节点注入验证检查点(Checkpoints),当检测到偏差超过阈值时提前终止并回退。
挑战三:上下文窗口污染。Agent 的记忆系统随着对话进行不断累积上下文,但 LLM 的上下文窗口是有限的。当上下文超出窗口大小时,系统需要做上下文截断或摘要压缩。这两个操作都可能丢失关键信息——截断可能丢掉用户的原始需求,压缩可能扭曲关键细节。这种「静默的信息丢失」是最难调试的问题之一,因为 Agent 不会报错,只是给出了质量下降的回答。解决方案是实现上下文健康度评分(Context Health Score),监控上下文中的信息密度、关键信息保留率和压缩损失率。
挑战四:工具调用语义模糊。Agent 选择调用哪个工具不是通过精确匹配,而是通过语义理解。这意味着工具选择错误不是「调用了错误的 API endpoint」这种硬性错误,而是「语义上近似但实际不对」的软性错误。例如用户问「帮我订一张去北京的高铁票」,Agent 可能错误地调用了「航班查询 API」而不是「高铁查询 API」,因为两者在语义上都与「出行订票」相关。解决方案是在工具调用层添加意图校验(Intent Validation),当工具返回结果与用户意图不匹配时触发二次确认或工具切换。
挑战五:成本不可预测性。由于 Agent 的执行路径不确定,每次请求的 token 消耗可能相差数倍。一个简单问题可能触发一次 LLM 调用(500 token),也可能触发五次工具调用加三次 LLM 调用(15000 token)。这种成本波动使得传统的「单次请求成本」估算完全失效。解决方案是建立动态成本预算(Dynamic Cost Budgeting),为每个 Agent Session 设定 token 上限,当累计消耗接近上限时触发降级策略(如使用更小的模型、减少工具调用次数或直接返回中间结果)。
// Agent 执行路径聚类分析示例
interface ExecutionTrace {
sessionId: string;
steps: Array<{
stepType: 'plan' | 'reason' | 'tool_call' | 'memory' | 'reflect';
toolName?: string;
latencyMs: number;
tokensUsed: number;
success: boolean;
}>;
totalTokens: number;
totalLatencyMs: number;
outcome: 'success' | 'partial' | 'failure';
}
// 将执行路径编码为特征向量
function encodePath(trace: ExecutionTrace): number[] {
const featureVec: number[] = [];
const typeCounts = { plan: 0, reason: 0, tool_call: 0, memory: 0, reflect: 0 };
for (const step of trace.steps) {
typeCounts[step.stepType]++;
}
featureVec.push(trace.steps.length); // 总步数
featureVec.push(typeCounts.tool_call); // 工具调用次数
featureVec.push(typeCounts.memory); // 记忆检索次数
featureVec.push(trace.totalTokens); // 总 token
featureVec.push(trace.totalLatencyMs); // 总延迟
featureVec.push(trace.outcome === 'success' ? 1 : 0); // 结果
return featureVec;
}
// 简单的路径相似度计算(余弦相似度)
function cosineSimilarity(a: number[], b: number[]): number {
const dot = a.reduce((sum, v, i) => sum + v * b[i], 0);
const magA = Math.sqrt(a.reduce((sum, v) => sum + v * v, 0));
const magB = Math.sqrt(b.reduce((sum, v) => sum + v * v, 0));
return dot / (magA * magB);
}
// 聚类分析:找出高频执行路径
function clusterPaths(traces: ExecutionTrace[], threshold = 0.85): string[][] {
const clusters: string[][] = [];
const assigned = new Set<string>();
for (const trace of traces) {
if (assigned.has(trace.sessionId)) continue;
const cluster = [trace.sessionId];
assigned.add(trace.sessionId);
const featuresA = encodePath(trace);
for (const other of traces) {
if (assigned.has(other.sessionId)) continue;
const featuresB = encodePath(other);
if (cosineSimilarity(featuresA, featuresB) >= threshold) {
cluster.push(other.sessionId);
assigned.add(other.sessionId);
}
}
clusters.push(cluster);
}
return clusters;
}| 挑战类型 | 典型症状 | 影响级别 | 推荐对策 |
|---|---|---|---|
非确定性路径 | 相同请求结果不一致 | 高 | 执行路径聚类 + 多轮测试 |
级联错误 | 最终结果完全错误但各步无报错 | 严重 | 端到端评估 + 检查点 |
上下文污染 | 回答质量随对话轮次下降 | 中 | 上下文健康度评分 |
工具语义模糊 | 调用了错误但相似的工具 | 高 | 意图校验 + 二次确认 |
成本波动 | 单次请求成本差异 10 倍以上 | 中 | 动态成本预算 + 降级策略 |
排查优先级:级联错误 > 非确定性路径 > 工具语义模糊 > 上下文污染 > 成本波动。级联错误最危险,因为它不会产生报错,只会产生「看似合理但完全错误」的结果,用户往往察觉不到。
危险信号:如果你的 Agent 在生产环境中出现了「用户说结果不对但系统没有报错」的情况,这就是典型的级联错误。必须立即实施端到端质量评估,否则错误会持续累积且难以追溯。
4Agent 可观测性架构设计
设计 Agent 可观测性架构需要回答三个关键问题:数据采集在哪里、数据如何关联和数据存储在哪里。这三个问题的答案共同构成了观测体系的技术骨架。
数据采集点的选择遵循一个原则:在每个状态转换和决策点植入探针。对于典型的 ReAct Agent,关键采集点包括:规划阶段(记录 Agent 制定的执行计划、选择的工具列表、预估的步骤数)、推理阶段(记录思维链内容、置信度评分、备选方案)、工具调用阶段(记录工具名称、输入参数、返回值、执行时间、错误信息)、记忆操作阶段(记录检索的关键词、返回的结果数、相关性评分、写入的新记忆)和输出生成阶段(记录最终答案、引用的信息来源、未满足的子任务)。
数据关联是 Agent 可观测性架构中最关键的设计决策。所有观测数据必须通过一组关联键(Correlation Keys)串联起来:Trace ID 标识一次完整的用户请求,Span ID 标识该请求内的一个原子操作,Session ID 标识一个多轮对话会话,Agent ID 标识具体的 Agent 实例,User ID 标识发起请求的用户。这五个键构成了观测数据的五维关联模型,支持从任意维度进行查询和分析。
数据存储策略需要根据数据类型的访问模式来设计。Tracing 数据具有高写入、低频查询、按 Trace ID 精确查找的特征,适合用列式存储(如 ClickHouse)或专用的分布式 Tracing 后端(如 Jaeger、Tempo)。Metrics 数据具有持续写入、频繁聚合查询、时序范围扫描的特征,适合用时序数据库(如 Prometheus、InfluxDB)。Logging 数据具有高写入、按需查询、全文搜索的特征,适合用搜索引擎(如 Elasticsearch、Loki)。
在成本敏感的场景中,可以采用分层存储策略:热数据(最近 7 天)存储在高性能的内存/SSD 层,温数据(7-30 天)存储在标准磁盘层,冷数据(30 天以上)存储在对象存储(如 S3)中,通过索引实现跨层查询。这种策略可以将存储成本降低 60-80%,同时保证关键数据的即时可用性。
架构选型建议:小型项目(月请求 < 10 万)可以用 LangSmith 或 Langfuse 的一体化方案,开箱即用。中型项目(10 万-100 万请求/月)建议采用 Langfuse + Prometheus 的组合。大型项目(100 万+/月)需要自建,使用 OpenTelemetry SDK + Jaeger/Tempo + Prometheus + Loki 的完整技术栈。
架构设计陷阱:不要把 Tracing、Metrics 和 Logging 强行塞进同一个存储系统。虽然一些一体化工具声称支持所有三种数据类型,但在数据量增长后,单一存储系统会成为性能瓶颈。正确的做法是让每种数据类型使用最适合的存储引擎,通过关联键实现跨系统查询。
5主流 Agent 可观测性工具对比
当前 Agent 可观测性工具市场已经形成了三个梯队:专用 Agent 观测平台(LangSmith、Langfuse、Arize Phoenix)、通用可观测性平台 Agent 扩展(Datadog LLM Observability、New Relic AI Monitoring)和开源 DIY 方案(OpenTelemetry + 后端组合)。选择工具时需要综合评估功能覆盖度、集成难度、成本和可扩展性四个维度。
LangSmith 由 LangChain 团队开发,是最早也是最成熟的 Agent 可观测性平台。它的核心优势在于与 LangChain/LangGraph 生态的深度集成——如果你使用 LangChain 构建 Agent,LangSmith 可以实现零代码接入的 Tracing。LangSmith 提供数据集管理、测试用例编排、A/B 测试和Prompt 版本控制等功能,形成了一个完整的 Agent 开发-测试-监控闭环。它的缺点是供应商锁定风险较高——Tracing 数据以 LangSmith 专有格式存储,迁移成本较高。定价方面,LangSmith 的 Plus 计划从 $39/月起步,适合中小团队。
Langfuse 是一个开源的 Agent 可观测性平台,设计上强调供应商中立和数据可移植性。它支持 LangChain、LlamaIndex、OpenAI SDK 等主流框架,通过 OpenTelemetry 兼容接口实现标准化数据采集。Langfuse 的核心竞争力在于灵活的评分系统——你可以定义任意维度的评分规则(如「回答准确性」「工具调用合理性」「响应延迟」),并为每个 Trace 自动或手动打分。Langfuse 支持自托管(Self-hosted),这意味着你可以完全控制数据存储和访问权限,对于有数据合规要求的企业是关键优势。社区版免费,商业版从 $500/月起步。
Arize Phoenix 是 Arize AI 推出的 Agent 可观测性工具,专注于LLM 应用的性能监控和质量评估。Phoenix 的独特优势在于嵌入可视化(Embedding Visualization)——它可以把 Agent 检索到的文档片段和生成的回答映射到低维空间,帮助你直观地看到检索质量和生成质量的关系。Phoenix 还支持漂移检测(Drift Detection),当 Agent 的输入分布或输出质量发生显著变化时自动告警。Phoenix 开源免费,云托管版本按用量计费。
Datadog LLM Observability 将 LLM 监控集成到了 Datadog 的全栈可观测性平台中。如果你已经是 Datadog 用户,这是最自然的选择——Agent 的 Tracing 可以与你的基础设施 Metrics、APM 数据、日志无缝关联。Datadog 的优势在于告警和仪表盘能力极其强大,支持复杂的告警规则(如「当工具调用失败率超过 5% 且 P99 延迟超过 5 秒时触发 P1 告警」)。缺点是价格较高,LLM 观测模块的额外费用约为 $0.10/百万 token。
OpenTelemetry(OTel) 是 CNCF 的标准化可观测性框架,正在快速增加对 LLM 和 Agent 的原生支持。OTel 的最大优势是供应商中立——你用 OTel SDK 采集的数据可以发送到任何兼容的后端(Jaeger、Tempo、Grafana、Datadog 等)。对于大规模生产环境,OTel + 自建后端的方案在成本和可控性上通常最优。缺点是集成难度较高——需要自己编写 Instrumentation 代码,配置后端存储和查询界面。
| 工具 | 开源 | LangChain 集成 | 自托管 | 评分系统 | 价格起点 | 适用规模 |
|---|---|---|---|---|---|---|
LangSmith | 否 | 原生深度 | 否 | 有限 | $39/月 | 中小团队 |
Langfuse | 是 | SDK 适配 | 是 | 灵活自定义 | 免费/$500/月 | 全规模 |
Arize Phoenix | 是 | SDK 适配 | 是 | 嵌入可视化 | 免费/按量 | 中小团队 |
Datadog LLM | 否 | SDK 适配 | 否 | 基础 | 按量付费 | 企业级 |
OpenTelemetry | 是 | 需自行集成 | 是 | 需自建 | 自建免费 | 大型生产 |
选型建议:如果你是 LangChain/LangGraph 用户且团队规模 < 50 人,LangSmith 是最佳选择——集成成本最低,功能最完整。如果你需要数据主权或多框架支持,选 Langfuse。如果你在 Datadog 生态内,直接用 Datadog LLM Observability。如果你需要极致的可控性和成本优化,选 OpenTelemetry + 自建后端。
避坑指南:不要在生产环境中使用工具的「免费层」——免费层通常有数据保留期限(如 7 天)和查询次数限制,当你的 Agent 出问题时,关键的 Tracing 数据可能已经被清理。生产环境至少选择付费计划,确保数据保留 ≥ 30 天。
6Agent 调试方法论:从现象到根因
Agent 调试与传统的断点调试有根本区别——你不能「暂停」一个 LLM 的推理过程,也不能「检查变量值」因为 LLM 的内部状态是不可解释的。Agent 调试需要一套全新的方法论,核心思路是:用结构化的观测数据替代直觉调试。
调试流程分为五个步骤:第一步,复现问题——收集失败请求的完整 Trace,确认问题可以在相同或相似输入下复现。如果无法复现,说明是非确定性错误,需要收集更多样本做统计分析。第二步,定位失败 Span——在 Tracing 树中找到第一个产出异常结果的 Span。注意,「第一个异常 Span」不一定是「根因 Span」——异常可能是上游 Span 的错误输入导致的。第三步,分析 Span 上下文——检查该 Span 的输入(包括 prompt、工具参数、检索到的上下文)、输出(LLM 的回复、工具返回值)和元数据(token 用量、延迟、置信度)。第四步,对比正常 Trace——找到功能正确的相似请求的 Trace,对比两个 Trace 在执行路径、工具选择和输入质量上的差异。第五步,制定修复策略——根据根因类型选择修复方案:如果是 Prompt 问题,优化提示词;如果是工具问题,修复工具实现或添加 fallback;如果是模型问题,考虑换用更强的模型或添加 Few-shot 示例。
常见根因类型及其诊断信号:
Prompt 缺陷的诊断信号是:工具调用序列正确,但 LLM 的推理内容(Chain of Thought)存在逻辑跳跃或事实错误。修复方案是添加约束条件、Few-shot 示例或结构化输出格式。
工具实现错误的诊断信号是:工具返回的数据格式正确但内容错误(如 API 返回了错误的城市天气)。修复方案是修正工具逻辑或添加结果验证层。
上下文不足的诊断信号是:Agent 在推理过程中反复检索相同信息或忽略已有信息。修复方案是优化检索策略、增加上下文窗口或改进记忆组织方式。
模型能力不足的诊断信号是:即使 Prompt 和工具都正确,模型仍然无法完成推理(如需要多步数学计算但模型跳过了中间步骤)。修复方案是升级模型或将复杂推理拆分为多个子任务。
系统性偏见的诊断信号是:Agent 在某一类请求上持续失败,但在其他类型上正常。例如只在处理中文请求时失败,或只在涉及日期计算时失败。修复方案是针对特定类型添加专项 Few-shot 示例或专门的子 Agent。
调试中最有价值的工具是Trace 对比器——将两条 Trace(一条成功、一条失败)并排展示,高亮显示它们在执行路径、工具选择、token 用量和输出质量上的差异。这种对比往往能在几秒钟内揭示根因。
// Agent 调试辅助工具:Trace 对比分析
interface SpanDiff {
spanName: string;
field: string;
successValue: string;
failureValue: string;
severity: 'critical' | 'warning' | 'info';
}
function compareTraces(
successTrace: ExecutionTrace,
failureTrace: ExecutionTrace
): SpanDiff[] {
const diffs: SpanDiff[] = [];
// 对比执行路径长度
const pathDiff = failureTrace.steps.length - successTrace.steps.length;
if (Math.abs(pathDiff) > 2) {
diffs.push({
spanName: 'ROOT',
field: 'path_length',
successValue: String(successTrace.steps.length),
failureValue: String(failureTrace.steps.length),
severity: 'warning'
});
}
// 对比 token 消耗
const tokenRatio = failureTrace.totalTokens / Math.max(successTrace.totalTokens, 1);
if (tokenRatio > 2 || tokenRatio < 0.5) {
diffs.push({
spanName: 'ROOT',
field: 'total_tokens',
successValue: String(successTrace.totalTokens),
failureValue: String(failureTrace.totalTokens),
severity: tokenRatio > 3 ? 'critical' : 'warning'
});
}
// 逐步骤对比工具调用
const maxLen = Math.max(successTrace.steps.length, failureTrace.steps.length);
for (let i = 0; i < maxLen; i++) {
const sStep = successTrace.steps[i];
const fStep = failureTrace.steps[i];
if (sStep && fStep) {
// 工具调用不一致
if (sStep.toolName !== fStep.toolName) {
diffs.push({
spanName: `step_${i}`,
field: 'tool_name',
successValue: sStep.toolName || 'none',
failureValue: fStep.toolName || 'none',
severity: 'critical'
});
}
// 延迟异常
if (fStep.latencyMs > sStep.latencyMs * 2) {
diffs.push({
spanName: `step_${i}`,
field: 'latency',
successValue: `${sStep.latencyMs}ms`,
failureValue: `${fStep.latencyMs}ms`,
severity: 'info'
});
}
}
// 步骤缺失或多余
if (!sStep && fStep) {
diffs.push({
spanName: `step_${i}`,
field: 'extra_step',
successValue: '不存在',
failureValue: fStep.stepType,
severity: 'warning'
});
}
if (sStep && !fStep) {
diffs.push({
spanName: `step_${i}`,
field: 'missing_step',
successValue: sStep.stepType,
failureValue: '不存在',
severity: 'critical'
});
}
}
// 按严重程度排序
const severityOrder = { critical: 0, warning: 1, info: 2 };
return diffs.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
}
// 使用示例
const diffs = compareTraces(successfulTrace, failedTrace);
console.log(`发现 ${diffs.length} 处差异:`);
for (const diff of diffs) {
console.log(`[${diff.severity.toUpperCase()}] ${diff.spanName}.${diff.field}: ${diff.successValue} → ${diff.failureValue}`);
}调试技巧:建立一个「已知问题库」,将常见的根因类型和修复方案记录下来。当新问题时,先在已知问题库中搜索相似案例——80% 的 Agent 问题属于已知的根因类型,可以直接套用修复方案。
调试陷阱:不要只修复「当前这个请求」的问题。如果一个问题出现了,它很可能以微小变体的形式再次出现。修复时一定要思考「这类问题的通用解法是什么」,而不是「这个特定请求怎么修好」。
7生产环境监控与告警策略
将 Agent 从开发环境推向生产环境,可观测性体系需要从调试模式切换到监控模式。两者的核心区别在于:调试模式关注单次请求的深度分析,而监控模式关注系统级别的健康状态和异常检测。
告警分层设计是生产监控的基础。按照严重程度,Agent 告警可以分为四层:P0 紧急告警(Agent 完全不可用、工具调用失败率 > 50%、安全违规事件),需要在 5 分钟内响应;P1 高优先级告警(P99 延迟 > 10 秒、Token 消耗异常飙升、连续 10 次请求失败),需要在 30 分钟内响应;P2 中优先级告警(P95 延迟 > 5 秒、工具调用成功率降至 85% 以下、上下文命中率下降),需要在 4 小时内响应;P3 低优先级告警(Token 用量超过预算 80%、新增未知执行路径),可以在下一个工作日处理。
质量监控是 Agent 生产环境独有的需求。传统软件的质量监控关注「功能是否正确」,而 Agent 的质量监控需要关注输出质量。这包括:事实准确性(回答是否包含虚假信息)、完整性(是否回答了用户的所有子问题)、安全性(是否输出了有害或不当内容)和一致性(相同语义的请求是否得到一致的回复)。这些质量指标无法通过自动化测试完全覆盖,需要结合自动化评估模型(如用一个强模型评估弱模型的输出)和人工抽检。
成本监控是 Agent 运营中的关键指标。由于 Agent 的 token 消耗具有高度不确定性,需要建立多维度的成本监控:按用户(识别高消耗用户)、按 Agent(比较不同 Agent 的效率)、按时间段(发现成本趋势变化)和按工具(识别最昂贵的工具调用)。当单次请求的平均 token 消耗超过基线 2 倍时触发告警,当单日总成本超过预算 80% 时触发预警。
仪表板设计应遵循「5 秒原则」——运维人员应该能在 5 秒内判断系统是否健康。推荐的仪表板布局:顶部一行展示核心健康指标(请求成功率、P95 延迟、当前成本/预算比),中部展示趋势图(过去 24 小时的请求量、延迟分布、Token 消耗),底部展示实时告警和Top 5 失败 Trace。
// 生产环境 Agent 告警引擎
interface AlertRule {
id: string;
name: string;
severity: 'P0' | 'P1' | 'P2' | 'P3';
metric: string;
condition: 'gt' | 'lt' | 'eq' | 'rate_gt';
threshold: number;
windowMinutes: number;
cooldownMinutes: number; // 防抖动冷却时间
}
interface MetricSnapshot {
metric: string;
value: number;
timestamp: Date;
windowMinutes: number;
}
const alertRules: AlertRule[] = [
{
id: 'tool-failure-rate',
name: '工具调用失败率过高',
severity: 'P0',
metric: 'tool_failure_rate',
condition: 'gt',
threshold: 0.50,
windowMinutes: 5,
cooldownMinutes: 15
},
{
id: 'p99-latency',
name: 'P99 延迟过高',
severity: 'P1',
metric: 'p99_latency_ms',
condition: 'gt',
threshold: 10000,
windowMinutes: 10,
cooldownMinutes: 30
},
{
id: 'token-spike',
name: 'Token 消耗异常飙升',
severity: 'P2',
metric: 'token_rate_ratio',
condition: 'gt',
threshold: 2.0,
windowMinutes: 15,
cooldownMinutes: 60
},
{
id: 'budget-warning',
name: '日成本接近预算上限',
severity: 'P3',
metric: 'daily_cost_budget_ratio',
condition: 'gt',
threshold: 0.80,
windowMinutes: 60,
cooldownMinutes: 240
}
];
class AlertEngine {
private lastFired: Map<string, Date> = new Map();
evaluate(snapshot: MetricSnapshot): AlertRule | null {
for (const rule of alertRules) {
if (snapshot.metric !== rule.metric) continue;
// 检查冷却时间
const lastFire = this.lastFired.get(rule.id);
if (lastFire) {
const elapsed = (snapshot.timestamp.getTime() - lastFire.getTime()) / 60000;
if (elapsed < rule.cooldownMinutes) continue;
}
// 评估条件
let triggered = false;
switch (rule.condition) {
case 'gt': triggered = snapshot.value > rule.threshold; break;
case 'lt': triggered = snapshot.value < rule.threshold; break;
case 'eq': triggered = snapshot.value === rule.threshold; break;
case 'rate_gt': triggered = snapshot.value > rule.threshold; break;
}
if (triggered) {
this.lastFired.set(rule.id, snapshot.timestamp);
return rule;
}
}
return null;
}
}告警设计原则:告警疲劳是生产监控最大的敌人。如果团队每天收到 50+ 条告警,很快就会忽略所有告警。确保每条告警都是「可行动的」(Actionable)——收到告警后,工程师应该明确知道需要做什么。如果一条告警不需要人工介入,它就不应该触发告警。
告警反模式:不要将「请求失败率 > 0%」设为告警条件。LLM 服务偶尔返回错误是正常的(网络波动、限流等),0% 失败率在实际中不可达。设置合理的阈值(如 5% 或 10%),避免虚假告警耗尽团队的响应能力。
8扩展阅读与进阶方向
Agent 可观测性是一个快速发展的领域,以下几个方向值得关注和学习:
OpenTelemetry LLM Semantic Conventions 是 CNCF 正在制定的 LLM 观测标准化规范。一旦正式发布,它将定义 LLM 和 Agent 可观测性的标准 Span 属性(如 llm.request.model、llm.response.token_count、gen_ai.operation.name),使得不同工具和后端之间的数据可以互操作。关注这个规范的进展,它将在未来 6-12 个月内成为行业标准。
Agent Benchmarking 是 Agent 可观测性的前置环节。在部署之前,你需要用标准化测试集评估 Agent 的能力基线。主流的 Agent 评测基准包括:AgentBench(评估 Agent 在真实环境中的任务完成能力)、WebArena(评估 Web 操作 Agent)、SWE-bench(评估代码修复 Agent)和TauBench(评估对话式任务 Agent)。建立持续基准测试(Continuous Benchmarking)流程,在每次 Prompt 或工具变更后自动运行评测,确保变更不会降低 Agent 质量。
LLM 安全观测是另一个重要方向。除了功能和性能监控,Agent 还需要安全层面的可观测性:Prompt 注入检测(监控输入中是否包含攻击性提示词)、数据泄露检测(监控输出中是否包含敏感信息)、越权操作检测(监控 Agent 是否尝试访问未授权的资源)和行为异常检测(监控 Agent 是否偏离了正常的行为模式)。
多 Agent 系统可观测性是下一个前沿。当系统包含多个协作的 Agent时,可观测性复杂度呈指数级增长——你需要追踪 Agent 之间的消息传递、任务委派、冲突解决和共识达成。目前的工具大多只支持单 Agent 观测,多 Agent 观测需要额外的编排层来聚合和关联多个 Agent 的观测数据。
推荐的学习资源包括:LangSmith 的官方文档(最佳的 Agent Tracing 入门教程)、Langfuse 的博客(深入的 Agent 观测实践案例)、OpenTelemetry 的 LLM 规范草案(了解标准化方向)以及各 Agent 框架的观测集成指南。
学习路径建议:先掌握单 Agent 可观测性(本文内容),再学习 Agent 基准测试和评测方法,最后探索多 Agent 系统的观测方案。不要跳过基础直接学多 Agent——单 Agent 的观测方法论是多 Agent 观测的基石。
领域趋势提醒:Agent 可观测性工具的 API 和数据结构仍在快速演进中。如果你在生产环境中依赖了某个工具的特定数据格式,建议在代码中做适配层封装,而不是直接依赖工具的原始 API——这样在工具升级或迁移时,适配成本最低。