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 篇(第二季 · 工程实现)。

相关推荐
冬奇Lab1 小时前
开源项目第167期:Buzz — Block 开源的人机协作工作空间,Agent 是成员不是 Bot
人工智能·开源·agent
提笔了无痕1 小时前
MySQL SQL 从 EXPLAIN 到索引优化,搞懂 SQL 为什么慢
android·sql·mysql
zhangphil2 小时前
Android OAID是什么?有什么功用?
android
KaneLogger3 小时前
花了2天写了个全平台的技能管理工具
aigc·agent·ai编程
ZhengEnCi4 小时前
什么是 Luke(循环工程)
llm
Android-Flutter4 小时前
android fragment 使用
android·kotlin
玉鸯4 小时前
Agent Harness 工程核心架构拆解与 300 行代码实现
python·agent
ZhengEnCi4 小时前
长上下文时代,RAG 还有必要吗?— 从企业级实践出发的深度分析
llm
迷茫中的自我4 小时前
KMP全栈开发:从Android到AI Agent的技术演进与实践
android·人工智能