我建议您对所需的每个参数使用意图,而不是使用实体。这将解决两个问题:
- 如果用户没有为所需参数提供正确的值,则对话框流
不会在循环中一遍又一遍地问同样的问题
- 您可以控制接下来要填充的参数
假设您需要 3 个参数来购买手表:颜色、日期/日期时间、成本
您的代理将具有以下意图:
-
buy_watch -> input_context = None, output_context = buy_watch
我想买手表
我想买黑色手表
...
-
get_color -> input_context = 颜色,output_context = buy_watch
黑色
我想要黑色的
...
-
get_date -> input_context = date, output_context = buy_watch
我明天想要它
我下周想要它
(这将捕获日期和日期范围,而不是其他任何内容,如果您获得其中任何一个,您可以有逻辑将值分配给参数)
-
get_cost -> input_context = cost, output_context = buy_watch
大约 10000
预算是15k
-
got_all_details --> event = e_got_all_details
对于每个意图,您都可以选择所有 3 个参数。
此外,您需要将参数的默认值设置为 $entity 以用于自我意图,#context.entity 用于其他参数。
例如,在意图get_color 中,您将拥有这些参数和默认值:
color = $color
date = #buy_watch.date
cost = #buy_watch.cost
最后,您必须为上述所有意图调用 webhook。
在 webhook 中,您必须检查传入意图的参数并根据缺少的参数设置 output_context + response_message。
params = intent_request["query_result"]["parameters"]
case 1 --> if not params["color"]: set output_context = color and response = what color do you want
case 2 --> if not params["date"]: set output_context = date and response = when do you want to buy
case 3 --> if not params["cost"]: set output_context = cost and response = what is your budget
case 4 --> if you get all params: call event e_got_all_details
Intent got_all_details 将在您获取所有参数时通过事件调用,无论您获取它们的顺序如何。
根据响应的 output_context 和您在 Intent 中配置的 input_context,将触发正确的 Intent 并且您将能够获得正确的值。
我遇到了类似的问题,在我看来,这是处理参数验证和处理意外值时最有效的方法(使用特定于意图的后续后备意图)。
编辑 1: 根据您从日期或日期范围实体获得的值,将有一个额外的逻辑来为日期分配值。
if params["date"] or params["date-range"]:
date = params["date"] if params["date"] else params["date-range"]
所有意图都会有训练短语,它们会尝试无任何顺序地捕获参数,但不要将它们标记为必需。
所以,如果用户说我明天想买一块手表,buy_watchintent 将被参数日期触发。代码将检查颜色和成本是否缺失,并在设置适当的output_context 后提示。
希望对你有帮助。