关联运行追踪
一个标识符将整个智能体运行过程串联起来——输入、模型及版本、每次工具调用及其参数和结果、最终动作——形成一条可在数月后重新播放的记录。难点不在于捕获,而在于既要足够完整以重构运行过程,又要足够克制以避免追踪存储库成为其所描述数据的第二份副本。
定义
关联运行追踪是关于智能体运行所做出的所有决策和行为的不可变、单标识符记录。它以极高的保真度进行捕获,以便他人事后能够在无法访问生成该运行的系统的情况下,端到端地重构该运行,并经过脱敏处理,以确保追踪记录不会比源系统更容易成为攻击目标。它是智能体决策的记录,而不是请求日志。
问题
智能体具有非确定性和多步骤的特点,因此无法仅从输出中推断出“发生了什么”。大多数团队确实进行了日志记录,但仍然无法回答为什么特定的运行会做出那样的行为:各步骤分散在不同的系统中且没有共享的标识符,Prompt 被记录为自那以后已发生更改的模板引用,或者从未捕获模型版本,导致无人能分清是行为发生了漂移还是模型发生了漂移。
适用场景
适用于任何其行为后果在日后会被追问的智能体:如追踪记录作为审计线索且可追溯性是义务而非偏好的受监管流程、需要寻找根本原因的事件、客户对结果提出异议,或者需要从真实失败中学习的评估循环。
解决方案
在入口点生成一个运行标识符,并将其传播到每个步骤、服务和重试中。关联性是其全部价值所在:同一运行中未关联的记录只是三条日志,而不是一条追踪。
记录渲染后的提示词,而不是其引用。模板 ID 解析出的是该模板今天的具体内容,这与模型当时看到的并不相同。
在每次调用时同时捕获模型及其版本。如果没有它,事后将无法区分是行为变化还是模型变化。
将工具调用记录为参数加结果,包括失败和重试。仅显示成功调用的追踪所描述的运行在现实中并未发生。
在捕获时进行脱敏,而不是在读取时。在写入记录之前,通过字段级规则丢弃或哈希处理机密和个人数据,因为在查询时应用的脱敏仍会将原始值留在存储中。
在尾部进行采样,而不是在头部。在运行结束后决定保留什么,以便保留错误、升级和异常,而稀释常规的成功记录。
使存储保持只追加(append-only)状态,并为其赋予其所描述的最敏感系统的访问控制权限,而不是日志后端自带的权限。
组件
优势
- 使非确定性故障可诊断:你可以回答为什么这次运行会执行此操作,而不是不断复现直到它再次发生。
- 将记录保存义务转化为具体的产物,而不是一种承诺。重构要么对随机选择的过去运行有效,要么无效。
- 用真实的失败而非虚构的失败来喂养评估,这就是基准测试(benchmark)与回归测试套件(regression suite)之间的区别。
- 将漂移与部署分离开来。通过在记录中包含模型版本,“情况变糟了”就变成了一个有答案的问题。
风险
- 追踪存储是最容易受到攻击的目标:它保存着与其所描述的系统相同的数据,但通常访问控制更弱且保留时间更长。
- 捕获成本随着流量增长,直到有人为了省钱而在头部进行采样,从而悄无声息地移除了恰恰最值得保留的运行记录。
- 脱敏移除了重构所需的内容。过度脱敏是隐蔽的,直到有一天有人试图重放某次运行却无法实现时才会暴露。
- 将数据量误认为覆盖率。数 TB 没有共享标识符的 Span 仍然无法回答关于单次运行的任何一个问题。
不适用场景
- 单步、确定性的调用,其中输入和输出就是全部内容。请求日志已经可以重构这些调用。
- 没有用户且没有合规义务的原型,其追踪流水线的成本超过了你能从中获得的任何收获。
- 适用规则完全禁止保留内容的情况。此时,追踪仅记录决策的发生及其元数据,而内容则不予保留——这是一种不同的产物,假装并非如此会产生该规则旨在避免的法律责任。
技术
示例
- 智能体向错误的客户发送电子邮件的事件。运行标识符将返回错误记录的检索、使用该记录的工具调用以及发送的消息关联起来,因此根本原因在于某一次查询,而不是耗费一周时间去尝试复现。
- 监管机构询问六个月前是如何做出某项决策的。重放路径仅凭追踪即可重建该运行,包括当天生效的模型版本。
- 模型升级后质量下降。因为每个 Span 都带有模型版本,所以对比是在两组真实运行的数据之间进行,而不是凭主观印象。
KPI
- 重构成功率
- 仅凭追踪即可端到端重建的随机选择的过去运行的比例。这是该控制项自身的测试,也是此处唯一一个无法通过捕获更多数据来满足的数字。
- 关联完整性
- 一次运行中带有运行标识符的 Span 比例。任何低于 100% 的情况都意味着某些步骤是不可见的,而缺失的步骤往往不是无关紧要的步骤。
- 敏感字段逃逸率
- 抽样记录中包含脱敏规则本应移除的值的比例。目标是零;任何其他数字都意味着追踪存储正在累积法律责任。
- 异常运行保留率
- 采样后保留的出错或升级运行的比例。基于头部的采样会使该指标趋向于采样率,而这正是该指标旨在捕获的失效情况。
已观测到的失效模式
- 无法证明任何事情的追踪:记录了每个步骤,但没有步骤共享标识符,重构一次运行意味着需要手动关联时间戳。
- 通过引用记录的提示词。模板发生了变化,因此日志现在描述的是模型从未见过的提示词,而且直到重构与输出相矛盾时才有人注意到。
- 保留常规记录的头部采样。你需要的运行在入口点就被丢弃了,而当时还没有人知道它会变得有价值。
- 作为泄露源的日志:原始工具参数将个人数据带入了一个比其来源数据库具有更广泛访问权限和更长保留期限的存储中。
- 缺失模型版本。行为变化和静默的模型更新在记录中看起来完全相同,导致调查卡在了一个本应由追踪来回答的问题上。
经验教训
- 关联性是最终产物,捕获只是原材料。购买了追踪后端却跳过标识符的团队,最终得到的只是存储空间而不是答案。
- 测试重构,而不是流水线。随机选择一次过去的运行并重建它——缺陷总是存在于没有人进行插桩的地方,只有尝试才能发现它们。
- 在写入时进行脱敏。任何推迟到读取时的脱敏都是保留原始值的决定,而存储的寿命往往比意图更长。
- 在尾部进行采样。基于头部的采样是在知道哪些运行有价值之前,就做出了丢弃这些有价值运行的决定。
- 在所有地方记录模型版本。它只占用一个字段,却能决定你是能诊断漂移还是只能为此争论不休。
常见问题
- 我们已经使用了追踪后端。这难道还没有解决吗?
- 后端为你提供捕获和存储。而此模式关注的是后端无法为你决定的三件事:是否有一个标识符贯穿整个运行、保真度是否足以在没有源系统的情况下重构它,以及你记录的内容是否可以安全保留。拥有优秀工具链的团队也经常无法通过重构测试。
- 完整捕获是否与数据最小化原则相冲突?
- 如果捕获意味着保留所有原始数据,那确实会冲突。该控制项有意兼顾了这两个方面——既足以重构,又不会使日志变成泄露源——而兼顾两者的关键在于捕获时的字段级脱敏,以及与证明记录合理性的合规义务相绑定的保留期限。你不能通过保留所有内容并称之为合规来消除这种张力。
- 多高的保真度才足够?
- 恰好足以通过对随机抽取的运行进行的重构测试即可,无需更多。这个阈值可以通过尝试来发现,这就是为什么该测试应该属于日常工作而不是审计。超出此范围捕获的任何内容都是成本和法律责任,而无法回答任何问题。