InfoQ

Presentation: Multi-Agent Patterns from Spotify’s AI Powered Advertising Platform

6.9内容质量
Presentation: Multi-Agent Patterns from Spotify’s AI Powered Advertising Platform

TL;DR · AI 摘要

Multi-Agent Patterns from Spotify’s AI Powered Advertising Platform - InfoQ InfoQ Homepage Presentations Multi-Agent Pat...

核心要点

  • 主题聚焦:Presentation: Multi-Agent Patterns from Spotify’
  • 来源:InfoQ,建议结合原文判断细节。
  • AI 分析暂不可用,本条为保底评分与摘要。
#AI#编程#后端#云计算#安全
打开原文

Spotify AI驱动广告平台的多代理模式 - InfoQ

InfoQ 首页 演讲 Spotify AI驱动广告平台的多代理模式

AI、机器学习与数据工程

从Token到特征:构建AI辅助工程的成本归因架构(10月29日网络研讨会)

Spotify AI驱动广告平台的多代理模式

点赞

新下拉阅读列表

  • 阅读列表

查看演讲

  • 垂直
  • 水平
  • 全屏

速度:

  • 1x
  • 1.25x
  • 1.5x
  • 2x

50:44

概述

Pratik Rasam分享了Spotify广告管理器如何使用Google ADK Java大规模运行生产级多代理系统。他介绍了关键架构模式、领域所有权模型、确定性防护措施和基于追踪的评估策略,详细阐述了在划分代理边界、优化工具模式和管理成本时学到的宝贵经验,同时避免单体代理陷阱。

个人简介

Pratik Rasam是Spotify的高级工程师,负责构建Ads AI——Spotify广告的多代理平台,用于AI驱动的广告。他在Spotify工程博客上合著过关于智能广告多代理架构的文章。

关于会议

QCon AI是由实践者主导的会议,专注于安全扩展这些工作负载所需的工程学科。它提供了直接访问同行组织在生产环境中使用的架构手册和失败指标的途径。

INFOQ 会议

  • 2026年10月8日,上午12点EDT 当AI加速开发时,您的CI流水线能跟上吗?演讲者:Eric Metaj - Datadog软件交付产品市场经理,Rohin Chandra - Datadog CI/CD优化产品经理
  • 2026年10月29日,上午1点EDT 从Token到特征:构建AI辅助工程的成本归因架构 演讲者:Martin Reynolds - Harness现场首席技术官

演讲稿

"在QCon AI会议上学习如何规模化运行AI。将AI从实验环境转移到生产环境会增加对平台和团队的压力。聆听资深同行解释如何控制推理延迟、构建安全的代理防护措施以及标准化内部平台。此外,5月12日前有早鸟优惠价格。立即注册"。

Pratik Rasam:"你刚才听到的广告,包括剧本、受众群体、定向投放,所有内容都是由我们Spotify广告管理器内部的生产平台构建的。如果你从事广告行业,就会知道创建广告涉及文案撰写、音乐生成等环节。现在这些都不需要了,我们只需要广告商描述他们想要的广告内容。这不是一篇研究性演讲,而是Spotify广告管理器正在规模化运行的实际生产代理。我也会分享在开发这个平台过程中犯下的错误。"

背景

我的名字是 Pratik,我是 Spotify Ads 的高级工程师。今天我将介绍构建 Ads AI 的平台。Ads AI 本质上是 Spotify 广告解决方案的多智能体平台。让我通过一些数据来说明我们在 GenAI 领域的表现规模。自去年推出以来,目前超过 70% 的广告都在使用 AI 工具。我们已为超过 7000 家广告商生成了约 20,000 个创意内容。这些是真实的广告活动、真实资金和真实受众。本次分享不仅仅是研究,而是正在实际运行并创造价值的生产代理。目前,我们大部分创意生成的主流程都由 Spotify Ads AI 生成。在深入架构之前,这个示例将在整个演讲中用于说明架构设计的不同阶段。让我们想象一下,我们正在为 QCon AI 创建一个广告。

品牌本身是 QCon。我们希望传达给听众的信息是:如果你想为高级工程师制定生产 AI 的操作手册,如果你想规模化部署 AI 解决方案,QCon AI 就是你要参加的会议。我们的目标受众是高级工程师、架构师和工程领导者。我们希望针对美国主要科技中心。我们的行动呼吁(CTA)是:立即注册。

"Ads AI" 的实际含义

我想确保我们理解一致。当我解释 "Ads AI" 的实际含义时,想象广告主说:"我想在美国科技中心为工程领导者投放广告。" 这是自然语言。我们所做的就是将这种自然语言提取为特定的受众意图。在这里,我们讨论的是将受众解析为技术领域,地理位置定位应为美国。目标是提高知名度。我们使用 Vertex AI 和内部 GCP 平台的 LLM 网关来实现这一点。当提取出意图后,会将其传递给我们的多智能体编排层,该层基于 Google ADK 运行。我们使用的是 Google ADK Java。我们按照职责划分并行智能体。对于你刚才听到的广告,我们有广告脚本生成智能体。我们还需要确保广告符合我们的政策,因此我们有广告护栏智能体。我们目前正在进行试点的还有受众推荐智能体。这些智能体的综合输出最终会生成两个独立的对象:一个是推荐的受众,一个是生成的创意内容。

一个智能体,一个包,一个负责人

在深入探讨模式之前,我想向你们展示我们最初是如何构建这个架构的。当我谈到智能体时,我指的是一个智能体、一个包和一个负责人。我们明确强制执行了这一要求,因为当智能体被构建为独立包时,该包本身会涉及所有权、职责、监控和提示本身的各个方面。如果你查看智能体广告脚本文件夹,我们会看到 Bazel 包,它涉及谁有权访问该智能体的依赖管理。我们有 lib-info。lib-info 是确定哪个团队拥有该智能体所有权的依据。我们有一个内部组件用于解决 PR 审查。假设你在该智能体中更改某个特定属性,这将触发团队进行所有权变更。

Monitoring-info 基本上是一个 YAML 文件,其中包含有关您的仪表板和 PagerDuty 告警的信息。在编写任何代理指令代码之前,我们的平台就已经为您提供了所有这些内容,包括指标、告警等完整配置。AgentFactory、Adapter、Service 和 AgentModule 是依赖注入框架,为代理本身提供完整的功能包。请注意,代理的 LLM 配置以前置元数据形式存储。这正是使架构变得有趣的地方。当我说不同团队负责不同代理时,我们通过 Bazel 可见性规则在水平层强制实施这一机制。所谓水平层,意味着广告脚本生成代理在受众解析器未允许其导入之前,将无法使用受众解析器。这种强制规则是在编译时层执行的。无需额外说明。

当您未特定导入某个代理时,基本上会遇到构建失败的问题。除了团队拥有的组件外,我们还拥有共享平台。共享平台提供指标生成、可追溯性等功能,而我们大多数工具的使用都围绕 Spotify Ads 的开发者 API 展开,该 API 会调用 Ads API。我们还有一个名为 kutest 的额外审核层,用于管理护栏策略。

代理架构栈

从团队层面宏观来看,整体技术栈如下所示。我们有一个 gRPC 服务,多个代理,以及由 Google ADK 控制的运行时上下文。团队 A 拥有其专属代理和工具,团队 B 拥有其专属代理和工具,团队 C 也可以拥有其专属代理和工具。所有这些代理最终都可以在共享上下文和共享运行时 ADK 上运行。工具可追溯性、工具上下文和运行时循环均由平台统一管理。从架构角度看,流程如下:客户端应用通过 gRPC 服务调用我们的服务接口,这些服务也负责会话管理。每当客户端发起调用时,需要负责与代理建立会话,最终进入 AI 代理层。

AI 代理层是各个代理实际驻留的位置。我们通过独立层强制实施了安全性和编排逻辑,而非在代理内部实现。这是因为我们希望在整个代理体验中保持统一的编排逻辑和护栏规则。最后一层是模型和工具平台,本质上是 LLM 运行时、插件以及为所有代理运行的可观测性配置。在整个讨论中,该平台具有三个核心属性:安全内容、模块化代理平台和灵活集成。这三个特性是我们希望贯穿所有代理接口的支柱。

这或许是整个演示文稿前半部分最重要的一页幻灯片。当处理多代理架构时,你始终需要思考的问题是:谁拥有什么?代理拥有情感、LLM判断和推理部分。在我们的示例中,使用场景类似于受众意图分析。我们希望理解广告商在说"我想为我们的运动鞋广告针对Z世代"时的真实含义,希望从这些信号中生成完整的广告简报。同时,我们也需要识别敏感话题。例如,如果某个广告描述不符合Spotify的广告政策,我们确实需要阻止该广告生成。在数据方面,我们绝不希望LLM猜测地理位置兴趣。在广告领域,我们有特定的兴趣细分群体,有特定的DMA定位。所有这些数据实际上都来自我们的API端点。

Spotify公开提供了我们工具当前正在访问的网络API。所有这些基础工作都发生在工具层。第三部分是应用程序代码本身。当有人问我是否应该让所有内容都由代理控制时,我的回答是否定的。这是因为任何可以确定性编码的内容都应该始终以确定性方式编码。在本次演示中,我会通过多个实例展示我们如何建立一些防护机制和确定性门控,以实现预期目标。

这就是今天播放列表的现状。我想先从为什么需要多代理架构开始。我们并不是仅仅因为代理很酷就使用它们。采用多代理架构的动机在于控制影响范围,为每个代理分配明确的责任。接下来我们将探讨如何划定代理边界。这可能是最漫长的讨论,因为也是最难进行的。理解代理职责与代码/工具中确定性处理的边界位置非常重要。第三部分是工具设计。工具设计本质上就是提示工程。我这样说是因为当我们定义工具时,也在定义其模式。该模式描述了工具的功能,这不仅是供我们这些开发者参考的文档,也会直接传递给LLM,帮助LLM准确理解该调用什么工具以及如何调用。随后我们将讨论通过评估和追踪实现可靠性。为了进行评估,我们需要先实现追踪,这也是我们将重点强调的部分。最后但同样重要的是,我会谈谈我们将会采取的不同做法。这突显了我们在代理架构初期旅程中曾犯过的错误。

让我们将时间倒回18个月前,思考一下我们对LLM的期待。如果回顾去年,从特定LLM模型中解析JSON并不简单。它可能返回类似JSON的响应,或者以Markdown格式包含三个代码块。随着时间推移,模型性能显著提升。如今,我们使用的模型已广泛采用JSON解析、模式校验和业务验证功能。第三点,业务逻辑验证至关重要,因为现在可以对模型返回的任何值添加额外的确定性检查,判断其是否合理。这部分内容将在后续幻灯片中进一步探讨。再回到一年前,如果需要编写带有自定义会话管理的代理并行执行,你可能需要自己实现。

如今,LangChain4j、Google Cloud ADK或CrewAI等框架提供了这些基础能力。过去的问题是如何设计系统,现在的问题变成了如何实现它。当我说"操作变得可观测"时,这属于供给侧的变革。可观测性领域的变化在于OTel GenAI约定为生成式AI工作流建立了标准化的可观测性规范。这些规范使通用追踪约定成为可能。过去,各团队需要自行编写注释和追踪代码,现在语义化约定使生成式AI工作流的标准化可观测性成为现实。借助这些标准化的可观测性追踪,现在可以追踪并重放判断模型。重放生产环境追踪使我们能够实际测试生产环境中的运行情况,无需创建合成测试。这最终避免了代理系统中"黑箱行为"的出现,即我们无法了解系统内部发生了什么。

第四点颇具趣味,它涉及需求侧。前三个举措更多属于供给侧,技术本身在进步。第四点则是需求侧提出了更高要求。多步骤流水线在传统软件开发中一直存在,变化在于每个步骤中现在都涉及LLM交互,这些交互可能包含多入口产品。当我说"多入口产品"时,指的是广告商可以先在移动应用上启动活动创建,然后在广告管理器或Ads API上继续创建。每个入口点可能有不同的意图和上下文。只有通过多代理流程才能将这些上下文拼接起来。最后一个要点是闭环测量。当使用生成式AI创建广告时,我们也能衡量这些广告的表现。当这些表现数据反馈到系统中时,我们就能明确哪些方法有效,哪些无效。

这种闭环测量是广告活动整体成功的重要指标。多代理系统一直存在,只是这四个特征(三个供给侧、一个需求侧)随着时间推移变得越来越好。我们有三个供给侧改进和一个需求侧改进。到2026年初,多代理系统还只是研究演示,如今已成为主流架构。

让我们来谈谈活动创建流程是怎样的。每当广告主登录Spotify Ads Manager时,他们需要提供自己的目标。例如,我的广告活动目标是什么?我的目标是什么?我的关键绩效指标(KPI)是什么?成功衡量标准有哪些?接下来是定位环节。我要针对哪些人群?当广告主指定目标人群时,实际上也在指定广告的展示位置。有哪些兴趣细分群体?比如,我想要针对QCon的技术爱好者,同时我还想添加人口统计过滤器。然后进入预算安排环节。我要花费多少?投放时间是什么时候?以及节奏控制规则是什么?接下来是创意上传环节,也就是你们在第一张幻灯片中听到的内容,广告主需要提供关于他们创意内容的详细信息。这里的问题显而易见,因为在创意层面,上下文信息在这里明显缺失,因为每个步骤都孤立地解决自己的问题,但并未提供创建创意所需的全局信号。

让我来演示一下当前广告管理器的使用方式。我们创建了一个QCon波士顿会议活动,广告主设定了年龄定位,详细定位选择了科技行业,语言覆盖所有语言。我希望这个活动适用于所有设备。这是一个音频广告活动。我想要以展示量作为优化目标。假设我每天的预算设置为15美元。现在进入下一步。这里我需要提供广告详细信息。我的广告主名称是什么?我的宣传语是什么?我还需要上传图片,但目前还没有。我们将重点关注本次演示的音频生成部分。这正是你们在第一张幻灯片中听到的广告创建方式。广告主提供核心信息和行动呼吁。行动呼吁与之前幻灯片中展示的内容类似。

当广告主选择生成按钮时,他们可以看到生成的脚本。我已经有了一份生成的脚本,但我们可以允许广告主生成多个版本,以便他们为活动选择最合适的脚本。正如你所看到的,在广告主创建广告活动的过程中,有一些信号对于广告创建非常重要。目前,当广告主提供创建广告脚本的输入时,他们提供的信息包括品牌、信息、目标和广告类别。这些是用于创建活动的五个叶子节点信号。相比之下,在右侧你可以看到一个可组合系统,不仅包含这五个信号,还可以使用已解析的受众群体、地区设置、活动过往表现、地理-年龄、性别组合、广告类别、投放目标组等信息。所有这些信息都可以为创建更优质的广告提供额外的上下文和更多信息。这种能力的解锁正是多智能体系统所倡导的优势。

智能体边界的划定

让我们从核心层面进行比较。在函数式风格中,当广告主执行提供品牌信号的任务时,他们提供资产并获取品牌语调和行动呼吁。在生成脚本时,他们提供品牌名称和行动呼吁,如之前演示所示。在这里,你实际上并没有品牌语调。同样,当你执行推荐定向时,你提供品牌名称和目标,但品牌语调和内容主题并未出现。当使用代理技术风格接口时,流程会提取自己的信号和会话上下文。在推荐定向之后,所有代理只需使用相同的共享会话状态,上下文会在每一步累积。在流程结束时,代理会获取品牌语调、行动呼吁和主题,这些元素使广告创作更加完整。

这正是我们最终想要实现的页面。目前我们拥有活动上下文,品牌语调和目标从广告主处获取。我们还拥有创意输出,脚本、视觉标语和格式通过UI界面提供。当活动提交后即开始运行。同时,我们会获取定向信息、地理属性(广告表现良好的地区)以及性能信号。我们拥有点击率、完成率、转化率等所有信号。想象一下,这个闭环实际上作为输入进入我们的漏斗,我们可以确定带有偏见提示和受众选择的对话脚本实际上表现更优。我们可以调整定向策略,也可以调整模型,使返回系统的漏斗能够提供有意义的洞察,说明哪些方法有效、哪些无效。这种双向流动是多代理系统使我们能够实现的关键。

在纠正之前的问题之前,让我先说明我们曾犯过的错误。作为所有热情的AI实验者,我们最初从一个单一代理和一个庞大的指令开始。这个代理负责脚本生成、安全限制、受众解析、搜索行为、验证、JSON模式、语调和区域设置。它拥有所有工具,所有功能都集中在一个大型模块中。想象一个包含1000行代码的函数。虽然它能运行,但同时也很脆弱。随着指令变化,该代理的行为出现了一些幻觉。我们没有采用隔离的方式识别问题,这导致我们得出结论:如果希望为特定代理分配专门职责,这必须作为我们初始POC后的改进措施。这是我们最终确定的分解方案。我们基本上采用了三个代理的架构。

我们目前正处于试点阶段的受众解析器,其主要职责是处理地理位置定向、人口统计信息、兴趣和排除条件。例如,如果广告商的简报中要求针对纳什维尔18至34岁女性的健身人群,这个代理程序将负责解析兴趣和地理位置定向。同时,我们还有广告脚本生成功能,它并行运行两个代理程序。其中一个是广告脚本安全检查代理程序,专门执行品牌安全检查;另一个是广告脚本生成代理程序。需要特别注意的是,这种代理程序的划分也取决于不同团队的职责归属。在广告系统中,广告创建和提交流程的不同领域由不同团队负责:我们有专门的受众管理团队,也有专门的创意管理团队。创意管理团队负责广告脚本生成代理程序,而受众定向团队则负责受众解析器代理程序。

这是一个值得遵循的指导原则。我们经常被问到:什么时候应该使用代理程序?什么时候需要编写代码?在我看来,模型虽然在不断改进,但仍然存在非确定性。如果行为语义的表述发生变化,这一定是代理程序或大语言模型(LLM)需要处理的范畴。例如,高级工程师、技术领导者等这类内容,都属于代理程序可以处理的范围。相反,如果规则、目录或数据发生变化,这则需要通过代码来实现。一个很好的类比是:如果某项功能可以通过代码实现,并且可以通过单元测试进行验证,那就应该用代码实现。我们通过一个非常有趣的案例学到了这一点。在广告管理平台中,我们目前支持这些年龄段的受众定向。

我们曾遇到一个案例,其中输入条件是“纳什维尔21岁以上的女性”。在这种情况下,代理程序直接输出了“21至99岁”。我希望有人能活到99岁,但遗憾的是,这个结果被下游系统拒绝了,因为它不属于我们支持的年龄区间。所需的修复措施非常明确:我们必须明确列举出七个年龄区间,以排除特定不支持的年龄。第二个bug则更加有趣。如果提示语是“13至17岁青少年的父母”,代理程序却错误地推荐了“13至17岁”而不是“父母”。这里所需的修复并不是人口统计数据,而是“人物画像”(persona)。这些案例在你测试代理程序时会出现,即使你使用的是最新大语言模型,仍会发现一些边缘情况,这些情况可能会让你感到意外,因为代理程序在这些场景中出现了错误。

另一个有趣的案例是地理定位。用户只需简单地说:“我想定位美国南部和中西部。”这些是非常通用的术语。在美国,“南部”代表13个州,“中西部”也代表12个州。如果你的工具没有将国家代码作为附加属性提供,那么“佐治亚”可能会被解析为国家而非州。我们发现,当工具本身内置了额外上下文作为防护机制时,能为代理提供更明确的定位解析依据。我们最终实现的另一个优化是,在调用LLM之前尽可能完成能做的所有工作。在我们最初为广告脚本生成设计多代理模式之前,每个LLM调用都是独立进行的。问题是,防护机制的运行与生成过程无关。

每当防护机制返回错误结果时,都会浪费我们的token资源,因为用户端没有实际输出内容。我们内部有一个内容审核分类器,可以提供分类结果。我们首先调用这个内部分类器,如果分类失败就提前返回。我们先进行门禁检查,只有通过后才调用LLM。当你发现组织内部已有解决方案可以无需调用LLM直接生成输出时,优先使用这些方案,因为从宏观角度看,这会大幅减少token浪费。

原型设计模式

在深入探讨代理的关键经验之前,我想先谈谈我们原型设计的模式。这是一个我们经常被问到的问题:“如果我想编写代理,应该如何编写?或者,我应该使用哪些模式?”在我们的项目中,Google ADK自带开发UI,我们为工程师搭建了若干原型模式,今天将与大家分享。这些是基本组件,通过组合和调整可以产生不同行为。我们有基础路由器、条件路由器、顺序流水线(这是我们最常见的工作流)、扇出-扇入模式(用于并行执行),以及最后的生成-批评循环(用于持续优化代理输出直至找到最佳结果)。

从基础代理和工具开始。这是最简单的代理调用方式,只有一个代理,LLM可访问特定工具集。它没有协调开销,易于单元测试和逻辑分析。需要注意的是提示负载问题。最终你会发现3到10个工具调用可能尚可接受,但8到10个工具调用可能导致LLM产生幻觉。如果感觉同时调用太多工具,应考虑将代理拆分为多个代理。下一个模式是顺序执行模式。这是我们在大多数工作流中常见的模式。顺序模式本质上是一系列代理运行,一个代理的输出作为另一个代理的输出键。在底层实现中,各步骤之间几乎没有连接。

这些可以通过顺序代理的子代理来确定。会话状态本身通过输出键进行维护。每个代理运行后,输出由输出键参数提供。添加和移除阶段非常简单。需要注意的是累积延迟。在工作流中添加的代理越多,显然等待时间会增加。如果顺序运行所有这些代理,平行处理的范围会受到限制。如果知道这些代理实际上可以并行运行,应尽量让它们并行执行。我还会谈到并行分发的模式。另一个需要注意的点是上游故障可能会影响整个链条。例如,如果研究者在此情况下失败,写作者将无法获得输出。这就像你顺序流程中的单点故障。

这是一个我们实际使用过的有趣代理模式。这里你看到的是Java提供了类似Flowable的事件处理机制。如果你正在扩展基础代理,可以随时重写runAsync函数。在这里,我们实现了一个分类代理,它将查询分类为计费问题或技术问题。如果是计费查询,会转给计费代理;如果是技术查询,会转给技术代理。我们还有一个默认模式,会转给通用代理。在确定使用哪个分支或路线时,这是一个非常有趣的模式。在这种情况下,路由器是单点故障。如果路由器本身无法确定要执行的任务,这时就需要检查分叉方法或默认路由的备用方法。

路由器本身会增加额外的延迟。模型也可能过度分类意图。例如,假设你有这样一个例子,技术代理和计费代理实际上执行相同的操作。在这种情况下,代理本身很难准确判断用户的意图。正如名称所示,平行分发和收集模式是指代理并行运行。当你明确知道代理A和代理B可以同时运行时,可以使用这种模式来并行执行这些代理。在我们的情况下,广告脚本生成时,我们并行运行广告脚本安全检查和广告脚本生成。在这个例子中,我们有一个审计代理和一个风格检查代理。这两个代理并行运行,然后有一个评审代理来审查最终的输出。

对于并行代理,需要注意的一点是每个代理都不知道其他代理实际执行了什么。这是在运行并行代理时需要记住的,顺序代理可用的信息在并行代理中是不可用的。显然,一旦你的并行代理达到线性规模,令牌消耗会显著增加。最后一个模式是我们的进一步优化方法,称为生成器-评判者循环模式。在示例中,你可以看到有一个SQL生成器和一个SQL评判者。SQL生成器的作用是生成SQL语句,而评判者的作用是判断生成的SQL是否通过或失败。你需要持续检查,直到评判者给出通过的许可。

存在一种可能性,即批评者可能会无限运行下去。循环代理拥有一种称为 maxIterations 的属性。这些属性允许我们防止 token 消耗失控,类似于退出策略。需要注意的是,每次迭代都是一次完整的 LLM 往返成本,因此成本可能会成倍增长。如果没有明确的退出策略,模型可能无法收敛。即使在这种情况下,你仍可能遇到竞态条件等问题。批评者本身也是一个 LLM。实际上,每次优化步骤你都需要支付两次费用。

边界要点

回到总结要点。这标志着我们关于代理的讨论结束。代理拥有推理能力。你应通过代理而非算术来识别意图、范围和上下文。任何确定性操作都应通过代码实现,任何语义或意图相关的内容都应由代理处理。在验证代理输出时,目前每个代理都具备模式验证功能。缺失字段防护、业务规则验证和空值检查,这些都是模型今天完全能够胜任的。在可能的情况下,应识别顺序与并行的模式。如果你有需要在代理运行中条件退出的用例,这在今天也是可行的。所有这些都在 gRPC 服务边界内封装。最终你会得到一个 gRPC 服务的最终调用,其中包含代理输出,即你的综合响应。最后一点,尽可能避免让代理执行多项任务。就像单一职责原则一样,代理越小越简洁,性能表现越好。

工具设计是提示工程

现在我们将转向工具。工具是代理的"手和腿",可以这样描述。一个被严重低估的要素是工具模式。什么是工具模式?它是一种注解,用于告诉 LLM 如何使用该工具以及该工具的描述。本质上这是 LLM 的契约,而不仅仅是共享文档。工具描述非常重要,我们将通过几个示例说明这些工具描述如何帮助我们确定地理定位。目前我们的工具设置方式是将工具和 API 视为不同实体。在更宏观的层面,我们有 Ads API,包含标准的 Web API,但代理调用不同工具时具有不同的意图。现在你将理解为什么我们将代理和工具捆绑在一起,而不是作为共享实体。

如果一个团队拥有其代理程序,它也拥有其工具。在这个例子中,我们有两个工具,分别称为searchGeoTargets,以及一个未来可能拥有的假设代理程序lookupGeoById。这些工具的意图完全不同,但它们的API是相同的。一个关键的启示是,您的工具不应仅限于API包装器,而应与代理程序的意图和代理程序实际请求的内容相关联。将代理程序的需求增强到工具中比其所提供的API更重要。与任何其他软件一样,工具也可能发生故障,因此让工具以非常优雅的方式失败非常重要。当我说“优雅的方式”时,基本上是指当工具失败时,代理程序应能够理解到底发生了什么。在本幻灯片的示例中,我想向大家展示的是,假设对兴趣分段进行了调用,而兴趣分段API由于某些原因未能提供兴趣ID。我们有两种处理方式。一种是不处理这个错误,从而导致代理程序无法处理的漂亮内部服务器错误。另一种方式是使用结构化响应,让代理程序了解具体发生了什么,并优雅地退出。

工具委托有不同的模式和组合方式,我想与大家讨论。首先,您可以将工具映射为一对一的上游API。这是您希望为特定客户端搜索调用特定API调用的情况。这种方法的优点包括:几乎没有开销,延迟最小,类似于直接合同。第二种方法是,工具可以将多个API调用组合成一个单一的工具调用。当您希望在单个工具功能中聚合某些API行为时,这种方法非常有用。请注意,工具调用也是LLM调用,因此这些调用也会产生成本。每当您在跟踪中进行工具调用时,都会看到该额外的LLM调用也会增加延迟。在某些情况下,工具可能需要会话状态,或者工具实际上可以上传会话状态。

工具拥有自己的上下文,称为ToolContext,可以将其线程到会话作用域中。如果工具想要更新或从该上下文中读取,您可以获取该上下文。在之前提到的示例中,我们从工具上下文中获取国家代码。回到第一张幻灯片,我们有相同的上游,但不同的代理需求。您可以有两个不同的代理使用两个不同的工具,但使用相同的API。工具设计的关键启示非常直接。当涉及到调用捆绑或拆分时,您需要确定哪些需要捆绑在一起,哪些需要分开。模式级别的接地是工具可以在描述中自身拥有的功能,以避免对数据的静态引用,从而避免昂贵的调用。如我之前提到的,将错误作为恢复提示非常重要,这在处理代理工具故障和为代理提供更多关于如何优雅退出的上下文方面至关重要。多代理包装是多个代理可以使用不同工具包装相同上游API调用的一种方式。

通过评估和追踪实现可靠性

现在我们已经讨论了很多工具相关内容,接下来谈谈可能出现的问题、需要测试的事项,以及我们最初采用的不良模式。作为传统软件工程师,我们喜欢编写单元测试。这些测试能够运行并让我们感到满足,因为系统运行得非常顺利。为了进一步增强我们的信心,我们还使用了带有模拟LLM的集成测试,确保管道连接和每个gRPC集成都正确无误。那么LLM调用本身会发生什么呢?LLM调用本身具有非确定性,而任何非确定性内容都容易产生幻觉。我们采取的这种“只有在收到投诉时才意识到问题”的方式非常糟糕,类似这样的评论应尽量避免。在评估方面,我想重点强调的是评估的前提条件,即追踪。

如果评估仅验证输出而没有追踪记录,那只是表面功夫。我之所以这样说是因追踪不仅包含代理的输出结果,还包含输出结果的完整过程。当我说“输出过程”时,您会发现代理有不同的指标,这些指标可以告诉您持续时间、工具调用、审核、延迟等信息,我们还添加了自定义的GenAI跨度来记录原始输入和输出。ADK提供了一个独立的指标插件,我们可以使用它将这种行为绑定到每个代理。一旦我们获取了这些遥测数据,就可以将它们导出到OTel用于监控Grafana仪表板,或者使用名为Braintrust的第三方供应商,它能以非常直观的用户画像方式展示代理调用的分布情况。评估的三个层次是工具轨迹。工具轨迹用于验证代理是否执行了正确的步骤。确定性资产,例如模式验证、Geo ID结构、年龄范围等。LLM作为评委,通过识别语气、品牌契合度和语义连贯性,这种局部LLM评委模式为我们提供了非常有效的最终评估步骤。

最后我要讨论的是实时评估。实时评估已被证明非常有用。当您在追踪中进行代理运行时,实际上可以运行一个评估器来处理实时流量。将实时评估应用于100%流量并不是个好主意,因为这也会增加成本。具体取决于您的使用场景。如果代理是新进入市场的产品,那么肯定要从较高的评估值开始。一旦您对其有充分信心,就可以调整评估值。这些完全可配置的参数我们可以随时间更改。我们在评估方面做的一件重要事情是,没有将评估附加到合并构建上。我们发现每次将代码合并到仓库时,实际上都会进行LLM调用。

这是一个我们希望避免的额外成本步骤。当开发人员编写自己的代理时,他们通常会离线迭代运行评估。我们确实有一个夜间流程,会为整个测试套件运行评估。这实际上就是一条跟踪记录的外观。这就是为广告脚本生成运行代理的每次调用和成本的示例。在这里,你可以看到两个并行的代理调用正在运行。在底部,你可以看到广告质量评分器最终正在运行。它定义了你的输出,并确定代理响应是好还是坏。关键的评估要点显而易见,我们显然希望为每个生产调用都有跟踪记录。我们可能不会为每个生产调用都进行实时评估,但跟踪记录肯定是有所帮助的。评估的三个层次——轨迹、确定性和裁判——是我们希望拥有的三大支柱。

我们不希望将评估作为CI门禁运行。我们希望按需运行,可能像夜间构建那样。实时评估确实传递着非常重要的信号,因为这些是生产流量。一个关键点是,裁判等于检测而非预防。每次裁判检测到异常时,你想要做的就是对这个异常进行强化,并添加一个新的断言。最终你拥有的断言越多,裁判的成本就越低。

结论

总结一下,如果我们从代理架构开始有所不同的做法,那就是不要使用单体代理,避免大量令牌使用。基本上,工具设计、可观测性和提示路由是我们希望避免使用全局系统提示的方面。我希望你今天能记住的是,不同的团队负责不同的代理。推理通过编排流动,然后返回到漏斗中。这就是目前整个多代理架构的现状。

查看更多带有文字稿的演讲

录制于:

2026年10月8日

由

  • Pratik Rasam

#### 相关赞助商

  • AI的物理限制:AI如何重塑数据中心

#### 相关赞助商

PostgreSQL为时间序列扩展而生:无需牺牲性能即可处理海量时间序列数据。了解Tiger Data如何实现高速数据摄入、快速查询和可扩展存储。了解更多。

#### 本内容属于AI、机器学习与数据工程主题

##### 相关主题:

  • 开发
  • 架构与设计
  • AI、机器学习与数据工程
  • 性能评估
  • 生成式AI
  • QCon AI波士顿2026
  • 提示工程
  • 模式
  • QCon软件开发大会
  • AI架构
  • 文字稿
  • 应用性能管理
  • 人工智能
  • 性能
  • 代理
  • 架构
  • InfoQ
  • 相关编辑
  • InfoQ热门内容 Uber Eats重建搜索管道以将端到端延迟降低50% 从可重用到可再生:重新思考共享UI组件库 未来网络安全:硬件内存安全、自动化治理与后量子密码学 OpenTelemetry使Kubernetes属性处理器随着可观测性模式成熟而稳定 玩具机器人:用于后台AI代理的开源收件箱 Akka测试:在65个开源项目中进行基于规范的AI交付