先说一个让我决定做这个项目的场景。当时我在一家电商公司负责客户体验,凌晨一点的会话记录里全是同一类问题:订单到底发没发、赠品为什么没给、这款和那款到底差在哪。客服团队忙得脚不沾地,工单还是堆成小山。我们最开始想上一个FAQ机器人,结果发现“答得上”根本不是难点,“让客户满意并且顺手多买一单”才是。所以后来我们直接立项做了这个“电商客服+导购智能体”,一个基于大模型Agent架构、同时承担售前咨询、商品导购和售后处理的统一会话系统。这篇文章是我把它从零搭起来之后的全过程复盘,涉及数据准备、模块拆解、导购策略、模型选型和踩坑记录,适合正在做电商客服智能化、或者准备在企业内部搭建Agent应用的技术团队参考。
1. 为什么要把“客服”和“导购”合体:立项时的真实判断
1.1 “能答”和“能卖”是两个不同的能力
大多数人以为客服智能体就是把客户的问题答对,导购智能体就是把商品推荐出去,两者做在一起只是“顺手”。但实际落地时你会很快发现,这两件事背后的评价体系完全不一样。客服的核心指标是解决率和满意度,要求的是稳定、不犯错;导购的核心指标是转化率和客单价,要求的是主动引导、制造需求。如果把客服话术的“克制”用在导购里,客户问一句你只答一句,转化率上不去;如果把导购的“主动”用在客服里,客户问退款你还在推新品,投诉直接拉满。
所以我和团队当时达成的第一个共识是:这两个角色必须在一个系统里,但必须有不同的“人格”和决策权重。真正的导购智能体不仅仅是“会推荐商品”,它需要理解客户的购物背景:是给家人买还是给自己用?是装修还是应急?客户是价格敏感型还是参数敏感型?这些信息在纯客服场景里往往是冗余的,但在导购场景里却直接决定了推荐策略。智能体的价值恰恰在于,它同时掌握客服和导购两个维度的上下文,并且能在同一场对话里灵活切换。
1.2 单智能体还是多智能体:我为什么选了单智能体
立项初期,有一部分同事支持做一个“客服Agent + 导购Agent + 调度Agent”的多智能体系统,听起来架构很酷,各司其职。我当时的判断是:第一版先不做多智能体。原因有三个。
第一,多智能体之间需要明确的通信协议和全局共享状态,开发量直接翻倍。第二,客户的问题往往横跨两个域,比如“这个有没有赠品”既是售后问题也是导购机会,消息在多个Agent之间飞来飞去,很容易掉链子。第三,两套Agent的模型调用成本、日志追踪、评测体系都要分别维护,对一个中小规模团队来说负担太重。
最终我们采用的是一个单Agent调度 + 业务域路由的设计:所有会话先进入口,经过业务域分类后进入对应功能模块,由同一个决策引擎调度。这样既保持了架构简单,又能在内部做业务隔离。等到线上跑稳定之后,导购策略引擎和售后处理引擎已经发展成两个独立服务,但对外仍然是一个Agent在响应,客户完全无感。这个设计决定了我们后期迭代的容错率:就算导购模块出了问题,售后客服还能继续正常工作。
1.3 分阶段交付:从售后切入,再叠加导购
这个项目最终分了三个阶段。第一阶段做单轮和多轮FAQ、订单查询、物流查询、售后流程办理,目标是先把客服团队的负担降下来;第二阶段做商品问答、参数对比、相似推荐、凑单推荐这些导购能力,目标是提升转化;第三阶段才做主动营销,比如客户在会话里表现出犹豫时触发促单话术、对高风险售后会话做预警等。这个顺序非常重要。
为什么先售后?因为售后问题意图相对明确,高频、责任边界清楚,模型比较容易学会;而导购需要用到促销策略、竞品信息、库存实时性,对数据准确性的要求非常高,做不好会直接损失客户信任。先把售后做到满意,客户才愿意在对话里被“推荐”,导购才有生长的土壤。把顺序搞反,大概率会看到一个满口推荐、却连退款流程都搞不清的“四不像”。
2. 开工前先盘家底:数据、系统边界和会话入口
2.1 要准备的五类基础数据
智能体不像常规软件,输入输出都是结构化的。它的效果天花板由它能拿到的数据决定。我们在动工前花了两周时间把公司里能用的资产全部盘点了一遍,最后归纳成五类:
| 数据类型 | 包含内容 | 用途 | 典型样例 |
|---|---|---|---|
| 商品主数据 | SPU/SKU、类目、属性、规格 | 商品问答、参数查询 | “这款尺寸是150cm” |
| 订单交易数据 | 订单状态、商品明细 | 订单查询、售后办理 | “您的订单已发货” |
| 物流数据 | 包裹状态、快递单号 | 物流跟踪问答 | “包裹目前在广州转运中心” |
| 政策规则 | 退货时效、价保规则、优惠券规则 | 售后处理与话术纠正 | “支持七天无理由退货” |
| 历史会话 | 脱敏后的客服聊天记录 | 意图挖掘、话术学习、评测样例 | 客户问“能便宜点吗” |
这里有一个最容易踩的坑:你以为商品数据是完整的,但一查看就会发现很多商品缺详细参数,甚至库存是负数。建议在开发前就把数据质量门槛定义清楚:优先保证商品名、规格、价格、库存四个字段非空;对于缺字段的商品,宁可让Agent回答“暂时没有参数信息”,也不要让模型瞎编。
2.2 客服域与导购域的边界怎么划
我建议用“责任矩阵”的方式把边界画清楚。我们当时把会话分成咨询类、交易异常类、导购类三类。售后问题比如“退款为什么没到账”,不管用户在过程中说了什么,都要优先走售后流程,导购动作只能作为次要动作。导购类问题比如“适合什么型号”“有没有替代款”,由导购域处理。
同时规定:当客户情绪评分较高,通过关键词检测到投诉、不满、损失等语言时,系统自动切到售后友好模式,所有导购动作全部暂停。边界的判定规则不一定要用大模型。我们用了大量关键词和正则规则做前置预判,只有当预判置信度不高时,才会调用大模型做意图分类,这样能明显降低成本。
2.3 会话入口设计:IM侧栏、H5、小程序怎么选
大多数电商客服智能体跑在实时聊天套件里,比如电商平台的店铺IM、企业微信、自建小程序。我们把这些入口全部接到一个统一网关,以会话ID作为唯一主键,把用户画像、最近订单、当前商品页上下文都注入这个会话ID。有一个很容易被忽略的细节:客户在聊天时很可能正在浏览一个商品页,智能体应该通过页面URL参数获知“当前在哪个商品”,才能真正理解“这个”指的是什么。如果不做上下文注入,客户说“这个”,智能体根本不知道哪个。
3. 核心模块拆解:意图识别、对话状态机和工具调用
3.1 意图识别分三级做,而不是只靠大模型
我们最后把意图体系分成了三级。一级意图包括售前咨询、售后咨询、订单咨询、闲聊;二级意图包括商品问参数、商品对比、比价、凑单、优惠券询问、退款、换货、催发货;三级是槽位和属性抽取,比如订单号、商品ID、价格区间。
第一版全部用规则加正则加意图词典来做,准确率能到八成;第二版加了一个精调的小模型做意图分类,准确率提到九成三;第三版才用大模型做兜底,处理规则和小模型都分不清的情况。我强烈建议不要一上来就用大模型做意图识别。原因有两个:一是意图识别要求低延迟和高一致性,同一个意图每次返回的标签必须一致,大模型因为采样参数的存在会产生抖动;二是意图识别是整个流程的入口,入口不稳定,后面全乱。
我们后来用的是一个路由表:请求进来先查规则,规则无结果再交给精调分类模型,最后才轮到LLM,而且LLM只做意图纠偏,不直接决定业务动作。这套混合策略在线上跑了很久,效果很稳。
3.2 对话状态机:让程序管状态,让模型做单次动作
这是整个项目里最关键的设计。多轮对话如果全凭LLM去记忆前面说了什么,会出现两个问题:一是上下文太长,成本高、速度慢;二是模型会“忘事”,前面说好的退款方式,后面又改口。我们最终把对话状态从Prompt里剥离出来,由后端程序维护一个状态机,LLM只负责输出“当前这一轮应该采取的动作”以及动作参数,至于这个动作能不能做、下一步走到哪,由程序根据状态表判断。
以售后申请退款为例:
| 状态 | 模型应输出 | 程序动作 |
|---|---|---|
| 待确认订单 | intent=review_order, order_id | 校验订单归属、查询可退款状态 |
| 待确认退款原因 | reason=七天无理由等 | 校验合法性、写入工单 |
| 待确认金额 | amount, refund_method | 校验金额范围、计算运费扣除 |
| 执行退款 | execute_refund | 调用支付网关、生成回执 |
这样做的收益非常明显:无论客户怎么绕圈子,对话都必须沿着状态机往下走,不会出现“已经退款了又问一遍”的情况。校验逻辑也可以放在程序里做,比如退款金额不能大于支付金额、未发货订单必须走拦截流程等。状态机把“不可控的大模型对话”变成了“可控的业务流程”。
3.3 工具调用:统一封装API和参数校验
智能体的工具层是整个系统与业务系统打交道的地方。我们没有让LLM直接连数据库,也没有允许它直接调用业务API。在API外层统一封装了一层工具层,用JSON Schema描述每个工具的参数、权限和副作用级别。举个例子:
{ "name": "query_order", "description": "查询当前会话客户订单信息,用于订单状态、物流、售后的基础查询", "parameters": { "type": "object", "properties": { "order_id": { "type": "string", "description": "订单号,如未明确给出,不要自行编造" } }, "required": ["order_id"] } }然后在Python端写了一个统一执行器:
def execute_tool(tool_name: str, args: dict, session: Session) -> ToolResult: # 1. 权限校验:只允许操作当前会话绑定的客户数据 if not session.is_owner(args.get("order_id")): return ToolResult(error="无权访问该订单") # 2. 参数规范化:去除空格、统一大小写等 args["order_id"] = normalize_order_id(args["order_id"]) # 3. 执行并记录日志 result = TOOL_REGISTRY[tool_name](**args) log_tool_call(session.id, tool_name, args, result) return result这个封装的作用有两个。第一,强制权限校验,避免会话串联导致的数据泄露;第二,便于审计,哪些工具在什么场景被调用了,出了问题能快速排查。还有一个细节,工具失败时不要把原始报错直接交给LLM,而是统一翻译成“查询失败,请稍后重试”这类安全提示,避免暴露内部接口信息。
3.4 多轮对话里容易漏的三个细节
这里说几个实际运行中踩出来的细节。指代消解要显式处理,比如客户说“那个便宜的呢”,系统要从最近的上下文商品列表中找出目标,而不是凭空猜测。拒绝要带替代方案,比如确实不能减免运费时,主动提出赠送优惠券,而不是生硬地说“不能”。超时中断时要保存会话摘要,客户第二天回来时能继续上下文。这些细节单独看都不起眼,但组合起来才构成“靠谱”的体验。
4. 导购策略设计:从“会接待”到“会转化”
4.1 不要按SKU本位推荐,要按场景推荐
我见过很多导购机器人会把客户当成搜索关键词来对待,客户问“暖风机”就推热卖的暖风机。但真正的购买动机往往藏在场景里:客户说“北方冬天卫生间用”,更合理的是推荐适合浴室使用、防溅水、带摇头功能的型号;客户说“给老人用”,就要推操作简单、安全保护多的款式;客户说“办公室工位用”,可能要便携、噪音小的款。
所以我们在导购策略层做了一个“场景理解 + 约束筛选 + 候选排序”的流程:先抽取商品约束条件,比如价格区间、功能、人群、使用场景;再用这些约束去筛商品库;最后针对候选商品输出推荐理由和横向对比。这样客户会觉得你听懂了他的需求,而不是简单地丢一个商品链接。
4.2 商品对比和评测问答应做成模板
客户问“A和B哪个好”是最常见的问题之一,也是最容易答错的问题。我们的做法是:先用信息抽取拿到两个商品ID,再从知识库中取出客观参数,生成一个两列对比表发给客户,再附上一句决策建议,比如“A更适合小户型,B功率更大”。
关键点在于,客观参数用结构化数据填充,主观建议才让模型自己措辞。这样做的好处是,即使模型的建议说错了,参数部分仍然可验证,客户可以自己判断,投诉风险低得多。对比表之后,如果客户继续追问“那哪个更耐用”,模型再结合商品评价和质保信息做回答,这时的准确率会高很多。
4.3 促单、挽单与优惠计算合并成“话术引擎”
促单的关键不是把“现在购买有优惠”放在所有回复里,而是判断时机。我们设计的逻辑是:当模型输出的回复意图为“正在比较”或“正在犹豫”时,才触发推荐优惠。当客户已经处于售后或投诉状态时,绝对不允许促单。
为了限制模型的自由度,我们做了一个独立于主Prompt的话术模板库,包含价格异议应对、缺货替代、限时优惠提醒、运费争议补偿等场景。每个模板都带有条件标签,由规则层决定哪些模板可以被当前会话使用。这样模型只负责把话术说自然,而不用思考“要不要给这个客户优惠”“能给多少优惠”这种需要业务判断的问题,优惠金额和适用范围全部由业务系统配置。
4.4 导购话术里绝对不能碰的底线
再强调一次:不能承诺库存、不能承诺价格保护、不能承诺赠品,除非这些信息已经在业务系统里明确配置。我们有一次让模型自己编了一个“下单立减50”的活动,结果根本没有这个活动,直接导致客诉。后来我们做了约束:所有涉及金额、库存、赠品的输出,必须由工具返回值提供,模型只能原文引用,不能自己生成数字。
这个约束放在Prompt层面还不够,还要在代码层做一次校验。我们写了一个post-processing函数,扫描模型回复中所有数字和“元”“件”“折”等关键词,与工具返回值的合法范围做比对,超出范围的直接拒绝并回退到安全话术。
5. 知识库、Prompt管理和模型选型
5.1 商品知识库:RAG还是直接结构化查询
我们做商品问答时,在RAG和结构化查询之间纠结了很久,最终结论是:高频、简单的参数查询走结构化查询,直接查商品参数表;长尾、非固定格式的知识问答,比如“这款适合什么人群”“和某款比哪个更耐用”,走RAG。
我不建议把RAG当万能药。它的主要毛病是召回不精准:客户问“适合多大脚码”,检索出来的文本可能包含“36-44”也可能包含“不适合大脚码”,模型有概率挑错。所以我们在RAG检索后面加了一个“参数候选校验”模块,凡是有明确参数值的,强制做抽取和校验,优先使用结构化字段,校验失败宁可回答“以商品页面描述为准”,也不要让模型自由发挥。
5.2 知识库更新与新鲜度问题
知识库更新是一个反复被忽视的问题。促销活动经常变化,商品上下架频繁,如果知识库存的是上一轮快照,就会出现昨天还推“活动价”、今天其实已过期的情况。我们在索引埋点里强制保留商品创建时间和内容最后更新时间两个字段,检索结果只返回更新时间为当前有效的内容。同时每天凌晨对全量索引做一次重建,配合ETL脚本从业务库同步新增和下线商品。
这件事听起来简单,但如果没有做,真实用户会立刻遇到“查得到但买不到”“价格对不上”的问题,信任度瞬间崩塌。
5.3 Prompt分场景管理,配套版本回滚
Prompt不能是一个巨大的“万能咒语”。我们把它按业务域拆成了五类:售后话术、商品问答、导购推荐、投诉安抚、闲聊。每个场景的Prompt都独立配置,内容里固定引用对应的工具和参数。这些是我认为很重要的小习惯:
- 在Prompt中明确智能体的身份和边界,比如“你是某电商平台的客服与导购助理”,避免模型身份含糊。
- 明确“所有金额、优惠、库存信息必须引用工具返回,不得自行生成”。
- 约定输入格式,把用户发言标为user_input,把上下文标为context,避免模型把输入和输出搞混。
Prompt的版本管理我们用一张简单的记录表:版本号、对应场景、改动内容、上线时间、灰度比例。每次改动先放5%流量验证24小时,再决定是否全量。不要相信“一次性改完”,Prompt的微小措辞变化都可能在导购输出上带来明显偏差。
5.4 大小模型分层与成本估算
成本是很多人不太愿意谈的痛点。我按我们当时的实际跑量算一笔账,假设每天1万次会话、每次3轮对话、每轮调一次模型:
- 规则与关键词处理:不调用模型,成本几乎为零,能处理约30%的问题。
- 精调小分类模型:按token计算,一天不到几十万token,成本可忽略。
- 大模型处理关键决策和生成话术:每轮约300到500 token,1万次会话大约是每天三百万到五百万token,按主流定价折算,一天在数百元级别。
这个成本比很多人预想得高,但也比“所有请求全走大模型”低很多。优化方向有三个:把工具调用和知识检索从Prompt里拆出去,减少模型见到的无关上下文;对固定策略话术做缓存;设置会话长度上限,超过15轮自动转人工或启用上下文摘要模式,防止单条会话成本失控。
6. 上线、灰度评估体系和踩坑实录
6.1 灰度节奏:先内测、再限量、再全量
上线不是一次性“开总开关”。我们做了一套灰度开关:先在研发群、客服群内测,这时所有对话都有客服在旁监听,可随时接管;放5%流量时,关闭所有主动导购动作,只做被动回答;等到售后满意度数据平稳之后,才逐步开放导购推荐和促单话术。整个过程花了近三周。
为什么要这么谨慎?因为导购能力的判断标准是“能否促成转化”,这种促成是软性的,客户可能因为一句不合适的话就流失;而客服能力的判断标准是“能否把问题解决”,错误处理直接且真实。我们实际上是把导购当作一个独立的新功能来灰度,客服域始终保持稳定。这样即使导购策略出了问题,也不会拖垮客服体验。
6.2 评估指标要按售前、售后拆开看
我们做了一个分域评估表,按周统计:
| 指标 | 售后域 | 导购域 |
|---|---|---|
| 意图识别准确率 | ≥ 93% | ≥ 90% |
| 知识答案有效命中 | ≥ 90% | ≥ 85% |
| 人工接管率 | ≤ 15% | ≤ 25% |
| 客户满意度(抽样) | ≥ 4.2/5 | ≥ 4.0/5 |
| 会话转化率 | 不适用 | 与人工同口径对比提升 |
| 平均解决耗时 | 下降40%以上 | 不适用 |
强调一点:不要只看“AI解决率”。衡量这类智能体的价值,还要看“售前咨询到成交转化”和“售后一次性解决率”。我们用了同口径对比法,在同一个入口随机分流,对比AI接待和人工接待的转化率与满意度差异,持续四周取数。这样才能让团队和市场都相信智能体不只是省人力,而是能直接贡献收入。
6.3 踩过的四个坑及修复方案
第一个坑是商品推荐推荐了下架或缺货商品。原因在于库存缓存和索引数据不一致,查询接口返回的商品状态是最新的,但索引里仍是旧的。修复方式是:在导购推荐返回前,增加一步库存状态校验,凡是不在售的商品强制过滤,宁可推荐得少,也不要推荐错。
第二个坑是AI承诺了未配置的优惠。刚才提到的“下单立减50”就是血泪教训。修复方式:所有金额、活动、赠品描述都从活动服务读取,模型输出对应位置用占位符,由工具层最终填充并校验。
第三个坑是转人工后AI又插嘴。客户已经转到人工坐席,模型还基于之前的上下文继续“建议购买”,两边同时回复导致体验灾难。修复方式:在会话状态里增加一个人工接管标志,一旦置为真,AI模块完全静默,直到人工主动释放。
第四个坑是会话上下文串线。多坐席同时接管多个会话时,出现过A客户的下文带到了B客户会话里,原因是有人直接用共享变量存储会话内存。修复方式:强制以session_id为key存储,会话快照加唯一ID,在工具调用层做身份校验,只允许访问当前会话绑定的用户数据。这个坑也再次印证了工具调用层权限校验的重要性。
6.4 日志复盘是一切的起点
项目上线后最重要的事,不是加新功能,而是把每天的会话日志吃透。我们每天把分布式日志落盘,记录会话ID、意图识别结果、状态机跳转、调用的工具、模型回复、是否转人工、客户反馈。然后用一个简单的脚本从中抽case做异常筛查,比如意图识别和客户二次提问不一致、工具调用超时、回复中包含未配置的金额字段。
这项工作比训练新模型更出成效。上线第一个月,光是日志筛查就解决了十几个或大或小的问题,后来也成了团队每周例行复盘的数据源。日志要早设计,不要等出问题了再补。
最后说一点我个人的体会。做这类智能体,最容易犯的错误是把模型当业务系统。真正能在线上稳定跑起来的Agent,靠的是数据清洗、权限校验、状态机设计和话术策略这些“脏活累活”,而不是一味换更大的模型。电商客服加导购智能体的核心竞争力,不取决于模型有多聪明,而取决于系统够不够稳、业务边界清不清、数据准不准。如果有人打算从零开始做,我建议就按这条路线走:先做售后域的客服能力稳住信任,再加导购域提升转化;用状态机管逻辑,用工具层管数据,用日志管迭代。这套流程走完,你收获的不只是一个能上线的智能体,还有一个能持续优化的迭代体系。