作为一名在AI工程方向折腾了好几年的开发者,我这两年最大的感受是:做AI Agent项目,最难的不是把模型接进来,也不是把工具链调通,而是当Agent上线之后,你根本不知道它在生产环境里干了什么。传统应用再有Bug,日志一拉、链路一追,总能定位;但Agent不一样,它每次的思考路径都可能不同,工具调用是多步嵌套的,输出结果还带着不确定性。你问它为什么这么做,它自己都解释不清。没有可观测性,做Agent就是在闭眼开车。
AI Agent可观测性,本质上就是给这个“黑盒”装上一套仪表盘:它输入了什么、理解了哪些意图、规划了哪些步骤、调用了哪些工具、拿到了什么结果、最终生成了什么答案,以及整个过程中消耗了多少token、花了多长时间、有没有出现语义偏差。这套体系不是简单加几条日志,而是要覆盖追踪(Tracing)、日志(Logging)、指标(Metrics)和评估(Evaluation)四个层面。
这篇文章我会结合自己实际踩坑的经验,把Agent可观测性的底层逻辑、设计方案、代码接入方法和排障技巧一次说透。不管你是刚入门的AI应用开发者,还是已经在负责Agent生产系统的工程师,读完应该都能直接上手。
1. AI Agent可观测性是什么:先搞懂你要监控的对象
AI Agent本质上是一个由大语言模型驱动的决策引擎。它接收用户意图,把一个大任务拆成若干子任务,然后循环执行“规划—行动—观察”这个闭环,直到得出最终结果。这跟传统后端服务完全不是一个逻辑,所以可观测性的设计思路也必须转换。
1.1 Agent不是普通服务:运行流程与传统可观测性的差异
传统软件的可观测性有一套成熟的三支柱体系:日志、指标、追踪。这套体系在微服务时代非常好用,因为所有请求路径都是代码写死的,任何一个入口进来的请求,都有明确的执行路线,Trace ID可以把各个服务的调用串联起来,哪个环节慢、哪个环节报错,一目了然。
但Agent的问题在于,它的核心算法是一套没有源码、无法断点调试的LLM。你没法在模型内部埋点,更没法通过堆栈信息定位“它为什么会这样想”。一次Agent运行,更像是一连串动态规划的决策过程。比如用户让你“查一下明天的天气,再根据天气情况给我写一封外出发货通知邮件”,Agent可能需要先调用天气API,再根据返回结果生成邮件,再调用邮件接口发出。这中间,它可能反复调整几次才能确定最终方案。传统监控能看到的,只是三次API调用各自的状态码和耗时,但看不到Agent为什么选择这样组合工具,更看不到如果第一次调用失败它如何改变策略。
这时候,可观测性的核心问题就从“系统是否正常”变成了“模型决策是否符合预期”。这要求我们不仅记录“发生了什么”,还要记录“模型接收了什么、输出了什么、它的推理过程是什么、最终结果是否合理”。这也是为什么AI可观测性领域最终指向了Tracing、Evaluation和Guardrails三个关键词的融合。
1.2 想要看清楚,先拆解Agent运行的六个关键环节
我在多次实践中梳理了一个Agent运行观测框架,核心是拆成六个观测点。这六个观测点,基本能覆盖一次Agent运行的所有重要信息:
| 观测点 | 需要记录的信息 | 典型问题 |
|---|---|---|
| 输入理解 | 用户原始输入、系统Prompt、上下文窗口内容 | Prompt注入、上下文被截断 |
| 规划决策 | LLM中间推理结果、选中的动作序列 | 逻辑混乱、重复规划 |
| 工具调用 | 工具名、参数、返回结果、耗时、错误码 | 工具超时、参数格式错误 |
| 上下文更新 | 新增了哪些观察结果、如何整合 | 上下文溢出、关键信息丢失 |
| 输出生成 | 最终回答、结构化输出、置信度 | 输出格式不符、模型幻觉 |
| 成本性能 | token消耗、API调用次数、延迟 | 成本失控、性能瓶颈 |
这张表是我每次给团队做Agent可观测性分享都会拿出来的。你会发现,相较传统监控只关心状态和性能,Agent观测更多了一层“语义正确性”。什么叫语义正确性?就是比如用户问“我上次的订单为什么还没发货”,如果Agent明明可以调用订单查询工具,却根据记忆脑补了一个不存在的发货状态,系统层面可能一切正常,但业务层面已经出大事故了。
所以,Agent可观测性不是简单地在代码里多打几个Log,而是要从“输入—决策—执行—反馈—输出—成本”的角度重新设计数据采集方案。只有这样,出了问题才能回溯到具体是哪一步的模型判断出了问题,而不是毫无头绪地把锅甩给“AI不可控”。
2. AI Agent可观测性为什么难:四大核心痛点拆解
先说清楚难在哪儿。很多人以为给Agent加上日志就行,但真正做了以后,你会发现难点远比想象中多。我把这两年遇到的障碍归纳成四类,几乎每一个都是传统可观测性方案解决不了的。
2.1 LLM的不确定性让传统日志形同虚设
传统软件的日志是确定性的,某一行代码执行了,就会产生一条日志;某个异常抛出了,就一定会记录错误。但在Agent里,LLM的输出是概率性的。同一个问题问十遍,十遍的思考轨迹可能都不重样。
这种不确定性让“断点—检查—修复”的传统调试方式基本失效。你打了20条调试日志,也很难复现问题的确切路径。我印象最深的一次Bug:Agent在处理用户关于订单状态的询问时,本来应该调用订单查询工具,结果模型在某个版本里突然“自作主张”,直接根据历史对话脑补了一个状态。从日志看,一切正常,没有报错,没有异常,但用户拿到的答案是错的。
这种问题,只有当你把模型的输入、输出和决策过程都记录下来,形成一个可回放的轨迹,才可能定位到“模型在那个时刻为什么选择跳过工具”。所以,Agent可观测性必须包含语义层面的信息,而不只是系统层面的日志。
2.2 多步推理与工具调用链路复杂,平铺日志难定位
Agent经常会走多轮交互。以最经典的ReAct模式为例,一个复杂任务要经历“思考→行动→观察→再思考→再行动”的多轮循环,每一轮还可能派生多个候选动作。最终Agent可能只执行了其中一个,但那些“未选择”的路径,恰恰可能藏着问题的答案。
此外,每个工具调用本身又是一个独立的请求—响应周期,可能涉及鉴权、重试、超时。多个工具之间还存在依赖关系:A工具的结果会决定B工具的调用参数,B工具的结果又会影响C工具的调用策略。如果把这些信息平铺成一个日志文件,排查问题时会非常痛苦,只能靠人肉把所有线索拼接起来。
我举一个实际场景。用户要求“搜索最近一周的行业新闻,汇总成摘要,发送到指定邮箱”。Agent先调用了搜索API,然后根据结果写了一版摘要,再调用了邮件API。这是三层嵌套逻辑。假如邮件发送失败,你要从邮件发送的日志往回追,先看摘要文本是否合规,还要看搜索关键词是否准确。如果没有一个把整条链路串起来的Trace结构,单靠查日志,等待你的只能是一宿无眠。
所以,Agent可观测性必须建立在“追踪树”或者“调用链”的概念之上。一次完整的Agent运行,应该对应一个树状结构,树干是推理循环,每个分支是工具调用或子Agent执行,这样才能把复杂路径理清楚。
2.3 语义化错误与静默失败:系统没报错,答案却错了
Agent系统里最令人头疼的是“静默失败”。什么叫静默失败?代码没有崩溃,接口没有抛异常,但最终结果完全不对。这种错误,传统监控系统是感知不到的。
举例来说,工具返回了一段JSON,LLM在解析时发现某个字段缺失。但Agent内部的异常处理可能把这个错误吞掉了,模型决定“忽略这个错误”,继续基于不完整的信息回答。在日志里,你只能看到一条“字段解析失败”的警告,但这警告对最终答案的影响有多大,日志完全说不清。
我们之前有一个RAG类Agent,系统Prompt里要求模型必须引用知识库里的原文。但偶尔模型会直接凭常识回答,完全忽略检索结果。从系统监控看,检索服务返回正常,LLM调用也返回正常,唯独答案本身是错的。这种“看着合理,实则编造”的幻觉类错误,只有引入评估环节才能抓出来。
所谓评估,就是给Agent每次输出打一个“语义正确性”或“任务完成度”的分数。比如用另一个更强大的Judge模型来审查答案是否忠于上下文、是否有幻觉、是否满足用户约束条件。如果分数低于阈值,再触发告警,让人工介入。这是AI Agent可观测性区别于传统APM最核心的地方。
2.4 成本与性能指标:token消耗和延迟成为新瓶颈
最后是成本与性能。Agent是非常消耗token的,一个多步推理任务可能轻松吃掉几万个token。与传统API监控不同,你需要精确跟踪每次Agent运行的input token、output token、缓存命中率、模型单价,否则月底看账单会非常“惊喜”。
我们之前做过一次优化,把系统Prompt压缩了30%,响应时间直接下降了40%。这个收益如果靠人工感知,很难发现。只有通过指标监控,看到平均token数和延迟的走势,才能知道改动到底有没有效。性能方面也一样,Agent的响应时间主要取决于LLM推理时间,推理时间又与输入长度正相关。上下文越长,延迟越高,两者是强关联的。
因此,Agent可观测性里,至少要包含以下几项指标:每次对话的token消耗量、按场景/用户维度的成本分布、平均响应延迟和P95延迟、模型调用失败率、工具调用失败率、缓存命中率等。这些指标如果还能跟Trace关联起来,就能直接定位“哪次Agent运行最贵”“哪个工具最拖慢速度”。
3. 可观测性体系设计:从trace到evaluation的完整拼图
理解了难点,我们再来看怎么做体系设计。这套体系我习惯用一个缩写来记:L-S-T-E,也就是Logging、Span Tracing、Metrics、Evaluation。四者缺一不可,但各有侧重。
3.1 Tracing:用Span还原Agent的每一次决策
Tracing是整套体系的骨架。没有它,其他一切都是散沙。Tracing的核心概念是Span。在Agent场景里,每个关键动作都生成一个Span,多个Span再组合成一个Trace。
我通常会把Agent一次完整的运行拆成这几个Span:
agent.run:最外层的根Span,代表一次Agent运行,包含用户ID、会话ID、整体耗时。agent.plan:规划步骤的Span,记录LLM接收到的Prompt和输出的推理过程。agent.tool_call:工具调用Span,记录工具名、参数、返回结果、错误信息。agent.memory:上下文读写Span,记录对话历史如何更新、哪些内容被写入记忆。agent.output:输出Span,记录最终回复内容和模型置信度。
每个Span都必须记录开始时间、结束时间、状态和父子关系。相当于构建了一张Agent运行的“决策地图”。我更倾向于把Prompt和Response都挂到Span的attribute里——对,这会增加存储成本,但价值非常大。模型到底有没有“听话”,看到原始输入输出才能判断。
有人会问,每次运行都存Prompt和Response,数据量不是爆炸吗?确实。我一般会做采样策略:对于完整会话、异常请求、高成本请求,全量保存;对普通请求,按10%到20%采样。这样既保留诊断能力,又控制了成本。
3.2 Logging:给异常诊断留一张“现场底稿”
日志的作用在Agent场景下有所退位,但没有它也不行。我现在的做法是,把日志定位为“辅助诊断”而非“主要依据”。主要用于记录三类信息:
第一,关键阶段的输入输出摘要,尤其是工具调用返回的错误信息。比如某次工具超时、解析失败、网络异常,这些摘要要短小精悍,方便快速扫读。
第二,异常事件,比如JSON解析失败、上下文截断、token超限、模型重试次数超限等。这些事件单独成一条日志,并且必须带上Trace ID和Span ID。
第三,业务层的“里程碑”动作,比如“用户取消了会话”“Agent尝试了三次仍未成功,转为人工兜底”。这些业务信号与系统日志相辅相成,能帮你判断用户侧发生了什么。
我要特别强调,所有日志都要能做关联跳转。也就是说,每条日志都要有trace_id和span_id字段。这样,你在看日志时发现一条“工具调用返回500”,点一下就能跳到对应的Trace里,看到完整的上下文。
3.3 Metrics:量化Agent整体健康度
指标是用来回答“系统整体健康吗”这个问题的。在Agent场景,我建议至少建立四类指标。
性能指标包括平均响应延迟、P95延迟、首token生成时间、工具调用耗时。稳定性指标包括Agent运行失败率、工具调用失败率、异常退出率。成本指标包括token消耗总量、平均每次请求token数、按模型和场景拆分的成本。业务指标包括任务完成率、用户满意度评分、人工介入率。
这些指标最终做成Dashboard,每次Agent版本更新后,我都会对比新旧版本在同一批指标上的表现,用它来判断新Prompt或新工具配置是否真的带来了提升。而不只是凭感觉说“好像变聪明了”。有一次,我们换了一个更大的模型,任务完成率确实涨了,但P95延迟从2秒涨到6秒,成本翻了三倍。通过指标卡对比,团队很快决定对部分简单场景回退到小模型,成本直接降回来,延迟也恢复。
3.4 Evaluation:判断Agent答得好不好,而不只是没报错
Evaluation是整个体系里,最容易被忽略但价值最高的部分。传统APM回答的是“系统有没有崩溃”,而Eval回答的是“Agent事情办得好不好”。
Eval分两类。一类是离线评估,在发布前,用一组固定的测试集去跑Agent,然后用规则或者一个Judge模型给结果打分,看版本是否达标再上线。另一类是在线评估,在真实生产环境中,对Agent的每个回答自动打分,分数低于阈值则告警或转人工。
在线评估怎么做最省事?我的方案是加一个“评判模型”(Judge LLM),让它对Agent的输入、输出和中间步骤进行审核。它可以判断:最终回答是否基于上下文,是否存在幻觉,是否遵循用户的隐性约束,语气是否合适,答案是否完整。打分会是一个结构化JSON,比如:
{ "score": 8, "hallucination": false, "missing_info": ["收货地址"], "reason": "回答基本正确,但未主动询问用户的具体收货地址" }这个打分的JSON会和当时的Trace关联起来,存到可观测性平台里。一旦发现某个会话得分过低,就可以顺着分数跳到Trace,看到底是哪一步出现了偏差。没有Evaluation的Agent可观测性,只能算做到了“能看”,还没做到“能评判”。
4. 实操:为Agent项目接入可观测性的完整过程
理论说再多,不如跑一遍代码。这一章我会从工具选型开始,然后给出一个用Langfuse实现的带Tracing的Agent最小示例,最后讲讲埋点设计的落地方式。
4.1 工具选型对比:Langfuse、LangSmith与OpenTelemetry
市面上的AI可观测性工具越来越多,我实际用过的主要有三类。先把结论放上:没有绝对最好的工具,只看你的使用场景。
| 工具 | 特点 | 接入成本 | 适合场景 |
|---|---|---|---|
| LangSmith | LangChain生态深度集成,Trace、Eval、Hub都有 | 低 | 快速原型验证、中小规模项目 |
| Langfuse | 开源,支持自托管,Trace、Prompt管理、成本分析齐全 | 中 | 数据敏感、私有化部署、精细成本控制 |
| OpenTelemetry + 自建后端 | 标准协议,可扩展强,能融入现有监控体系 | 高 | 大型企业、Agent只是系统一部分 |
我对LangSmith的评价是“体验最顺滑”,尤其是跟LangChain配合时,几乎零代码接入。但如果你用的是自研Agent框架,或者对数据隐私要求很高,LangSmith的云服务模式会让你有顾虑。Langfuse的好处在于开源且可以自己部署,数据全部在自己手里,而且它不仅做Tracing,还内置了Prompt版本管理和成本分析,对生产环境很友好。
至于OpenTelemetry,它本身不是一套Agent可观测性方案,而是一种标准协议。如果你的团队已经有成熟的监控平台,想把Agent调用也统一纳入链路追踪体系,那用它最合适。成本高在需要自己搭建采集器、存储和展示端,但一旦搭好,收益也很稳定,标准统一,不会被某个商业工具绑定。
4.2 代码实操:用Langfuse给Agent加上Tracing
接下来,我用一个最简单的Python示例,演示如何用Langfuse给Agent加可观测性。假设我们的Agent是一个带工具调用的助手,支持查询天气等功能。
首先安装依赖:
pip install langfuse openai初始化Langfuse客户端:
from langfuse import Langfuse langfuse = Langfuse( public_key="pk-xxx", secret_key="sk-xxx", host="https://cloud.langfuse.com" # 如果是自部署,改成你自己的地址 )创建Trace并添加Span:
trace = langfuse.trace( name="agent-run", user_id="user_123", session_id="conv_456" ) with trace.span(name="agent.plan") as span: # 模拟LLM规划 plan_result = "call_tool(weather_api, city=北京)" span.update( input={"query": "北京今天适合跑步吗?"}, output={"plan": plan_result} ) with trace.span( name="agent.tool_call", input={"tool": "weather_api", "params": {"city": "北京"}} ) as span: # 模拟工具调用 tool_result = {"temp": 18, "wind": "3级", "aqi": 45} span.update(output=tool_result)如果你希望细致记录LLM调用的token消耗,可以用Generation类型:
generation = trace.generation( name="llm-call", model="gpt-4o-mini", input={"prompt": "你是天气预报助手,请总结天气信息"}, output={"content": "北京今天18度,微风,空气质量优,适合跑步"}, usage={"input": 1200, "output": 300, "total": 1500} )这个Generation接口会自动帮你统计token和费用,在Langfuse的Dashboard里,可以看到每次Agent运行花了多少钱、每个模型的调用占比是多少。
在实际的Agent中,这些Span的创建应该放在主循环的对应位置,确保每次规划、工具调用、输出都生成对应的Span。我一般还会在agent.tool_call里增加错误字段,比如把tool_result["error"]记下来。这样当工具失败时,Trace里能看到失败原因,而不需要翻底层日志。
4.3 埋点设计:用Observer模式解耦可观测性逻辑
接入Langfuse很简单,但真正工程化时,我建议做得更系统一点。不要在每个工具调用里到处塞可观测性代码,那样代码会变得很难维护。更优雅的是一个统一的Observer接口,把可观测性逻辑和业务逻辑解耦。
一个参考设计:
from typing import Protocol class AgentObserver(Protocol): def on_start(self, task: str) -> None: ... def on_plan(self, plan: str) -> None: ... def on_tool_call(self, tool_name: str, params: dict, result: dict) -> None: ... def on_error(self, error: Exception) -> None: ... def on_finish(self, answer: str, cost: float) -> None: ...然后写一个基于Langfuse的实现类:
class LangfuseObserver: def __init__(self): self.langfuse = Langfuse(public_key="pk-xxx", secret_key="sk-xxx") self.current_trace = None def on_start(self, task): self.current_trace = self.langfuse.trace(name="agent-run", input={"task": task}) def on_plan(self, plan): self.current_trace.span(name="agent.plan", input={"plan": plan}) def on_tool_call(self, tool_name, params, result): self.current_trace.span( name="agent.tool_call", input={"tool": tool_name, "params": params}, output={"result": result} ) def on_error(self, error): self.current_trace.span( name="agent.error", output={"error": str(error)} ) def on_finish(self, answer, cost): self.current_trace.span( name="agent.output", output={"answer": answer, "cost": cost} )在Agent主循环里,只调用Observer接口,不直接依赖Langfuse。以后想切换回LangSmith或OpenTelemetry,只需要换一个Observer实现,Agent核心代码一行都不用动。这就是我在项目里推荐的架构:可观测性是一个“旁路系统”,不应该侵入Agent的核心逻辑。
埋点设计还需要注意几个细节:
- 原始的大文本(比如完整Prompt、长文档上下文)不建议直接存到可观测性平台的属性里,里面的有用信息要先做摘要,全文可以存到对象存储,再在Trace里引一个链接地址。
- 涉及用户隐私的字段,必须在进可观测性平台前做脱敏,最好用哈希或掩码处理。
- 每个请求必须保证有全局唯一的
trace_id和conversation_id,并且贯穿上下所有环节。
5. 常见问题与排查技巧实录
工具接好了,埋点也加上了,但真正上线后,你会发现可观测性帮你看到的问题,往往比预想中要多得多。这一章我挑几个高频问题,讲一讲我自己的排查经验。
5.1 Agent“死循环”:明明结果一样,为什么还在重试
有段时间,我们的Agent在生产环境频繁超时,通过Trace发现它在同一轮循环里反复调用同一个工具超过20次。每一次返回的结果一模一样,但Agent仍然选择重试,既没有尝试新策略,也没有向用户坦白“我搞不定”。
这个问题的根因,是模型在拿到同样的错误反馈后,没有足够的“跳出”信号。比如天气API返回了“city not found”,模型可能认为这是临时错误,所以一遍遍重试。光在前端提示词里加“如果失败就停止”根本不够,因为模型在循环中的短期记忆会逐渐忽略这句约束。
我的排查流程是:先去Trace里数一下agent.plan和agent.tool_call的循环次数,确认是不是同一个动作反复出现。然后观察工具返回的错误信息是否具有区分度。如果错误都是相似的,就要在Agent框架层强加一个“最大循环次数”限制,比如最多执行5轮,超出后触发兜底逻辑。我们还改进了系统Prompt,加入一句“如果你连续两次拿到相同的结果,请换一种方式处理,或者直接告诉用户无法完成”。效果立竿见影。
5.2 模型输出格式不稳定:JSON解析失败的背后
另一个高频问题,是Agent要求LLM输出JSON,但模型偶尔会在JSON前后加一段解释性文字,导致解析器崩溃。日志里会报JSONDecodeError,但Agent通常会选择重试一次,有时候碰巧成功,有时候一直失败。
这类问题的处理,不建议靠无限重试。重试白白增加cost,还可能放大延迟。更好的方案是:Prompt里明确要求“只输出JSON,不要任何多余内容”,并且在系统里多给两个few-shot示例。如果模型服务商支持JSON Mode或者结构化输出,直接打开这个功能,从模型侧约束格式。
在排查时,Trace里的agent.outputSpan记录了模型返回的原文,你可以直接看到它是怎么不听话的。有一次我们发现模型在JSON前输出了句“好的,以下是你需要的结果:”,原因是我们用的提示词模板里,有一个示例的回复用了这样的表达,模型的few-shot学习把多余的礼貌用语也学会了。排查到这一步,就非常清晰了。
5.3 上下文被截断:Agent开始“一本正经地胡说八道”
多轮会话里,上下文窗口满之后Agent会主动截断,这是个大坑。尤其当Agent先调用了几个工具,把一批工具结果写进上下文,再继续后面的决策时,早期的关键信息很容易被“挤出去”。系统日志里都是context truncated警告,但Agent本身不会因为这个报错,它就是在缺失信息的基础上继续作答,而且答得理直气壮。
我们的排查方法是:在Trace里看每个Span的token数量变化,找到是哪个环节导致token数暴增。同时关注上下文管理策略,看它是简单粗暴地从最早对话开始丢,还是用了更智能的摘要压缩或向量检索。对于重要场景,我会专门为“上下文截断次数”配置告警,如果某个会话截断超过3次,自动转接人工。这样即使模型自己无法判断信息是否完整,人工兜底也能保证服务质量。
5.4 Agent可观测性排查速查表
把日常高频现象和排查方向整理成一个速查表,方便大家遇到问题时快速定位方向:
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| 答非所问 | 上下文被截断、RAG检索结果不相关 | 看Trace里的context token变化、检索结果 |
| 同一动作反复执行 | 模型陷入循环、工具错误信号不清晰 | 数agent.plan循环次数,检查工具错误字段 |
| 工具调用总失败 | 参数生成错误、工具本身不稳定 | 看工具调用Span的参数和返回错误码 |
| 回答前后矛盾 | 多轮历史管理混乱、关键信息丢失 | 检查memory span和上下文更新策略 |
| 答案看着合理但实际是编的 | 模型幻觉 | 配合Evaluation打分,并人工复核这条Trace |
| 成本突然暴涨 | prompt过长、重试过多、死循环 | 查看token消耗指标,定位最贵的Trace |
这些排查技巧,如果没有一套完整可观测性体系,基本是空谈。没有Trace,你连“是不是同一动作反复执行”都看不出来。这也是我反复强调Tracing是地基的原因。
6. 落地路径与未来方向
把整套体系说完了,最后聊聊怎么落地,以及这个方向正在往哪走。
6.1 从零到一:三步搭建Agent可观测性体系
很多团队一开始就想做全套,我的建议是分三步走,不要一口吃成胖子。
第一步,解决“能不能看到”的问题。选一款工具(Langfuse或LangSmith都行),把Agent的主循环用Span包起来,至少覆盖plan、tool_call、output三个关键节点,先做到单次请求内部可回放。
第二步,解决“能不能衡量”的问题。在Trace的基础上,加入指标和Eval。定义好自己业务的核心指标,比如客服Agent的“问题解决率”、订单Agent的“查询成功率”,把这些指标接入可观测性Dashboard。同时建一套离线评估集,在每次版本更新前跑一遍,避免“上线后才知道变差了”。
第三步,解决“能不能自动预警”的问题。把在线Evaluator和告警联动。当Eval分数低于阈值、工具失败率升高、token消耗异常时,自动通知开发或运营。这一步已经具备比较强的生产可用性。
很多团队卡在第一步和第二步之间。我的建议是,先不要纠结指标定义得多完美,只要能把Trace完整记录下来,后面随时可以补Eval和告警。最怕的是Trace都没接,每天都在靠用户反馈猜问题。
6.2 未来方向:可观测性从诊断到自动修复
这个领域变化非常快,我已经看到几个明显的趋势。
第一个趋势,是可观测性和评估的深度融合。未来Tracing平台会把Eval作为一等公民,每个Agent动作都自带语义评估结果。不只是“这一步耗时多少”,还有“这一步决策是否合理”。这会让用户从“发现问题”直接跳到“理解问题”。
第二个趋势,是自动根因分析和修复。现在的可观测性平台只能告诉你哪出了问题,但未来的平台会尝试自动定位到某个Span、某一段Prompt,甚至自动生成修复建议。我们团队已经开始在尝试,让一个专门排查Bug的Agent去读另一个Agent的Trace,判断错误类型并建议修改Prompt。这听起来很赛博,但确实已经在落地了。
第三个趋势,是多Agent系统的可观测性。以前我们追踪的是单个Agent,现在不少场景里已经是多个Agent协作完成任务了,比如一个负责规划、一个负责执行、一个负责审核。多Agent之间的消息传递、委托调用、结果汇总,都需要更复杂的跨Agent调用链追踪能力。这比单Agent的可观测性难度高一个量级,需要基于OpenTelemetry这类标准化协议往下走。
老实说,我一开始做AI Agent可观测性完全是出于无奈——生产环境的Agent问题根本没法排查,无意中摸索出了一套方法。后来才发现,这套体系不仅在排障时救过我,更重要的是它改变了团队对Agent系统的认知方式:从“不可解释的黑盒”变成“可以被理解、被评估、被改进的工程系统”。如果你正准备把Agent推上生产,我建议不要等技术债堆起来再补可观测性,从第一天就把Trace、Log、Metric、Eval这四根柱子打好。到后面你会感谢自己这个决定。