第 25 章 · 可观测性
Harness 锚点|判别清单第 7 项「可观察性」——基于会话格式的追踪、成本与调试。
那笔说不清的账单
那个卖家的选品 Agent 上线一周后,他收到 API 账单——比预估高了三倍。他想弄明白钱花哪了:是哪个卖家用得凶?哪类调研最烧 token?还是某个 Agent 卡在死循环里空转了一夜?他打开系统一看——什么记录都没有。他不知道 Agent 当时想了什么、调了哪些工具、每步花了多少 token、在哪一步出的错。这笔账,查无可查。
Agent 天生比传统程序更难观测:它的行为是非确定的(non-deterministic)(同样输入可能不同输出)、多步的(multi-step)(一次任务几十步)、烧钱的(costly)(每步都是 API 调用)。传统程序你还能靠“复现 bug”来排查,Agent 很多问题只发生一次、无法复现。没有可观测性,生产 Agent 就是个定时炸弹。
可观测性的三支柱:日志、追踪、指标
可观测性(Observability) 的核心,是让系统的内部状态从外部可见。业界把它拆成经典的“三支柱(three pillars)”,对 Agent 一样适用:
- 日志(Logs):记录“发生了什么”。每条消息、每次工具调用、每个错误,都是一条带时间戳的离散事件。日志回答的是“这一刻具体发生了什么”。
- 追踪(Traces):记录“一次任务的完整链路”。从用户请求到最终答案,中间每一步的顺序、耗时、输入输出——像一棵调用树(每个节点是一次模型调用或工具调用)。追踪回答的是“这次任务到底走了哪条路径”。
- 指标(Metrics):量化的数字。token 用量、成本、延迟、成功率、工具调用次数——可聚合、可画曲线、可设告警。指标回答的是“整体趋势和健康度如何”。
三者互补:指标告诉你“出问题了”(成本曲线突然抬头),追踪告诉你“哪一次任务出的问题、走到哪断的”,日志告诉你“那一步具体错在哪”。
为什么追踪对 Agent 尤其重要
三支柱里,追踪(trace) 对 Agent 是重中之重。
传统 Web 请求往往是“一进一出”——收到请求、查个库、返回结果,链路很短。而一次 Agent 任务是多步的,甚至是多 Agent 的:它可能想了五步、调了三个工具、其中一个工具又触发了子 Agent……这条链路又长又分叉。出了问题,你需要看到的不是某一条孤立日志,而是“这次任务完整地走了哪条路径、每步花了多久、输入输出是什么、在哪个节点断的”。
这就是 trace 的价值:它把散落的日志按一次任务的因果顺序串成一棵树,让你能顺着链路一步步回放。对 Agent 来说,一条完整的 trace,基本等于“把它当时的思考和行动全程录像”。
用 pi 实现:会话格式就是天然的追踪
这里 pi 有个巧妙之处:它的会话格式(session format)(第 12 章)本身就是一份结构化的完整记录。
回顾一下,pi 的会话持久化在 ~/.pi/agent/sessions/,每条消息都带元数据——角色、内容、工具调用、token 数、时间戳。这意味着:一次 Agent 任务的完整轨迹,已经天然地存在会话文件里了。你不需要额外埋点(instrumentation),会话本身就是一条 trace。
基于这个基础,可观测性可以这样做:
// 会话本身即追踪:读取一个会话,就能还原完整执行链路
const session = await pi.loadSession(sessionId);
for (const msg of session.messages) {
console.log({
role: msg.role, // user / assistant / tool
tool: msg.toolCall?.name, // 调用了哪个工具
tokens: msg.usage?.total, // 花了多少 token
at: msg.timestamp, // 什么时候
});
}
// 汇总成指标
const totalCost = session.messages.reduce((s, m) => s + (m.cost ?? 0), 0);
再加上 pi 的 SDK(docs/sdk.md),你可以把这些数据导出到专业的可观测平台——比如遵循 OpenTelemetry 标准接到 Logfire、Langfuse、Grafana 等。而 pi-ai 层(第 23 章)在模型调用处统一记录 token 和定价,让成本追踪(cost attribution) 变得准确——这直接连到下一章的预算控制。
技术可观测不等于经营可评估
日志能告诉你工具有没有报错,Trace 能告诉你 Agent 走了哪条路径,但它们不能自动回答“这项能力是否改善了经营结果”。要回答后一个问题,必须让一次 Agent 运行与业务对象、流程状态和最终结果关联起来。
| 指标层级 | 要回答的问题 | 指标示例 |
|---|---|---|
| 经营结果 | 这项能力最终创造或保护了什么价值? | 转化率、履约时效、缺货率、解决率、退款损失 |
| 流程结果 | 目标流程是否更快、更稳、更少返工? | 处理时长、一次通过率、转人工率、异常积压 |
| AI 质量 | 判断、检索和执行是否正确? | 任务成功率、引用正确率、工具参数正确率 |
| 风险治理 | 是否越权、误执行或违反业务规则? | 策略拦截率、错误审批、敏感数据访问、事故数 |
| 成本与采用 | 单位结果是否划算,团队是否真正使用? | 单任务成本、人工复核成本、活跃使用率、放弃率 |
把业务关联标识带进 Trace
除 sessionId、userId 和 tenantId 外,生产 Trace 还应携带 capabilityId(哪项 AI 能力)、businessObjectId(哪笔订单/线索/工单)、workflowState(执行前后状态)、outcomeOwner(结果负责人)和 experimentVersion(模型、Prompt、策略组合)。最终业务结果可能几小时或几天后才出现,因此还需要一个回写机制,把结果异步关联到原始 Trace。
没有业务关联标识,可观测性只能帮助工程团队解释“系统发生了什么”;有了结果回写,它才能帮助业务团队判断“这项能力值不值得继续投入”。
可观测性的三个实际用途
有了三支柱的数据,它们在生产里主要派三个用场:
- 调试(debugging):Agent 行为异常时,翻出那次会话(trace),一步步看它当时想了什么、调了什么、哪步的输出不对劲——问题往往一目了然。这也是为什么“会话即追踪”这么值钱:异常本来难复现,但轨迹已经录下来了。
- 成本归因(cost attribution):哪个用户、哪类任务、哪个工具最烧钱?卖家那笔翻三倍的账单,有了按会话/用户聚合的指标就能定位到元凶,才谈得上优化。
- 质量评估(quality evaluation):成功率、平均步数、常见失败模式——这些聚合指标是持续改进 Agent 的依据,也是判断“改了提示到底有没有变好”的标尺。
从观测到评测:把真实会话变成回归集
可观测性还有一个经常被低估的价值:它是评测数据的来源。
很多团队一开始做 Agent 评测,会凭空编一批问题。但最有价值的样本,其实来自真实会话:
线上失败会话 → 抽取输入、工具轨迹、错误点 → 写成 golden case → 每次发布前回放
pi 的会话格式天然适合这件事,因为你能从 trace 里看到:
- 用户原始问题是什么。
- Agent 调了哪些工具、参数是什么。
- RAG 命中了哪些来源。
- 哪一步 token / 成本异常。
- 最终回答是否引用了正确依据。
把这些会话沉淀进附录 D 那种任务集,你就有了一套不断长大的回归测试。以后改 prompt、换模型、重建 RAG 索引,不再靠“我感觉更好了”,而是跑一遍真实样本,看关键行为有没有退化。
从第一天就记录
可观测性最容易犯的错,是“等出了问题再想加”。但前面说过,Agent 很多问题只发生一次、无法复现——如果当时没记录,就永远查不到了。你没法对着一个已经消失的现象打断点。
所以有一条铁律:从第一天起就持久化会话、记录 token 和成本。这不是等系统“成熟了”才做的锦上添花,而是地基。pi 默认就在做前者(会话持久化),你要做的是别关掉它、并把关键指标接出来。埋点这件事,晚一天,就可能永久丢掉一批本可查清的问题。
真实案例:pi-app 让长会话“不再是黑箱”
可观测性不只是给工程师看的后台指标,也能直接做进用户界面。pi 的 Web 界面 pi-app 就把 Agent 的内部状态摆到了最显眼的位置——它在顶部实时显示:
- 上下文占用:当前用了多少窗口,离压缩还有多远(第 9 章)。
- 花费:这个会话到目前花了多少钱(靠
pi-ai的准确定价)。 - 压缩结果:什么时候压缩过、压掉了什么。
- 系统提示:当前生效的系统提示是什么。
pi-app 团队对这个功能的描述一针见血——“长会话不再像黑箱”。这正是本章的核心:可观测性就是让系统的内部状态从外部可见。它还印证了“会话即追踪”的思路——因为一次会话的完整轨迹已经结构化地存在文件里,pi-app 只是把它读出来、展示给人看,不需要额外埋点。
一个启发:面向用户的 Agent 产品,值得把成本、上下文、压缩这些“内部状态”也变成 UI 的一部分——用户对一个能看到自己“想什么、花多少”的 Agent,信任度会高得多。
动手看看
随便跑一个多步任务,然后直接去 ~/.pi/agent/sessions/ 打开对应的会话文件——你会看到每条消息的角色、工具调用、token、时间戳全在里面。对照本章说的“三支柱”,想想这一份文件里其实同时藏着日志(每条消息)、追踪(整条链路)和指标(把 token 一加就是)。
再写个十行的小脚本,遍历一个会话把每步的 tool 和 tokens 打出来、末尾累加出总成本。跑一遍你就体会到“会话即追踪”不是口号——不埋一个点,你已经能还原整次任务并算清这笔账。
实战中的几个坑
坑一:等出了问题才想起加可观测。
- 现象:线上冒出个诡异行为,想查却发现什么都没记,而它再也不复现了。
- 原因:把可观测当成“后期优化”,没从第一天做。
- 对策:第一天就持久化会话、记 token 和成本;pi 默认记会话,别手贱关掉。
坑二:日志记了,但串不成一次任务。
- 现象:满屏离散日志,却看不出“这条错误属于哪次任务、前后发生了什么”。
- 原因:只有日志、没有追踪,缺少把事件串成链路的 trace/会话 ID。
- 对策:给每次任务一个会话/trace ID,让所有事件挂到同一条 trace 上(pi 的会话天然就是这条 trace)。
坑三:成本算不准,归不到人。
- 现象:总账单知道,但说不清哪个用户/任务/工具烧的。
- 原因:token 和定价没在统一的一层记录,或没按维度打标签。
- 对策:在模型层(pi-ai)统一记 token 与定价,给每次调用打上用户/任务标签,才能聚合归因。
坑四:埋点太重,拖慢 Agent 或撑爆存储。
- 现象:为了“全都记”,把每条巨大的工具输出原样落盘,存储和延迟双双失控。
- 原因:没区分“该记摘要”和“该记全量”。
- 对策:关键元数据(角色、工具名、token、耗时)全记,巨大内容做截断/摘要;按需采样,别无脑全量。
对比:其他框架
可观测性各家投入差别很大,都围绕“追踪每一步 + 记录 token 与成本”展开。
| 框架 | 可观测性怎么做 | 特点 |
|---|---|---|
| LangGraph | 一等平台 LangSmith:追踪、评估、成本一站式,图的每个节点/每次调用都能可视化 | 四家里可观测最成熟 |
| CrewAI | 不带专门追踪平台,靠回调/日志或接第三方(OpenTelemetry、外部追踪服务) | 需自行接入 |
| PydanticAI | 与 Logfire 深度集成(基于 OpenTelemetry),直接追踪运行、工具调用、结构化输出 | 观测体验是它的亮点 |
| Agno | AgentOS 内建监控面板,直接看运行、token 与成本 | 开箱即用 |
| pi | 会话格式本身就是结构化追踪,无需埋点;pi-ai 统一记 token 与成本,可经 SDK 导出到 OpenTelemetry 等 | 追踪几乎免费,导出靠标准协议 |
一句话点破:各家差别只在“平台现不现成、埋点重不重”——但共性是一致的:围绕 trace 把一次任务串起来,并在模型层统一记 token 与成本。理解这个共性,接哪家的可观测平台你都知道该导出什么。
小结
- Agent 非确定、多步、烧钱,很多问题只发生一次,没有可观测性就是定时炸弹。
- 三支柱:日志(发生了什么)、追踪(完整链路)、指标(量化数字)——对 Agent,追踪(trace) 尤其关键,它把散落事件按因果串成一棵可回放的树。
- pi 的会话格式本身就是天然的追踪,无需额外埋点;
pi-ai层在模型调用处统一记录 token 与成本,可经 SDK 导出到 OpenTelemetry 等外部平台。 - 三大用途:调试(回放异常会话)、成本归因(定位烧钱的人/任务/工具)、质量评估(成功率、步数、失败模式)。
- 真实会话可以沉淀成附录 D 的回归测试集,让 prompt、模型、RAG 和工具变更都有客观对照。
- 从第一天就记录——很多问题当时没记就永远查不到;pi-app “长会话不再是黑箱”正是把内部状态变成 UI 的示范。
可观测性让我们“看得见”成本。下一部分 Part 8,我们进入企业级特性,第一件事就是“管得住”成本——Token 预算控制。