很多 AI 聊天产品是「边写边发」的:模型每生成几个字,屏幕上就多出几个字。看起来快,等待感也小。purser 面向顾客的自动回复没有这样做,这是我们最早定下、到现在也没改的一个决定。
发出去的字收不回来
客服回复和闲聊不一样,里面有退货期限、运费、保修条件。模型写错一个条件,后果是具体的。
举一个我们在 staging 上真实遇到的例子:知识库写的是「未拆封 30 天内可退」,模型写出来的是「30 天内可退」。少了「未拆封」三个字,意思就变了。
如果是边写边发,这句话在顾客屏幕上一个字一个字出现的时候,已经没有机会拦了。就算下一秒发现有问题,顾客已经读到了,甚至已经截了图。字一旦发到顾客那边,就收不回来。
所以我们的顺序是:
- 写作模型把整条回复写完(最多 400 个输出 token)。
- 另一个专门做判断的模型拿这条回复去对照它引用的资料——你的文章、政策、商品数据和订单数据——逐项打分:有没有依据、是不是超出了政策的承诺、有没有和资料矛盾、有没有泄露不该给的数据。
- 通过了才发给顾客。没通过,顾客收到的是「感谢您的留言,我们的客服会尽快回复您。」,对话交给你的团队,被拦下的那一稿留在记录里。
上面那个「30 天内可退」,判断模型给「与资料矛盾」打了 0.65,超过 0.5 的线,被拦下转了人工。我们认为这是对的,不会为了多放行几条去调松它。
生成和核对期间,顾客的聊天窗口里显示「正在输入…」,核对通过后,整条回复一次出现。
核对要多久
判断模型核对一条回复,在我们自己 staging 的记录里,中位数大约 0.26 秒。它的分数是按真实样本校准过的:有依据的好回答通常在 0.75–0.88 之间,编造或泄露信息的回答在 0.02–0.05 之间,阈值 0.5 落在两者中间。
核对本身不慢。慢的是整条链路。
代价:顾客要多等几秒
我们不打算回避这一点。刚开始在 staging 上量的时候,21 轮真实对话的端到端延迟中位数是 5.3 秒,p90 是 8.3 秒;我们给自己定的目标是中位数 4 秒以内。
这段时间里我们做了几件事:
| 做了什么 | 效果(staging 实测) |
|---|---|
| 推测写作:写作模型不再等分诊(判断顾客意图和语言那一步)结束,两边同时开始;分诊回来发现语言对不上,就丢掉重写 | 同一时段 60 轮对比,总延迟中位数从 5.0 秒降到 4.2 秒;写作以外的部分 p50 从 1.6 秒降到 1.1 秒,p90 从 2.9 秒降到 1.6 秒 |
| 检索缓存:重复的问题直接用缓存结果;缓存只等 150 毫秒,没命中就立刻去搜,不让缓存拖慢搜索 | 相同问题省掉一次检索 |
| 对冲请求:一次检索超过 1.5 秒没回来,再发一个相同的请求,谁先回来用谁 | 砍掉偶发的 3–4 秒长尾 |
| 关掉检索的上下文扩展 | 每次约省 0.3 秒,答案来源不变 |
缓存按工作区和知识库版本分开,知识库一改就失效,不会把过期内容或别人的内容答给你的顾客。
另外,问「我的包裹到哪了」这类订单状态问题,不走写作模型,直接用订单数据生成回复,在 staging 上是 1.6–2.7 秒。
还有一处是写作模型「先查一下再写」:大约五分之一的回合,模型会先调一次工具去查店铺政策,再动笔,这种回合总共要 7 秒多。原因是政策为空时我们没在提示里写明,模型就自己去查。现在每一轮都把政策写清楚(没有设置就明说「没有设置」),已经预取过的就不再提供这个工具,所有回合都一步写完。
做完这些之后,staging 上 58 轮的中位数是 4.5 秒,最后这一处改完后服务端的中位数约 3.3 秒。剩下的时间主要是两块:没命中缓存的检索(1.2–1.4 秒,大头是把问题转成向量),和写作模型本身(1–3 秒)。
什么地方可以边写边发
有人把关的地方。收件箱里给客服看的 AI 建议回复,客服读过、改过才会发出去,理论上可以边写边显示。目前我们的做法是在后台生成、同样经过核对,通过的才整条放到回复框下面,客服按 Tab 采纳。
面向顾客的那一侧,我们会继续选择「晚一点,但说的都有依据」。
想看回复被拦下的原因
每条被拦下的回复和它的分数都留在记录里。怎么设置 AI 在哪些问题上可以自己回答,见 AI 自主程度。