论证为什么 OpenTelemetry 应成为 LLM 应用可观测性标准,对生产环境监控有直接指导价值。
几天前,我和 Chatwoot 联合创始人 Pranav 进行了一次现场对话,讨论他的团队在 LLM 可观测性方面遇到的问题。
简短版本:在生产环境中构建、调试和改进 AI Agent 会迅速变得混乱。LLM 可观测性的默认库存在多个竞争标准。而许多声称基于 OpenTelemetry 的库(如 OpenInference)并不严格遵守其约定。这给试图在整个堆栈上获得更好可观测性的用户带来了问题。
这是我们讨论内容的总结,以及我认为这对任何将 LLM 功能推向真实产品的人意味着什么。欢迎观看完整视频。
我和 Pranav 的渊源可以追溯到 2021 年的 YC 时期,看到我们的道路如何演进总是很有趣。Chatwoot 创建了一些非常引人注目的东西——一个开源客户支持平台,统一了你能想象的每个渠道上的对话:实时聊天、电子邮件、WhatsApp、社交媒体等。一切都在一个仪表板中。
但这里开始变得有趣。他们构建了一个称为 Captain 的 AI Agent,可以在所有这些渠道上工作。你一次构建逻辑,无论支持查询来自电子邮件、实时聊天还是 WhatsApp,它都可以处理。相当不错,是吧?
问题以最出乎意料的方式开始在生产环境中显现。有时他们的 AI 会随机用西班牙语回复,而它绝对不应该这样做。其他时候,回复并不完全正确,他们对原因毫无头绪。
这是 Pranav 开始 LLM 可观测性之旅的地方,也反映了我在许多构建 LLM 应用的公司中看到的情况。你需要理解:
没有这种可见性,你基本上是在生产环境中盲目飞行。
这是事情变得真正有趣,坦白说,令人沮丧的地方。Pranav 探索了几个解决方案:
OpenAI 的原生追踪看起来很有前景,显示了丰富、详细的跟踪,包括防护栏、Agent 流和工具调用。但它紧密耦合到 OpenAI 的 Agent 框架。另外,它只以原子单位提供跟踪。如果你想根据属性筛选 span 或只查看特定的 span,你做不到。
New Relic 易于集成,因为他们已经在使用它,并且它支持 OpenTelemetry。但 UI 需要点击 5-6 层才能看到相关信息。当你试图调试生产问题时,这不太理想。
Phoenix 引起了他们的注意,因为它遵循 OpenInference 标准,提供了更丰富的、特定于 AI 的 span 类型。你可以轻松地筛选只有 LLM 调用、工具调用或 Agent span。跟踪非常漂亮和信息丰富。
但这里是关键所在:Chatwoot 主要是一个 Ruby on Rails 商店,你猜怎么着?没有 OpenInference 的 Ruby SDK。此外,Phoenix 没有完全遵守 OTel 语义约定,所以如果你通过 OpenTelemetry 直接发送遥测数据,它不能识别 span 的类型等。
如上例所示,Phoenix 不会将使用 OpenTelemetry span 类型发送的数据显示为"未知"。
这是对话变得非常技术性并揭示了一个根本性行业问题的地方。本质上有两个标准正在出现:
OpenTelemetry 是行业标准。它有每种语言的库,它是生产就绪的,并被广泛采用。但它是为传统应用而不是 AI 工作流构建的。它只支持基本的 span 类型:internal、server、client、producer、consumer。就这些。
OpenInference 是专门为 AI 应用创建的。它有丰富的 span 类型,如 LLM、tool、chain、embedding、agent 等。你可以轻松查询"显示我所有的 LLM 调用"或"工具执行有哪些"。但它较新,语言支持有限,并且没有被广泛采用。
悲剧的部分是什么?OpenInference 声称"OpenTelemetry 兼容",但正如 Pranav 发现的那样,这种兼容性很肤浅。你可以将 OpenTelemetry 格式数据发送到 Phoenix,但它不能识别 AI 特定的语义,只是将所有内容显示为"未知" span。
对于使用 Ruby 等语言的团队,这些语言没有直接的 OpenInference SDK 支持,这变得更加具有挑战性。Pranav 必须在以下选项中选择:
这些都不是很好的选择。
在 SigNoz,我们全力支持 OpenTelemetry。一个原因是:OTel 的一致性能够跨整个堆栈提供开箱即用的体验。例如:我们可以根据 span 类型和属性自动显示外部 API 使用情况和性能。当应用的某些部分通过非 OTel 约定发送遥测时,这些视图会降级。
Chatwoot 的情况类似:他们的整个产品已经发出 OTel。仅为 LLM 引入第二个遥测标准会碎片化画面,并复杂化他们如何进行可观测性。这也将他们的可观测性分隔到不同的产品中,这使得在发生问题时很难解决问题。
选择一个遥测支柱 - 如果你的大多数应用是 OTel,即使意味着添加更丰富的属性直到 GenAI 约定追上,也要优先为 LLM 保持 OTel 原生。
LLM 特定库 - 即使你必须使用 OpenInference 之类的 LLM 特定库,也要尽量让你的使用尽可能接近 OpenTelemetry,这样你就意识到你使用了哪些可能会破坏事物的非 OTel 属性。
关注 OTel GenAI 工作组 - OTel GenAI 工作组中有积极的工作进行。关注那里发生的工作,并分享你的使用案例,以便 OpenTelemetry 构建的标准能够满足大多数常见用例。
随着 LLM 空间仍在快速演进,作为一个社区,我们需要发出声音,以便标准是稳健的。
我们继续投资 OpenTelemetry 原生 LLM 可观测性,以便团队不必在稳定性和清晰性之间进行选择。具体来说,这意味着:
使用 OTel span/属性模型化 LLM 调用时的清晰仪表板和跟踪。你可以在我们的 LLM 可观测性文档中找到示例和仪表板。尽管我们在文档中也使用 OpenInference 之类的 LLM 特定库(因为它们仍然是人们最容易入门的方式),但我们已经尽可能地将仪表板保持接近 OTel 标准。我们还计划在 OTel GenAI 语义约定变得更加成熟时积极更新此内容。
为流行框架提供指导和示例,以发出 OTel 友好的遥测,包括 LangChain/LangGraph、LlamaIndex、LiteLLM、Vercel AI SDK 和 Pydantic AI。
构建利用 OpenTelemetry 语义约定的功能,以便你在 SigNoz 中获得很好的开箱即用体验,并遵守让你的服务、数据库、队列和 LLM Agent 保持在一个连贯画面中的深思熟虑的默认值。
如果你在与这些权衡作斗争,我们很乐意听到对你造成的破坏以及你实际上每天使用的"丰富语义"。
非常感谢 Pranav 的深入探讨,特别是从 Ruby 的角度。如果你在推出 AI 功能并关心可操作性,请添加你的声音:推动 OpenTelemetry 中更丰富的 GenAI 语义,并分享真实跟踪(已清理),显示你需要看到的内容。
如果你想比较笔记或需要帮助将你的 LLM 遥测纳入 OTel 原生视图,请与我联系。