ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AI Agent购物实战:原理与Python比价Agent实现

AI Agent购物实战:原理与Python比价Agent实现 不少同学第一次接触 AI Agent 时会把注意力放在聊天生成、文档总结、内容创作这些偏“文本”的能力上。但真正让 Agent 从一个演示项目变成可用工程的方向往往是它能不能和外部系统发生真实交互比如查库存、比价格、创建订单、跟踪物流。围绕“AI Agent 购物”这个话题我梳理了它背后的技术原理、典型的工具调用方式并且用 Python 实现了一个可运行的比价 Agent。如果你准备做 AI 应用开发或者正在调研 Agent 工程实践这篇文章会给你一条可以直接上手的路径。为了让内容更容易落地我会先解释 AI Agent 购物和传统自动化的区别再逐步拆解架构然后给出代码示例、运行结果、常见报错排查以及实际项目里需要注意的安全和工程问题。整个思路不绑定某个具体电商平台重点是把“智能体如何自主完成购买链路”这件事讲清楚。1. 背景AI Agent 购物到底是什么1.1 从“推荐”到“执行”的关键转变传统的电商推荐系统本质上是给用户展示候选商品点击、下单、支付仍然依赖用户手动完成。推荐系统的核心是“匹配”把用户特征和商品特征做相关性计算然后输出一个排序结果。它的能力边界在“建议”不在“行动”。AI Agent 购物则往前走了一步智能体不仅要理解“我想买一副降噪耳机”这样模糊的意图还要把意图拆解成一系列可执行的动作。比如搜索商品、筛选商家、对比价格、核对库存、生成购物车清单甚至在某些场景下调用下单接口。这里的关键词是“自主决策”也就是智能体根据当前环境反馈动态决定下一步调用哪个工具。用一个简单类比普通脚本是“写死的流水线”用户输入什么脚本就执行预先定好的步骤AI Agent 则像一个“带计划的实习生”它知道目标是什么也能根据实际情况调整路径。这个区别看上去很小但在真实业务里会带来完全不同的工程复杂度。1.2 AI Agent 与传统购物脚本的区别对比维度传统脚本 / 爬虫AI Agent 购物目标理解依赖固定规则和结构化参数可以理解模糊的自然语言意图步骤编排预先写死流程动态规划根据中间结果调整工具扩展新增能力需要改代码注册新工具即可复用异常处理遇到未预料的返回就崩溃可以结合上下文重新规划输出形式固定格式数据自然语言 动作记录这里需要说明并不是所有购物场景都适合用 Agent。如果业务只有固定的比价需求直接写一个定时脚本调用公开接口性能更高、出错率更低。Agent 的优势场景是那些需要“理解意图 多步决策 动态反馈”的任务比如多条件筛选后的比价、跨平台商品比较、根据预算做出购买建议。1.3 典型的应用场景AI Agent 购物并不是一个空泛的概念在工程上可以落到以下几类场景比价助手用户说“预算 300 以内要支持主动降噪的蓝牙耳机”Agent 搜索多个渠道按价格和评分排序。库存监控Agent 定时检查目标商品是否有货一旦补货就通知用户或按授权执行后续流程。订单助手结合用户购物车和优惠券信息帮助用户计算最优凑单方案。售后助理用户表达“耳机到了但连不上手机”Agent 判断是否需要退换货并引导用户提交售后单。这些场景的共同特点是有明确的目标、有可调用的外部工具、有中间状态的判断依据。准备好这几个条件Agent 才有发挥空间。2. 技术原理Agent 是如何“学会”买东西的2.1 核心循环感知、规划、行动、观察业界讨论 Agent 时经常提到 ReAct 模式其实就是把“推理”和“行动”交替进行。用一句话概括模型先根据当前局面决定做什么做事之后把结果重新喂回模型模型再决定下一步做什么。对应的循环可以写成用户输入 → 意图解析 → 规划工具序列 → 调用工具 → 观察返回结果 → 生成回复或继续下一步 → 循环直到目标完成这个循环里最容易出问题的环节是“规划”。模型可能规划出不存在的工具可能漏掉关键参数也可能陷入来回调用同一个工具的循环。所以在工程实现时要给 Agent 设置最大执行步数并记录每一步的工具调用和结果方便事后追踪。2.2 工具调用是 Agent 的“手”大模型本身不能直接查询数据库也不能直接调用电商平台的订单接口。它需要一组外部函数也就是工具。每个工具通常包含三个属性名称、描述、参数结构。名称和描述用来让模型理解“这个工具是干什么的”参数结构用来规范调用格式。在购物场景里常见的工具有这些search_products(keyword) 搜索商品 get_product_detail(product_id) 查询商品详情 check_stock(product_id) 检查库存 compare_price(keyword) 多平台比价 create_order(user_id, product_id, quantity) 创建订单 query_logistics(order_id) 查询物流有了工具之后Agent 的工作就变成了“选择合适的工具、填充正确的参数、根据结果决定是否继续”。这个思路不依赖某一个具体的大模型也不依赖某一个具体的框架。2.3 记忆短期上下文与长期偏好购物 Agent 需要记忆。短期记忆指的是当前对话上下文例如用户已经看过哪些商品、比较过哪些价格长期记忆则指用户的偏好比如“经常买无糖饮料”“常用的收货地址”。短期记忆一般通过消息列表维护长期记忆可以落在数据库或向量数据库中需要时通过检索取回。工程上要注意记忆不是越多越好。上下文过长会带来更高的调用成本和更长的响应时间甚至让模型忽略关键指令。更合理的做法是只保留与当前任务相关的状态把长期偏好做一次精简后注入提示词。2.4 技术选型从规则到框架技术选型可以分三个层次。最底层是纯规则实现适合教学和简单场景也就是下一节我会给出的代码示例。中间层是接入大模型并配合 Function Calling让模型能够自主选择工具。再往上可以使用成熟的 Agent 框架比如 Python 生态的 LangChain、LlamaIndexJava 生态的 Spring AI它们封装了模型调用、工具注册、对话记忆等通用能力。选择框架时不要只追新要看团队技术栈和维护成本。如果团队主要是 Java 后端引入 Spring AI 比引入一套 Python 框架更平滑如果只是一个内部小工具直接写几十行代码也可能比引入框架更可控。3. 环境准备与项目结构3.1 开发环境本节示例代码使用 Python 编写。为了兼容大部分环境我尽量使用标准库不依赖重量级第三方框架。你本机需要满足以下条件Python 3.9 或更高版本一个命令行终端或者任意 Python IDEVS Code / PyCharm 均可如果后续要接入大模型接口需要准备一个可用的模型服务地址和 API Key版本不必完全一致核心语法在 Python 3.9 以上的环境中都能运行。如果你的环境是 Python 3.8建议把代码中的类型注解去掉或改成兼容写法。3.2 项目目录建议按下面的结构创建项目ai-shopping-agent/ ├── src/ │ ├── __init__.py │ ├── models.py # 数据模型 │ ├── mock_data.py # 模拟商品数据 │ ├── tools.py # 工具函数 │ └── agent.py # Agent 主逻辑 ├── main.py # 入口文件 └── requirements.txt # 依赖文件本示例可留空这个结构虽然小但已经具备了 Agent 工程的基本分层数据模型、外部资源、工具层、智能体调度层。后续扩展时可以把 tools 继续拆分成电商接口、物流接口、支付接口等模块。4. 实战实现一个可运行的比价 Agent4.1 定义数据模型先定义商品的数据结构。用 dataclass 可以让代码更清晰也方便后续序列化。# 文件路径src/models.py from dataclasses import dataclass dataclass class Product: 商品信息 product_id: str name: str store: str price: float stock: int delivery_time: str这个模型包含商品 ID、名称、店铺、价格、库存、配送时效。实际项目中这里可能还需要加商品图片、评分、优惠券信息等但核心的对比维度已经足够覆盖。4.2 准备模拟商品数据我们模拟三个商城的数据用列表直接写死。真实项目中这里应该替换成对不同平台的 API 调用。# 文件路径src/mock_data.py from src.models import Product PRODUCT_DB [ Product(P001, 无线蓝牙耳机 Pro, 商城A, 299.0, 200, 次日达), Product(P002, 无线蓝牙耳机 Pro, 商城B, 259.0, 150, 3天), Product(P003, 无线蓝牙耳机 基础版, 商城C, 199.0, 0, 次日达), Product(P004, 降噪耳机 ProMax, 商城A, 899.0, 50, 次日达), ]注意第三行数据中基础版耳机价格最低但库存为 0。这个细节是为了让 Agent 在排序时能区分“有货”和“缺货”商品避免把缺货商品当成最优结果推荐给用户。4.3 实现工具函数工具层是整个 Agent 能“动手”的基础。这里实现搜索、详情查询、库存检查、比价四个工具。# 文件路径src/tools.py from typing import List, Optional from src.models import Product from src.mock_data import PRODUCT_DB def search_products(keyword: str) - List[Product]: 根据关键词搜索商品 keyword_lower keyword.lower() result [] for p in PRODUCT_DB: if keyword_lower in p.name.lower(): result.append(p) return result def get_product_detail(product_id: str) - Optional[Product]: 按 ID 查询商品详情 for p in PRODUCT_DB: if p.product_id product_id: return p return None def check_stock(product_id: str, quantity: int 1) - bool: 检查商品库存是否满足数量要求 product get_product_detail(product_id) if product is None: return False return product.stock quantity def compare_price(keyword: str) - List[Product]: 比价先返回有货商品再返回缺货商品各自按价格升序排列 products search_products(keyword) if not products: return [] available [p for p in products if p.stock 0] unavailable [p for p in products if p.stock 0] available.sort(keylambda p: p.price) unavailable.sort(keylambda p: p.price) return available unavailable这些函数和普通工具函数没有区别重要的是它们被 Agent 调用的方式。每个函数只做一件事参数简单返回结构清晰这样无论是规则型调度还是大模型工具调用都能正确对接。4.4 实现 Agent 主流程Agent 的核心是规划器和执行器。下面的实现省略了大模型改用简单的关键词规则做规划目的是让你先看清“规划 → 调用工具 → 格式化结果”的骨架。# 文件路径src/agent.py from src.tools import compare_price, search_products, check_stock class ShoppingAgent: 极简购物 Agent演示规划、行动、观察三个环节。 def __init__(self): self.context {} def plan(self, user_input: str) - list: # 规则型规划根据用户输入中的关键词决定工具调用顺序 if 比价 in user_input or 价格 in user_input: return [search, compare] if 库存 in user_input or 有货 in user_input: return [search, stock] return [search, compare] def _extract_keyword(self, user_input: str) - str: # 去掉常见的动词和意图词剩下商品关键词 for word in [帮我, 看看, 比价, 价格, 库存, 有货, 商品, 查一下]: user_input user_input.replace(word, ) return user_input.strip() def run(self, user_input: str) - str: steps self.plan(user_input) keyword self._extract_keyword(user_input) for step in steps: if step search: self.context[products] search_products(keyword) elif step compare: self.context[sorted_products] compare_price(keyword) elif step stock: products self.context.get(products, []) self.context[stock_status] [ (p, check_stock(p.product_id)) for p in products ] return self._format_result(keyword) def _format_result(self, keyword: str) - str: sorted_products self.context.get(sorted_products) if not sorted_products: return f没有找到与“{keyword}”相关的商品。 lines [f“{keyword}”比价结果如下] for index, product in enumerate(sorted_products, 1): stock_text 有货 if product.stock 0 else 缺货 lines.append( f{index}. {product.name} | {product.store} f| ¥{product.price} | {stock_text} | {product.delivery_time} ) return \n.join(lines)这里的 context 字段用来暂存中间结果。虽然示例很小但它已经体现了一个 Agent 的基本设计规划器输出步骤执行器按步骤调用工具结果先落到上下文最后统一格式化输出。后续把 plan 替换成大模型决策时其余部分基本不用改动。4.5 运行与验证入口文件非常简洁。# 文件路径main.py from src.agent import ShoppingAgent if __name__ __main__: agent ShoppingAgent() result agent.run(帮我看看无线蓝牙耳机的比价) print(result)在项目根目录执行python main.py预期输出如下“无线蓝牙耳机”比价结果如下 1. 无线蓝牙耳机 Pro | 商城B | ¥259.0 | 有货 | 3天 2. 无线蓝牙耳机 Pro | 商城A | ¥299.0 | 有货 | 次日达 3. 无线蓝牙耳机 基础版 | 商城C | ¥199.0 | 缺货 | 次日达从结果可以看到Agent 没有把最便宜的缺货商品排到第一位而是优先展示有货且价格更优的商城B。这说明工具函数内部的“有货优先 价格升序”策略起到了作用。如果你把用户输入改成“查一下无线蓝牙耳机库存”Agent 会走另一条工具链输出各商品的库存状态。5. 进阶接入大模型让 Agent 理解复杂意图5.1 为什么规则型 Agent 不够用刚才的示例里规划器靠关键词判断用户意图。问题在于自然语言变化太多“有没有 300 以内的降噪耳机”“性价比高一点的耳机推荐下”这类表达很难用关键词规则覆盖全。规则型 Agent 一旦遇到未登记的句式就会退回默认路径导致输出不符合预期。接入大模型之后意图理解交给模型Agent 只需要维护好工具列表和执行循环。比如用户说“预算 300 以内要主动降噪”模型可以解析出预算范围和功能需求再决定调用 search_products并自动生成合理的筛选逻辑。这就是大模型给 Agent 带来的核心价值从“写死规则”变成“语义驱动”。5.2 用 Function Calling 让模型选择工具Function Calling 是目前主流的大模型工具调用方式。简单说你在请求里定义好 JSON Schema 形式的工具列表模型会根据用户输入决定调用哪个工具并把参数以 JSON 格式返回。下面是一个示意代码以 OpenAI 兼容的 Chat Completions 接口为例具体字段以你实际使用的模型服务为准。# 文件路径src/llm_agent.py示例思路需按实际模型服务调整 import json import requests TOOLS [ { type: function, function: { name: search_products, description: 根据关键词搜索商品, parameters: { type: object, properties: { keyword: {type: string, description: 商品关键词} }, required: [keyword] } } }, { type: function, function: { name: create_order, description: 确认价格和库存后为用户创建订单, parameters: { type: object, properties: { user_id: {type: string}, product_id: {type: string}, quantity: {type: integer, default: 1} }, required: [user_id, product_id] } } } ]接下来是循环执行的核心逻辑。模型每次返回可能包含两种结果要么提示还需要调用工具要么直接生成最终回复。代码需要循环处理直到模型不再请求工具。def call_llm(messages): # 这里是对模型服务的一次真实调用请替换成你的接口地址和鉴权方式 resp requests.post( urlYOUR_LLM_ENDPOINT, headers{Authorization: Bearer YOUR_API_KEY}, json{messages: messages, tools: TOOLS}, timeout60, ) return resp.json() def execute_tool(name: str, arguments: dict): # 实际项目中应把工具名映射到对应的 Python 函数 if name search_products: from src.tools import search_products products search_products(arguments[keyword]) return [p.__dict__ for p in products] if name create_order: # 订单创建必须二次确认这里只做占位 return {status: pending_confirmation} raise ValueError(f未知工具: {name}) def run_agent_with_llm(user_input: str) - str: messages [{role: user, content: user_input}] max_steps 5 for _ in range(max_steps): data call_llm(messages) message data[choices][0][message] messages.append(message) # 模型没有要求调用工具说明要生成最终回复 if not message.get(tool_calls): return message[content] for tool_call in message[tool_calls]: name tool_call[function][name] arguments json.loads(tool_call[function][arguments]) result execute_tool(name, arguments) # 把工具执行结果回传给模型让模型继续决策 messages.append({ role: tool, tool_call_id: tool_call[id], content: json.dumps(result, ensure_asciiFalse) }) raise RuntimeError(Agent 执行超过最大步数请检查工具调用逻辑)这段代码有两个关键点。第一工具结果必须回传给模型模型才能根据最新信息生成下一步动作。第二必须设置最大执行步数否则模型可能一直在“查询—返回—再查询”的循环里打转既浪费 token又拖慢响应。5.3 多轮对话与购物状态管理接入大模型后Agent 还需要维护购物状态。简单的做法是把整个对话消息列表保存在内存里每个用户一个 session。更可靠的做法是把购物车、订单状态放到 Redis 或数据库中。举例来说用户先问“有 300 以内的降噪耳机吗”Agent 返回两个选项用户接着说“第一个下单”这时 Agent 必须知道“第一个”指的是上文中的哪个商品。如果状态只存在模型上下文里一旦 session 超时或进程重启用户就丢失了购物进度。因此生产环境建议把以下信息持久化用户身份与授权信息当前会话中的候选商品列表已加入购物车的商品待确认的订单草稿5.4 人工确认是不可省略的一环这里必须强调涉及支付、订单创建的环节Agent 无论如何都不应该完全自主执行。推荐的模式是 Human-in-the-Loop也就是 Agent 负责搜索、筛选、生成订单草稿但在真正下单和支付前必须让用户明确确认。实现上可以把 create_order 设计成两个接口一个生成待确认订单一个确认订单。生成订单只写入草稿状态确认订单才真正提交。这样可以避免模型误解用户意图也可以避免用户家庭住址、支付方式等信息被错误使用。6. 常见问题与排查思路问题现象常见原因解决思路模型没有调用任何工具工具描述不清晰或模型服务不支持工具调用检查工具名称和 description确认模型接口支持 Function CallingAgent 反复查询同一商品缺少最大步数限制或上下文缺失关键状态设置 max_steps记录已执行步骤避免重复调用工具返回 JSON 解析失败模型返回的参数不合法或接口返回结构变化增加异常处理解析前先校验字段必要时重试一次价格和库存数据不准数据源更新延迟或缓存策略过期时间太长为不同数据设置合理的 TTL关键决策前实时查一次用户误下单缺少人工确认环节意图判断不准确下单前二次确认使用待确认订单模式下面针对高频问题展开说明。6.1 模型不调用工具模型不调用工具最常见的两个原因是工具描述不清晰和工具列表太长。描述不清晰时模型无法把用户意图映射到正确的工具工具列表过长时模型可能忽略靠后的工具。建议把高频工具放在前面description 写成“该工具用于……适用于……场景”并保持每个工具的职责单一。6.2 Agent 陷入死循环死循环在真实项目中几乎一定会遇到。比如模型反复调用 check_stock但忽略了库存不足于是不断重新查询。解决办法是在循环里增加“已尝试步骤”的记录如果发现同一个工具被连续调用多次就中止循环并让模型换策略或者直接提示用户当前无法完成该任务。6.3 下单前的安全校验如果你真的实现了下单工具必须加三层保护。第一层是权限校验确认当前用户有权限执行订单操作第二层是价格和库存二次确认避免界面显示数据和实际下单数据不一致第三层是人工确认订单必须等待用户明确同意。任何绕过这三层的做法都会在真实业务里带来巨大的资损风险。7. 最佳实践与工程建议7.1 权限最小化Agent 能访问的工具和接口应该遵循最小权限原则。购物 Agent 不需要访问用户历史订单时就不要给它注册查询历史订单的工具不需要修改收货地址时就不要把地址修改接口暴露给它。每一个额外权限都意味着多一个被误用的可能。7.2 全程可观测生产环境的 Agent 必须记录完整的执行轨迹包括用户输入、意图解析结果、工具调用名称、传入参数、返回结果、每一步耗时。常用做法是把这些信息写入结构化日志或者使用调用链追踪系统。没有可观测性Agent 出了错误你只能靠猜。7.3 缓存与限流购物场景里商品价格和库存变动频繁但如果每个请求都实时拉取所有数据接口压力会非常大。建议设置分层缓存热门商品用短 TTL 缓存下单前再做一次实时校验。同时对模型服务调用做限流避免突发流量打爆上游。7.4 不要存敏感支付信息购物 Agent 往往需要和支付系统交互但千万不要在自己的数据库里存储完整银行卡号、CVV、明文密码。支付环节尽量跳转到第三方支付平台或使用标记化令牌。即使是模拟购物场景也应该从一开始就养成不落盘敏感信息的习惯。7.5 测试策略Agent 的测试比普通接口更复杂因为输出不一定稳定。建议构建一个固定工具返回结果的测试桩把模型服务替换成 mock验证 Agent 的规划逻辑、参数填充和异常处理是否符合预期。再去和真实模型做联调最后做小流量灰度。8. 总结与学习路线本文从 AI Agent 购物这个概念出发介绍了智能体从“理解意图”到“调用工具”再到“观察反馈”的完整循环并给出了一个不依赖大模型也能运行的比价 Agent 示例。更重要的是在进阶部分演示了如何通过 Function Calling 让大模型自动选择工具以及如何通过人工确认机制保证下单安全。如果你打算继续深入下一步可以按这样的顺序学习先熟悉 ReAct 模式的实现细节然后练习给不同工具编写 JSON Schema再尝试把对话记忆和长期偏好接入 Agent最后研究如何对 Agent 做系统化评估。购物场景只是 Agent 的一个入口同样的架构换一组工具就能迁移到订票、客服、数据查询等方向。在实际项目里优先关注两个风险点一是 Agent 的工具调用是否在授权范围内二是下单支付环节是否有人工确认兜底。建议先把本文的比价示例跑通再逐步加入真实接口和模型调用。如果这篇文章对你有帮助可以收藏备用下个项目里就会用到。
返回列表