繁体   English   中英

在Dialogflow上没有错误时,Google智能助理出错

[英]Error on Google Assistant while no error on Dialogflow

我创建了一个聊天机器人,告知用户我(扩展)家庭的成员以及他们住在哪里。 我已经创建了一个包含MySQL的小型数据库,其中存储了这些数据,并且只要这是合适的,我就会使用PHP脚本来获取它们,具体取决于用户与聊天机器人的交互。

我的聊天机器人包含Default Fallback IntentDefault Welcome Intent

  • Names
  • Location_context

第一个意图( Names )是通过诸如“谁是约翰史密斯?”之类的短语训练的。 并有一个输出上下文(称为context ,持续时间为10个问题)。 这个问题的一个可能答案是“约翰是我的叔叔。” 第二个意图( Location_context )由诸如“他住在哪里?”之类的短语训练。 并有一个输入上下文(来自Names )。 对这个问题的一个可能的答案是“约翰住在纽约。”

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中,在询问例如“谁是John Smith?”之后。 得到正确的答案“约翰是我的叔叔。” 然后我问“他住在哪里?” 我得到了正确答案“约翰住在纽约。” 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助手中输入完全相同的问题(在Talk to my test app后),我在第一个问题上得到了相同的答案,但我得到的是“住在洛杉矶”。 对于第二个问题。 请注意这个答案中的两件事。 首先,变量$first_name没有任何值(因为它没有设置),并且位置'洛杉矶'是数据库中最后一个的系列成员的位置。 因此返回此位置是因为$first_name$last_name在mysql查询中没有分配值(因为它们未设置),并且由于某种原因返回了数据库的最后一个人的位置。

令人非常沮丧的是,我无法检查Google智能助理的json响应,因为我可以在Dialogflow中轻松完成。 然而,在经过一些实验后我发现在Google智能助理中, $lifespan始终为0(在第一个和第二个问题中),并且在第二个问题的json响应中, $first_name$last_name根本没有设置,即使在Dialoglow中,它们被设置,它们包含我在上面发布的json响应中显示的全名。 此外谷歌助理返回actions_capability_screen_output$json->result->contexts[0]->name中,而显然这两个问题在Dialogflow $json->result->contexts[0]->namecontext (上下文的名称) 。

因此,Google智能助理第二个问题中json响应的contexts分支似乎是这样的:

"contexts": [
          {
            "name": "actions_capability_screen_output",
            "parameters": {},
            "lifespan": 0
          }
        ]

另一方面,如上所示,DIalogflow中第二个问题中json响应的contexts分支是:

"contexts": [
      {
        "name": "context",
        "parameters": {
          "given-name.original": "John",
          "last-name.original": "Smith",
          "given-name": "John",
          "last-name": "Smith"
        },
        "lifespan": 9
      }
    ]

为什么Google智能助理无法识别context并且它不会处理与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上下文?

你实际上没有发表你不是的证据。 你所展示的只是context[0]没有命名为“context”。 您应该记录整个context数组以查看所有这些内容

error_log( $json->result->context );

您将看到的是,已经设置了许多上下文。 这包括一个名为actions_capability_screen_output ,该操作由Google上的操作创建,用于指示您正在可以显示到屏幕的设备上运行。 它可能还有一个名为actions_capability_audio_output的表示它可以说出结果。 它还应该包含一个命名context ,它是您设置的context

但为什么这些其他上下文没有设置given-namelast-name参数?

因为当这些上下文处于活动状态时未设置这些参数。

您不能只假设参数将在第一个上下文中设置 - 您需要查找已设置它们的上下文并从这些特定上下文中获取值。

参数仅在设置它们的上下文中。 (事实上​​,您可以在输出上下文中设置其他参数作为回复的一部分。)

如果有多个上下文,如何找到包含我的参数的上下文?

遍历context数组并查找与您期望的名称匹配的数组。 然后,您可以从那里获得所需的参数。

为什么Google上的操作会将生命周期重置为0?

事实并非如此。 Google 上的操作设置其他上下文(您看到其中一个),其中包含特定于AoG的其他信息,并且它的生命周期为0(这意味着它将在此轮后删除,但它们将在下一次再次设置它通过)。 他们将其设置为0,因为某些上下文可能每次都会更改(特别是支持哪些表面)。

有没有更好的方法在没有上下文的情况下做到这一点?

不是真的 - 上下文非常棒,它们是最好的解决方案。

我不是PHP的最大专家,但我已经使用了一点。 我认为您的问题是Dialogflow不会将您的结果解释为JSON,而是一个简单的字符串。

从错误中,我看到:

Expected BEGIN_OBJECT but was STRING at line 2 column 1 path $.

假设您的响应是有效的JSON,那么您可能需要手动告诉Dialogflow该响应需要被解释为JSON

看起来你似乎已经在PHP响应的顶部做了这个,但是也许你应该验证JSON响应没有任何异常会导致上面的错误。

- 在更新之前回答我的帖子 -

最后我发现我得到了一个Expected BEGIN_OBJECT but was STRING at line 2 column 1 path $. 错误除非我在源代码中注释掉这些行:

error_reporting(E_ALL);
ini_set('display_errors', 'on');

如果我评论这两行,那么我没有得到任何错误,但最终的回答是“生活在洛杉矶”,而“约翰住在纽约安吉利斯”是完整/正确的回应。 显然,评论这两行并不能真正解决我的问题。 出现此问题的原因是,由于某些原因,当Dialogflow正确识别它时,Google智能助理无法识别为NamesLocation_context上下文定义定义的上下文。 因此, $first_name$last_name甚至没有在第二个问题中设置('他住在哪里?)这就是我对这个问题得到不完整/错误回答的原因。

关于我的问题的更新声明请看我上面的编辑。

- 在更新后回复我的帖子 -

如果我在Location_context intent中添加以下两个参数,我可以解决我的问题:

  • 参数名称:给定名称,姓氏。
  • 实体:@sys.given-name,@ sys.last-name。
  • value:#context.given-name,#context.last-name。

所以,我基本上是传递的价值given-namelast-name从参数Names意在将Location_context意图。

如果我这样做,那么Google智能助理第二个问题中json响应的contexts分支似乎变成这样:

"contexts": [
      {
        "name": "actions_capability_screen_output",
        "parameters": {
          "given-name.original": "John",
          "last-name.original": "Smith",
          "given-name": "John",
          "last-name": "Smith"
        },
        "lifespan": 0
      }
    ]

(同样,我无法直接检查Google智能助理的json输出,但我只是进行了一些测试,以了解json响应的格式和内容)

通过这种方式,我可以通过我的PHP脚本检索该人的全名并获得正确的答案(“约翰住在纽约。”)到第二个问题(“他住在哪里?”)。

但是,我仍然想知道为什么有必要在Dialogflow中执行此操作,而无需在Location_context intent中添加任何参数...

另外我不确定Google Assistant会以这种方式识别两个意图之间的上下文,因为lifespan再次为0(即使我得到了我想要的内容)...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM