教程中心工作流
工作流

用 Twilio + LLM 把 AI 客服接进 WhatsApp(半小时跑通沙箱)

2026.09.16· 6 个步骤 · 16 分钟阅读· 💬 WhatsApp Agent

做海外业务,你迟早会发现:用户全在 WhatsApp 上,而不是你的 App 里。与其逼他们下载新应用,不如把 AI 客服直接「开」进 WhatsApp。Twilio 的 WhatsApp Sandbox + Flask + 大模型 能让你半小时内跑通一个会收消息、查知识库、自动回复的智能体。本教程手把手带你从沙箱到生产意识。

💬 本教程适合:做出海/海外客服、想用 WhatsApp 触达用户的团队。需要一点 Python 基础。

先搞懂:沙箱是什么?

WhatsApp 正式号码要审核,周期长。Twilio 提供沙箱(Sandbox):一个共享测试号,你用 join 码加入就能立刻收发消息,适合先把链路跑通。正式上线再申请 Business API 号码。两者代码几乎一致,只是号码与合规要求不同。

Step 1:开通 Twilio 与 WhatsApp 沙箱

1 注册并加入沙箱
1. 注册 Twilio 免费账号(twilio.com)
2. 控制台 → Messaging → Try it out → Send a WhatsApp message
3. 记下分配给你的沙箱号(形如 +14155238886)
4. 用你的个人 WhatsApp 给该号发 join 加一段英文词(控制台可见)
5. 收到确认 = 已加入你的沙箱

费用与合规:沙箱免费仅用于测试;正式对外必须走 WhatsApp Business 审核,且模板消息、营销内容受Meta 政策约束。本教程仅做技术演示,群发营销前务必读清平台规则。

Step 2:最小 Flask webhook

2 先让机器人回「收到」

Twilio 在你收到消息时会 POST 到你的 webhook。用 Flask 接住,返回 TwiML 即可回复。

from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse

app = Flask(__name__)

@app.route("/whatsapp", methods=["POST"])
def reply():
    msg = request.form.get("Body", "")
    resp = MessagingResponse()
    resp.message("收到你的消息:" + msg)
    return str(resp)

if __name__ == "__main__":
    app.run(port=5000)
💡 把本地服务用 ngrok 暴露:ngrok http 5000,把https://xxx.ngrok-free.app/whatsapp填到沙箱设置的 When a message comes in。发消息即可收到回执。注意 ngrok 免费版地址每次重启会变。

Step 3:接大模型做智能回复

3 知识库优先,LLM 兜底

先查本地知识库( pricing/hours 等高频问),命中就直接答;没命中再交给大模型,省 token 又稳。

KNOWLEDGE = {
    "pricing": "基础版每月 49 美元起。",
    "hours": "周一至周五 9:00-18:00。",
}
@app.route("/whatsapp", methods=["POST"])
def reply():
    msg = request.form.get("Body", "").lower()
    resp = MessagingResponse()
    for k, ans in KNOWLEDGE.items():
        if k in msg:
            resp.message(ans)
            return str(resp)
    # 没命中走 LLM(用任意 OpenAI 兼容 SDK)
    ai = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role":"system","content":"你是客服助手,用中文简洁回答。"},
                  {"role":"user","content": msg}],
    )
    resp.message(ai.choices[0].message.content)
    return str(resp)

外部输入不可信:用户发来的 Body 是外部输入,拼进提示词前要做长度与内容校验,避免被注入带偏;返回内容也建议先人审关键场景。

Step 4:加会话记忆与指令

4 让对话连续

用每个用户的 WhatsApp 号码当 key,存最近 N 条历史,拼进 messages,机器人就能记得上下文。

history = {}  # 生产用数据库,勿用内存
def reply():
    sender = request.form.get("From", "")
    msg = request.form.get("Body", "")
    hist = history.get(sender, [])
    hist.append({"role":"user","content": msg})
    hist = hist[-10:]  # 只留最近 10 条
    ai = client.chat.completions.create(model="gpt-4o-mini", messages=hist)
    hist.append({"role":"assistant","content": ai.choices[0].message.content})
    history[sender] = hist
    ...
🔑 记忆要设上限(条数/字数),既控成本也防上下文溢出;生产环境用 Redis/数据库替代内存字典,否则重启即丢。

Step 5:人审兜底与护栏

5 危险动作必须人确认

涉及退款、下单、转账等敏感操作,机器人只生成「待确认草稿」,必须人工点确认才执行;并对高频消息做限流。

# 伪代码:敏感意图识别
if "退款" in msg or "下单" in msg:
    resp.message("该操作需人工确认,已转接客服,请稍候。")
    # 触发人工工单,不自动执行
    return str(resp)

绝不自动执行危险操作:WhatsApp 是强触达渠道,自动退款/扣款/发营销一旦出错影响面大。所有写操作走 human-in-the-loop,机器人只读取与建议。

Step 6:从沙箱到生产

6 上线前要做的
· 申请 WhatsApp Business 号码并完成 Meta 审核
· 把 Flask 部署到稳定公网(Render / Railway / 自有服务器),配 HTTPS
· 用固定域名/webhook,替代会变的 ngrok
· 模板消息(template)用于主动触达,受平台模板规则约束
· 配置费用告警,防止消息量失控
🎉 沙箱验证完逻辑,生产只换「号码 + 托管地址 + 合规模板」,业务代码基本不动。后续可把 LLM 换成你自己的 Agent,接订单/物流等后端系统。

常见问题速查

现象原因与解决
收不到消息webhook 地址填错/未公网可达;ngrok 地址变了
回复 200 但用户没收到返回的不是合法 TwiML 文本
沙箱加不进join 码拼错或发给了错误号码
生产发不出去Business 号码未审核/模板未过