php – 在Dialogflow上没有错误时,Google智能助理出错
作者:互联网
我创建了一个聊天机器人,告知用户我(扩展)家庭的成员以及他们住在哪里.我已经创建了一个包含MySQL的小型数据库,其中存储了这些数据,并且只要这是合适的,我就会使用PHP脚本来获取它们,具体取决于用户与聊天机器人的交互.
我的聊天机器人包含默认后备意图和默认欢迎意图的两个意图:
>姓名
> Location_context
第一个意图(姓名)是通过诸如“谁是约翰史密斯?”之类的短语训练的.并有一个输出上下文(称为上下文,持续时间为10个问题).这个问题的一个可能答案是“约翰是我的叔叔.”第二个意图(Location_context)由诸如“他住在哪里?”之类的短语训练.并有一个输入上下文(来自名称).对这个问题的一个可能的答案是“约翰住在纽约.”
Names intent包含两个参数:
>参数名称:给定名称,姓氏.
>实体:@sys.given-name,@ sys.last-name.
> value:$given-name,$last-name.
这两个参数表示用户给出的全名. Location_context意图不包含任何参数.
PHP脚本如下:
<?php
$dbServername = '******************';
$dbUsername = '******************';
$dbPassword = '******************';
$dbName = '******************';
$conn = mysqli_connect($dbServername, $dbUsername, $dbPassword, $dbName);
// error_reporting(E_ALL);
// ini_set('display_errors', 'on');
header('Content-Type: application/json');
$method = $_SERVER['REQUEST_METHOD'];
if($method == 'POST'){
$requestBody = file_get_contents('php://input');
$json = json_decode($requestBody);
$action = $json->result->action;
$first_name = $json->result->contexts[0]->parameters->{'given-name'};
$last_name = $json->result->contexts[0]->parameters->{'last-name'};
$lifespan = $json->result->contexts[0]->lifespan;
$sql = "SELECT * FROM family WHERE name LIKE '%$first_name%$last_name%';";
$result = mysqli_query($conn, $sql);
$resultCheck = mysqli_num_rows($result);
if ($resultCheck > 0) {
while ($row = mysqli_fetch_assoc($result)) {
$person = $row;
}
switch ($action) {
case 'Name':
$speech= "$first_name is my" . $person["name"] . ".";
break;
case 'Location':
$speech = "$first_name is living in {$person["location"]}.";
break;
default:
$speech = "Please ask me something more relevant to my family";
break;
}
}
else {
$speech = "Sorry, $first_name $last_name is not a member of my family.";
}
$response = new \stdClass();
$response->speech = $speech;
$response->displayText = $speech;
$response->source = "agent";
echo json_encode($response);
}
else
{
echo "Method not allowed";
}
?>
在Dialogflow中,在询问之后“约翰史密斯是谁?”得到正确的答案“约翰是我的叔叔.”然后我问“他住在哪里?”我得到了正确答案“约翰住在纽约.”
Dialogflow对第二个问题的json响应是:
{
"id": "*****************************",
"timestamp": "2018-04-04T08:26:39.993Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "Where is he living"
"action": "Location",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "context",
"parameters": {
"given-name.original": "John",
"last-name.original": "Smith",
"given-name": "John",
"last-name": "Smith"
},
"lifespan": 9
}
],
"metadata": {
"intentId": "*****************************",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"webhookResponseTime": 93,
"intentName": "Location_context"
},
"fulfillment": {
"speech": "John is living in New York.”,
"displayText": "John is living in New York.",
"messages": [
{
"type": 0,
"speech": "John is living in New York."
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success",
"webhookTimedOut": false
},
"sessionId": "*****************************"
}
但是,当我在Google助手中输入完全相同的问题(在与我的测试应用程序交谈后),我在第一个问题上得到了相同的答案,但我得到的是“住在洛杉矶”.对于第二个问题.请注意这个答案中的两件事.首先,变量$first_name没有任何值(因为它没有设置),并且位置’洛杉矶’是数据库中最后一个的系列成员的位置.因此返回此位置是因为$first_name和$last_name在mysql查询中没有分配值(因为它们未设置),并且由于某种原因返回了数据库的最后一个人的位置.
令人非常沮丧的是,我无法检查Google智能助理的json响应,因为我可以在Dialogflow中轻松完成.然而,在经过一些实验后我发现在Google智能助理中,$lifespan始终为0(在第一个和第二个问题中),并且在第二个问题的json响应中,$first_name和$last_name根本没有设置,即使在Dialoglow中,它们被设置,它们包含我在上面发布的json响应中显示的全名.此外,Google智能助理会在两个问题中返回$json-> result-> contexts [0] – >名称的actions_capability_screen_output,而显然在Dialogflow $json-> result-> contexts [0] – > name是context(上下文的名称).
因此,Google智能助理第二个问题中json响应的上下文分支似乎是这样的:
"contexts": [
{
"name": "actions_capability_screen_output",
"parameters": {},
"lifespan": 0
}
]
另一方面,如上所示,DIalogflow中第二个问题中json响应的上下文分支是:
"contexts": [
{
"name": "context",
"parameters": {
"given-name.original": "John",
"last-name.original": "Smith",
"given-name": "John",
"last-name": "Smith"
},
"lifespan": 9
}
]
为什么Google智能助理无法识别上下文,并且它不会处理与Dialoglow所示相同的json响应?
如何在Dialogflow中检查Google智能助理的整个json响应?
解决方法:
除了你的问题,这里还有很多事情要做.让我们试着一点一点地打破它们.
为什么我最初在响应中遇到错误?
因为ini_set(‘display_errors’,’on’);将任何错误发送到标准输出,这是您要发送回Dialogflow的. Dialogflow的解析器向Google发送内容非常严格,因此额外的输出会导致问题.
我怎么才能看到发生了什么?
你应该使用像error_log()这样的东西来记录事物.这将记录在你想要的任何文件中,这样你就可以看到来自Dialogflow的确切JSON以及你认为你发回的内容.
您可以使用类似的东西
error_log( $request_body );
确切地看到从Dialogflow发送的JSON是什么.这会将正文记录到系统错误记录器(可能是HTTP error_log,除非您将其设置在别处),这样您就可以检查它并查看发送给您的所有内容.
好的,我可以看到发生了什么.为什么JSON不同?
因为Google上的操作系统提供的信息多于其他代理商提供的信息.这些是以相同的方式(或应该)发送给您的,但会有更多.例如,您将看到通过JSON提供的originalRequest对象.
但是 – 您期望的所有信息都应该存在.更多的是它.
为什么我不能在更改要发送到Google上的操作之前看到Dialogflow从我的webhook中获取什么?
好问题.这有时会记录在“agentToAssistantDebug”下的“调试”选项卡中,但并非总是如此.您需要使用其他工具来确切了解您作为测试基础架构的一部分所回复的内容.
为什么我没有通过Google上的操作获取上下文上下文?
你实际上没有发表你不是的证据.你所展示的只是context [0]没有命名为“context”.您应该记录整个上下文数组以查看所有这些内容
error_log( $json->result->context );
您将看到的是,已经设置了许多上下文.这包括一个名为actions_capability_screen_output的内容,该操作由Google上的操作创建,用于指示您正在可以显示到屏幕的设备上运行.它可能还有一个名为actions_capability_audio_output的表示它可以说出结果.它还应该包含一个命名上下文,它是您设置的上下文.
但为什么这些其他上下文没有设置给定名称和姓氏参数?
因为当这些上下文处于活动状态时未设置这些参数.
您不能只假设参数将在第一个上下文中设置 – 您需要查找已设置它们的上下文并从这些特定上下文中获取值.
参数仅在设置它们的上下文中. (事实上,您可以在输出上下文中设置其他参数作为回复的一部分.)
如果有多个上下文,如何找到包含我的参数的上下文?
遍历上下文数组并查找与您期望的名称匹配的数组.然后,您可以从那里获得所需的参数.
为什么Google上的操作会将生命周期重置为0?
事实并非如此. Google上的操作会设置其他上下文(您看到其中一个),其中包含特定于AoG的其他信息,并且它的生命周期为0(这意味着它将在此轮后删除,但它们将在下一次再次设置它通过).他们将其设置为0,因为某些上下文可能每次都会更改(特别是支持哪些表面).
有没有更好的方法在没有上下文的情况下做到这一点?
不是真的 – 上下文非常棒,它们是最好的解决方案.
标签:json,php,dialogflow,api-ai,actions-on-google 来源: https://codeday.me/bug/20190522/1153047.html