在逛多了“大模型榜单”之后你可能会发现一个现象很多模型在聊天、写作、数学推理里表现惊艳可一旦让它去执行“帮我挑一款 200 元以内、今天能发货的礼物放到购物车”它就开始顾左右而言他——要么只给推荐理由要么把商品页信息解析错要么甚至编造一个不存在的 SKU。这正是购物类 Agent 评测最难的地方你要检验的不是“会不会说话”而是“能不能把事情办成”。最近 Accio 开源 CommerceAgentBench 基准并在社区公布了一批模型表现其中最受关注的信息是在开源权重模型里Qwen3.8-Max 整体表现最强。先说结论这件事值得关注不是因为又多了一个榜单而是它把“电商 Agent”这个细分赛道的评测标准往前推了一步。通用 Agent 评测回答不了的问题——商品的真实价格怎么解析、库存和发货承诺怎么校验、加购和结算到底怎么算完成——正是 CommerceAgentBench 这类专业化基准想解决的。这篇文章不会只做新闻转述。我会从五个层面展开这个基准到底在测什么为什么电商 Agent 需要专门评测而不是套问答基准“开源权重模型整体最强”这句话意味着什么如果想让自己的 Agent 也跑通类似评测环境、代码、打分流程该怎么搭最后给出工程落地时的常见问题和建议。1. 为什么一个电商 Agent 基准值得认真看过去一年Agent 应用层最热闹的方向之一就是“帮用户做决策、做执行”的智能体。购物类 Agent 又是其中天然适合商业化的一类需求高频、价值可量化、流程边界相对清楚。但做过的团队都知道购物 Agent 的实际体验要做到“可用”远不是一个能聊天的模型加一个商品搜索接口那么简单。真实用户指令往往是这样的“预算 200 元以内的生日礼物适合送女生。”“帮我找一款支持明天到的机械键盘茶轴优先。”“这个手机在另一家店是不是更便宜如果便宜 50 块以上就换一家买。”这些指令看起来不难但放到真实的电商环境里Agent 要先理解用户约束再去检索商品、打开详情页、核对价格与库存、考虑发货时间最后还要安全地执行动作。整个链路里任何一个环节出错最后都等于任务失败。问题在于多数传统评测只能证明“模型知道怎么回答”很难证明“模型能在真实环境里按步骤完成任务”。这也是 CommerceAgentBench 这类基准的切入点它试图把一个购物 Agent 的完整执行过程拆成可重现、可打分、可对比的任务。对普通开发者来说它的参考价值有三层选型价值如果你要在项目里接入开源权重模型可以看它们在 Agent 执行链路里的真实排序而不是只看单轮问答分。工程价值它展示了电商类 Agent 评测任务应该如何设计包括环境、动作、约束、打分。行业价值它推动了“执行能力”而不是“对话能力”成为 Agent 的核心评价维度。需要提前说明的是这篇文章的代码与命令属于通用演示目的是帮你建立评测工程的基本框架并不代表 Accio 官方仓库的实际实现。真要复现 CommerceAgentBench请以官方文档为准。2. CommerceAgentBench 评测的对象会聊天与会下单是两种能力“Accio”这个名字取得很聪明。在《哈利·波特》里它是“飞来飞去”咒喊一声就能让远处的物体飞到你手里。AI 购物助手的核心任务恰好接近这个动作不是给用户一段正确句子而是把符合要求的商品、价格、库存以及最后的交易结果一步步“召唤”回来。2.1 Agent、Benchmark、Task 是什么关系先理清概念。这里的“Agent”指的是能自主调用工具的智能体它接收一个自然语言目标在多次交互里决定调用哪些工具、解析什么结果、最终执行什么动作。“Benchmark”是一套可重复运行的评测标准是多个任务、环境和评分规则的集合。“Task”则是其中最基础的一条条任务通常包含一条指令、一个初始环境以及判定成功与否的条件。一条典型电商 Agent 任务可能长这样初始状态一个模拟商城环境有商品页、搜索页、购物车。用户指令自然语言描述的购物需求。可用工具搜索商品、查看详情、加购、结算、返回上一页等。完成条件用户约束被满足并且执行到了指定的结束动作。2.2 一个电商 Agent 需要什么能力从我接触的同类项目看电商 Agent 的能力地图通常分五层能力层要解决的问题评测时重点观察指令解析把“预算200以内送女生礼物”拆成可执行条件是否遗漏预算、对象、时间等限制商品检索在商品列表里找到候选商品是否用了合理的关键词与筛选条件页面理解从详情页读出价格、库存、发货承诺是否把“满减价”与“原价”搞混决策规划在多步搜索、对比后做出选择是否在信息不足时反复横跳交易执行加购、结算、提交订单是否真正走到了指定动作这个分层很重要。它会直接影响评测任务的设计如果只测“模型最后输出的那段话是否像推荐语”那很多模型都能过关。但 CommerceAgentBench 这类以执行为导向的评测会去看模型有没有真正调用加购工具、加购的商品是否满足预算约束、页面解析到的价格是否和用户要求一致。所以读它的结果时别把“Agent 能力强”简单理解成“生成能力强”。能稳定完成电商任务需要的是指令跟随、工具调用、结构化输出、长上下文利用和结果校验五种能力的组合。3. 为什么购物类 Agent 不适合只用通用问答基准打分一个常见的误区是既然大模型都能做多轮对话那只要找一个强的推理模型包装成 Agent 就行。实际踩过坑的人会告诉你完全不是这么回事。通用问答基准测的是“正确答案”比如“下列哪个选项符合描述”。这类题目不依赖网页、不依赖商品详情、不需要执行动作模型只要在记忆里检索知识就能回答。购物 Agent 却是在一个动态、结构复杂、充满噪音的环境里做多步决策。同样是“给我推荐一款防晒霜”问答模型可以凭借训练记忆给出一段漂亮文案但 Agent 必须回答另外几个问题现在有货吗价格是多少有没有运费能及时发货吗后一类问题模型无法纯粹靠记忆作答必须去读环境返回的数据。更深一层的问题是通用评测往往会“因为生成流畅就给分”但购物场景里流畅不等于正确。一个模型完全可以写出一句话“我推荐 A 商品它定价 189 元满足你的 200 元预算。”可如果它看到的真实页面显示价格是 259 元那这句话就是幻觉。再往下如果模型把一个“已下架”的商品推荐出去那它在真实场景里造成的不是丢分而是用户时间与信任的损失。电商 Agent 评测还要特别注意两个容易被忽视的指标。第一是约束不违反率。用户说“预算 200 元以内”Agent 最后推荐了 199 元的商品表面看成功了但如果有 18 元运费最后结算变成 217 元这算不算完成在真实购物语境里这大概率不算。基准设计得好的话会把这类“隐性越界”单独计分。第二是“加购”和“成交”要分开。一个只会把商品放进购物车的 Agent和一个能确认库存、价格并走到结算的 Agent能力门槛完全不同。如果评测只把“推荐了商品”当成功模型很容易用“文本层面完成任务”来刷分——这在可执行的购物 Agent 里恰恰是最需要警惕的。所以专门的电商 Agent 基准存在的理由很朴素它在努力测量“用户目标是否真实达成”而不是“模型解释得是否足够动听”。4. “开源权重模型整体最强”这句话的分量围绕 CommerceAgentBench 发布的信息里讨论最集中的判断是在开源权重模型中Qwen3.8-Max 整体表现最强。读这句话时先要把“开源权重模型”和“开源模型”区分开。开源权重通常意味着模型参数文件公开可下载使用者可以自托管推理但训练数据、完整训练代码不一定公开商用许可也各有条款。是否允许商用、是否需要额外授权要以后续具体协议为准。那“在开源权重模型中整体最强”到底意味着什么我觉得要从三个维度理解。一是能力边界。Agent 评测的复合性很强不是单点能力突出就能拿总冠军。一个模型想排名靠前必须同时在指令理解、工具调用格式、多轮上下文一致性、最终决策上都不拉胯。能从整体维度跑赢其他开源权重模型说明 Qwen3.8-Max 在这些能力的综合表现上取得了相对优势。二是落地含义。开源权重模型能进前排对开发者是实打实的好消息。电商类 Agent 经常要处理商家商品库、用户行为等带有敏感性的数据很多团队并不愿意把所有请求都送到外部 API。如果能自托管一个开源权重模型并且它在执行类任务上不掉队那意味着“性能”和“可控性”不再必须二选一。三是需要冷静的部分。“整体最强”是相对排名不等于在所有子任务里都最强。某个模型可能在中文长尾商品识别上更好另一个可能在英文结算流程里更稳。你在实际项目中选型还是要拿自己的任务子集做验证不能只看一条总榜。另外开源权重模型的 Agent 能力受到部署条件影响很大。同一个模型用不同推理框架、不同上下文长度、不同工具定义方式去跑最终结果可能有明显差异。这提醒我们评测时必须固定推理服务和 prompt 模板否则很难判断差别的来源。5. 动手跑这类评测之前环境与前置条件如果你也想在自己的项目里搭一套电商 Agent 评测并不需要一开始就做得很重。一个最小评测工程通常包括四部分可选模型的推理服务。一个确定性的商城环境快照。一组带指令与约束的评测任务。对执行轨迹的记录与自动打分。下面用通用命令演示环境准备。要注意这里不是 Accio 官方仓库的安装步骤只是一个可参考的模板。版本号请以实际项目为准不要照抄。5.1 创建 Python 虚拟环境python -m venv .venv source .venv/bin/activate pip install -U pip如果你的 Agent 要操作真实网页通常会用到浏览器自动化工具。下面是 Playwright 的安装示例。pip install playwright playwright install chromium这里提醒一句评测环境越接近真实生产结果越可信但也会越不稳定。真实商城页面一天一变会给回归评测带来噪音。入门阶段更推荐先录制一份固定的页面快照或在本地跑一个模拟商城服务。5.2 准备推理服务与模型如果你评测的是开源权重模型可以先在本地启动一个兼容 OpenAI 协议的推理服务把地址和密钥写进环境变量。export LLM_BASE_URLhttp://127.0.0.1:8000/v1 export LLM_API_KEYEMPTY这只是示意。实际部署需要根据模型情况配置显存、并发和上下文长度不同推理框架的启动参数也不一样请参考对应模型与框架文档。6. 评测流水线的核心环节拆分环境准备完之后评测不是“跑一个脚本看看结果”这么简单。电商 Agent 评测流水线通常要拆成四个环节。6.1 任务生成与真值定义先要有一组带有明确约束的任务。比如下面这个任务核心约束是“预算 200 元以内”“可以今天发货”。定义任务时最需要注意的是“可验证”。每一条约束都要能通过结构化的方式判断。比如价格约束不能只看模型输出的自然语言而要去查它最终加购的商品详情里结构化价格字段到底是多少。如果评测任务本身不可验证后面所有分数都会失去意义。6.2 模型与环境交互评测脚本把用户指令发给模型模型决定调用工具评测脚本执行工具后把结果返回给模型。如此多轮直到模型输出最终回复或触发终止条件。这一环节最容易出的问题是“工具返回结果不结构化”。如果直接把整个 HTML 塞给模型模型往往会在长篇文本里看漏价格或发货字段。更稳的方案是在工具层做一次抽取返回 JSON。6.3 过程日志与最终打分评测真正有价值的部分在于“过程可回放”。每一轮模型回复、每一次工具调用、每个商品的价格与库存状态都应该记成 JSONL 日志。最后打分时不仅看 Agent 是否执行了加购动作还要回放日志检查动作对应的商品是否真的满足所有约束。这也是评测与普通对话测试最大的差异对话测试关心“说了什么”Agent 评测关心“做了什么、做对没有”。7. 最小示例从任务定义到执行与打分下面用一套极简代码演示电商 Agent 评测的基本结构。再次强调这是为了讲清链路而写的演示模板不是 Accio 官方实现也不保证所有细节都和官方一致。7.1 定义一条评测任务文件tasks/demo_task.json{ task_id: gift_budget_v1, instruction: 帮我找一个预算 200 元以内、适合送女生的生日礼物最好今天能发货。找到后把商品加入购物车。, environment: demo_mall_snapshot_v1, constraints: [ { type: price_lte, value: 200, currency: CNY }, { type: ship_mark, value: today } ], finish_action: add_to_cart }这里的约束设计很关键。我不建议把约束只放在自然语言指令里因为自然语言需要二次解析会引入不确定性。把关键约束结构化后打分阶段就能用代码直接判断 Agent 的选择是否合规。7.2 模型调用与工具执行循环文件eval_runner.py下面代码是一个“模型调用 工具执行”的骨架。真正评测时execute_tool需要连接你自己的商城快照环境并返回结构化结果。# eval_runner.py # 演示用模板需要根据你的实际评测环境补齐 execute_tool 的实现 import json import os from openai import OpenAI client OpenAI( api_keyos.getenv(LLM_API_KEY, EMPTY), base_urlos.getenv(LLM_BASE_URL, http://127.0.0.1:8000/v1), ) TOOLS [ { type: function, function: { name: search_product, description: 根据关键词搜索商品返回商品列表。, parameters: { type: object, properties: { keyword: {type: string, description: 搜索关键词} }, required: [keyword] } } }, { type: function, function: { name: get_product_detail, description: 获取商品详情包括价格、库存、发货信息。, parameters: { type: object, properties: { product_id: {type: string} }, required: [product_id] } } }, { type: function, function: { name: add_to_cart, description: 把指定商品加入购物车。, parameters: { type: object, properties: { product_id: {type: string}, quantity: {type: integer, minimum: 1} }, required: [product_id] } } } ] def execute_tool(name: str, args: dict, env: dict): # 真实评测时这里要连接沙箱商城或页面快照 # 并返回结构化的商品数据而不是把整段 HTML 丢给模型。 if name search_product: return env[catalog].search(args.get(keyword, )) if name get_product_detail: return env[catalog].detail(args.get(product_id, )) if name add_to_cart: return {ok: True, product_id: args.get(product_id)} return {error: unknown_tool} def run_one_task(task: dict) - dict: # 按 env_id 加载一个确定性的商城快照 env __import__(catalog_snapshot).load(task[environment]) messages [{role: user, content: task[instruction]}] trace [] for step in range(20): resp client.chat.completions.create( # 部署时可替换成你要评测的开源权重模型ID modelqwen3.8-max, messagesmessages, toolsTOOLS, tool_choiceauto, ) msg resp.choices[0].message messages.append(msg) trace.append({ step: step, role: assistant, content: msg.content, tool_calls: msg.tool_calls and [c.model_dump() for c in msg.tool_calls], }) if not msg.tool_calls: return { task_id: task[task_id], status: finished, trace: trace, } for call in msg.tool_calls: fn_name call.function.name fn_args json.loads(call.function.arguments) result execute_tool(fn_name, fn_args, env) messages.append({ role: tool, tool_call_id: call.id, content: json.dumps(result, ensure_asciiFalse), }) trace.append({ step: step, tool: fn_name, args: fn_args, result: result, }) return { task_id: task[task_id], status: max_step, trace: trace, }这段代码想表达三个重点。第一模型的目标不是直接输出“