4个核心指标,让你的Agent在生产环境中稳如泰山
没有监控的Agent,就像在黑夜中闭眼狂奔
想象一下这个场景:你精心打造的AI Agent在测试环境表现完美,响应迅速,工具调用准确。但上线第二天,用户突然反馈“机器人不动了”,而你只能对着黑乎乎的终端不知所措——不知道哪里出了问题,不知道瓶颈在哪里,甚至连Agent是不是还活着都不确定。
这种“盲人摸象”式的运维,在传统应用时代就已经够可怕了,在AI Agent时代简直就是灾难。因为Agent的复杂性远超传统应用:它不仅有自己的处理逻辑,还要调用外部工具,还要和大模型API交互,任何一个环节出问题,都会导致整体失效。
今天,我就带你搭建一套完整的Agent监控体系,让你的Agent在生产环境中稳如泰山。
为什么Prometheus成了监控界的“标准答案”?
在开始写代码之前,先聊聊为什么选择Prometheus。其实市面上的监控系统不少,Zabbix、Nagios、OpenFalcon各有拥趸,但Prometheus能脱颖而出,靠的是三点:
第一,指标优先的数据模型。 Prometheus把所有的监控数据都定义为指标(metric),每个指标可以有多个标签(label)。比如一个请求计数指标,可以打上“成功/失败”的标签,这样我们既能看总量,又能按状态筛选,非常灵活。
第二,主动拉取(Pull)的数据采集模式。 相比传统的推模式(Push),Prometheus定期从你的应用拉取数据,这样可以准确判断应用是否存活。如果拉取失败,说明应用可能已经挂了。
第三,强大的查询语言PromQL。 这是Prometheus的精髓所在。你可以用PromQL对指标进行聚合、计算、预测,比如“计算过去5分钟的错误率”、“预测未来24小时的磁盘使用量”,这些复杂的分析在PromQL中往往只需要一行表达式。
4.1 从零开始:为Agent装上监控探头
理论说再多都不如实干,我们先来看一段代码。这段代码虽然简短,但它完整地展示了Prometheus监控的三个核心要素:指标定义、数据采集、服务暴露。
python
from prometheus_client import start_http_server, Counter, Histogram
import time
# 定义指标
REQUEST_COUNT = Counter('agent_request_total', 'Total agent requests', ['status'])
REQUEST_LATENCY = Histogram('agent_request_latency_seconds', 'Request latency')
TOKEN_USAGE = Counter('agent_token_usage_total', 'Total tokens used', ['model'])
def monitor_agent_execution(func):
def wrapper(*args, **kwargs):
start_time = time.time()
try:
result = func(*args, **kwargs)
REQUEST_COUNT.labels(status='success').inc()
return result
except Exception as e:
REQUEST_COUNT.labels(status='error').inc()
raise e
finally:
latency = time.time() - start_time
REQUEST_LATENCY.observe(latency)
return wrapper
# 启动 Metrics Server
start_http_server(8000)
这段代码看起来简单,但里面包含了很多精心设计的细节。我们来逐一拆解。
三个关键指标,监控Agent的“心跳”
代码中定义了三个指标,分别对应Agent监控的三个方面:
第一个是REQUEST_COUNT,一个Counter类型的指标。 Counter只增不减,适合统计总量。我们给它加了一个status标签,用来区分成功和失败的请求。这样设计的好处是,我们可以通过PromQL计算出实时的成功率:sum(rate(agent_request_total{status="success"}[5m])) / sum(rate(agent_request_total[5m]))。
第二个是REQUEST_LATENCY,一个Histogram类型的指标。 Histogram用来记录数据的分布情况。这里记录的是请求延迟,但Histogram不仅仅是记录平均值,它会自动把延迟数据分桶存储,比如≤0.1秒的请求有多少个,≤0.5秒的有多少个,≤1秒的有多少个。有了这些分布数据,我们才能计算出P99、P95这些关键的分位值。
第三个是TOKEN_USAGE,又是一个Counter类型。 这个指标专门用来统计Token消耗,加了model标签是为了区分不同模型的使用量。为什么Token消耗这么重要?因为对于很多Agent应用来说,大模型API调用是最大的成本来源。监控Token消耗,既能控制成本,又能通过消耗量的突增来发现异常流量。
装饰器模式:无侵入式监控
再看这个monitor_agent_execution装饰器,它的设计很有讲究。通过Python的装饰器语法,我们把监控逻辑和业务逻辑完全解耦了。
python
@monitor_agent_execution
def handle_user_request(user_input):
# 正常的业务处理代码
# 不需要关心任何监控逻辑
return agent.process(user_input)
这种设计的好处显而易见:业务开发人员不需要懂监控,不需要手动记录指标,只要在函数上加上这个装饰器,监控就会自动生效。而且统计逻辑非常精准:
-
start_time在函数开始前记录 -
try块中执行真正的业务逻辑,成功后记录成功计数 -
except捕获异常,记录失败计数后重新抛出,不影响业务异常处理 -
finally保证无论如何都会记录延迟数据,即使发生了异常
这种“关注点分离”的设计思想,值得在每个项目中推广。
Metrics Server:让数据可以被采集
最后一行start_http_server(8000)启动了一个HTTP服务器,默认路径是/metrics。Prometheus会定期访问这个地址来拉取数据。返回的数据格式是这样的:
text
# HELP agent_request_total Total agent requests
# TYPE agent_request_total counter
agent_request_total{status="success"} 1243
agent_request_total{status="error"} 56
# HELP agent_request_latency_seconds Request latency
# TYPE agent_request_latency_seconds histogram
agent_request_latency_seconds_bucket{le="0.1"} 892
agent_request_latency_seconds_bucket{le="0.5"} 1156
agent_request_latency_seconds_bucket{le="1"} 1287
agent_request_latency_seconds_bucket{le="+Inf"} 1299
agent_request_latency_seconds_count 1299
agent_request_latency_seconds_sum 487.23
这种纯文本格式是Prometheus原生支持的,人类可读,机器易解析。Grafana可以通过这个接口获取数据,然后绘制出漂亮的仪表盘。
4.2 四个核心指标,盯住Agent的命门
指标不是越多越好。很多团队恨不得把所有的数据都监控起来,结果就是告警成天响,真正的问题反而被淹没了。根据经验,对于Agent系统,只要盯住下面四个指标就够了。
| 指标名称 | 说明 | 告警阈值建议 |
|---|---|---|
| P99 Latency | 99%的请求响应时间 | > 10秒(视业务而定) |
| Error Rate | Agent执行出错的比例 | > 1% |
| Token Consumption | 每分钟消耗的Token数量 | 突增 > 200% |
| Tool Usage | 各工具被调用的频率 | 核心工具调用降为零 |
P99延迟:用户体验的“底线”
为什么关注P99而不是平均延迟?假设你有100个请求,其中99个都在1秒内返回,但有1个因为某种原因花了50秒。平均延迟是(99×1 + 50)/100 = 1.49秒,看起来还不错。但P99延迟是50秒,这揭示了真相:最慢的那个用户等了近一分钟。
对于Agent应用,P99延迟最能反映用户体验。10秒的阈值可能看起来很长,但要考虑到Agent可能需要多次调用大模型,每次调用都可能耗时2-3秒。如果阈值设得太低,比如1秒,那告警可能永远不会停。
错误率:1%是分水岭
1%的错误率阈值是一个经验值。对于成熟稳定的系统,错误率应该控制在0.1%以下。但在Agent这种复杂系统中,各种不确定性太多,1%是一个相对合理的警戒线。
需要注意的是,这里的“错误”要准确定义。超时算不算错误?大模型返回空内容算不算错误?工具调用失败但重试成功算不算错误?这些都需要和业务方达成共识。
Token消耗:突发增长是攻击信号
Token消耗的监控有两个作用:成本控制和异常发现。成本控制好理解,我们按量付费,需要知道钱花在哪了。异常发现更有意思:如果某个客户的Token消耗突然增长200%以上,很可能是被攻击了,或者他的业务出现了异常。
这种“突增”告警不能用固定阈值,需要用环比。PromQL的predict_linear函数甚至可以基于历史数据预测未来趋势,提前预警。
工具调用频率:核心功能的心跳
Agent的特色在于调用外部工具。一个客服Agent可能每天调用1000次“查询订单”工具,如果这个调用量突然降为零,即使所有技术指标都正常,也说明业务出问题了——可能是用户问的问题变了,也可能是工具本身不可用。
这个指标需要结合业务来设定。核心工具可以设置“降为零”告警,次要工具可以设置“下降50%”告警。
从数据到洞察:PromQL的魔法
有了这些指标,我们还需要把它们转化为直观的图表和及时的告警。PromQL的强大之处就在这里体现出来了。
比如我们要监控过去5分钟的错误率,可以用这样的查询:
text
sum(rate(agent_request_total{status="error"}[5m]))
/
sum(rate(agent_request_total[5m])) * 100
这个查询的逻辑是:计算5分钟内每秒错误请求数,除以5分钟内每秒总请求数,再乘以100得到百分比。用了rate函数而不是直接计数,是为了避免毛刺,让曲线更平滑。
要监控P99延迟,可以用:
text
histogram_quantile(0.99, sum(rate(agent_request_latency_seconds_bucket[5m])) by (le) )
histogram_quantile函数会根据我们之前分桶的数据,估算出P99延迟的具体数值。注意这里用rate也是必要的,因为histogram的bucket是累积的,需要用rate转化为每秒的速率才能正确计算分位值。
对于Token消耗的突增告警,我们可以设置一个复杂的告警规则:当前1小时的消耗量,超过昨天同时段消耗量的2倍,就触发告警。
text
sum(rate(agent_token_usage_total[1h])) > 2 * sum(rate(agent_token_usage_total[1h] offset 1d))
offset关键字是PromQL的特色,可以轻松获取过去某个时间点的数据。
Grafana仪表盘:让数据“说话”
数据有了,查询有了,最后一步是用Grafana把它可视化。一个设计良好的监控仪表盘应该有三层结构:
第一层是全局概览,放最重要的几个数字:当前请求量、错误率、P99延迟。这一层要让值班人员一眼看出系统整体健康度。
第二层是趋势分析,用折线图展示各项指标的变化趋势,时间范围可以选择6小时、24小时、7天。这一层用于排查问题时看模式、找规律。
第三层是详细分解,可以按Agent类型、按工具、按模型来分解各项指标。比如发现错误率升高了,立刻就能看到是哪个Agent的错误率在升高,是哪个工具调用失败了。
颜色编码也很重要:绿色表示正常,黄色表示警告,红色表示严重。人类对颜色的反应是最快的。
总结:监控体系的核心思想
回到开篇的那个场景,如果你已经按照本文的方法搭建了监控体系,当系统出问题时,你会在第一时间收到告警,打开Grafana就能看到是哪个指标异常,顺着异常指标能快速定位到具体问题——可能是某个工具接口变慢了,可能是某个模型的API密钥过期了,可能是流量突然暴涨需要扩容。
这就是监控体系的价值:变被动救火为主动发现,变黑盒猜测为白盒定位。
总结一下本文的核心要点:
-
监控不是事后补救,而是事前预警。 设计指标时要想着“这个指标出问题了我该怎么办”,否则这个指标就是无用的。
-
指标要少而精。 P99延迟、错误率、Token消耗、工具调用频率,这四个指标已经能覆盖Agent系统90%的问题。
-
Prometheus的三板斧:Counter累加计数,Histogram分布统计,Gauge实时测量,掌握这三个指标类型就够用了。
-
装饰器模式是Agent监控的最佳实践,业务零侵入,维护成本低。
-
告警阈值要动态调整,没有一劳永逸的阈值,要根据实际运行情况持续优化。
最后,监控不是目的,稳定性才是。有了完善的监控体系,我们才能真正做到“稳如泰山”,在复杂多变的AI Agent世界里,掌握主动权。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)