那个三天就上线的客服机器人,两周后为什么被悄悄下线了
先讲一个常见的失败剧本,你大概率见过类似的。
一个典型的翻车过程
某独立开发者的朋友接了个小项目:给一家做本地生活服务的商家搭客服机器人。第一天的方案很“务实”——把商家整理的 200 多条 FAQ 直接塞进 prompt,调用模型,返回答案。本地测试效果不错,三天就上线了。
然后问题开始排队出现:
第一周:答非所问。 用户的问题很少和 FAQ 原文一致。“退款多久到账”和“我上周买的东西钱什么时候退给我”对模型是两回事,但把 200 条 FAQ 全塞进上下文,模型经常挑错答案,或者干脆自由发挥,编出商家根本没有的退款政策。
第二周:无法处理追问。 用户问“你们营业到几点”,机器人答“10 点”。用户接着问“那周末呢”,机器人回复“请问您想了解什么业务”——它没有对话状态,每一轮都是失忆重启。
第三周:成本失控。 200 条 FAQ 全量注入,每轮对话的 token 消耗是普通聊天的十几倍。商家月底看到账单直接要求停用。项目悄悄下线。
问题不在于模型能力,而在于把“能跑通 demo”当成了“能上线的系统”。下面给出正确的路径。
正确的架构:分层,而不是一锅炖
拆成四层,每层职责单一:
- 知识检索层:FAQ 不进 prompt,进向量库。用户提问先做向量化检索,只取最相关的 3~5 条作为上下文。这一步同时解决“答非所问”和“token 爆炸”两个问题。
- 意图识别层:用一个轻量模型或分类器判断用户意图——是 FAQ 类问题、多轮任务(如查订单),还是闲聊/投诉需要转人工。
- 对话管理层:维护会话状态机。FAQ 类走单轮检索问答;任务类走多轮流程(槽位填充);无法识别的积累到阈值就转人工。
- 模型调用层:所有请求经过统一的 AI API 网关。
关键实现步骤
以多轮任务中最常见的“查订单”为例,核心是槽位填充逻辑:
SLOTS = {"订单号": None, "问题类型": None}
def fill_slots(user_input, state):
if state["waiting_for"] == "订单号":
if order_id := extract_order_id(user_input):
state["slots"]["订单号"] = order_id
state["waiting_for"] = "问题类型"
return "收到订单号。请问是查询物流、申请退款还是其他问题?"
return "没找到订单号,请提供下单短信里的那串数字。"
# ... 问题类型同理,槽位填满后调用检索层生成最终答复整体落地清单:
- [ ] FAQ 清洗去重,每条拆成“标准问法 + 答案 + 同义改写 ×3”
- [ ] 向量化入库,检索时做相似度阈值过滤,低于阈值回退到澄清话术
- [ ] 意图分类单独跑一个便宜的小模型,不和大模型混用
- [ ] 多轮任务画状态机:明确每个槽位缺失时的追问话术和放弃条件
- [ ] 所有模型调用收口到一个网关层,日志、重试、模型切换都在这里做
- [ ] 设置兜底:连续两轮识别失败,直接转人工并附上完整对话记录
为什么统一 AI API 网关能省下大量维护成本
上面这套架构至少要调三类模型:嵌入模型(向量化)、小模型(意图分类)、大模型(生成答案)。失败案例里的另一个隐患这时候才暴露——如果每处都直接 new 一个各家的客户端,你会同时维护三套 SDK、三套鉴权方式、三套错误码。
统一网关的价值在三个地方:
一处切换,处处生效。 某家模型涨价或降智,你在网关改一个配置,意图分类从 A 家切到 B 家的 OpenAI 兼容接口,业务代码一行不动。反过来,如果没有这层,每次换模型都是一次全链路回归测试。
统一监控与预算。 所有调用走同一个出口,你可以按功能(检索/分类/生成)分别设限额和告警。FAQ 场景设低温度、限制输出长度,防止失控发挥——这些策略收敛在一处,而不是散落在各个调用点。
统一降级链路。 主模型超时自动切备用模型、失败自动重试,这些逻辑写一次就覆盖所有场景。客服场景对可用性敏感,这层保险比事后救火便宜得多。
一点收尾的提醒
FAQ 客服机器人是 AI 应用里门槛最低、但“从 demo 到能用”距离最远的一类。先检索后生成、状态机管多轮、网关管调用,这三件事做齐,两周被下线的剧本基本不会发生在你身上。
如果你正准备动手,可以先在 https://api.thistoken.ai/register 注册一个统一网关账号,把嵌入、分类、生成三类调用先跑通——架构图上的第四层,十分钟就能立起来,剩下的时间留给真正难的知识整理和多轮设计。
---
不想折腾多家供应商的接入差异?在 https://api.thistoken.ai/register 注册,用一个 base_url 调用所有模型。