DialogFlow开发的Google Home应用迁移Alexa:后续意图触发方案咨询
在Alexa Skill中实现多轮递进式对话的方法(适配自有API场景)
我太懂你这种从DialogFlow转Alexa时的挫败感了——DialogFlow的后续意图把多轮对话做得像搭积木一样简单,而Alexa这边一开始摸不着门道真的很正常!结合你用自有API而非Lambda的场景,我给你梳理几个实用的实现思路:
核心逻辑:用会话属性(Session Attributes)跟踪对话进度
和DialogFlow自动维护上下文不同,Alexa需要你手动管理对话的“状态”——也就是当前问到了哪一步,已经收集到了哪些用户信息。会话属性会在整个对话周期内保留,正好用来存这些关键数据。
步骤1:先拆解对话流程,定义状态和槽位
先把你的需求拆成明确的递进步骤,比如:
- 状态1:初始启动,询问第一个问题(低维护/功能性花园)
- 状态2:已收集第一个偏好,询问第二个问题(是否喜欢放松型花园)
- 状态3:已收集前两个信息,询问第三个问题(是否要种蔬菜)
- 状态4:所有信息收集完成,调用自有API返回结果
同时,把要收集的信息定义成对应槽位:比如自定义槽位GardenType(值为low maintenance/working),系统槽位YES_NO(用来处理后两个问题的是/否回答)。
步骤2:在自有API中根据会话状态处理请求
你不需要为每个步骤单独创建意图(当然也可以,但更高效的是用一个主意图配合状态判断)。比如创建一个GardenRecommendationIntent,然后在你的API服务端按以下逻辑处理:
伪代码示例(服务端处理逻辑)
# 假设这是你的自有API处理Alexa请求的核心逻辑 def handle_alexa_request(request_data): # 读取会话属性(如果没有则初始化) session_attrs = request_data.get('session', {}).get('attributes', {}) current_step = session_attrs.get('current_step', 1) slots = request_data.get('intent', {}).get('slots', {}) # 按当前对话步骤分支处理 if current_step == 1: # 第一次触发,直接问第一个问题 return { "outputSpeech": {"type": "PlainText", "text": "您偏好低维护型还是功能性花园?"}, "shouldEndSession": False, "sessionAttributes": {"current_step": 2} } elif current_step == 2: # 收集第一个回答,验证有效性 garden_type = slots.get('GardenType', {}).get('value') if not garden_type or garden_type not in ['low maintenance', 'working']: # 用户回答不符合要求,重新引导 return { "outputSpeech": {"type": "PlainText", "text": "抱歉我没听清,您是偏好低维护型还是功能性花园呢?"}, "shouldEndSession": False, "sessionAttributes": {"current_step": 2} } # 保存信息,进入下一轮 session_attrs['garden_type'] = garden_type session_attrs['current_step'] = 3 return { "outputSpeech": {"type": "PlainText", "text": "您是否喜欢可放松的花园?"}, "shouldEndSession": False, "sessionAttributes": session_attrs } elif current_step == 3: # 收集第二个回答 relax_pref = slots.get('RelaxPreference', {}).get('value') if not relax_pref or relax_pref not in ['yes', 'no']: return { "outputSpeech": {"type": "PlainText", "text": "抱歉我没听清,您是否喜欢可放松的花园呢?请回答是或否。"}, "shouldEndSession": False, "sessionAttributes": session_attrs } session_attrs['relax_preference'] = relax_pref session_attrs['current_step'] = 4 return { "outputSpeech": {"type": "PlainText", "text": "您是否想要在花园中种植蔬菜?"}, "shouldEndSession": False, "sessionAttributes": session_attrs } elif current_step == 4: # 收集第三个回答,调用自有API veggie_pref = slots.get('VeggiePreference', {}).get('value') if not veggie_pref or veggie_pref not in ['yes', 'no']: return { "outputSpeech": {"type": "PlainText", "text": "抱歉我没听清,您是否想要在花园中种植蔬菜呢?请回答是或否。"}, "shouldEndSession": False, "sessionAttributes": session_attrs } # 调用你的业务API api_result = call_your_garden_api( garden_type=session_attrs['garden_type'], relax_pref=relax_pref, veggie_pref=veggie_pref ) # 返回结果并结束会话 return { "outputSpeech": {"type": "PlainText", "text": api_result.get('reply', '根据您的需求,为您推荐适合的花园方案。')}, "shouldEndSession": True }
可选方案:用Alexa Dialog Management简化槽位填充
如果觉得手动写状态判断太繁琐,你可以用Alexa的Dialog Management功能(在Skill Builder后台配置)。它能自动帮你引导用户填充缺失的槽位,适合槽位之间没有依赖的场景:
- 在意图中添加所有需要的槽位,标记为
Required - 为每个槽位设置
Prompt(缺失时的提问语) - 配置完成后,Alexa会自动依次询问用户所有槽位,收集完成后再把完整数据发送到你的API
不过如果你的后续问题需要根据前面的回答动态调整(比如用户选了低维护就跳过某个问题),还是手动用会话属性的方式更灵活。
关键注意事项
shouldEndSession必须设为False:多轮对话过程中,这个字段一定要设为False,否则会话会直接中断,用户没法继续回答。- 错误处理不能少:一定要处理用户回答不符合预期的情况(比如没听清、回答不在槽位选项里),重新引导用户,避免体验断裂。
- 跨会话保存可选:如果需要长期保存用户偏好,可以用Alexa的Persistent Attributes,但需要用户授权。
内容的提问来源于stack exchange,提问作者Codebricks
相关产品推荐
相关产品推荐

