重新精确表述这一发现
四分之一的 agent 部署在无监控状态下运行。常见的解读是组织层面的:团队交付太快,没有人对可靠性负责,治理滞后。这种解读令人安心,但基本是错的。当一个系统没有稳定的步骤边界、没有共享的关联标识符、没有 span schema 时,监控就不是纪律问题——而是缺失的原语。你无法靠堆 dashboard 来弥补一个从未发出你想要告警的事件的架构。
为什么监控会被跳过
框架输出的是日志,不是 trace。 典型的 agent 循环写的是人类可读的行:发送了 prompt、选择了工具、解析了响应。日志行产生成本低,但几乎无法聚合。没有父子关系、没有时长、没有状态字段、没有属性命名空间。查询“哪些运行调用了退款工具超过三次”变成了对非结构化文本做正则匹配,这就是为什么没有人去构建这个告警。
数据分散在不同系统中。 模型调用在推理提供商那里。工具调用在应用日志里。检索在向量存储里。策略决策在网关里。每个系统对同一个逻辑操作都有自己的标识符,而且彼此不一致。如果没有在运行边界生成、并传播到每一跳的关联 ID,重建单个 agent 步骤就需要按时间戳 join 四家厂商的导出数据——而一旦两次调用落在同一毫秒内,这种方法就会失效。
埋点是在上线之后才加的。 等到团队决定需要 trace 时,agent 已经重构了两次,工具已经被包上了重试逻辑,步骤边界已经消融成一串异步回调。事后补 span 意味着重新定义什么才算一个步骤,这是设计变更,而不是可观测性变更。它会因为要与功能开发竞争、且在首次严重事故之前没有可见的用户影响而被无限期推迟。
把埋点作为构建期契约

另一种做法是把可观测性视为 agent 接口的一部分,像类型签名或 schema 迁移一样强制执行。
每个步骤都发出一个 span。 步骤是系统能够独立重试、拒绝或计费的任何单元:一次模型调用、一次工具调用、一次检索、一次策略评估。span 携带输入、输出、成本、延迟以及允许该操作的政策决策。成本不是事后从 token 数推导出来的指标;它是发出时写入的属性,因为定价会变化,而在长保留窗口上做追溯重算正是审计轨迹的葬身之地。
关联 ID 跨边界传播。 运行 ID 只生成一次,然后贯穿出站 HTTP 头、数据库会话上下文和消息队列元数据。具体机制是由运行时注入、由每个适配器读取的上下文对象,因此调用外部 API 的工具不需要知道自己正在被追踪——HTTP 客户端包装器附加请求头,数据库驱动设置会话变量,队列发布者复制该字段。当下游服务记录同一个 ID 时,trace 就端到端闭合了,无需手工拼接。
采样策略要事先声明。 对每次运行做全保真追踪,在大规模下很少负担得起。构建期契约要说明采样策略:哪些运行始终被追踪(被拒绝的操作、高成本运行、每次部署的前 N 次),哪些按概率采样,以及什么会被丢弃。采样决策在根 span 处做出,这样被采样掉的一次运行是一致地缺席,而不是半存在——后者正是让 trace 数据不可信的失败模式。
一个最小的 span schema 长这样:
{
"trace_id": "run_8f2c...",
"span_id": "step_01",
"parent_span_id": null,
"kind": "model.invoke",
"started_at": "2025-01-01T10:00:00.000Z",
"duration_ms": 812,
"attributes": {
"model": "...",
"input_tokens": 1042,
"output_tokens": 233,
"cost_units": 0.0041,
"policy_decision": "allow",
"policy_rule": "read_only_tools"
},
"status": "ok"
}
权衡是真实存在的:每个适配器都必须参与,而只要有一个工具没有埋点,整条链就断了。缓解办法是让运行时拒绝执行不接受上下文对象的工具——这是编译期或启动期的检查,而不是运行期的指望。这一约束不受那

trace 只有在能回答关于具体操作的问题时才有用。
可查询性是审计的试金石。 一个无法按工具名、参数哈希、策略规则或操作者过滤的 trace 只是调试辅助,不是审计轨迹。这意味着 schema 必须包含监管者和事故响应者会问到的字段,而不只是框架碰巧发出的字段。如果“展示所有 agent 在没有人审批 span 的情况下调用支付工具的运行”这个问题无法用单次查询回答,那么埋点就是不完整的。
对行为不变量告警。 错误计数是 agent 系统中最弱的信号,因为失败模式通常是一次本不该发生的成功调用。有用的不变量是结构性的:每次运行的工具调用率对照声明的上限、每次运行的花费对照预算属性、被拒绝操作的数量、检索与模型调用的比率,以及工具出现在其许可策略集之外。这些都可以从 span 计算得出,并且在模型升级后保持稳定,不像延迟阈值会随提供商变化而漂移。
保留与脱敏属于 schema 的一部分。 事后才决定哪些字段包含个人数据,意味着要重新处理历史 trace,这既昂贵,而且一旦原始载荷已经消失往往就不可能。相反,在定义时就把每个属性标记为保留、哈希或脱敏,让管道在写入时应用规则。代价是脱敏字段的调试保真度降低,以及 schema 必须随分类规则变化而版本化。这个成本低于在收到数据主体访问请求时才发现 prompt 和工具输出正躺在某家可观测性厂商的存储里、没有任何字段级策略。
当这成为构建期要求时,会发生什么变化
“四分之一 agent”这个统计数字描述的是一群从未拥有这些原语的系统。那些在启动前就定义步骤边界、生成运行 ID、将其传播到每个适配器并声明采样与保留策略的团队,之后面对的不是一个监控决策——而是一次 schema 迁移,这是一项被充分理解的工程任务。令人不适的部分在于,这项工作发生在有任何可见问题来证明其必要性之前,而且它会限制新工具添加的速度。这就是诚实的权衡:以更慢的工具集成为代价,换取一个其行为可以被重建、查询和控制的系统。另一种选择是一群 agent,它们之所以被信任,恰恰是因为没有人能看到它们在做什么。
封面照片:Suki Lee / Pexels。
