AI Agent 工程实践(17):Agent 为什么需要可观测性(Observability)?

📅 2026/7/24 8:04:59 👁️ 阅读次数 📝 编程学习
AI Agent 工程实践(17):Agent 为什么需要可观测性(Observability)?

发布时间:2026-07-12
标签:AI Agent|LLM|Observability|可观测性|工程实践


系列导航

上一篇:AI Agent 工程实践(16):Agent 为什么需要状态(State)?
下一篇: AI Agent 工程实践(18):Agent 如何做 Benchmark?

本文是 [AI Agent 工程实践] 系列的第 17 篇(第二季 · 工程实现)。


Agent 上线第二周,用户投诉"答案不对"。我去查日志,发现 Agent 调了三个 Tool、做了五次 LLM 推理、中间还重试了两回——但没有任何记录告诉我,到底是哪个环节出了错。

是 Prompt 写偏了?是 LLM 幻觉了?是 Tool 返回了脏数据?是重试时状态乱了?完全不知道。像一个病人说"我不舒服",但没有体温计、没有血常规、没有 CT——你只知道他病了,不知道病在哪。

那一刻我意识到,Agent 缺了最后一道防线:Observability。没有它,Agent 就是一个黑箱——你只知道它做错了,不知道它为什么做错。这一篇,把黑箱切开。


本文你将学到

✓ 为什么 Agent 的 Observability 和传统后端完全不同——不是日志就够了
✓ 四个被忽视的核心概念:Trail(留痕)/ Audit(审计)/ Trace(追踪)/ Benchmark(评测)
✓ 完整观测链路:Prompt → LLM → Tool → Latency → Trace → Metrics
✓ 一个可落地的 Agent 观测数据模型——直接套用到项目里

适合阅读

✓ Agent 上线后发现"出了错不知道谁的责任"的人
✓ 用 LangSmith / LangFuse / Arize 但不确定该记什么的开发者
✓ 意识到"Agent 不只是调 LLM——它是多步推理 + 多工具调用的复杂系统"的人


问题背景

Agent 的调试比传统后端难一个数量级。传统后端出问题时,你查一条 SQL、看一个函数的出入参,基本能定位。Agent 出错时,你的排查链路可能是:

"到底是哪一步错了?"Agent 跑了五步——Planning → Tool A 调用 → LLM 推理 → Tool B 调用 → Review。最后答案不对,但每一步单独看都没大毛病。问题出在步骤之间的组合效应,单步日志看不出来。

"是 LLM 的问题还是 Tool 的问题?"LLM 返回了正确的函数调用,但 Tool 返回了过期数据导致推理偏差——责任在 Tool,但表象是 LLM"胡说了"。没有 Trace 串起来,你会调错方向。

"为什么同样的输入,这次对了上次错了?"不是灵异事件——是中间某个 Tool 的返回变了一点点,导致了蝴蝶效应。没有 Benchmark 做回归对比,你永远发现不了。

"用户的数据隐私有没有被泄漏给 LLM?"审计合规问题——你的 Agent 把用户的 PII 传给了一个第三方 Tool。没有 Audit Trail,你连"有没有泄漏"都不知道。

一句话:Agent 不是单步函数调用,是多步推理 + 多工具调用的复杂系统。你不能只观测"最后结果对不对"——你要观测每一步、每个环节、每条决策链路。


错误尝试

第一次:只记最终输出

上线后只记录了"用户问了什么、Agent 回了什么"。觉得中间过程不重要。

结果:出错时完全不知道怎么排查——只知道"答案错了",不知道为什么错。观测最终输出 = 只看了电影的最后一帧,却想搞清楚整个剧情。

第二次:把 Agent 当普通 Web 服务打日志

照搬后端那套——每个 Tool 调用前后打一条INFO日志,每条 LLM 请求记一次。

结果:日志很快爆炸——一次复杂任务可能产生 50+ 条日志。没有 Trace 把它们串起来时,50 条分散的日志比 0 条日志更难用。日志量 ≠ 可观测性。没有结构化、没有关联,日志就是噪音。

两次尝试指向同一个教训:Agent 的可观测性,不能靠"最终结果"(太粗),也不能靠"打散日志"(太细没关联)。需要一个中间层——把每一步串成一条完整的 Trace,再在 Trace 上做 Audit 和 Benchmark。


关键观察

我把"Agent 排错的时间"和"有没有可观测"做了对比:

排错场景无可观测有可观测
LLM 幻觉导致错误靠感觉怀疑"可能是 LLM 的问题"Trace 显示该步 LLM 输出偏离预期
Tool 返回脏数据不知道,反复调 LLM 试Trace 显示 Tool 返回了过期数据
性能瓶颈在哪猜"可能是 Tool A 慢"Latency Trace 精确到每步耗时
新版本比旧版本差在哪靠用户反馈感知Benchmark 回归对比

没有可观测性的 Agent 是黑箱——你只知道它做错了,不知道它为什么做错。

60% 的排错时间耗在"定位",不是"修复"。Observability 把定位从小时级降到分钟级。

四个概念的精确区别

这四个是本文最核心的概念辨析:

概念回答什么问题数据粒度典型产出
Trail(留痕)"谁做了什么"事件级审计日志
Audit(审计)"为什么做出这个决策"决策级决策追溯链
Trace(追踪)"经过哪些环节、每步耗时多少"请求级调用链 + 火焰图
Benchmark(评测)"这次的质量和以前比怎么样"任务级质量分数 + 回归报告

四者不是平行关系,是递进关系:Trail 是原始数据(事件记录)→ Audit 在 Trail 上做决策追溯 → Trace 在 Trail 上做性能分析 → Benchmark 在 Trace 和 Trail 上做质量量化。先有 Trail,才有后面的一切。


最终方案:Agent Observability 四件套

观测链路:Prompt → LLM → Tool → Latency → Trace → Metrics

你给的六步链路——每步观测什么清楚:

每一步观测什么

  • Prompt:版本号(模板改了不知道,排查就是噩梦)、参数填充结果
  • LLM:input/output tokens、模型名、temperature、完整的 prompt + response
  • Tool:工具名、入参、出参、耗时、是否成功
  • Latency:每步耗时(LLM 推理时间 / Tool 响应时间 / 端到端总时间)
  • Trace:Trace ID + Span ——把上面所有步串成一条完整的调用链
  • Metrics:成功率、平均延迟、token 消耗、用户反馈分数

Trail + Audit:决策可追溯

# 一个完整的 Trace 数据结构 trace_id: "trace_20260712_001" user_id: "user_42" task: "查询订单状态并生成报告" spans: - id: span_1 type: llm_call model: claude-sonnet-4-20250514 input_tokens: 1200 output_tokens: 340 latency_ms: 1200 prompt_version: "v2.3" - id: span_2 type: tool_call tool: db_query input: { sql: "SELECT status FROM orders WHERE id=?" } output: { status: "shipped" } latency_ms: 45 - id: span_3 type: llm_call input_tokens: 800 output_tokens: 520 latency_ms: 900 decision_chain: # Audit:为什么得出这个结论 - "span_1: LLM 决定需要查询订单" - "span_2: 查询返回 shipped" - "span_3: LLM 基于 shipped 生成报告" final_output: "您的订单已于 7 月 10 日发货..." benchmark_score: 4.2 # Benchmark:这次的质量分数

Audit 不是独立系统——它是 Trace 上的一条"决策链"视图。你不需要额外存审计数据,只要 Trace 存得好,Audit 是 Trace 的一种查询方式。

Trace:调用链串联

Trace 是 Agent Observability 的骨架——没有 Trace ID,所有 Span 是孤岛:

@trace(span_type="llm_call") async def llm_invoke(prompt, model): # 自动记录:input/output tokens、latency、model return await model.generate(prompt) @trace(span_type="tool_call") async def tool_execute(tool_name, args): # 自动记录:tool_name、args、result、latency result = await tools[tool_name](**args) return result

所有 Span 在同一个 Trace ID 下自动串起来。出问题时,不是翻 50 条分散日志——是查一条 Trace,看到完整链路。

Benchmark:质量可量化

Benchmark 回答最核心的问题:这次运行的质量,和上次比是变好还是变差?

不是"感觉变差了"——是上次平均分 4.2、这次 3.8,下降了 0.4。Benchmark 不需要复杂——用户反馈评分(👍/👎)、人工抽检分数、自动评测(RAGAS 等)都可以。


架构图 / 流程图

Agent Observability 的完整架构

关键点:Trace Store 是唯一数据源——Audit / Metrics / Benchmark 都是 Trace 的不同查询视图。不额外维护数据,只维护一种数据(Trace),多种用途。


代码或配置示例

最小可落地的 Trace 记录

class AgentTrace: def __init__(self, task_id: str): self.trace_id = f"trace_{task_id}" self.spans = [] self.start_time = now() def span(self, span_type: str, **kwargs): """记录一个 Span——自动计时""" start = now() yield self.spans.append({ "type": span_type, "latency_ms": (now() - start).ms, **kwargs, }) def to_audit_trail(self) -> list: """从 Trace 生成审计链:哪些决策导致了最终结果""" return [ f"{s['type']}: {s.get('summary', '')}" for s in self.spans if s["type"] in ("llm_call", "tool_call") ]

从 Trace 到 Benchmark

def benchmark_score(trace: AgentTrace, user_rating: int) -> float: """综合质量分:用户反馈 + 系统指标""" total_latency = sum(s["latency_ms"] for s in trace.spans) latency_penalty = 1.0 if total_latency < 5000 else 0.7 # 5s 内不加罚 return user_rating * latency_penalty # 简单加权

代码不长,但最小可行——有 Trace ID 串联、有 Latency 记录、能从 Trace 生成 Audit Trail、能算出 Benchmark 分数。Observability 不需要一开始就上全套平台——先把这些数据记下来,后面怎么用都好说。


设计权衡

候选方案优点缺点为什么不选
只记最终输出零成本无法排查只看最后一帧
全量打散日志信息多无关联、噪音大、存储爆炸50条无关联日志比0条更差
上全套平台(LangSmith等)功能全初期重、集成成本高先记数据,平台可以后上
结构化 Trace + 四视图轻量、可演进需设计 Span 结构选择理由:先记对数据,工具可迭代

不一定要上全套观测平台。第一版:结构化 Trace → 存数据库 → SQL 查 Audit → Grafana 看 Metrics → 手动 Benchmark。平台可以迭代,但 Trace 数据结构一旦设计错了,改的代价极高。先想清楚"记什么",再想"用什么记"。


总结

✅ 没有 Observability 的 Agent 是黑箱——你知道错了,不知道错在哪。
✅ 四个概念递进:Trail(留痕·原始数据)→ Audit(审计·决策追溯)→ Trace(追踪·性能链路)→ Benchmark(评测·质量量化)。
✅ 完整观测链路:Prompt → LLM → Tool → Latency → Trace → Metrics,每步观测什么从第一天就该明确。
✅ Trace Store 是唯一数据源——Audit / Metrics / Benchmark 都是 Trace 的不同查询视图。
✅ 先记对数据,再选工具——Trace 数据结构设计错了,后面的一切都是错的。


参考资料

  • LangSmith / LangFuse 文档→ Agent 追踪与审计的工程实现参考
  • OpenTelemetry→ 分布式追踪标准,Agent Trace 的概念参照
  • 第 16 篇:Agent State→ State 的 history 是可观测性的第一步
  • 第 04 篇:Review 复盘机制→ Review 需要数据,Observability 提供数据
  • 第 15 篇:RAG 知识治理→ Evaluate 闭环依赖 Benchmark 数据

系列导航

上一篇:AI Agent 工程实践(16):Agent 为什么需要状态(State)?
下一篇: AI Agent 工程实践(18):Agent 如何做 Benchmark?

本文是 [AI Agent 工程实践] 系列的第 17 篇(第二季 · 工程实现)。