让模型只选FAQ编号,避免客服乱报价
这套n8n客服流程先用关键词匹配FAQ,匹配失败后才让模型从候选问题中返回编号或null。最终回复取自维护好的答案表,使模型不再直接生成价格、保修与营业时间等信息。
AI 深度解读
让模型直接回复客户,最容易出事的不是语气,而是它随口报出一个不存在的价格、保修条款或营业时间。作者给小型服务商做 WhatsApp FAQ 机器人时,立了一条规则:模型只能选答案编号,不能写答案。
这套 n8n 方案的价值,是把 AI 的权限缩到一个可校验的范围:能匹配就发送预先审核的内容,匹配不了就转人工。不过,它能挡住编造答案,未必能挡住选错答案。
模型只选 ID,为什么更容易管住
作者把 FAQ 存在 Google Sheet 或 CSV 中,每条包含 id、question、keywords、answer 四个字段。示例业务是一家空调清洗服务公司。
收到问题后,先用普通关键词评分匹配。作者称,大多数咨询不需要调用 AI 就能命中,但没有给出命中率或样本量。只有关键词没匹配上,才把客户问题,以及 FAQ 的编号和问题列表发给 LLM,要求它只返回一个 ID 或 null。
接下来由程序校验:返回值必须与某个已知 ID 完全一致,否则统一视为未知。校验通过后,程序逐字发送该 ID 对应的库存答案。
模型负责选择,业务系统负责提供最终措辞。
这比提示模型「不要编造价格」多了一层程序约束。即使模型输出自由文本,程序也不会把它发给客户。但如果模型返回了一个格式正确、语义错误的 ID,校验仍会通过,这个边界后面还要讨论。
真正上线,匹配逻辑只占流程的一部分
作者给出的完整处理顺序如下,它解决的是重复消息、退订、人工接管与 FAQ 回复之间如何配合的问题:
Customer message -> Webhook (GET verify / POST messages)
-> X-Hub-Signature-256 HMAC check (bad signature -> 401, nothing processed)
-> Dedupe on message id (Meta retries webhooks)
-> STOP / START opt-out handling
-> Chat in human handoff? -> stay silent
-> Asked for "agent / human" or sent a photo/voice note? -> handoff
-> FAQ match (keywords) -> fallback: LLM picks an FAQ id
-> Reply via Graph API POST /{phone_number_id}/messages
最该看的是签名校验这一行:它在任何业务处理之前。Meta 使用 app secret 为 Webhook 签名,n8n 的 Webhook 节点要开启 raw body,才能用原始请求体做 HMAC 校验。签名错误就返回 401,不继续处理。
消息去重也不能省。Meta 会在响应较慢时重试 Webhook,不按 message id 去重,客户可能收到两三次相同回复。
人工接管则需要持续状态。未知问题、null、自由文本、API 错误,以及客户主动要求 agent / human、发送照片或语音,都会触发转人工:客户收到一次等待员工回复的通知,店主收到 WhatsApp 提醒,机器人保持静默,直到人工恢复。
退订同样贯穿全流程。STOP / START 都有确认消息,退订后的会话不再收到消息,也包括预约提醒。
测试结果能证明到哪一步
作者把 Code 节点逻辑放到独立 .js 文件,再生成 workflow JSON,方便脱离 n8n 做单元测试。他报告,在真实 n8n 实例上、使用模拟 Graph API,完成了 16/16 的运行验证。
这支持流程可以被自动验证,但不能据此认定真实客户问题的匹配准确率已经过检验。原文没有给出关键词与 LLM 的对照数据,也没有披露选错 FAQ 的比例。
预约提醒是可选功能:预约开始前 24 小时内发送,每个预约只发一次,并跳过退订用户。原文还指出,超出 24 小时客户服务窗口后,需要使用获批的 WhatsApp template。预约时间与会话窗口是两套判断,不能混成一个条件。
文章同时在售卖 $19 的成品包,包含可导入的 n8n 工作流、使用 SQLite 保存状态的 Python FastAPI 服务、31 个 pytest 测试、Docker + Caddy HTTPS 部署及 Meta Cloud API 指南。另一个 $29 的 n8n + LangGraph 获客模板要求点击 Approve 后才发送。这些是产品说明,不能替代方案效果的证据。
我的判断
我赞成把价格、保修、营业时间这类业务事实交给审核过的数据,让模型只做有限选择。相比直接生成回复,它的输出范围更容易控制;相比纯关键词,又保留了处理不同问法的机会。
但作者说最坏情况只是人工回答,这句话需要收窄。已知 ID 只证明答案存在,不证明答案适用于当前问题。 库存答案过期、关键词误命中、模型选错编号,都可能让客户收到错误报价。
因此,这套模式降低的是自由生成带来的风险。它是否比纯关键词更准确、能减少多少人工工作,原文没有对照数据,目前只能当作作者的实践经验。
能拿来做什么
- 在 n8n 或 Node FAQ 服务里,把价格、服务范围、保修政策存成带稳定 ID 的审核答案,并校验模型返回值是否精确命中已知 ID。
- 给匹配流程补上「返回合法 ID,但选错问题」的测试,尤其检查价格相近、服务名称相似的 FAQ。
- 把人工接管和退订保存为会话状态,让后续消息与预约提醒都读取这些状态。
- 参考作者拆分
.js逻辑的做法,独立验证签名、去重、匹配和状态切换,再接入工作流运行。