Agent AtlasAI Agent 知识库
05.04工程化 · Engineering

可观测性与调试

Trace、Span、Token、工具调用与回放:Agent 出问题时,如何定位到具体那一步。

Agent 出问题时,日志里只有一句「回答不对」。你需要知道:它看到了什么、选了哪个工具、传了什么参数、模型为什么这么决定。

Trace 与 Span

一次用户请求是一条 Trace,其中的每个操作是一个 Span:

text
trace: task_8f2c  (总耗时 12.4s, 18,930 token)
├─ span: input_guard       12ms
├─ span: retrieve          340ms
│   ├─ span: embed         80ms
│   └─ span: vector_search 210ms
├─ span: llm_call_1        2.1s   (model=..., 4,200 in / 180 out)
├─ span: tool:search_docs  620ms  (ok, 3 results)
├─ span: llm_call_2        1.8s
├─ span: tool:create_refund 410ms (ok, refund_id=...)
├─ span: llm_call_3        3.2s
└─ span: output_guard      9ms

没有这种树状结构,你只能看到「总耗时 12 秒」,无法知道是检索慢、模型慢,还是重试了三次。

每个 Span 要记录什么

字段说明
trace_id / span_id / parent_id关联关系
name操作名,如 llm.chat、tool.search
start_time / end_time耗时
statusok / error / cancelled
model / provider模型版本
prompt_version提示词版本号
input_tokens / output_tokens成本
temperature / max_tokens参数
tool_name / arguments / result_summary工具调用
error_code / error_message错误
user_id / tenant_id归因(脱敏)
session_id / task_id多轮与任务关联

不要记录完整提示词和完整工具返回(体积大、含敏感信息)。记录哈希、长度、摘要,需要时再按 ID 取原文。

提示词版本化

提示词必须能对应到一次具体运行:

json
{
  "prompt_id": "support_agent",
  "prompt_version": "v14",
  "prompt_hash": "sha256:9f2c...",
  "template_vars": { "locale": "zh-CN", "plan": "pro" }
}

没有版本号,你无法回答「上周通过率下降是不是因为改了提示」。提示词应该和代码一起提交、一起发布。

工具调用要记录成败与参数

工具是最容易出问题的环节:

  • 模型传错参数;
  • 权限不足;
  • 超时;
  • 返回空结果;
  • 部分失败。

记录:

json
{
  "tool": "create_refund",
  "arguments": { "order_id": "A1024", "amount": 299.0 },
  "status": "error",
  "error_code": "AMOUNT_EXCEEDS_PAID",
  "retryable": false,
  "duration_ms": 210
}

参数可能含 PII,入库前脱敏;但保留结构,便于统计「哪个字段最容易错」。

指标面板

至少四组:

质量

  • 任务成功率;
  • 人工接管率;
  • 用户重试/重新生成率;
  • 评估集通过率(按版本)。

过程

  • 平均步数 / P95 步数;
  • 工具调用次数与错误率;
  • 死循环检测次数;
  • 重试率;
  • 拒答率。

性能

  • TTFT;
  • 端到端 P50/P95/P99;
  • 各 Span 耗时占比;
  • 队列等待时间。

成本

  • 每任务 token;
  • 每任务金额;
  • 缓存命中率;
  • 按模型/工具/租户拆分。

把这四组放在一个面板上,能快速判断「变慢了」是模型、工具还是流量。

调试工作流

  1. 定位 Trace:按 task_id、用户、时间、错误码找到具体请求;
  2. 看时间线:哪一步最慢?哪一步开始偏离?
  3. 看上下文:模型当时看到了什么?检索结果相关吗?工具返回完整吗?
  4. 看决策:为什么选这个工具?参数从哪来?
  5. 复现:用相同的模型版本、提示版本、工具 mock 重跑;
  6. 修复:改提示/工具/流程;
  7. 回归:加入评估集,防止再犯。

可回放(replay)是 Agent 可观测性的核心能力。理想情况下,能回到任意一步,修改状态后从那里继续。

采样与成本

全量记录成本高。策略:

  • 错误全量:所有失败请求完整记录;
  • 慢请求全量:P95 以上全量;
  • 正常请求采样:1%–10%;
  • 高风险动作全量:退款、发送、删除;
  • 保留期分层:原始 trace 7–30 天,聚合指标长期保留。

常见工具

工具特点
OpenTelemetry标准协议,可对接任意后端;GenAI 语义约定在完善
Langfuse开源,trace、评估、提示管理一体
LangSmith与 LangChain 生态结合紧密
Arize Phoenix开源,偏评估与可观测
Helicone网关层,易接入,成本分析
Braintrust评估与实验管理

自建也不难:OpenTelemetry + ClickHouse/BigQuery + Grafana。关键是字段设计一致。

告警

不要只告警「错误率」。Agent 特有的信号:

  • 平均步数突然上升(可能陷入循环);
  • 工具错误率上升(下游 API 变了);
  • 拒答率上升(检索/提示坏了);
  • 单任务成本突增;
  • P95 延迟突增;
  • 某租户错误率异常(隔离问题);
  • 评估集通过率下降(发版回归)。

告警要带 trace 链接和最近一次失败样本,否则值班的人还得自己找。

隐私与合规

  • 日志脱敏:手机号、邮箱、身份证、地址、token;
  • 提示词里不放大段 PII;
  • 工具参数按字段脱敏,而不是整条丢弃;
  • 支持按用户删除 trace;
  • 跨境数据存储要合规;
  • 访问日志本身要审计。

反模式

只记最终输出

出问题无法定位。至少记录工具调用、模型调用、错误。

记录完整提示词

体积大、含敏感信息、检索困难。记录版本 + 哈希 + 摘要。

trace 不关联业务 ID

用户投诉时找不到对应请求。task_id、session_id、user_id 必须贯穿。

没有提示版本

无法归因。提示词必须版本化。

只做聚合指标

平均值掩盖长尾。要看 P95/P99 和失败样本。

检查清单

  • 每次请求有 trace_id,贯穿所有调用
  • LLM、工具、检索、审批都有 span
  • 记录模型、提示版本、token、耗时、错误
  • 工具参数与结果有摘要,PII 脱敏
  • 有质量、过程、性能、成本四组面板
  • 错误与慢请求全量保留,正常采样
  • 能按 trace 回放与复现
  • 关键异常有告警与样本链接

小结

  • Agent 调试依赖树状 trace,而不是一行日志。
  • 模型、提示版本、工具参数、token、错误,一个都不能少。
  • 指标要覆盖质量、过程、性能、成本。
  • 错误全量、正常采样,兼顾成本与可追溯。
  • 可回放是从「猜」到「定位」的关键。

下一篇讲失败时怎么兜住:可靠性工程。

读完了?进度会保存在本地浏览器。
内容会持续修订。发现错误或想补充,欢迎反馈。 遇到问题?查排查手册 →