多模态追踪:当各种模态必须共享一个 ID
一位用户拨通了你的客服 Agent。他们说话,Agent 倾听,用户在通话中途上传了一张错误截图,Agent 同时对图片和转写文本进行推理,最后通话以一封总结修复方案的邮件收尾。三天后用户投诉过来:修复没有生效,邮件也从未送达。你打开可观测性栈,发现三个独立 UI 里躺着三条互不相干的追踪。语音流水线给你一条 ASR 追踪。视觉流水线给你一段图片上传的 span。LLM 调用给你一条带 token 数和工具调用的聊天追踪。这些仪表盘里没有任何东西告诉你:它们其实是同一次对话。
这就是没人愿意写的那种复盘。不是因为数据缺失——每一个模态都老老实实记录了它该记录的东西——而是因为跨模态的"接合"从来就没建起来。每条流水线都从自家模型供应商默认配置里长出了自己的追踪约定,而把它们绑在一起的那一次对话轮次,只存在于设计这个 Agent 的那位工程师的脑子里。
多模态首先是一个追踪问题,其次才是一个建模问题。我们花了两年时间争论哪个模型能同时处理文本、像素和波形,几乎没花时间争论:当它真的这么干的时候,我们怎么调 试。结果就是这一代生产级 Agent——happy path 上跑得漂亮,可一旦有人需要回溯实际发生了什么,立刻变成考古项目。
那棵忘了根的 span 树
分布式追踪是建立在一个干净的心智模型之上的。用户点了一下。一个根 span 打开。每一个下游调用都成为一个子 span。父子关系刻画了执行层级,三个月后你能调出这条追踪,看到完整故事。
多模态流水线在大多数团队还没察觉的地方破坏了这个模型。音频开始流式传输的那一刻,语音子系统打开自己的根 span。图片通过另一个通道到达时,视觉子系统打开自己的根 span。当编排器终于触发一次 chat completion,LLM 调用又打开自己的根 span。这些子系统每一个都是由不同团队、用各自 SDK 自带的默认值进行埋点的,没有谁被告知:它们其实都是同一次对话轮次的孩子,而那一次轮次在任何地方都没有表征。
你最后得到的是三棵 span 树,本来它们应该是同一棵树的三条分支。语音追踪有 ASR 延迟和轮换节奏的详尽时序数据。视觉追踪有图片二进制工件和编码流水线。LLM 追踪有 prompt、响应和工具调用。统一它们的那段对话不是 span,甚至不是一个 header。它只是一个事实,存在于你的代码里,而你的遥测管线里没有任何东西知道这个事实本应顺流传递下去。
W3C 的 traceparent header 正是为这种缝合而设计,但它是为通过 HTTP 流动而设计的。当你的模态边界并不是 HTTP 边界时——音频走 WebRTC 管道在流式传输,图片走另一个独立的上传通道,而 LLM 调用是唯一拥有 HTTP 请求可以挂 header 的环节——这套标准的传播机制就悄无声息地失效了。修复办法不是技术性的。修复办法是认识到:你流水线中的每一个模态边界都是上下文可能丢失的地方,要把每一次穿越都当作一次网络调用来埋点。
对话轮次才是真正的工作单元
多模态 Agent 中真正重要的"跳"不是 span,而是轮次。一个轮次是对用户而言有独立意义的最小交互单元:用户说话、Agent 倾听、Agent 思考、Agent 回应。在那个轮次内部,Agent 可能转写音频、检索文档、查看图片、调用工具,并生成一段合成回复。用户并不把这些感知为彼此独立的事件。对用户来说,这一轮要么成了,要么没成。
语音可观测性平台已经开始把轮次视作一等原语——把音频输入、转写候选、prompt 执行、工具调用和合成语音作为一条相互关联的记录来记录。这是正确的抽象,而且它能从语音推广出去。一个多模态轮次就是用户做了什么、以及 Agent 回应了什么,全部串在一个能跨越这一轮所触及的所有模态而存活下来的 ID 之下。
要点是:在用户动作边界处铸造这个 ID——在任何子系统有机会打开自己的 span 之前的那一刻——并把它作为不透明的元数据穿过每一种模态的中间表示。音频帧带上轮次 ID。图片上传带上轮次 ID。工具调用带上轮次 ID。缓存写入带上轮次 ID。LLM 调用最终发生时,它继承轮次 ID。当追踪 UI 加载时,每一个打上这个 ID 标签的 span 都按用户实际经历的顺序排列在同一条时间线上。
这件事比听上去更难,因为轮次 ID 必须在每一个模态把数据移交给另一个模态的地方都能存活下来。视觉流水线吃进一张图片,吐出一个特征向量和一段描述;这两者都得把轮次 ID 向 LLM 一路携带过去。ASR 流水线吃进音频,吐出转写;转写也得带上轮次 ID。负责这些流水线的团队往往没有动力去穿一段他们自己根本不消费的元数据,而消费它的 Agent 团队,只有在有人请他们从日志里重建一次轮次时,才会发现这条缺口。
模型到底看到了什么
最糟糕的多模态复盘是那种最终答案为"我们不知道"的复盘。你有 LLM 的响应。你有用户的投诉。你没有用户上传的图片,因为它进了视觉流水线的 bucket,按自己的留存周期被清掉了。你没有音频,因为它进了 ASR 厂商的存储,你从来没拿过副本。你只有 ASR 产出的转写,而它未必准确反映音频里真正说了什么。
- https://mlflow.org/blog/multimodal-tracing
- https://hamming.ai/blog/voice-agent-observability-voice-observability
- https://hamming.ai/resources/voice-agent-incident-response-runbook
- https://blog.dograh.com/why-observability-matters-in-building-voice-agents-traces-evals-guide/
- https://aos.owasp.org/spec/trace/extend_opentelemetry/
- https://uptrace.dev/blog/opentelemetry-ai-systems
- https://thenewstack.io/jaeger-v2-ai-observability/
- https://oneuptime.com/blog/post/2026-02-06-trace-multimodal-ai-pipelines-opentelemetry/view
