[控场AI]
· 5 分钟阅读· 2,731 字

珠宝珠宝WhatsApp助手:把价格挡在模型之外

珠宝珠宝WhatsApp助手:把价格挡在模型之外

让模型完全不碰价格数字,用分类、单一数据源和输出扫描三层隔离杜绝错误报价。

文章介绍了一套面向印度珠宝店 WhatsApp 助手的“价格隔离”设计,核心原则是模型永远不产生价格数字。系统先用规则加小模型做意图分类,命中价格类意图(查金价、工费、报价、换购估值、折扣)就直接升级给销售团队;非价格问题若命中店主审核过的固定 FAQ 则返回固定文本,其余未知意图转人工前台。若店主希望展示当日金价,只能读取唯一一条人工维护的记录,且超过 6 小时即拒绝使用,回复模板明确标注时点并以到店确认为准。输出侧再用正则扫描货币符号或重量单位紧邻数字的文本,拦截发送作为第二道防线。作者强调升级日志比准确率指标更能指导运营,测试集应来自真实匿名消息并每次重跑。

给印度珠宝店的 WhatsApp 助手,最危险的故障不是回复冒犯,而是自信地报出一个错误数字——昨天的金价、旧价目表里的工费,或者模型凭空捏造的一个数。这篇文章介绍一种“价格隔离”设计:让模型完全不碰价格相关的回答,从源头杜绝错误报价。

珠宝WhatsApp助手价格隔离设计示意

核心思路:分类先行,价格意图直接转人工

这套设计的第一条规则非常直白:模型永远不产生数字。系统先对用户消息做意图分类(规则加一个小模型),一旦命中价格类意图,就不进入生成环节,直接升级给销售团队。

PRICE_INTENTS = {"rate_today", "making_charges", "quote", "exchange_value", "discount"}

def handle(msg):
    intent = classify(msg.text)
    if intent in PRICE_INTENTS:
        return escalate(msg, team="sales", reason=intent)
    if intent in APPROVED_FAQ:
        return reply(msg, APPROVED_FAQ[intent])
    return escalate(msg, team="front_desk", reason="unknown")

非价格类问题如果命中店主审核过的 FAQ(营业时间、地址、停车、预约、一般政策),就直接返回固定文本。这些内容不会每天变化,因此可以放心让模型“照本宣科”。其余未知意图同样转人工前台。

意图分类(Intent Classification) 是对话系统中的基础环节:把用户输入映射到预定义类别(如“查金价”“问营业时间”“投诉”),再按类别路由到不同处理路径。常见实现有基于关键词/正则的规则匹配、基于嵌入向量的语义相似度,以及微调的小型文本分类模型。这里采用“规则加一个小模型”的混合方案,是因为价格类意图的召回率比精度更重要——宁可把非价格问题误判为价格问题而转人工,也不能漏掉一次报价请求。规则负责覆盖高频表达(如“today rate”“making charge”),小模型则兜住规则未覆盖的变体,包括 Hinglish 混合表达。分类结果直接决定后续是否进入生成环节,因此分类器本身也需要持续用真实消息回归测试。

真要展示金价?单一数据源加时间戳

有些店主希望助手能分享当天的展示金价。这种情况下,读取必须来自唯一一条由人工更新的记录,并且超过时效就拒绝使用。

MAX_AGE = timedelta(hours=6)

def displayed_rate(now):
    rec = rates.latest()
    if rec is None or now - rec["updated_at"] > MAX_AGE:
        return None
    return rec

回复模板会明确说明这是某时点的店内展示价,最终价格以到店确认为准。模型在这里不填充任何内容,只负责把模板里的占位符替换成数据库里的值和更新时间。

时效性校验(TTL / Freshness Check) 是数据管道中防止“陈旧数据被当作实时数据使用”的通用手段。做法是为每条记录附带更新时间戳,读取时计算 now - updated_at,超过预设阈值就视为无效。这里选择 6 小时,是因为印度珠宝店的展示金价通常一天内多次人工调整,超过半天未更新的记录很可能已经偏离市场。相比在数据库层做定时清理,读取时校验更简单,也不会因清理任务失败而放行旧数据。对模型而言,它只接触经过校验的结构化值和时间戳,不参与“这个价格还准不准”的判断——判断权留在确定性代码里。

输出侧兜底:扫描数字与货币/重量单位

即使是非价格类回复,也要在发送前做一次文本扫描:如果生成内容里出现货币符号或重量单位紧邻数字(如 ₹、Rs、INR、rupees、g、gm、grams、tola),就拦截发送。这能抓住模型“热心”地在无关回答里附送估价的情况。

MONEY = re.compile(r"(₹|rs\.?|inr|rupees?)\s*\d|\d+\s*(g|gm|grams?|tola)\b", re.I)

def safe_to_send(text):
    return not MONEY.search(text)

这道输出检查是输入分类之外的第二道防线,两者叠加后,价格数字从模型侧泄漏的概率被压到很低。

输出护栏(Output Guardrail) 是在模型生成之后、消息发出之前执行的检查层,与输入侧的意图分类形成纵深防御。正则在其中是最轻量的一种:它不判断语义,只匹配模式,因此速度快、行为可预测,适合拦截“货币符号或重量单位紧邻数字”这类高置信度风险。需要注意其局限:正则无法识别用文字拼出的数字(如“twenty-two thousand”)、Unicode 变体或跨行拆分,也无法区分合法数字(如“我们 10 点开门”)与报价。因此它应作为最后一道网,而非唯一防线;命中时选择拦截转人工而不是自动改写,可避免引入新的错误。

升级日志比准确率指标更有用

每次升级都要记录原因。运行几周后,日志会告诉店主:客户最常问什么、员工响应速度如何。对于一线运营来说,这些信息比任何模型准确率数字都更有价值——它直接指向该补什么 FAQ、该培训谁、该调整哪个流程。

测试:用真实消息构建价格拦截测试集

测试集应当来自真实(匿名化)消息,包括 Hinglish 和语音转写文本,断言每一条价格相关消息都会触发升级。每次修改分类器或提示词,都要重跑这套测试。这比泛泛的“回复质量评估”更能防止回归。

这套设计为什么值得借鉴

它的价值不在于代码多复杂,而在于把“模型不该做的事”用工程手段锁死。价格是珠宝零售里最敏感、最易变、最容易被模型幻觉污染的信息类型,把它从生成路径里彻底移除,换来的是可预期的安全边界。对于任何涉及实时报价的垂直行业助手,这个模式都可以直接迁移。

披露:作者运营孟买的 AI 自动化机构 NxFlowAI,首个工作流审计需 72 小时。

#WhatsApp AI助手#价格隔离#珠宝零售AI#意图分类#AI幻觉防护#AI自动化#价格时效性
分享:

相关推荐