面向更便捷在线买卖的智能体:其架构、延迟与成本技术,以及评测实践。
- 分类智能体
- 产品Claude 平台
- 日期2026 年 9 月 2 日
- 阅读时间5分钟
- https://claude.com/blog/the-anatomy-of-effective-commerce-agents
- 作者Ali ShazalMatthew Koen
过去一年里,我们与电商行业的众多团队——包括零售商、市场平台、旅游、娱乐和电信运营商——合作,使用 Claude 构建电商智能体。
这些智能体已投入生产环境,企业客户在使用它们后,购物车金额更大,卖家运营效率也更高。它们还共享一个简单的架构:Claude 运行在智能体循环中,配备一组技能、工具和一套强大的评测套件。
本文面向正在构建这些(或其他面向消费者的)智能体的工程师和工程负责人。第 1 部分介绍架构,这部分只需决策一次。第 2 部分介绍延迟和成本。第 3 部分介绍生产环境:记忆、安全、评测,以及如何在组织内扩展这项工作。
参考实现
我们还提供了一份
蓝图
,帮助你在 Claude 上构建商务智能体。其中包含工程团队在数天内让商务智能体运行起来所需的测试框架、模式和护栏,并提供了面向零售、旅游、电信和票务平台的购物智能体与商家智能体的参考实现。
anthropics/commerce-agents →
本指南内容
- Part 1: The architecture
- 什么是商务智能体?
- 技能,而非子智能体
- 系统提示词还是技能:按使用频率决定
- 工程智能体工具
- UI 组件即工具
- Part 2: Making it fast and affordable
- 最小化任务完成延迟
- 感知延迟
- 提示词缓存
- 选择模型及其配置
- Part 3: Running it in production
- 跨会话存续的记忆
- 安全:强制机制位于 harness 层
- 评测:交付一个非确定性系统
- 在大型组织中落地发布
- 展望未来
架构
在标准智能体循环中使用一个模型,以技能应对长尾需求,以工具调用你已在运行的系统。你只需做一次这个决定。
什么是电商智能体?
我们将电商智能体定义为:能够简化在线目录中买卖流程的智能体。
有些智能体面向消费者:它们负责搜索、比较、替换并组装订单。这可能是零售购物车、旅行行程、手机套餐变更,或为某场演出预留的座位。有些智能体面向商家:它们解答销售相关问题、开展促销和营销活动,并管理库存与定价。

核心架构是在标准智能体循环中运行的一个模型:围绕目标进行推理、探索上下文、通过工具采取行动、通过技能学习流程、提出澄清性问题,并观察结果,直到目标完成。
其前方没有对对话进行分段的意图路由器,其后也没有一组特定领域的智能体。
工程背景
用技能,而非子智能体
商务智能体必须覆盖跨多个品类和意图的广泛能力,这让人很容易想为每个领域创建一个子智能体。
实践证明这种做法并非最优,因为一次商务对话是跨越多个意图和轮次的紧密耦合会话,需要大量共享上下文。
在子智能体架构中,编排器持有购物车或暂存变更、用户偏好以及对话历史。
每一次向子智能体的交接都是一次有损状态的操作,这往往会影响子智能体回复的质量,进而影响整体回复质量。除此之外,每次交接还可能消耗数倍的 token,并增加数秒的延迟。
而且这些领域很少能干净地切分开。一个退货流程可能需要订单历史、当前购物车和产品目录,这意味着按领域划分子智能体的做法要么在每个地方都重复访问这些数据,要么就得在任务中途进行交接。
随着模型越来越智能,它们也能处理更长的上下文、更多的技能和更多的工具,因此当前放置规则背后的限制会随着每一代模型的更新而逐渐放宽。
相反,智能体技能能为你提供类似的按领域模块化和上下文控制,却无需承担交接的代价,因为技能指令会加载到已经掌握完整历史记录的主智能体中。
在我们对多个企业部署的对比中,一个带技能的单一智能体在质量上始终优于“一个提示词包打天下”的设计和子智能体设计,而且通常每个任务的成本和延迟也更低。
子智能体真正能发挥价值的地方,在于编排器可以将它们作为工具来调用,以处理某个狭窄或自包含的任务——这类任务受益于拥有自己专用的上下文窗口。
一个常见的生产示例是深度研究子智能体,子智能体会搜索并阅读文档、编写并运行代码、遍历数据模型,也会碰壁走入死胡同。所有工作都在一个或多个子智能体内部完成,只有一份精简的答案返回给编排器。
另一个例外是已有自己专用智能体的领域。如果你的药房或金融服务体验运行着一个带有自身合规体系的专用智能体,正确的做法可能是交接(hand-off),由该智能体接管任务,并通过自己的循环直接与用户协作,直到任务完成。
区别在于对话的所有权。交接让领域智能体成为用户的对话对象,而委派则保留编排器,在单次交互中让领域智能体进进出出,每一次交换都会造成性能损耗。
系统提示词还是技能:按使用频率决定
决定将一组指令放入系统提示词还是技能时,主要考虑因素是智能体使用它的频率。加载技能会消耗一次模型交互,因此智能体在大多数交互中都需要的内容通常应放入系统提示词。
不过,这确实取决于你的流量分布情况,以及评估所显示的智能体行为。一个不错的起点是:任何与三分之一或以上流量相关的内容——无论是在上线前预判到的,还是在生产环境中观察到的——都应放入系统提示词,其余内容则放入技能。
如果某项技能可以根据你已有的信号(例如用户到达时所在的页面)进行预测,我们建议在首次模型调用之前从 harness 中注入该技能,并跳过加载技能的额外一轮交互。
关键指令,如安全和法律规则、品牌约束,以及关键用户事实(如过敏信息),始终放在系统提示词中。
对于电商智能体而言,这意味着产品搜索放在提示词中,因为几乎每次会话都会用到它,而技能则承载长尾功能。
在我们的参考实现中,购物智能体的提示词包含 grounding、购物车和结账语义、展示规则,其余功能由以下技能覆盖:搜索发现、购买研究、规划目标、客户关怀和记忆个性化。
商家智能体采用同样的拆分方式,其技能包括绩效洞察、目录列表、库存运营、定价促销和营销活动,每个运营领域对应一个技能。
在提示词中
购物智能体
Grounding、购物车和结账语义、展示规则以及产品搜索。
购物技能
长尾功能
搜索发现 · 购买研究 · 规划目标 · 客户服务 · 记忆个性化
商家技能
每个运营领域一个技能
业绩洞察 · 商品目录列表 · 库存运营 · 定价促销 · 营销活动
工程智能体工具
我们关于为智能体编写高效工具的博文涵盖了工具设计的总体原则。在商务领域,有两点最为关键:
在核心系统和逻辑之上构建智能体工具。
一家商务公司已经拥有搜索和排序、购物车、偏好与画像存储、库存系统、促销和活动引擎、销售分析等系统,每一个都承载着多年调优的逻辑,并且能看到模型永远无法触及的信号。
智能体的工具应当调用这些系统,而不是重新实现它们,而工具边界正是这些系统逻辑的终点、模型判断接管的起点。
例如,当智能体调用 search_products 时,返回的结果应当已经完成排序;它的职责是决定哪些结果能服务于用户的目标、展示多少条,以及如何呈现。
工具结果即上下文。
只返回模型用于推理的字段,其余全部丢弃。每条搜索结果行上的图片 URL 通常是罪魁祸首。
根据需要,在工具内部对原始响应进行重塑,包括在数据本身无法明确下一步时追加一个后续步骤。
这在错误场景中尤其重要,此时模型从指令中获益比从错误代码中获益更多。例如,添加一条错误指令“查询可用性时请包含产品 ID”,而不是返回一个笼统的 403。
UI 组件即工具
大多数电商智能体的响应是 UI 组件而非文本,无论是产品轮播图、行程单、座位图还是图表。这意味着智能体必须输出一种模式(schema)而不是文本。
团队有时会先提示模型输出自定义标签,然后在客户端解析这些标签。但随着应用规模的扩大,这种做法会失效,原因如下:
- 模型在你的标记语言上的训练程度不如在工具调用上的训练程度,因此随着嵌套组件的增加,可靠性会下降。仅靠提示词并不能保证输出格式良好的数据。
- 标签定义位于系统提示词中,因此每新增一个组件都会使上下文膨胀,而每一次编辑都可能导致提示词其他部分出现回归问题。
- 过去的对话最终会以一种只有你的解析器才能读取的格式存储,因此加载历史记录意味着要么在客户端解析原始消息,要么以模型 API 非原生的格式保留第二份副本。
经得起考验的模式是把每个 UI 组件都做成一个工具。模型调用 present_products、present_itinerary 或 present_plan_comparison,并携带类型化参数;你的服务器验证并丰富该调用,然后发出一个事件;你的客户端负责渲染。
由于这些组件本质上是工具调用,它们已经以原生格式存在于 messages 数组中,因此重新加载旧对话时无需再次解析。下面以及参考仓库中展示了一个演示型工具契约的示例。

代价在于流式传输的粒度。工具调用的每个顶层参数都会在服务器端进行缓冲以用于验证,因此即使开启了流式传输,演示型工具的子组件也是分步到达的。这会影响感知延迟。
要获得 token 级别的流式传输,请在工具定义中设置 eager_input_streaming: true,这会跳过缓冲,同时也就跳过了服务器端的模式保证。
在我们的评估中,Claude Sonnet 级别及以上的模型出现模式违规的情况非常罕见,但仍建议为调用包裹一层重试机制,以应对偶发的漏网之鱼。
演示型工具还能让智能体记录屏幕上显示的内容。当客户说“第一家酒店”或“左边往下数第三个”时,布局信息就在 messages 数组中,位于最近一次演示调用的参数里。
要做到这一点,参数必须反映渲染后的布局,因此要按照 UI 的结构方式来组织它们,采用有序的行和轮播形式,而不是让客户端重新排列的扁平列表。
让它又快又实惠
从端到端延迟和感知延迟两条战线同时下手,让缓存来承担成本。这些都不应该消耗智能算力来实现。
延迟在电商中很重要,而面向消费者的界面是最不容忍延迟的。然而,在智能体界面上,我们反复看到能推动留存率、参与度和购物车规模等指标提升的,是结果的质量。
与边际延迟收益相比,答案是否相关、任务是否真正完成,对这些指标的影响更为关键。
所以要双管齐下地攻克延迟。通过良好的工程实践将端到端延迟降到最低,同时配合降低感知延迟(因为观看智能体工作的时间会被视为进展)。
每个用户都有一个延迟预算,下面的技术能让智能体保持在预算之内,而且不需要消耗智能算力来实现。
最小化任务完成延迟
任务完成延迟是所有模型轮次中“最后一个 token 生成时间”加上“工具处理时间”的总和。这给你提供了三个可优化的方向:更少的轮次、更快的工具、更快的 token 生成。这些方向有时会相互冲突,所以需要最小化的是总和,而不是其中任何一个单项。
更少的轮次
预先加载可能需要的上下文,提高模型智能水平,并让模型并行调用相互独立的工具。
更快的工具
优化工具自身的后端,并在工具参数完整后立即主动调度执行。
更快的 token 生成
通过运行你的评测套件来选择模型及其配置。
更少的轮次
查询的复杂性会增加轮次,而这通常不在你的控制范围内。模型智能水平和相关上下文能帮助智能体用更少的轮次完成任务。我们在这方面的一些关键经验包括:
- 预先加载可能需要的上下文。如果用户是从产品页面打开助手,或者商家是从营销活动仪表盘打开助手,就把该页面的数据放入会话上下文中。对话很可能围绕这些内容展开,直接从上下文中回答不会增加额外的轮次。
- 提升模型智能。更聪明的模型能减少完成任务所需的整体轮次,因为智能体可以更高效地规划并发出工具调用。这往往比它们较慢的 token 生成速度更重要。如果你的查询偏向复杂,或生产环境中每个任务超过约五轮交互,那么更快的模型往往就是更聪明的那个。具体哪个更优取决于你的流量特征,因此应按照下文“选择模型”部分所述,通过对比测试来抉择。
- 让模型并行调用相互独立的工具。商业用例通常需要大量并行操作:无论是搜索多个产品、查询多份政策文档,还是从多个销售数据源获取记录。并行工具调用可确保多个独立查询不会消耗额外的交互轮次。提示模型在单轮内调用多个工具,并以一个用户消息的形式返回一组工具结果数组(参见并行工具使用文档)。
更快的工具
- 优化工具自身的后端。有时工具确实会真正地扇出——一个带有“获取今日快照”查询的商家智能体会在三次独立调用中分别读取销售、库存和活动状态。但我们经常看到,工具边界成了缺失后端逻辑被拼凑起来的地方:一个库存可用性检查会调用目录服务获取 SKU、按门店调用库存服务、调用履约服务获取截止时间,然后在工具自身代码中应用替换规则和取货资格判断后才给出答复。这个工具如今承载了过多的领域知识,随着规则变化很难保持正确,并且携带了本应放在上游系统中的逻辑。当你发现自己在工具中编写这类逻辑时,解决方案是创建一个能回答该问题的后端端点,并用智能体工具来调用它。
- 急切地派发工具调用。工具参数会像其他 token 一样从模型中流式输出,因此当每个工具的参数完整流出时,执行框架就可以立即发起该工具的调用,并在模型仍在流式输出其他并行工具或内容块的同时处理其结果。我们发现这能把原本数秒的间隔缩短到几百毫秒,而 Claude Agent SDK 默认就是这么做的。你应该提示模型先输出最耗时的调用,以获得最大的延迟收益。

感知延迟
感知延迟是指用户感受到的、从发出请求到屏幕出现反馈之间的时间。在面向消费者的场景中,这一点尤为关键,因为任何交互摩擦都会影响结账转化率和收入。有两种技术可以在不改动模型的情况下缩短感知延迟:
- 组件边生成边流式传输。一个典型的电商回复通常包含 500–700 个输出 token,如果不采用流式传输,用户就要面对五秒甚至更久的加载动画。将展示工具的每个参数在流式生成的同时发送给客户端,并逐步渲染页面。
- 展示工作过程。当智能体在收集上下文时,用通俗的语言为每个步骤渲染一行简短的进度提示(例如“正在查找水边的酒店”)。你可以根据工具已有的参数来构建这些提示(例如商品搜索的查询词),也可以额外添加一个 `user_facing_message` 参数工具,提示模型来撰写这行文字。

提示词缓存
提示词缓存是你最大的成本削减机会,而电商流量非常适合利用它。缓存输入 token 的读取成本仅为全新 token 的十分之一,虽然缓存写入有约 1.25 倍的溢价,但缓存前缀在第二次使用时即可收回成本。在面向客户、流量庞大的应用中,你有一个独特的机会,可以利用最便宜的默认 5 分钟缓存过期时间,达到非常高的缓存命中率。
我们见过的表现最好的电商部署,缓存命中率能达到 90–99%,而这正是从一开始就应该以此为目标进行设计的区间。我们的经验表明,在约 100k token 规模下,缓存 token 的读取速度也快约 1.5 到 2 倍,而且随着 token 数量增加,这一速度优势基本呈线性扩展。
缓存是基于前缀的。一个请求会从缓存中读取,直到遇到与先前请求不同的第一个字节为止,因此重要的不仅是上下文里有什么,还包括它们的排列顺序。可以把一个请求看作三个片段,按它们变化的频率排序:
- 全局部分:系统提示词和工具定义的大部分内容,在每个会话中完全相同。这是你最“热”的缓存,在规模效应下,很可能不会过期。请确保它在各轮对话和各个会话之间保持逐字节一致,并在其末尾设置一个缓存断点。
- 会话部分:每个用户各自的上下文和对话历史,在不同会话之间有所不同,但在同一个会话内保持稳定。这部分位于全局部分之后。
- 易变内容:会话中会变化的任何内容,例如当前时间或当前页面。请将其放在请求的最末尾,既可以作为最新用户轮次中带标签的块,也可以在支持对话中途系统消息的模型上,作为追加到消息数组中的系统角色消息。我们见到最常见的错误是把时间戳或当前页面放在系统提示词的开头,这会在每次请求时悄悄破坏缓存。

这里有两个实现细节需要记住。首先,技能应作为工具结果加载,而不是附加到系统提示词中。这样技能正文就会进入对话前缀,并随之前缀一起被缓存。
其次,在每一轮中向前滚动你的断点:一次请求允许的断点数量有限,因此请将最新的断点移到每个用户轮次的末尾。这样每一轮都能从缓存中读取累积的历史记录,包括搜索结果等较长的工具结果。

选择模型及其配置
模型大小和推理投入设置是同一类权衡——用智能换取延迟和成本——你应该通过测量来同时选择两者:
- 选定你的指标和底线。选择你的业务所依赖的质量指标(任务完成率、答案相关性、有据准确性)、你不愿低于的评测分数,以及你的 p50 和 p99 延迟与成本预算。
- 全面扫描。在你考虑采用的每一个模型和每一种推理强度上,运行你完整的评测套件。我们建议,对于商家智能体,从 Opus 开始,因为其任务以分析为主;对于消费者智能体,从 Sonnet 开始,因为延迟权重更高。如果你有生产流量,请根据你真实的查询组合对结果进行加权。然后让数据说话。有时,Opus 5 在购物车驱动任务上的提升足以证明其相比 Sonnet 的成本差异是合理的,有时则不然。
- 仔细阅读结果。有两件事经常让团队感到意外。第一,提示词是为特定模型调优的,因此用同一个提示词进行扫描,可能会让那些并非为其编写的模型表现不佳。较小的模型通常需要当前模型能自行推断出的指令,而较大的模型则会不折不扣地遵循较小的模型所忽略的指令。在排除任何候选模型之前,针对每个候选模型的失败案例进行几轮迭代,是一个成本低廉的步骤。第二,更智能的配置有时会在延迟上胜出(最常见的是 p90 和 p99),尽管其 token 生成速度较慢,因为它能更好地规划工具调用,在最复杂的请求上需要的轮次更少。
衡量每个完成任务的成本,而不是每次模型调用的成本,因为一个更便宜的模型如果需要更多轮次,或失败更频繁,实际上并不便宜。当结果接近,且成本符合你的单任务经济性和延迟要求时,选择智能。质量是驱动采用和留存的因素,并且能在未来 6 个月随着模型变得更好,为你留出构建空间。
在生产环境中运行
记忆、安全、评测,以及在组织内扩展工作规模:什么能让智能体通过生产环境的考验并持续运行下去。
最后,我们讨论了是什么让智能体真正落地生产:记忆、安全、评测,以及如何在整个组织中扩展这项工作。
跨越会话周期的记忆
你与客户之间的关系和互动至关重要。记忆让智能体能够从上次对话结束的地方继续,而不是从零开始。一位在三月份提到过坚果过敏的购物者,不应该在六月份还要重复一遍;一位每周一都会查看同样三个广告活动的商家,也不应该每次都重新说出它们的名字。长期记忆——即那些应当跨会话周期保留的事实——是你构建的一个系统,它包含三个部分:事实如何存储、如何写入,以及如何读取。
存储记忆
记忆属于你的系统,而不是模型本身。
当档案规模较小且智能体是唯一读取者时,一个扁平的 markdown 档案文件是可行的。但大多数生产级电商智能体会很快超出这种模式的承载能力,而实际的替代方案就是你已经在运营的数据库。一条事实就是一条小型的有类型记录:一个键(例如 shoe_size、default_store、preferred_report_cadence)、一个简短的值、一个类别,以及它来源的会话。有些键是你预先决定好的,每个用户都会拥有;其余的则由提取器自行发现。随着存储规模的增长,数据库始终保持可查询性,让你能够在特定属性上构建确定性的行为,并能与你已有的用户数据关联起来。
对于面向商家的智能体,记忆应按“人”而非“账号”来区分。商家登录账号通常由多名操作员共用,因此每位操作员都需要有自己的独立档案,且读取时必须遵循该操作员的权限:门店经理的智能体不应回忆起区域经理曾陈述过的事实。
在电商领域,智能体记忆承载着个人数据。值得记住的事实往往正是受监管最严格的数据,而不同司法管辖区之间的规则也各不相同。应将记忆视为一个数据处理设计问题,而不仅仅是存储问题。具体而言,这意味着四件事:
- 明确你愿意保存哪些类型的记忆。在写入路径上强制执行这一限制,通过一个所有保存操作都必须经过的校验器来实现,而不是仅靠提示词来约束。
- 为用户提供查看、更正和删除已存储数据的方式。将删除功能接入你的账号注销和数据请求流程中。
- 设定保留期限。几年前的偏好很可能已经过时,因此保留期限有助于保持记忆事实的新鲜度。
- 记忆应作为按部署实例可配置的开关。这样,无法承担这些义务的地区可以在不启用记忆功能的情况下运行。
写入记忆
以异步方式写入记忆。在每一轮对话结束时,或在长会话中每隔几轮,由独立线程或进程中的智能体读取对话内容,并在存储中创建、更新或删除事实,同时随着会话推进维护自身的工作上下文。
它不会给对话增加任何延迟,并且在我们内部的电商记忆评测套件上,事实召回率提升了 13%。
显而易见的替代方案——让智能体调用工具来保存一条事实——对于延迟敏感的电商智能体而言是错误的做法。每一次保存都是面向用户回合内部的一次工具调用,而且除非整个商店都在上下文里,否则一次保存需要先做一次读取才能更新或去重,这本身就是一轮往返。
它还会在每个回合给智能体增加一个额外的决策点,而在我们的评测中,这种注意力竞争表现为记忆遗漏。
将提取器分离出来,还能让你对它进行精准的提示词设定。它只读取用户和助手的文本,从不读取工具结果,因此产品描述或评论不会变成关于用户的事实。它的提示词会明确什么算作事实——比如用户声明的尺码、饮食限制、履约偏好、商家常用的物化视图——什么不算,比如来自商品列表的任何内容或一次性细节。

读取记忆
记忆分三层读取。
始终在上下文中
一小部分固定的事实会在每个回合都进入上下文:那些几乎每个请求都依赖的事实,比如购物者的默认商店和履约偏好,或者运营者的商店和角色。
每回合预取
与当前请求相关的事实会按轮次预先获取,所依据的信号与预加载技能时相同:一次鞋子搜索会拉取尺码和品牌偏好,一次营销活动问题会拉取运营人员常用的指标。
置于查询工具之后
其余所有内容都置于一个查询工具之后。
由于记忆属于每个用户各自的上下文,因此所有这些内容都放入会话段中,位于全局缓存断点之下。
安全:执行机制位于框架层
提示词是安全行为的起点,但在商业场景中,安全不能仅靠提示词来执行。这类失败往往涉及资金损失且常常无法挽回,而一条提示词规则可能因一次注入或一个不良样本就被跳过。以下每一条规则都在代码层面强制执行,同时作用于消费者端和商家端智能体,并且只定义一次,让所有运行时共享同一套规则。
模型负责提出方案;由人或策略来执行
没有任何模型工具调用能够直接转移资金或改变业务状态。订单提交、支付、退款、价格变更和营销活动上线,最终都落在由框架层控制而非模型控制的动作上。
在消费者端,这一点是结构性的:结账工具渲染购物车并附带一个提交订单的按钮,而智能体所调用的后端接口根本不存在任何扣款方法。
在商家侧,每个写入工具都会生成一个带有服务器生成 ID 的分阶段变更,而 apply_change 仅对已通过真实界面获批的 ID 才会成功:该界面可以是运营人员门户中的按钮、CLI 中的确认,也可以是智能体在 Managed Agents 上运行时平台自身的工具审批提示。
护栏会在 apply 时根据当前限制重新检查,而非依据变更暂存时生效的限制。无论界面为何,其形态都是一致的:模型最危险的动作是提出建议,而审批则经由你的企业针对该类变更已在使用的 maker-checker 流程完成。
写入与渲染仅接受服务器签发的 ID
该测试框架会按会话记录服务器向模型下发的每一个 ID,而这份记录是任何写入或渲染操作唯一会接受的密钥。
购物车仅接受服务器在本会话中返回的产品 ID,商家工具仅接受智能体实际读取过的 listing 和 campaign ID。以任何其他方式出现的 ID——无论是模型幻觉产生的、用户粘贴的,还是植入在评论中的——都会在后端看到之前就被拒绝。
同样的规则也适用于 UI。展示工具接收 ID,而服务器自行填充产品、订单或变更记录,因此卡片只会渲染服务器自身填充的记录。
该规则同样覆盖委派智能体:商家分析子智能体可以读取数据,但绝不会增加智能体可写入的 ID 集合。
对于费用、披露及其他受监管内容,模型只负责选择披露哪款产品,而服务器端则从已批准的文案中逐字提供全部内容。同样的费用字段也位于商家智能体的受保护清单中,因此交易双方都无法更改或改写这些内容,评测会对渲染出的字符串进行逐字节比对。
设有上限的交易必须能应对重复请求
大多数电商界面都会限制单个用户可购买某件商品的数量——无论是出于票务配额、促销定价还是防欺诈考虑——而智能体会以人类点击按钮时从未有过的方式去重试、改写措辞和并行操作。
因此,该上限是在写入后按行强制执行的,这样第二次“再加两件”就无法叠加超出上限;同时,同一会话内的购物车写入会被串行化,确保单轮中的并行工具调用无法合并后突破上限。
商家变更同样按照价格波动上限、折扣深度、补货规模和活动预算的限额进行检查,此外还有一份任何变更都不得触碰的受保护字段清单。这条规则可以推广:对最终状态而非请求本身执行每一项限制,并按会话串行化写入操作。
第三方内容经过净化处理
在电商场景中,大部分上下文内容是由非你方人员撰写的——卖家、评论者、竞争对手——因此每一次后端读取都属于不可信输入,都要经过同一个净化器处理。
由第三方生成的每一条工具结果,例如商品列表、评论、政策、卖家消息和存储的记忆,在模型看到之前都会被净化处理,并包裹在带有固定标签的围栏中。
净化器会剥离控制字符和双向字符,移除任何模仿围栏标记的内容,化解模仿对话轮次或工具调用的文本,并限制大小,旨在防止恶意列表冒充系统或填满上下文。
提示词承担了契约的另一半:围栏内的文本是供报告参考的材料,绝不作为行动依据。
评测:交付一个非确定性系统
从微小的提示词改动到引入新工具,任何变化都可能以难以预测的方式改变智能体行为,而你所交付的改动往往不是导致性能回退的那一个。评测正是你在部署之前发现这些问题的手段。我们之前关于智能体评测的博客文章涵盖了通用实践。本节则聚焦于电商智能体的具体细节。
评估快照,而非对话
模型的 API 是无状态的,因此智能体的输出是系统提示词、工具和消息数组的函数。这意味着电商对话可能达到的任何状态都可以被直接构造出来。因此,创建评测用例意味着构造测试状态、附加测试用户消息,然后让智能体从该状态开始运行。
然后对结果进行评分:最终状态和渲染后的响应,包括最后一次写入的参数。在大多数情况下,我们建议不要对智能体达成结果的路径进行评分,因为这类测试用例很脆弱且限制过多。
模拟用户评估(由第二个模型扮演用户,并由评判模型对整个对话进行评分)并不是一种好的衡量工具。两个非确定性系统交互需要更大的样本量,每次试验成本更高,更难评判,而且产生的失败难以归因。它们对于发现覆盖缺口和对智能体进行整体观感检查很有用,因此可以用它们来发现案例,然后将每个案例写成快照。

在严苛条件下评估行为
大多数团队未能正确测试注入的状态。一个案例应该编码失败的前提条件,而不仅仅是任务。如果某种行为只在繁忙的第一轮多次工具调用之后出现,或在会话早期出现矛盾之后才出现,那么从干净状态开始的案例会在每种配置下都通过,无法提供有意义的数据。
我们观察到大多数测试套件都偏重于这类“干净状态”的用例,所以请确保你的测试中有一部分是从冗长、混乱或相互矛盾的历史记录开始的。
覆盖不同类型的商务智能体评测
有效的评测需要同时测试期望行为与非期望行为。
对于每一个正面用例,都要写出对应的反面用例:每一个“应当拒绝”都要配一个“应当提供”,每一个“应当先询问”都要配一个“应当直接执行”。缺少反面用例是我们在一套测试集中发现的最常见缺口。
针对以下方面进行评估:
- 构成你流量主体的核心请求,因为这里的失败会影响大多数会话。这些请求包括简单查询、多约束请求、产品和套餐问题,以及多意图消息。对于这些问题,要检查每一个价格、可用性和属性是否都能追溯到返回的数据,并且智能体在数据缺失时能如实说明,而不是凭空编造。
- 依赖上下文的请求,例如引用屏幕上的内容、从先前轮次延续下来的约束条件,以及针对现有购物车进行的写入操作。对记忆能力的评估也归入此类。需要检查记忆是否被提取、检索,并最终改变了回答结果。
- 安全与品牌相关场景,此类场景一旦出错就会造成金钱或信任方面的损失。这些场景包括试图进行的提示注入、试图读取其他用户数据的行为,以及需要逐字节核验的受监管语言。将注入分为两类:一类是用户撰写的注入,即指令来自用户自身的消息;另一类是数据平面注入,即指令被植入产品名称、评论或通过网络工具结果获取的网页片段中。
- 界面评估,用于确保渲染出正确的组件、条目数量上限得到遵守,并且面向用户的文本中不包含任何内部标识符。同时也要测试超时和空结果的情况。
- 同时涉及多种能力的请求。运营人员问:“如果我把这个降价 15%,我的库存够不够覆盖需求?”这既是定价问题,也是库存问题。正确的答案会在降价方案中附带库存预测;错误的答案则只处理了其中一半而忽略了另一半。按单一能力编写的评测无法发现这类问题,因为每个评测只考核自己负责的那一半。要为需要相邻两种能力协同处理的请求编写测试用例,并对答案的两半部分都进行评分。
与领域专家共同编写评测,并使用真实事件
与能直接看到失败案例的领域专家合作设计测试用例,例如产品、法务、商家运营、客户关怀和品类管理团队的成员。真实的失败案例是最佳的评测素材,每个用户流程准备 50-100 个评测用例是一个不错的起点。
务必确保用例的多样性,如上文所述。生产环境的对话记录是获取新用例的绝佳来源,尤其是那些棘手的案例。编码智能体擅长生成额外的用例和对抗性变体。参考代码库中包含一个 Claude Code 插件,其中内置了基于我们推荐方法构建的评测编写技能。
在大型组织中交付上线
在商业企业中,智能体由多个工程团队共同构建。搜索、结账、定价、营销技术、客户关怀和商品目录平台各自拥有智能体所依赖的系统,各自按自己的节奏发布,并且各自都会希望添加或修改某个工具、技能或提示词规则。
与传统的服务不同,智能体没有严格的模块边界来保护其他部分:定价团队所做的修改,会与结账功能共享同一个上下文窗口。
一个诱人的解决方案是把系统拆分成许多子智能体,每个业务单元一个。正如第一部分所讨论的,出于质量方面的考虑,我们不建议这样做。相反,我们概述了降低多团队协作风险的过程:
- 所有权跟随系统而定。每个技能和工具都有唯一的所有者团队。例如,定价团队拥有促销工具和定价技能,客服团队拥有订单与退货工具以及客户服务技能。共享提示词中,通用部分由单一的平台级所有者负责,领域特定部分则由领域所有者负责。
- 一项变更随其测试用例一起发布,CI 会运行为其选定的一组测试。贡献技能的团队也需要贡献其测试用例,包括针对相邻技能的负面用例和边界用例。在每次拉取请求时都运行完整测试套件过于缓慢且成本过高,难以持续,因此应从中构建一个 CI 测试集。该测试集将包含一组覆盖最高流量请求的核心用例,以及所有安全用例。在此基础上,再运行与本次变更相关的用例。对于技能而言,这意味着运行其自身的用例以及相邻技能的边界用例。对于工具而言,则是运行所有调用该工具的用例。对于共享提示词而言,由于所有内容都会读取系统提示词,因此需要运行完整的评测套件。我们建议在几次试验中设置通过率门槛,并关注缓存命中率和每次交互的成本。同时,在每晚以及每次发布前运行完整套件也是一个良好的实践。跨团队的回归问题会在这些运行中被发现。
- 智能体也应该纳入发布日历。它是一个部署单元,因此一次糟糕的变更会同时影响到每一位用户。先将提示词和技能变更推送到金丝雀(canary)试点群体,保留一个无需部署即可关闭某项技能的开关,并在高峰期前像冻结其他系统一样冻结智能体。
关于这一安排中人的一面,请参阅《构建高效的人机智能体团队》。
展望未来
本文所描述的大部分内容与模型本身无关。工具调用的是你已在运行的系统,技能编码的是你已在遵循的流程,评测是将你的产品需求文档写成测试,而管控框架(harness)执行的是你会为任何客户执行的策略。模型会持续进步,当更好的模型发布时,我们描述的架构会将其作为一次配置变更并配合一轮评测扫描来采纳。其他一切照常运行。
同样重要的是思考你的产品形态路线图。这套架构的生命周期将超越聊天面板。同一个智能体可以应用于语音场景,也可以在用户询问之前主动针对票价下降采取行动。对于已经拥有评测和工具的团队来说,这些只是展示层项目。更长远来看,你店面的一部分流量将来自代表用户购物的智能体。那些让你的自有智能体保持合规的溯源、分级和审批规则,也正是让你能够安全地向这些智能体开放工具的关键。
商业领域向来奖励那些让购买流程尽可能顺畅的做法。智能体让这件事变得容易得多。请查看完整的参考实现,其中包含消费者端和商家端智能体,以及适用于零售、旅游、电信和娱乐领域的可运行示例。
致谢
作者:Matthew Koen 和 Ali Shazal。特别感谢 Michael Segner、Rodrigo Olivares、Amandeep Khurana、Aiza Usman、John Lopus 及其他人的贡献。
用 Claude 改变你所在组织的运作方式
The architecture, latency & cost techniques, and eval practices for agents that make it easier to buy and sell online.
- Category
- Product
- DateSeptember 2, 2026
- Reading time5min
- https://claude.com/blog/the-anatomy-of-effective-commerce-agents
- Author(s)Ali ShazalMatthew Koen
Over the past year, we've worked with teams across the commerce industry — retailers, marketplaces, travel, entertainment, and telecom providers — to build commerce agents using Claude.
These agents are in production, and enterprise customers have seen larger carts and more efficient seller operations when using them. They also share a simple architecture: Claude in an agent loop equipped with a set of skills, tools, and a strong eval suite.
This post is for the engineers and engineering leaders building these (or other consumer facing) agents. Part 1 covers the architecture, which you decide once. Part 2 covers latency and cost. Part 3 covers production: memory, safety, evals, and scaling the work across an organization.
Reference implementation
We've also provided a
blueprint
to help build commerce agents on Claude. It contains the harnesses, patterns, and guardrails an engineering team needs to get a commerce agent running in days, with reference implementations of a shopping agent and a merchant agent for retail, travel, telecom, and ticketing platforms.
anthropics/commerce-agents →
In this guide
- Part 1: The architecture
- What is a commerce agent?
- Skills, not subagents
- System prompt or skill: decide by frequency
- Engineering agent tooling
- The UI components are tools
- Part 2: Making it fast and affordable
- Minimizing task completion latency
- Perceived latency
- Prompt caching
- Choosing the model and its configuration
- Part 3: Running it in production
- Memory that survives the session
- Safety: enforcement lives in the harness
- Evals: shipping a non-deterministic system
- Shipping with a large organization
The architecture
One model in a standard agent loop, with skills for the long tail and tools that call the systems you already run. You decide this once.
What is a commerce agent?
We define a commerce agent as an agent that simplifies buying and selling across an online catalog.
Some agents face consumers: they search, compare, substitute, and assemble the order. That could be a retail cart, a travel itinerary, a mobile plan change, or seats held for a show. Some agents face the business: they answer questions about sales, run promotions and campaigns, and manage inventory and pricing.

The core architecture is a model in a standard agent loop: reasoning about a goal, exploring context, taking actions through tools, learning procedures through skills, asking clarifying questions, and observing the results until the goal is accomplished.
There is no intent router in front of it that segments the conversation and no set of domain specific agents behind it.
Engineering context
Skills, not subagents
A commerce agent has to cover a wide range of capabilities across many categories and intents, which makes it tempting to create one subagent per domain.
In practice this proves suboptimal, because a commerce conversation is one tightly coupled session across multiple intents and turns, and requires considerable shared context.
In a subagent architecture, the orchestrator holds the cart or staged changes, the user's preferences, and the conversation history.
Every handoff to a subagent is a state-lossy operation, which often impacts the quality of the subagent’s response and, consequently, the overall response. On top of that, each handoff can cost several times the tokens and adds seconds of latency.
The domains also rarely separate cleanly. A returns flow might need the order history, the current cart, and the product catalog, meaning a subagent-per-domain approach either duplicates that access everywhere or hands off mid-task.
As models get smarter, they also handle longer context, more skills, and more tools, so the limits behind today's placement rules loosen with each model generation.
Instead, agent skills give you similar per-domain modularity and context control without the handoff tax, because the skill instructions load into the main agent that already holds the entire history.
In our comparisons across several enterprise deployments, a single agent with skills consistently has outperformed both the one-prompt-for-everything design and the subagent design on quality, and often at a lower cost and latency per task.
Where subagents do earn their place is when the orchestrator can call them as a tool for a narrow or self-contained task that would benefit from its own dedicated context window.
A common production example is a deep-research subagent, where the subagent searches and reads documents, writes and runs code, traverses data models, and hits dead ends. All the work happens inside one or more subagents, and only a compact answer comes back to the orchestrator.
The other exception is a domain that already has its own purpose-built agent. If your pharmacy or financial-services experience runs a dedicated agent with its own compliance surface, the right move can be a hand-off, where that agent takes over the task and works with the user directly through its own loop until the task is done.
The distinction is ownership of the conversation. A hand-off makes the domain agent the user's counterpart, while delegation keeps the orchestrator, bouncing the domain agent in and out within a single turn and degrading on every exchange.
System prompt or skill: decide by frequency
The main factor when deciding whether to put a set of instructions within a system prompt or skill is how often the agent will need it. Loading a skill costs a model turn, so anything the agent needs on most turns generally goes in the system prompt.
This does, however, depend on how your traffic is distributed, and what agent behavior your evals show. A good starting point is that anything relevant to a third or more of your traffic, whether anticipated before launch or observed in production, goes in the system prompt, and the rest goes in skills.
If a skill is predictable from a signal you already have, such as the page the user arrived from, we recommend injecting it from the harness before the first model call and skipping the extra turn to load the skill.
Critical instructions, such as safety and legal rules, brand constraints, and key user facts such as allergies, always go in the system prompt.
For commerce agents, this means product search lives in the prompt, since nearly every session touches it, and skills carry the long tail of features.
In our reference implementation, the shopping agent's prompt holds grounding, cart and checkout semantics, and presentation rules, and the following skills cover the rest: search-discovery, purchase-research, planning-goals, customer-care, and memory-personalization.
The merchant agent splits the same way, with performance-insights, catalog-listings, inventory-operations, pricing-promotions, and marketing-campaigns as its skills, one per operational domain.
In the prompt
Shopping agent
Grounding, cart and checkout semantics, presentation rules, and product search.
Shopping skills
The long tail
search-discovery · purchase-research · planning-goals · customer-care · memory-personalization
Merchant skills
One per operational domain
performance-insights · catalog-listings · inventory-operations · pricing-promotions · marketing-campaigns
Engineering agent tooling
Our post on writing effective tools for agents covers tool design in general. Two points have mattered most in commerce:
Build agent tools on top of your core systems and logic.
A commerce company already has search and ranking, a cart, a preferences and profile store, an inventory system, promotion and campaign engines, sales analytics, and more, each encoding logic tuned over years and seeing signals the model never will.
The agent's tools should call those systems, not reimplement them, and the tool boundary is where their logic ends and the model's judgment takes over.
For example, when the agent calls search_products, the results should arrive already ranked; its job is to decide which results serve the user's goal, how many to show, and how to present them.
Tool results are context.
Return the fields the model reasons with and drop the rest. Image URLs on every search row are the usual offender.
As needed, reshape the raw response inside the tool, including appending a next step when it isn't obvious from the data.
This is especially relevant for error scenarios, where the model benefits from instructions instead of error codes. For example, add an error instruction "Include a product ID when querying availability," instead of a generic 403.
The UI components are tools
Most commerce agent responses are UI components rather than prose, whether a product carousel, an itinerary, a seat map, or a chart. That means the agent has to emit a schema rather than text.
Teams sometimes start by prompting the model to emit custom tags and parsing them on the client-side. This stops working as the surface grows, because:
- The model isn’t as well trained on your markup as it is on tool calls so reliability drops as nested components get added. Well-formed data is not guaranteed just through prompting.
- The tag definitions live in the system prompt, so every new component bloats context and every edit risks regressions elsewhere in the prompt.
- Past conversations end up stored in a format only your parser can read, so loading history means either parsing raw messages on the client or keeping a second copy in a format that isn't native to the model API.
The pattern that has held up is to make each UI component a tool. The model calls present_products, present_itinerary, or present_plan_comparison with typed arguments; your server validates and enriches the call and emits an event; and your client renders it.
As the components are tool calls, they're already in the messages array in native format, so you don’t need to re-parse when you reload an old conversation. An example presentation-tool contract is illustrated below and in the reference repo.

The tradeoff is streaming granularity. Each top-level argument of a tool call buffers on the server for validation, so the sub-components of a presentation tool arrive in steps even with streaming on. This impacts perceived latency.
To get a token-level stream, set eager_input_streaming: true on the tool definition, which skips the buffering and with it the server-side schema guarantee.
In our evals, schema violations are very rare on Claude Sonnet-class models and up, but wrap the call in a retry for the cases where one slips through.
Presentation tools also give the agent a record of what's on screen. When a customer says "the first hotel" or "the third one down on the left," the layout is in the messages array, in the arguments of the last presentation call.
For that to work, the arguments have to reflect the rendered layout, so structure them the way the UI is structured, as ordered rows and carousels rather than a flat list the client rearranges.
Making it fast and affordable
Attack latency on two fronts, end-to-end and perceived, and let caching carry the cost. None of it should spend intelligence to get there.
Latency matters in commerce, and consumer surfaces are the least forgiving. However, on agentic surfaces, what we have consistently seen move metrics like retention, engagement, and cart size is the quality of the outcome.
Whether the answer was relevant and the task actually completed was more critical to those metrics as compared to marginal latency gains.
So attack latency on two fronts. Minimize end-to-end latency through good engineering, and pair that with dropping perceived latency (since time spent watching an agent work reads as progress).
Every user has a latency budget, and the techniques below keep the agent inside it without spending intelligence to get there.
Minimizing task completion latency
Task completion latency is the sum, over model turns, of time to last token plus tool processing. That gives you three levers to work towards: fewer turns, faster tools, and faster tokens. These levers sometimes compete, so the thing to minimize is the sum rather than any one of them.
Fewer turns
Load likely context up front, increase model intelligence, and have the model call independent tools in parallel.
Faster tools
Optimize the tool's own backend, and dispatch tools eagerly as their arguments complete.
Faster tokens
Choose the model and its configuration by sweeping your eval suite.
Fewer turns
Query complexity adds turns, and is generally out of your control. Model intelligence and relevant context help the agent get to task completion in fewer turns. Some of our key learnings in this area include:
- Load likely context up front. If the user opened the assistant from a product page, or a merchant opened it from a campaign dashboard, put that page's data in the session context. The conversation is likely about it, and answering from context costs no extra turns.
- Increase model intelligence. Smarter models can decrease overall turns in the completion of a task as the agent can more efficiently plan and issue its tool calls. That often outweighs their slower tokens. If your queries skew complex, or production shows more than about five turns per task, the faster model is frequently the smarter one. Which one that is depends on your traffic, so choose by sweep, as described under "Choosing the model" below.
- Have the model call independent tools in parallel. Commerce use cases often require many operations in parallel: be it searching for multiple products, querying many policy docs, or fetching records from many sources of sales data. Parallel tool ensures multiple independent queries don’t burn additional turns. Prompt the model to call many tools within a turn and return the results in one user message as an array of tool results (see the parallel tool use docs).
Faster tools
- Optimize the tool's own backend. Sometimes a tool genuinely fans out – a merchant agent with a "get today's snapshot" query reads sales, inventory, and campaign status in three independent calls. But we often see the tool boundary become the place where missing backend logic gets stitched together: an availability check that calls the catalog for the SKU, the inventory service per store, and the fulfillment service for cutoffs, then applies substitution rules and pickup eligibility in the tool's own code before answering. That tool is now overloaded with domain knowledge, hard to keep correct as the rules change, and is carrying logic that should sit in an upstream system. When you find yourself writing that logic in a tool, the fix is one backend endpoint that answers the question, and calling that with an agent tool.
- Dispatch tools eagerly. Tool arguments stream out of the model like any other tokens, so the harness can execute each tool’s call as its arguments complete and process it while the model is still streaming other, parallel tools or content blocks. We've seen this take multi-second gaps down to a few hundred milliseconds, and the Claude Agent SDK does it by default. You should prompt the model to emit its slowest call first for maximum latency gains.

Perceived latency
Perceived latency is the time a user feels until the screen does something. It’s especially critical in consumer-facing use cases where any transaction friction impacts checkout rates and revenue. Two techniques shorten it without touching the model:
- Stream components as they form. A rendered commerce response is typically 500–700 output tokens, which without streaming is five or more seconds of a spinner. Send each parameter of a presentation tool to the client as it streams and render the page progressively.
- Show the work. While the agent is gathering context, render a short progress line for each step in plain language (for example, "finding hotels near the water"). You can build it from the tool's existing arguments (such as the query for a product search), or add an additional user_facing_message parameter tool that prompts the model to write the line.

Prompt caching
Prompt caching is your largest cost reduction candidate and commerce traffic is well-suited for it. Cached input token reads cost a tenth of fresh ones, and while cache-writes carry a premium of roughly 1.25x, a cached prefix pays for itself on its second use. In customer facing applications where volume is large, you have a unique opportunity to hit very high cache levels using the cheapest, default 5 minute cache expiration.
The best commerce deployments we've seen run at 90–99% cache hit rates, and that is the range to design for from the start. Our experience has shown cached token reads are also around 1.5 to 2x faster at ~100k tokens, with relatively linear scaling the more tokens there are.
Caching is prefix-based. A request reads from cache up to the first byte that differs from a previous request, so what matters is not just what is in the context but the order it is in. Think of a request as three segments, ordered by how often they change:
- Global: most of the system prompt and tool definitions, identical across every session. This is your warmest cache and, at scale, will likely not expire. Keep it byte-identical across turns and sessions and put a cache breakpoint at its end.
- Session: per-user context and conversation history, which differ across sessions but stay stable within one. This segment comes after the global one.
- Volatile: anything that changes within a session, such as the current time or the current page. Put it at the very end of the request, either as a tagged block in the newest user turn or, on models that support mid-conversation system messages, as a system-role message appended to the messages array. The most common mistake we see is a timestamp or the current page at the top of the system prompt, which silently breaks the cache on every request.

There are two implementation details to remember here. First, skills should be loaded as tool results rather than appended to the system prompt. The skill body then lands in the conversation prefix and is cached along with it.
Second, roll your breakpoints forward in each turn: a request allows a limited number of breakpoints, so move the newest one to the end of each user turn. Each round then reads the accumulated history, including long tool results such as search responses, from cache.

Choosing the model and its configuration
Model size and the effort setting are the same tradeoff – intelligence against latency and cost – and you should choose both by measurement:
- Pick your metric and your floor. Pick the quality metrics your business runs on (task completion, answer relevance, grounded accuracy), the eval score you won't go below, and your p50 and p99 latency and cost budgets.
- Sweep. Run your entire eval suite across every model and effort level you'd consider. We recommend starting at Opus for merchant agents, whose tasks are analysis-heavy, and Sonnet for consumer agents, where latency weighs more. If you have production traffic, weigh the results by your real query mix. Then let the numbers decide. Sometimes Opus 5's lift on cart-driving tasks justifies the cost difference over Sonnet, and sometimes it doesn't.
- Read the results carefully. Two things regularly surprise teams. The first is that a prompt is tuned to a model, so a sweep run with one prompt may underperform other models that it wasn't written for. A smaller model usually needs instructions the current model infers on its own, and a larger one will follow instructions to the letter that the smaller one was ignoring. A few rounds of iteration on each candidate's failing cases is a cheap step before ruling any of them out. The second is that a more intelligent configuration sometimes wins on latency (most commonly on p90 and p99) despite slower tokens, because it plans its tool calls better and needs fewer rounds on the most complex requests.
Measure cost per completed task rather than per model call, since a cheaper model that needs more turns, or fails more often, is not cheaper. When the result is close, and the cost fits your per-task economics and latency, choose intelligence. Quality is what drives adoption and retention, and allows for room to build for the next 6 months as models become better.
Running it in production
Memory, safety, evals, and scaling the work across an organization: what gets an agent through production and keeps it there.
Lastly, we talk about what gets an agent through production: memory, safety, evals, and scaling the work across an organization.
Memory that survives the session
The relationship and interactions you have with your customers matter. Memory is what lets an agent pick up where the last conversation left off instead of starting from nothing. A shopper who mentioned a nut allergy in March shouldn't have to repeat it in June, and a merchant who checks the same three campaigns every Monday shouldn't have to name them each time. Long-term memory, the facts that should survive across sessions, is a system you build and it has three parts: how facts are stored, how they are written, and how they are read.
Storing memories
Memory belongs in your systems, not in the model.
A flat markdown profile works when profiles are small and the agent is the only reader. Most production commerce agents outgrow it, and the practical replacement is the database you already operate. A fact is a small typed record: a key (such as shoe_size, default_store, preferred_report_cadence), a short value, a category, and the session it came from. Some keys you decide up front and every user gets; the rest the extractor discovers. A database stays queryable as the store grows, lets you build deterministic behavior on specific attributes, and joins to the user data you already have.
For merchant-facing agents, key memory by person rather than by account. Merchant logins are often shared between operators, so each operator needs their own profile, and reads have to respect that operator's permissions: a store manager's agent should not recall a fact a district manager stated.
In the commerce domain, agent memory holds personal data. The facts worth remembering are often the most regulated ones, and the rules between jurisdictions differ. Treat memory as a data-handling design problem and not just a storage one. In practice that means four things:
- Decide which types of memories you are willing to hold. Enforce that at the write path, with a validator that every save goes through, rather than in the prompt alone.
- Give users a way to see, correct, and delete what is stored. Wire deletion into your account-deletion and data-request flows.
- Set a retention period. A preference from a few years ago is likely to be outdated, so a retention period helps keep memory facts fresh.
- Memory should be a per-deployment switch. This allows regions that can't take on these obligations to run without it.
Writing memory
Write memory asynchronously. At the end of each turn, or every few turns in a long session, an agent in a separate thread or process reads the conversation and creates, updates, or deletes facts in the store, keeping its own working context as the session goes on.
It adds nothing to the conversation's latency, and achieved 13% higher fact recall on our internal commerce memory eval suite.
The obvious alternative, a tool the agent calls to save a fact, is the wrong one for a latency-sensitive commerce agent. Every save is a tool call inside a user-facing turn, and unless the whole store is in context, a save needs a read first to update or dedupe, which is a round of its own.
It also puts one more decision in front of the agent on every turn, and in our evals that competition for attention showed up as missed memories.
Separating the extractor also lets you prompt it precisely. It reads only the user's and the assistant's text, never tool results, so a product description or a review can't become a fact about the user. Its prompt says what counts as a fact — a stated size, a dietary constraint, a fulfillment preference, a merchant’s usual materialized views — and what doesn't, such as anything from a listing or a one-off detail.

Reading memory
Read memory in three layers.
Always in context
A small fixed set of facts goes into context on every turn: the ones nearly every request depends on, such as a shopper's default store and fulfillment preference, or an operator's store and role.
Pre-fetched per turn
Facts relevant to the current request are pre-fetched per turn from the same signals that pre-load a skill: a shoe search pulls sizes and brand preferences, a campaign question pulls the operator's usual metrics.
Behind a lookup tool
Everything else sits behind a lookup tool.
Since memory is per-user context, all of it goes in the session segment, below the global cache breakpoint.
Safety: enforcement lives in the harness
The prompt is where safe behavior starts, but in commerce it can't be where safety is enforced. The failures are financial and often irreversible, and a prompt rule is one injection or one bad sample away from being skipped. Every rule below is enforced in code, on both the consumer and the merchant agent, and defined once so every runtime shares it.
The model stages; a person or a policy applies
No model tool call moves money or changes the business. Order placement, payments, refunds, price changes, and campaign launches all end in an action the harness controls instead of the model.
On the consumer side this is structural: the checkout tool renders the cart with a button to place the order, and the backend interface the agent calls has no charge method at all.
On the merchant side, every write tool produces a staged change with a server-generated ID, and apply_change succeeds only for IDs that have been approved through a real surface: a button in the operator's portal, a confirmation in the CLI, or the platform's own tool-approval prompt when the agent runs on Managed Agents.
The guardrails are re-checked at apply time against current limits, not the limits in force when the change was staged. Whatever the surface, the shape is the same: the model's most dangerous action is to propose, and the approval routes through the maker-checker flow your business already uses for that kind of change.
Writes and renders accept only server-issued IDs
The harness keeps a per-session record of every ID the server has handed the model, and that record is the only key any write or render will accept.
The cart accepts only product IDs the server returned to this session, and the merchant tools accept only listing and campaign IDs the agent has actually read. An ID that arrived any other way — hallucinated, pasted by a user, planted in a review — is refused before the backend sees it.
The same rule covers the UI. Presentation tools take IDs, and the server fills in the product, order, or change records itself, so a card only renders records the server itself filled in.
It covers delegates too: the merchant analysis subagent reads data but never adds to the set of IDs the agent may write to.
For fees, disclosures, and other regulated content, the model chooses which product to disclose and the server supplies every word from approved copy. The same fee fields are on the merchant agent's protected list, so neither side of the counter can change or paraphrase them, and evals check the rendered strings byte for byte.
Capped transactions must hold to repeated requests
Most commerce surfaces cap how many of an item one user can buy — for ticket allocations, promotional pricing, or fraud control — and an agent will retry, rephrase, and parallelize in ways a human clicking a button never did.
The cap is therefore enforced on the line as it would be after the write, so a second "add two more" can't stack past it, and cart writes for one session are serialized so parallel tool calls in a single turn can't combine to exceed it.
Merchant changes are checked the same way against caps on price movement, discount depth, restock size, and campaign budget, plus a list of protected fields no change may touch. The rule generalizes: enforce every limit on the resulting state rather than the request, and serialize writes per session.
Third-party content is sanitized
In commerce most of the context is written by people who aren't you — sellers, reviewers, competitors — so every backend read is untrusted input and goes through one sanitizer.
Every tool result authored by a third party, such as listings, reviews, policies, seller messages, and stored memory, is sanitized and wrapped in a fence with a fixed label before the model sees it.
The sanitizer strips control and bidirectional characters, removes anything that imitates the fence markers, defuses text that imitates a conversation turn or a tool call, and caps the size, which is designed to stop a hostile listing from impersonating the system or filling the context.
The prompt carries the other half of the contract: fenced text is material to report on, never to act on.
Evals: shipping a non-deterministic system
Anything from a small prompt change to a new tool can change agent behavior in ways that are hard to predict, and the change you're shipping is often not the one that regresses. Evals are how you find that out before you deploy. Our earlier blog post on evals for agents covers the general practice. This section covers specifics for commerce agents.
Evaluate snapshots, not conversations
The model’s API is stateless, so what the agent outputs is a function of the system prompt, the tools, and the messages array. This means any state a commerce conversation can reach can be constructed directly. So creating an eval case means constructing the test state, appending the test user message, and letting the agent run from there.
Then grade the outcome: the final state and the rendered response, including the arguments of the last write. In most cases, we recommend against grading the path the agent took to get there as such test cases are brittle and restricting.
Simulated-user evals, in which a second model plays the user and a judge grades the whole conversation, are a poor tool for measurement. Two non-deterministic systems interacting need larger samples, cost more per trial, are harder to judge, and produce failures that are hard to attribute. They are useful for finding coverage gaps and for a general vibe check on the agent, so use them to discover cases, then write each case as a snapshot.

Evaluate for behaviors in tough conditions
Most teams fail to properly test the injected state. A case should encode the preconditions of a failure, not just the task. If a behavior only emerges after a busy first turn with several tool calls, or after a contradiction earlier in the session, a case that starts from a clean state passes on every config and provides no meaningful data.
We've observed most suites to be heavy on such clean-state cases, so make sure a share of yours starts from long, messy, or contradictory histories.
Cover the different types of commerce agent evals
Effective evaluation requires testing both desired and undesired behaviors.
For every positive case, write its negative counterpart: a "should serve" for every "should refuse," a "should just do it" for every "should ask." Missing negatives are the most common gap we find in a suite.
Evaluate for the following:
- Core requests that make up the bulk of your traffic, since a failure here affects most sessions. These include simple lookups, multi-constraint requests, product and plan questions, and multi-intent messages. For the questions, check that every price, availability, and attribute traces back to returned data, and that the agent says when data is missing rather than inventing it.
- Context-dependent requests, such as references to what is on screen, constraints carried over from earlier turns, and writes against an existing cart. Evaluating memory falls into this bucket as well. Check that memories were extracted, retrieved, and changed the answer.
- Safety and brand cases, where a failure costs money or trust. These include attempted injection, attempts to read another user's data, and regulated language, which is checked byte for byte. Split injection into two cases: user-authored injection, where the directive comes from the user's own message, and data-plane injection, where it is planted in product names, reviews, or web snippets that arrive via tool results.
- Interface evaluations, to ensure the right component is rendered, item caps are respected, and there are no internal identifiers in user-facing text. Test for timeouts and empty results too.
- Requests that belong to multiple capabilities at once. An operator asks "if I mark this down 15%, do I have enough stock to cover the demand?" That is a pricing question and an inventory question together. The right answer stages the markdown with a stock projection attached; the wrong answers do one and skip the other. Evals written per capability won't catch this, because each grades only its own half. Write cases for the requests that need two neighboring capabilities together, and grade both halves of the answer.
Write evals with SMEs and use real incidents
Partner with the subject-matter experts who see the failures firsthand, such as team members in Product, Legal, Merchant Ops, Customer Care, and Category Management, to design test cases. Real failures make the best evals, and 50-100 eval cases per user flow is a good starting point.
Make sure to have a variety of cases, as outlined above. Production transcripts are a great stream for sourcing new cases, especially the tricky ones. Coding agents are good at generating additional cases and adversarial variants. The reference repository includes a Claude Code plugin with an eval-authoring skill built with our recommended approach.
Shipping with a large organization
In a commerce enterprise the agent is built by many engineering teams. Search, checkout, pricing, marketing tech, customer care, and the catalog platform each own systems the agent depends on, each ships on its own cadence, and each will want to add or change a tool, a skill, or a prompt rule.
Unlike a service, an agent has no strict module boundary protecting the others: a change made by the pricing team shares a context window with checkout.
The tempting fix is to break the system into many subagents, one per business unit. As discussed in Part 1, we recommend against it for quality reasons. Instead, we outline the process for de-risking multi-team collaboration:
- Ownership follows the systems. Every skill and tool has a single owner team. For example, pricing owns the promotion tools and the pricing skill, care owns the order and returns tools and the customer-care skill. The shared prompt has a single platform-level owner for the common parts and domain owner for the domain-specific section.
- A change ships with its cases and CI runs a set chosen for it. A team contributing a skill also contributes its cases, including the negative cases and the boundary cases against neighboring skills. Running the full suite on every pull request is too slow and too expensive to survive, so build a CI set from it instead. That set will consist of a core set of cases with the highest-traffic requests and every safety case. On top of that, run the cases for whatever the change touched. For a skill, that means its own cases and its neighbors' boundary cases. For a tool, it is every case that calls it. For the shared prompt, it is the full eval suite since everything reads the system prompt. We recommend gating the pass rate over a few trials, and on cache hit rate and cost per turn. It is also a good practice to run the full suite nightly and before every release. Cross-team regressions are caught in these runs.
- The agent should also be inside the release calendar. It's one deployment unit, so a bad change reaches every user at once. Roll prompt and skill changes to a canary cohort first, keep a switch that turns off one skill without a deploy, and freeze the agent ahead of peak periods the same way you freeze other systems.
For the human side of this arrangement, see Building effective human-agent teams.
Looking ahead
Most of what this post describes is not about the model. The tools call systems you already run, the skills encode procedures you already follow, the evals are your product requirements doc written as tests, and the harness enforces policy you would enforce for any client. Models will keep improving, and when a better one ships, the architecture we describe adopts it as a config change with an eval sweep. Everything else keeps working.
It is also important to think about your roadmap for product surfaces. The architecture will outlast the chat panel. The same agent can work over voice, and it can proactively act on a fare drop before the user asks. For a team that already has the evals and the tools, those are presentation-layer projects. Further out, some of the traffic to your storefront will come from agents that shop on behalf of users. The same provenance, staging, and approval rules that keep your own agent in bounds are what will let you open your tools to those agents safely.
Commerce has always rewarded making the buying process as smooth as possible. Agents make that a lot easier. Check out the complete reference implementation, with both the consumer and the merchant agent and runnable examples for retail, travel, telecom, and entertainment.
Acknowledgements
Written by Matthew Koen and Ali Shazal. Special thanks to Michael Segner, Rodrigo Olivares, Amandeep Khurana, Aiza Usman, John Lopus and others for their contributions.