审计追踪的不匹配:当用户、智能体和工具各有各的日志时
一名监管人员给你发了一封邮件,只问了一个问题:该用户是否授权了这笔交易?六小时后,三名工程师正在聊天频道里,试图将聊天界面的对话日志、规划代理(planner agent)的推理追踪以及工具的 API 记录关联起来。聊天日志记录了轮次 ID(turn ID)和用户可见的消息,但没有工具调用的细节。规划器追踪记录了工具调用的记录,其时间戳与聊天日志相差几百毫秒。工具日志记录了 API 调用及其自身的关联 ID(correlation ID),而该 ID 在代理的记录中无处寻觅。下游服务的日志则有另一个 ID,且没有回溯链接。团队最终通过关联用户 ID 和大致的时间戳重建了答案,祈祷没有什么关键信息因错过一个轮次而产生偏差,最后向法务部门提交了一份 PDF 文件。
这就是审计追踪不匹配(audit trail mismatch)。每一层的负责人(owner)都认为自己的日志没问题——而且从单体来看,它们确实没问题。缺失的产物是那个本应存在的“关联视图(joined view)”,并且没人为它的缺失负责。团队只有在发生事故、客户升级投 诉或监管机构强制要求关联数据时,才会发现它并不存在。
这种情况之所以会发生,是因为“代理”其实是由独立系统组成的流水线,每个系统都有自己的可观测性方案,并且由不同的团队在不同的时间进行埋点。聊天界面发布的是侧重于用户可见内容的“产品日志”。代理运行时发布的是侧重于规划步骤和提示词构建的“开发人员日志”。工具发布的是侧重于请求和响应的“API 日志”。下游服务发布的是侧重于自身 SLO 的“集成日志”。这四个日志中有三个早在代理出现之前的数年就已经存在,而且没有一个是为参与单一的端到端叙事而设计的。
四个互不一致的日志
为了让这种失败变得具体,让我们跟踪一个典型的代理栈中的单一用户操作,并查看每一层捕捉到了什么。
用户在聊天界面输入“发送第二季度报告给我的 CFO”。聊天日志记录了一个轮次 ID、用户的文本、助手可见的回复以及会话 ID。它不记录模型发出的工具调用,也无法记录——聊天日志是在工具调用出现之前编写的,并将其视为不透明的内部流量。
代理运行时日志记录了一个规划器追踪:系统提示词(system prompt)、组装好的上下文、规划器选择的工具、构建的参数以及总结的响应。它有自己的请求 ID。回到聊天界面的链接是“用户 ID + 大致相同的时间戳”,因为聊天界面没有传递关联标头(correlation header)。
工具日志记录了一个 API 调用:方法名、参数、HTTP 状态、延迟、租户 ID 以及 工具自身的关联 ID。代理运行时通过一个不透传运行时请求 ID 的 SDK 调用了该工具,因此工具日志只能通过租户和时间戳与代理日志关联。
下游服务日志——即实际发送报告的邮件提供商——记录了一个消息 ID、接收者、附件哈希和发送时间。工具通过一个不转发上游 ID 的供应商 SDK 发送请求。邮件提供商在边界处标记了一个全新的消息 ID。
四个日志。四种 ID 方案。零重叠。关联它们需要(用户 ID 或 租户 ID)且(带容差的时间戳)——这种查询返回错误行的频率与不可靠的集成测试一样高,而且是悄无声息地出错。关于“该用户是否授权了这笔交易”的审计故事是由人工通过交叉引用活动窗口重建的,而且每当用户的会话包含多个工具调用时,情况就会变得更糟。
需要放在同一个记录中的三个事实
修复方案不是“增加更多日志”。每一层都已经记录了足够多的日志。修复方案是认识到代理操作承载了合规审查需要共同恢复的三个截然不同的事实,并围绕这些事实设计审计记录,而不是围绕每个子系统易于输出的内容来设计。
这三个事实是:用户请求了什么、代理决定为此做什么以及工具实际执行了什么。它们并不是同一个陈述。用户请求的是“发送第二季度报告给我的 CFO”。代理决定使用从上下文中推导出的特定附件、接收者和主题来调用 email.send。工具执行了一个产生消息 ID 的 HTTP POST,并由下游提供商处理,而该提供商可能遵循也可能没有遵循每一个标头。
仅捕获其中一个事实(用户的文本、规划器的意图或 API 的效果)的日志在个体上是真实的,但在回答授权问题时集体失效。监管机构关心的是关联:用户请求了 X,系统推断出 X',现实世界接收到了 X''。X 和 X'' 之间的偏差才是合规问题的核心,而当每一层的日志只知道三者之一时,这种偏差就无法被检测到。
一个可行的代理操作审计记录应该是一个包含所有三个事实的单一文档,在操作完成的那一刻编写一次,并由用户操作边界处生成的交易 ID(transaction ID)进行索引。聊天层、代理层、工具层和下游层各自照常记录日志——但它们也会将交易 ID 输出到各自的日志中,一个专门的审计流水线通过读取交易的权威追踪来组装这“三个事实”记录,而不是在事后关联四个异构的日志流。
- https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-agent-spans/
- https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/
- https://artificialintelligenceact.eu/article/12/
- https://artificialintelligenceact.eu/article/19/
- https://www.helpnetsecurity.com/2026/04/16/eu-ai-act-logging-requirements/
- https://tetrate.io/learn/ai/mcp/mcp-audit-logging
- https://www.loginradius.com/blog/engineering/auditing-and-logging-ai-agent-activity
- https://galileo.ai/blog/ai-agent-compliance-governance-audit-trails-risk-management
- https://www.getmaxim.ai/articles/ai-agent-audit-logs-full-visibility-over-tool-usage/
- https://scalardynamic.com/resources/articles/21-when-logs-lie-how-clock-drift-skews-reality-and-breaks-systems
- https://oneuptime.com/blog/post/2026-02-06-resolve-clock-skew-opentelemetry-distributed-traces/view
- https://www.oreilly.com/library/view/mastering-distributed-tracing/9781788628464/ch03s07.html
- https://www.datadoghq.com/blog/llm-otel-semantic-convention/
- https://langwatch.ai/blog/trace-ids-llm-observability-and-distributed-tracing
- https://portkey.ai/blog/the-complete-guide-to-llm-observability/
