餐厅电话点餐不一定需要 App、网站或用户登录。通过 Amazon Connect、实时语音能力、Amazon Connect AI agent,以及经由 MCP 暴露后端工具的 Amazon Bedrock AgentCore Gateway,可以把一通电话串成完整流程:接听来电、理解自然语言、查询菜单、确认订单,并将结果交给餐厅后端系统。
这类系统的关键不只是“让模型会聊天”,而是把电话、实时语音、业务推理和可控工具调用组织成一条可靠链路。
一通电话背后的系统分工
可以把架构拆成四层,每层解决不同问题:
- Amazon Connect:负责电话号码、呼入路由、队列、营业时间和通话生命周期。
- Amazon Connect Agentic Voice:负责实时语音交互,让系统能够边听边说,而不是等整段录音结束后再处理。
- Amazon Connect AI agent:负责理解顾客意图、维护点餐上下文、追问缺失信息,以及决定什么时候调用工具。
- Amazon Bedrock AgentCore Gateway:把菜单查询、库存检查、价格计算和订单提交等后端能力以 MCP 工具形式提供给 AI agent。
典型调用路径可以表示为:
顾客电话
-> Amazon Connect
-> Agentic Voice 实时语音处理
-> Amazon Connect AI agent
-> AgentCore Gateway / MCP tools
-> 菜单、库存、订单和支付后端
这里的边界很重要。模型可以负责理解“我要两个辣味鸡肉汉堡,其中一个不要洋葱”,但不应该直接拼接 SQL、修改订单数据库,或自行猜测价格。涉及业务事实和状态变更的动作,都应通过经过授权的工具完成。
把点餐对话设计成状态机
自然语言很灵活,订单状态却必须明确。一个可落地的电话流程通常包含这些状态:
- 欢迎与识别意图:确认顾客是点餐、查询营业时间,还是咨询配送范围。
- 收集商品:解析商品、数量、规格、配料和备注。
- 补齐必要信息:当商品缺少尺寸、套餐或取餐方式时,主动追问。
- 复述订单:逐项读回商品和数量,展示或播报价格。
- 确认履约信息:收集自取或配送所需的信息。
- 提交订单:调用后端工具创建订单,并取得订单号。
- 结束通话:确认总价、取餐时间或配送信息。
AI agent 可以自由理解表达方式,但流程中的关键节点应有明确约束。例如,订单提交工具只能在顾客明确确认后调用;库存不足时,系统必须回到商品选择环节,而不是继续创建订单。
可以给 agent 一条类似这样的系统指令:
你是餐厅电话点餐助手。
规则:
1. 用简短、自然的句子回应,适合电话语音播放。
2. 每次只询问一个缺失信息。
3. 不要猜测菜单、价格、库存或营业时间,必须调用对应工具查询。
4. 在提交订单前,逐项复述商品、数量、选项、取餐方式和总价。
5. 只有顾客明确说“确认”“就这样”或同义表达后,才能调用 create_order。
6. 工具报错时,用通俗语言说明暂时无法完成,并提供转人工选项。
这类提示词不能替代后端校验,但能减少对话偏离。真正的价格、库存、门店营业状态和订单状态仍应由工具返回,并在服务端再次验证。
用 MCP 工具连接真实业务
AgentCore Gateway 的价值在于把后端能力整理成 AI 可以发现和调用的工具。可以这样规划最小工具集:
| 工具 | 作用 | 是否改变状态 |
|---|---|---|
get_menu |
查询当前门店菜单、规格和价格 | 否 |
check_item_availability |
检查商品和选项是否有库存 | 否 |
calculate_order_total |
根据订单草稿计算价格和税费 | 否 |
create_order |
在顾客确认后创建订单 | 是 |
get_store_hours |
查询营业时间和预计取餐时间 | 否 |
工具接口应使用结构化输入和输出,而不是让模型解析一段不稳定的自然语言。例如,订单提交接口可以采用这样的 JSON:
{
"store_id": "store-001",
"fulfillment": {
"type": "pickup",
"customer_name": "Alex"
},
"items": [
{
"menu_item_id": "burger-spicy",
"quantity": 2,
"options": ["no-onion"]
}
],
"customer_confirmation": true
}
下面是一个可以直接运行或改造成 Lambda、容器服务处理器的 Python 示例。它演示了服务端必须做的两件事:重新计算订单金额,以及拒绝没有明确确认的订单。示例数据仅用于本地验证,生产环境应替换为菜单数据库和订单服务。
from decimal import Decimal
from typing import Any
MENU = {
"burger-spicy": {"name": "Spicy Chicken Burger", "price": Decimal("8.50")},
"fries": {"name": "Fries", "price": Decimal("3.00")},
}
def create_order(payload: dict[str, Any]) -> dict[str, Any]:
if payload.get("customer_confirmation") is not True:
raise ValueError("customer_confirmation must be true")
total = Decimal("0")
normalized_items = []
for item in payload.get("items", []):
menu_item_id = item["menu_item_id"]
quantity = int(item["quantity"])
if quantity < 1 or menu_item_id not in MENU:
raise ValueError("invalid menu item or quantity")
menu_item = MENU[menu_item_id]
total += menu_item["price"] * quantity
normalized_items.append({
"menu_item_id": menu_item_id,
"name": menu_item["name"],
"quantity": quantity,
"options": item.get("options", []),
"unit_price": str(menu_item["price"]),
})
if not normalized_items:
raise ValueError("order must contain at least one item")
return {
"order_id": "demo-order-1001",
"store_id": payload["store_id"],
"items": normalized_items,
"total": str(total),
"status": "accepted",
}
if __name__ == "__main__":
sample = {
"store_id": "store-001",
"fulfillment": {"type": "pickup", "customer_name": "Alex"},
"items": [
{"menu_item_id": "burger-spicy", "quantity": 2, "options": ["no-onion"]}
],
"customer_confirmation": True,
}
print(create_order(sample))
运行方式:
python order_tool.py
在真实系统中,工具还应验证门店标识、顾客输入、幂等键、库存和权限。create_order 最好接收一个通话会话或请求 ID,避免电话重试、网络重放或模型重复调用造成重复订单。
语音体验比文本聊天更苛刻
电话交互没有屏幕,顾客无法回看购物车。因此,语音层需要控制信息密度和节奏:
- 一次只读出有限数量的信息,长订单可以分组确认。
- 商品名称、数量和选项使用固定表达,避免同音词造成误解。
- 金额和订单号需要重复一次,必要时按数字分组播报。
- 对沉默、打断、重复询问和背景噪声设置明确策略。
- 识别失败或工具不可用时,提供转人工或回拨路径。
实时语音能力适合处理用户的打断和自然停顿,但它不应成为业务逻辑的唯一控制点。通话记录、工具调用、订单草稿和最终提交结果都应写入可观测系统,便于客服处理争议和定位失败原因。
建议至少记录以下事件:
{
"call_id": "call-abc123",
"event": "tool_call",
"tool": "calculate_order_total",
"request_id": "req-789",
"latency_ms": 420,
"result": "success"
}
日志中要注意脱敏。姓名、电话号码、地址和支付相关信息不应以不受控的明文形式长期保存;同时需要按门店、环境和角色限制工具访问权限。
上线前的检查清单
这套方案适合从窄场景开始,例如只支持单门店、固定菜单、自取订单和少量常见修改。验证稳定后,再逐步加入配送、优惠券、多个门店和支付流程。
上线前可以检查:
- Connect 呼入流程是否能正确处理营业时间、排队和转人工。
- 语音 agent 是否能处理打断、沉默、口音和重复确认。
- AI agent 是否绝不绕过工具猜测价格或库存。
- MCP 工具是否有输入校验、权限、超时、幂等和审计日志。
- 订单提交前是否强制顾客确认,提交后是否播报订单号。
- 工具失败、菜单为空和库存变化时,是否有可理解的降级路径。
- 是否用真实通话脚本测试高频订单、复杂备注和边界输入。
Amazon Connect 解决了电话入口,Agentic Voice 解决了实时语音交互,AI agent 负责对话推理,而 AgentCore Gateway 把推理连接到可控业务工具。把这些组件组合起来时,最值得优先设计的不是更长的提示词,而是清晰的订单状态、严格的工具契约和可追踪的失败处理。这样,餐厅得到的才是一条可以运营的电话点餐链路,而不只是一个会说话的演示程序。