news 2026/9/26 7:05:57

Gemini AI购物直播拆解:Function Calling与多轮状态管理实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Gemini AI购物直播拆解:Function Calling与多轮状态管理实战

1. 从一场直播演示说起:AI购物到底在演示什么

Gemini那场直播我反复看了三遍。第一遍看热闹,第二遍看交互细节,第三遍专门盯着它调用工具时的参数传递和状态流转。很多人看完的第一反应是"这不就是个语音助手加购物车吗",但如果你真的动手搭过类似的Agent,就会知道这场演示里藏着的技术密度远比表面看起来高得多。

所谓"用AI购物",拆开来看其实是三件事的串联:意图理解、工具调用、多轮状态维护。用户说一句"帮我找一双适合雨天跑步的鞋,预算800以内",系统要做的不是关键词匹配,而是先把这句话翻译成结构化的查询条件——场景是雨天跑步、品类是跑鞋、价格上限800、隐含需求是防滑和防水。然后它需要调用商品检索接口,拿到候选集,再根据用户后续的反馈("太丑了""有没有轻一点的")动态调整查询参数,而不是重新开始一轮对话。

这场演示真正让我感兴趣的点在于,Gemini在购物场景里展示的是一种**"边聊边操作"的混合模式**。它不是先问完所有问题再给结果,而是在对话过程中就把筛选、比价、加购这些动作穿插进去。这背后依赖的是函数调用(Function Calling)机制和会话状态的持久化。我在自己的项目里复现过类似流程,踩过的坑后面会细说。

这篇文章适合三类人看:一是想搞清楚AI Agent在电商场景怎么落地的开发者;二是正在做AI应用、想知道工具调用链路怎么设计的同学;三是对Gemini能力边界好奇、想自己动手试一把的爱好者。我会从演示拆解讲到技术原理,再给出一套可以跑通的实操方案,最后把我在实际搭建中遇到的坑和解决思路完整摊开。

2. 拆解直播里的购物链路:意图、检索、决策三段式

2.1 意图理解不是"听懂话",而是"翻译成结构化查询"

大多数人以为AI购物的第一步是语音识别,其实语音转文字只是最外层。真正的核心是把自然语言翻译成可执行的查询对象。直播里用户说"我想买一个送给刚搬新家的朋友的礼物,不要太贵",Gemini没有直接搜"礼物",而是先追问了朋友的兴趣、预算范围、是否需要包装。这个追问行为本身就是意图理解的一部分——它识别出当前信息不足以构成有效查询,于是主动补全槽位(Slot Filling)。

我在自己的实现里用的是"槽位+意图"的双层结构。意图层判断用户是要搜索、比价、加购还是售后;槽位层负责收集品类、价格区间、场景标签、偏好属性这些字段。Gemini的演示里没有暴露它的内部结构,但从交互节奏能看出来,它至少维护了五到六个槽位,并且支持槽位的动态增删。比如用户后来说"对了,朋友对气味敏感",系统立刻新增了一个"无香型"的筛选条件,而不是把这个信息丢掉。

这里有个容易忽略的细节:槽位不是越多越好。我一开始设计了十几个槽位,结果用户每说一句话系统都要追问三四个问题,体验极差。后来改成"核心槽位必填、扩展槽位按需触发",核心槽位只有品类和预算,其他槽位在检索结果不理想时才主动询问。这个策略调整之后,平均对话轮次从7.2轮降到了3.8轮。

2.2 商品检索接口的调用时机与参数构造

直播里Gemini调用检索的时机很有意思。它不是等所有信息收集完才调用,而是在信息足够构成一次有效查询时就先调一次,拿到结果后再根据用户反馈细化。这个策略的好处是用户能快速看到反馈,不会觉得系统在"审问"自己。

参数构造这块,我实测下来最关键的是查询条件的优先级排序。假设用户说了五个条件,但商品库里有三个条件同时满足的结果为零,系统需要知道先放宽哪个。我的做法是给每个槽位设一个权重:品类和价格是硬约束,场景标签是软约束,品牌偏好是弱约束。检索时先按硬约束过滤,软约束用于排序,弱约束只在结果充足时作为加分项。

Gemini的演示里有一个细节:当用户说"有没有便宜点的"时,系统没有重新检索,而是在已有结果集里按价格升序重排。这说明它维护了一个会话级的结果缓存,而不是每次都打接口。这个设计在真实场景里非常重要,因为电商接口的延迟通常在200到500毫秒,如果每轮对话都重新请求,用户体验会明显卡顿。

2.3 决策环节:AI怎么"替用户做选择"

购物场景里最难的不是找到商品,而是帮用户做决策。直播里Gemini展示了一个能力:当用户面对三个候选商品犹豫时,它会主动对比关键差异,比如"第一款防水等级更高但重了80克,第二款轻但只有两个配色,第三款价格最低但评价里提到尺码偏小"。这种对比不是简单的参数罗列,而是基于用户已表达的偏好做加权。

我在实现这个功能时用了一个简单的评分模型:每个商品在用户关注的维度上打分,然后加权求和。权重来自用户在对话中提到的偏好词频,比如用户三次提到"轻",那重量维度的权重就调高。这个方法很粗糙,但实测效果比让大模型直接"凭感觉推荐"要稳定得多,因为大模型的推荐理由经常前后矛盾。

提示:决策环节一定要保留"用户否决"的出口。直播里用户说"都不太满意",Gemini立刻回到检索环节并询问是否放宽某个条件。如果系统只会推荐不会回退,用户很快就会失去耐心。

3. 工具调用背后的技术骨架:Function Calling怎么串起来

3.1 函数定义的设计原则:少而精,参数要扁平

Gemini的Function Calling机制允许你注册一组函数,模型根据对话内容决定调用哪个、传什么参数。我在项目里注册了六个函数:search_products、get_product_detail、compare_products、add_to_cart、get_cart、apply_coupon。听起来不多,但每个函数的参数设计花了我最多时间。

核心原则是参数扁平化。我一开始把搜索参数设计成嵌套对象,比如{"filters": {"price": {"max": 800}, "category": "shoes"}},结果模型经常传错层级。改成扁平结构{"category": "shoes", "price_max": 800, "price_min": 0}之后,参数准确率从七成提升到了九成五以上。大模型对嵌套结构的处理能力确实弱一些,这是实测结论。

另一个原则是给参数设默认值。比如price_min默认0,sort_by默认"relevance"。这样即使用户没说,模型也不会因为缺参数而调用失败。我在函数描述里明确写了"如果用户未指定,使用默认值",模型基本能遵守。

3.2 多轮对话中的状态管理:别把历史全塞进上下文

直播里Gemini能记住用户三轮前说的"预算800",这说明它做了状态管理。但状态管理不等于把全部对话历史塞进上下文。我试过把最近十轮对话原封不动传给模型,结果token消耗暴涨,而且模型经常被早期信息干扰,比如用户一开始说"随便看看",后来明确说要买,模型还在纠结"随便看看"这个表述。

我的方案是维护一个结构化的会话状态对象,只把关键槽位和最近两轮对话传给模型。状态对象长这样:

{ "intent": "search", "slots": { "category": "running_shoes", "price_max": 800, "scene": "rainy_running", "preferences": ["lightweight", "non_slip"] }, "last_results": ["sku_001", "sku_002", "sku_003"], "turn_count": 4 }

每次模型返回后,我用一个轻量的解析逻辑更新这个对象,而不是让模型自己维护。这样做的原因是模型对结构化状态的读写不如代码可靠,让它专注于"理解"和"决策",状态维护交给程序。

3.3 错误处理:工具调用失败时AI该怎么接话

这是直播里没展示但实际开发中最头疼的部分。商品接口超时、库存查询返回空、优惠券校验失败,这些情况在真实环境里天天发生。如果工具调用失败后模型直接说"抱歉我做不到",用户体验就断了。

我的做法是给每个函数定义降级返回。比如search_products超时后返回一个空结果加错误码,同时在函数描述里告诉模型"如果返回错误码TIMEOUT,告知用户稍后重试并建议放宽条件"。实测下来,模型能根据错误码生成合理的回复,比如"刚才查询有点慢,要不我们把价格范围放宽一点再试试?"

还有一个坑是模型会编造工具返回结果。我遇到过模型在接口返回空列表时,自己虚构了三个商品推荐给用户。解决办法是在系统提示里明确写"只能使用工具返回的数据,不得自行生成商品信息",并且在代码层做校验,如果模型输出的商品ID不在返回结果里,直接拦截重试。

4. 自己动手复现:一套可跑通的AI购物Agent方案

4.1 环境准备与依赖选择

要复现这套流程,你需要三样东西:一个支持Function Calling的大模型接口、一个商品数据源、一个会话管理层。商品数据源我用的是本地SQLite,建了一张商品表包含品类、价格、场景标签、重量、防水等级等字段,大概两千条模拟数据。真实场景接电商平台的开放接口也行,但调试阶段本地数据更可控。

模型接口这块,Gemini的API支持函数调用,文档里有完整示例。如果你用其他模型,逻辑是相通的,关键是确认它支持并行函数调用和多轮函数调用。并行调用是指模型一次返回多个函数调用请求,比如同时查商品和查库存;多轮调用是指模型拿到函数结果后继续发起新的调用。这两个能力决定了你的Agent能不能处理复杂购物流程。

会话管理我用的是Redis存状态对象,key是会话ID,过期时间设30分钟。如果你只是本地测试,用内存字典也够,但要注意进程重启后状态会丢。

4.2 核心代码结构:从用户输入到商品推荐

整个流程分四步:接收用户输入、更新会话状态、调用模型、执行函数并回传。我用Python写了一个简化版,核心逻辑大概长这样:

def handle_user_input(session_id, user_text): state = load_state(session_id) messages = build_messages(state, user_text) response = model.generate( messages=messages, tools=TOOL_DEFINITIONS, tool_config={"mode": "AUTO"} ) if response.has_tool_calls: results = [] for call in response.tool_calls: result = execute_tool(call.name, call.args) results.append(format_tool_result(call.id, result)) state = update_state(state, response, results) save_state(session_id, state) return handle_user_input(session_id, None) # 带着工具结果再问模型 state = update_state(state, response) save_state(session_id, state) return response.text

这段代码里最关键的是递归调用那一步。模型返回工具调用请求后,程序执行工具,把结果作为新的消息追加到对话里,再让模型生成最终回复。Gemini的API里这个流程有标准写法,注意工具结果的格式要严格符合接口要求,否则模型会解析失败。

4.3 提示词设计:让模型知道"什么时候该问,什么时候该做"

系统提示词我改了十几版,最后稳定下来的版本核心是三条规则:第一,信息不足时优先追问,但一次最多问两个问题;第二,能通过工具获取的信息不要问用户;第三,推荐商品时必须给出至少一个具体理由,理由必须来自工具返回的数据。

第三条规则特别重要。我一开始没加这条,模型推荐商品时说"这款很适合你",完全是空话。加上规则后,它会说"这款防水等级IPX6,重量240克,符合你提到的雨天和轻量需求",可信度完全不一样。

还有一个小技巧:在提示词里给几个少样本示例(Few-shot),展示一轮完整的"用户说→模型调用工具→模型回复"流程。我放了两个示例,一个简单查询一个多轮筛选,模型的表现明显更稳定。示例不用长,每个控制在五行以内。

5. 实测中暴露的问题与我的处理方式

5.1 模型"过度热情":不该加购的时候加购

测试初期遇到一个典型问题:用户只是问"这个多少钱",模型就自动调用了add_to_cart。原因是我的函数描述里写了"当用户对商品表达兴趣时可加入购物车",模型把"问价格"理解成了"表达兴趣"。

修复方式是把触发条件写得更严格:"仅当用户明确说出'加入购物车''我要买''下单'等指令时才调用此函数"。同时我在代码层加了一道校验,如果用户输入里没有购买意图关键词,即使模型请求加购也拦截。这个双重保险很有必要,因为模型对模糊表述的判断确实不稳定。

5.2 价格计算的精度问题:别让AI做算术

直播里有个环节是计算优惠后的价格,我特意留意了Gemini的表现。它算对了,但我在自己项目里用其他模型测试时,遇到过算错的情况,比如满减和折扣叠加时顺序搞反。后来我把价格计算全部放到代码里,模型只负责决定"用哪张优惠券",具体金额由程序算好再告诉模型。

这个原则可以推广到所有涉及数值计算的场景:模型做决策,代码做计算。折扣、税费、运费、分期,这些统统不要让模型碰。我在函数里加了一个calculate_final_price,输入商品ID和优惠券ID,返回精确到分的价格,模型直接引用这个结果。

5.3 会话超时后的状态恢复

用户聊到一半去干别的事,二十分钟后回来说"就刚才那个吧",这时候会话状态可能已经过期了。我的处理是保留最近一次的结果快照,即使主状态过期,也能从快照里恢复出用户上次看的商品列表。快照存的是商品ID和关键属性,不存完整对话,存储成本很低。

如果快照也过期了,系统会礼貌地请用户重新描述需求,同时尽量从用户这句话里提取线索。比如"就刚才那个"提取不出有效信息,但如果用户说"就刚才那双跑鞋",系统能提取出"跑鞋"这个品类,重新检索后大概率能找到同一批商品。

注意:会话恢复功能一定要做,但不要做得太"聪明"。我试过让模型根据过期会话的残留信息猜测用户意图,结果经常猜错,反而让用户困惑。老老实实说"抱歉刚才的会话已结束,您说的是哪类商品"比自作聪明要好。

6. 从演示到产品:还差哪些关键能力

直播演示和真实产品之间有巨大的鸿沟,我踩过之后总结出三个必须补齐的能力。

第一个是商品数据的实时性。演示里商品信息是静态的,真实场景里价格会变、库存会变、促销会变。我的方案是在检索函数里加一层缓存,缓存时间设60秒,同时给每个商品返回一个"数据更新时间"字段,模型在推荐时可以提及"当前价格"而不是"标价"。

第二个是多模态输入。用户可能发一张图片说"我想要类似的",这时候纯文本的Function Calling就不够了。Gemini支持图片输入,但要把图片特征转成检索条件需要额外的处理。我的做法是用图片描述模型先生成文字描述,再把描述作为搜索关键词,实测召回率大概七成,够用但不算理想。

第三个是个性化记忆。演示里每次对话都是独立的,真实产品需要记住用户的历史偏好。我在会话状态之外加了一个用户画像层,记录用户常买的品类、价格带、品牌偏好。这个画像不直接传给模型,而是在检索时作为排序权重使用,避免模型被历史信息带偏。

最后分享一个我在调试中总结的小技巧:每次修改提示词或函数定义后,用同一组测试用例跑一遍回归。我准备了二十条典型用户输入,覆盖简单查询、多轮筛选、模糊表达、错误恢复等场景,每次改动后跑一遍,看通过率有没有下降。这个习惯帮我避免了好几次"改了一个问题引入两个新问题"的情况。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 7:05:42

社区快递后台管理系统:SSM框架Java毕设全流程实战解析

小区门口的快递架又堆满了,包裹找不到、取错件、滞留好几天没人管——这个场景你我都不陌生。而“社区快递后台管理系统”这个题目,几乎就是为Java毕业设计量身定做的:它业务主线清晰,角色划分明确,既能把SSM框架的核心…

作者头像 李华
网站建设 2026/9/26 7:04:48

中兴M3/U30Air刷亚太系统:突破区域锁的5G频段解锁实战

1. 项目概述:为什么“中兴M3和U30Air刷入亚太系统”不是一次普通升级,而是一次精准的设备功能重定义中兴M3和U30Air这两款设备,表面看是两款不同定位的终端——M3是面向企业级场景的多模融合网关,U30Air则是主打便携与快速部署的轻…

作者头像 李华
网站建设 2026/9/26 7:04:42

Halo后训练框架深度拆解:从SFT到偏好优化的全流程实战

1. 从一条推荐说起:Halo 后训练框架到底是个什么东西Hugging Face 的 CEO 在社交平台上点名推荐了一个叫 Halo 的后训练框架,这件事在圈子里传开之后,我身边不少做模型训练的朋友第一反应都是——"又一个训练框架?跟 TRL、Ax…

作者头像 李华
网站建设 2026/9/26 7:04:13

金融服务产品落地核心:账户体系、资金通路与风控引擎实战解析

1. 金融服务的底层逻辑:为什么大多数人做不成"financial-services" 这五个字在行业里被说得太泛了。做支付的说自己是金融服务,做贷超的也说是金融服务,做SaaS工具的照样贴着金融服务的标签。我入行这些年,见过不少团队…

作者头像 李华
网站建设 2026/9/26 7:02:41

Codex会话延续功能解析:提升AI编程协作效率的实践指南

1. 这次更新到底改了什么:从“一次性问答”到“可持续会话”Codex 这次加的那个被大家叫做“续命按钮”的东西,说白了就是会话延续能力。以前用 Codex 写代码,最让人抓狂的地方在于:你给它一段需求,它给你一版代码&…

作者头像 李华
网站建设 2026/9/26 7:01:56

OpenRouter Batch API 批量推理实战:半价成本与工程化避坑指南

1. 批量推理这件事,为什么值得单独聊做AI应用开发的朋友大概率都遇到过这种场景:白天用户请求稀稀拉拉,晚上跑数据清洗、内容打标、离线摘要的时候,几万条文本要过一遍大模型。这时候你会发现两件事——第一,钱烧得比想…

作者头像 李华