用 Amazon Nova 2 搞个 WhatsApp 点餐助手
最核心的逻辑是把 WhatsApp 的入口和后端的点餐逻辑彻底解耦。如果直接把业务逻辑写在 Webhook 处理函数里,以后想加个 Telegram 或者 App 端的入口就得重写。目前的架构是:WhatsApp Cloud API 负责接客 → API Gateway 转发 → Lambda 异步处理 → Bedrock AgentCore 执行 → 通过 MCP (Model Context Protocol) 访问餐厅后台(菜单、购物车、订单等)。
这里有个关键的性能细节:WhatsApp 的 Webhook 要求必须在极短时间内返回 200 OK,否则 Meta 的服务器会认为请求失败并疯狂重试,导致同一个订单被触发好几次。所以我的 Lambda 必须设计成异步触发模式,先秒回 200,再把任务丢给后台处理。
在模型选择上,我用了两种 Nova 2 的版本来分工。处理文字交互的是 Amazon Nova 2 Lite,走的是 Bedrock Converse API;而处理语音笔记和实时通话的则是 Amazon Nova 2 Sonic。这种组合最让我意外的是,即便用户先发了一段文字,紧接着发一段语音说“刚才那个给我来一份大份的”,Sonic 配合 AgentCore 的跨通道记忆,居然能准确识别出“那个”指的是之前的文字订单,这一点比我之前试的单模态方案强很多。
部署这套东西不能手动点控制台,太乱了,必须用 AWS CDK。整个资源依赖链条大概是这样的:
一、基础设施层
首先得通过 CDK 部署两个 API Gateway。一个是对外的公共 HTTPS Webhook,用来接 Meta 的回调;另一个是内部的 IAM 授权 API,专门给点餐逻辑用,保证安全性。
二、逻辑处理层
编写 Lambda 函数来解析 WhatsApp 传过来的 JSON 报文。如果是语音消息,需要先调用 Media API 把语音文件拉下来,再交给 Nova 2 Sonic 转换。
三、Agent 编排层
在 Bedrock AgentCore 中配置 Agent,通过 MCP 协议定义好 get_menu 和 update_cart 等工具。
具体的部署配置大概长这样(以 CDK 简化版为例):
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigw from 'aws-cdk-lib/aws-apigateway';
export class WhatsAppOrderingStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// 接收 WhatsApp Webhook 的公共接口
const webhookApi = new apigw.RestApi(this, 'WhatsAppWebhookApi', {
restApiOptions: {
name: 'whatsapp-webhook',
},
});
// 异步处理逻辑的 Lambda
const processorLambda = new lambda.Function(this, 'OrderProcessor', {
runtime: lambda.Runtime.NODEJS_18_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('lambda-handler'),
});
webhookApi.root.addMethod('POST', new apigw.LambdaIntegration(processorLambda));
}
}目前最让我头疼的是 Meta WhatsApp Business Platform 的权限配置。你得先在 Meta 开发者后台把 Webhook URL 填好,然后通过一个验证请求(Verification Request),如果你的 Lambda 没有正确处理 hub.challenge 参数,验证永远过不去。
另外,建议大家在测试阶段不要直接用正式的 Business 账号,先用 Sandbox 账号,否则每发一条消息都要面对复杂的模板审核,开发效率极低。