跳到正文

购物助手:Uber Eats 上的智能杂货购物

了解 Uber 的智能 AI 助手如何将购物清单、食谱和膳食计划的文本或照片转化为可直接下单的 Uber Eats 购物车。

本文目录文章开头

简介

杂货购物往往始于电商应用之外:冰箱上的手写清单、一张食谱截图,或是一个模糊的计划,比如“本周的健康早餐”。将这种原始意图转化为一个实用的购物车,比关键词搜索要复杂得多。系统必须理解目标,将其映射到商店库存,选择相关商品和数量,并遵守各种限制,同时让购物者始终掌控全局。

今年早些时候,我们推出了购物车助手(Cart Assistant)的测试版,以简化 Uber Eats 上的购物流程。该产品还在 Uber 的年度产品展示会 GO-GET 上亮相。借助购物车助手,购物者可以输入提示词或上传图片,系统会生成一个购物车草稿,供其在下单前查看和编辑。

本篇博文介绍了其背后的系统:一个用于规划、相关性判断、数量选择、限制执行、护栏和评估的多提示词状态图。

Figure 1: Example Cart Assistant flow showing creating a grocery cart from a handwritten list

图 1:购物车助手流程示例

从搜索优先到购物车优先的购物方式

传统杂货应用的流程是搜索优先。购物者将意图拆分为单个查询,比较商品,决定数量,并逐件构建购物车:

意图 -> ([手动搜索 -> 手动选择商品] x N) -> 购物车 -> 结账。

购物车助手将流程转变为:

意图 -> 购物车草稿 -> 用户审核 -> 结账。

重要的变化在于,购物者不再需要手动将每个意图转化为单独的搜索查询和商品选择。

架构:多提示词状态图

购物车助手采用多提示词状态图:一种工作流,其中每个步骤负责一项专注的推理、数据获取或验证任务。每次 LLM 调用都有明确的职责和结构化输出,并通过确定性 API、验证层和状态转换将这些调用连接起来。LLM 处理模糊性;确定性系统处理检索、定价、资格、模式验证、聚合和购物车构建。

Figure 2: Simplified system architecture of Cart Assistant

图 2:简化架构

阶段

职责

机制

购物车计划生成

解析文本或图像输入,分类意图,并生成包含搜索词、商品上下文、数量上下文和约束条件的计划项

LLM 结构化输出

候选检索与信息增强

查询商店库存,并为候选商品补充目录元数据、可用性、价格、优惠、促销和可售单元信息

后端搜索与目录 API

语义相关性判定

确定哪些候选商品在上下文中最佳地满足每个计划项

带结构化输出的 LLM 评分标准

价格与优惠约束执行

应用商品级价格上限、促销或优惠偏好、资格过滤条件以及购物车级价格上限

确定性约束优化

数量选择

将人类数量转换为可购买单元,或选择合理的默认值

LLM 推理与确定性算术/验证

护栏

验证模式、受支持的意图、提示安全边界、商品约束和生成内容

确定性检查与基于 LLM 的检查

购物车组装

汇总各项结果并构建要返回的购物车

确定性聚合器

内容优化

在需要时生成简洁的面向购物者的文本、食谱说明或膳食计划指导

LLM 结构化输出

购物车计划生成

Figure 3: A simplified pseudo-schema of the Cart Plan output

图 3:购物车计划输出的简化伪模式

每个计划项都成为一个独立的工作单元,可以并行地进行搜索、重新排序、过滤和数量解析。

购物者请求可能很复杂。单个提示可能包含一份食谱和一个带有额外约束条件的购物清单。例如:“我想为两个人做意大利面。另外还要加纸巾和纯素蛋白粉;蛋白粉的价格要控制在 $20 以内。”规划器需要在结构化字段中捕获并保留所有信息,以供后续步骤使用。

规划器还将检索语言与推理上下文分离开来。例如,查询:“我想做无麸质千层面”会导致其中一个计划项为:{..., “search_terms”: ["gluten-free pasta"], “item_context”: “for lasagna; gluten-free is a strict user constraint”, …}。这种分离使检索系统能够接收简洁的查询,而后续的 LLM 步骤则能接收到该商品被需要的原因。

价格约束在计划的正确层级被捕获。如果购物者说“牛奶低于5美元”,规划器会将该限制附加到牛奶项目上。如果购物者说“鸡蛋、面包和牛奶总价低于30美元”,规划器会记录一个购物车级别的限制,后续阶段使用实际商店价格、库存、优惠和促销来执行该限制。同样,“打折零食”、“麦片优惠”或“最便宜的培根”等请求会变成结构化信号,供后端排序和过滤使用。

语义相关性与约束

规划器创建项目后,Cart Assistant 会从商店库存中检索候选产品。下一个问题是:在当前上下文中,哪个产品最能满足这个计划项目?

我们使用一个带有约束评分标准的专用语义相关性步骤。该评分标准帮助模型区分直接匹配、合理变体、可接受替代品、相邻产品和较差匹配,而不会将决策变成自由文本。

上下文很重要。如果购物者要求“炖菜用的西红柿”,罐装切丁西红柿可能是有力候选。如果他们要求“沙拉用的西红柿”,新鲜西红柿更可能合适。如果他们说“不要乳制品”,系统应选择纯素奶酪而非传统奶酪。

我们还将语义相关性与价格和数量分开。一个产品可能相关但太贵,不符合促销或优惠请求,或者仅以不实用的包装尺寸提供。拆分这些关注点使系统更易于调试和评估。

数量选择

自动为每个项目选择正确的单位数量是系统中最看似简单实则复杂的部分之一。购物者经常用口语表达数量:“12个鸡蛋”、“3个西红柿”、“2杯面粉”、“派对零食”或“两个孩子的每周早餐计划”。商店以目录术语销售产品:纸盒、捆、磅、多包装、液量盎司等。

Cart Assistant 将确定性计算与专用的 LLM 推理步骤相结合。模型对数量上下文和包装细节进行推理;随后确定性算术和验证确保答案映射到可购买的单位。

几个例子说明了为什么这值得单独一个阶段:

  • “12个鸡蛋”应解析为一盒12个装的纸盒,而不是12盒。
  • “8瓶水”可能解析为8瓶装、12瓶装、两组6瓶装或单瓶,具体取决于可用产品和包装尺寸容差。
  • “2杯面粉”或“1杯罗勒”需要不同的体积到重量假设,因为产品形态和密度很重要。

数量步骤使用数据信任层级:产品标题和描述通常包含人类可读的包装线索,而结构化字段提供确认或后备。常见杂货知识有助于解决剩余的歧义,确定性检查确保结果是可销售的。

规划器还保留数量来源。明确数量和系统估计数量之间存在有意义的区别。“12个鸡蛋”应被严格遵守;为煎饼食谱推断的鸡蛋可以四舍五入到实用的包装尺寸。

护栏与安全执行

购物车助手接受开放式自然语言和图像输入,但系统本身在有界的购物流程内运行。护栏在购物者输入、中间购物车状态和面向购物者生成的内容之间强制执行这一边界。它们帮助助手区分杂货购物请求与不受支持的意图,抵御提示注入和指令劫持尝试,并确保购物车决策和生成文本都基于商品目录数据、购物车状态和受支持的产品功能。

我们将护栏分为确定性检查和基于 LLM 的检查。确定性检查验证结构化输出、必填字段、枚举值、价格约束、数量计算、产品资格、可用性,以及所选商品是否真的可以组装成有效的购物车。基于 LLM 的检查处理更模糊的决策,例如请求是否在领域范围内、指令是否试图覆盖系统行为,或者食谱、膳食计划、替代品或购物车摘要文本是否合适且忠实于所选产品。

这为系统提供了多次安全失败的机会。格式错误的计划可以在检索前被拒绝。不受支持的请求可以被路由到安全响应,而不是被强行放入购物车。相关商品如果违反价格、优惠、偏好或资格约束,仍然可以被过滤。如果生成的内容没有基于购物车或购物者的请求,也可以被修改或抑制。通过将护栏视为状态图的一部分,而不是最终的审核环节,我们使每个阶段都更容易检查、调试和评估。

并行性与延迟

一个杂货请求可能包含许多计划中的商品。顺序处理它们会使延迟直接随商品数量增加。

通过动态异步执行路径并发处理商品,我们将延迟瓶颈从顺序的单商品延迟转移到有界的并行批次。性能现在主要由最慢的商品路径和我们的并发限制决定,而不是商品的原始数量。在依赖关系允许的情况下,护栏和内容优化会异步于主单商品循环运行,而不是阻塞每个商品解析路径。

我们还使用不同规模的模型、推理设置和提示调优来控制 LLM 延迟。

评估驱动开发

LLM 很强大,但它们也是高度敏感的随机系统。微小的变化可能产生令人惊讶的巨大行为偏移。在传统系统中,小的代码更改通常具有相对可预测的影响范围,可以从第一性原理进行推理。对于 LLM,情况并非总是如此。一个改进食谱请求的提示更新可能会损害简单的购物清单。措辞、标点或格式的微小变化有时会产生与变化不成比例的结果,并且难以从第一性原理解释。

在这样的系统中,你无法自信地改进你无法可靠测量的东西。这使得评估成为开发循环的核心部分,而不是事后补充。

针对 Uber 的购物车助手,我们构建了一个评测驱动开发框架,该框架通过大量精心整理的合成请求和匿名化的生产环境衍生边缘案例来评估变更。该框架使用两个互补的层:

  • 严格确定性验证:针对客观正确性的基于规则的检查,例如商品识别、预期商品包含、架构有效性、数量处理、约束传播以及预期失败行为。
  • LLM 即评判者:一个经过人工输入校准的多模态 LLM 评判者,会在整体体验、搜索词质量、约束遵守情况和文本响应质量等多个维度上评估语义和体验质量。

这为从事该系统工作的工程师和 AI 智能体创建了一个实用的工作流:更改系统,针对基线版本和候选版本运行评测,通过步骤级跟踪检查回归问题,并决定是修复该行为还是明确接受这种权衡。解决方式可能涉及更改产品逻辑,或者在某些情况下,当跟踪记录显示是评估者而非产品行为对某个案例评分错误时,优化评判者的评分标准。

我们还将相同的评估系统应用于生产查询分析,帮助我们监控助手在满足真实用户需求方面的有效性。

结论

构建购物车助手挑战了我们重新思考人们与数字店面互动的方式。杂货购物本质上是个性化的、杂乱的,并且受到现实世界约束的限制。

通过将问题分解为状态图架构,我们用一个更可控、可检查的流水线取代了单一 LLM 提示词的不可预测性:以确定性检索、验证和约束执行为支撑的专注式模型调用。其结果是一个系统,它能将杂乱的杂货购物意图转化为一个有用的购物车草稿,同时保留购物者审查、编辑和决定的能力。

致谢

作者谨此感谢我们后端和展示领域的核心工程团队成员:Yunjia Dai、Ritish Rana、Devin Garg、Jhonatan Gomes Cavalcanti、Hugo Deiro、Luiz Felipe Baby Miranda、Daniel Hara、Diego Fidalgo、João Mousinho、Renan Ferrari、Guilherme Artem dos Santos、Ankur Sharma 和 Sri Vinod Palacharla。

此外,非常感谢我们的 PM、UX、QA、Michelangelo 和 Python Platform 团队提供的宝贵合作与支持。

封面图片来源:由 ChatGPT 使用 AI 生成。

及时获取 Uber Engineering 的最新动态——在 LinkedIn 上关注我们,获取我们最新的博客文章和见解。

阅读显示设置

调整正文排版

当前浏览器记住选择,应用于文章正文。手机上正文宽度以屏幕可用空间为限。

图表完整性提示

普通文章遇到图表保存问题时显示提示。