【Dialogflow】 일문 일답으로 FAQ에 대답하는 채팅봇

최근 웹사이트의 오른쪽 하단에 나오는 채팅봇을 잘 보는군요.
이 글에서는 이전에 AutoML로 분류된 음식점 FAQ을 Dialogflow에 넣어 정확도를 살펴 보겠습니다.

구현 정책


  • FAQ 중 하나를 하나의 Intent에 할당
  • Intent 이름은 일련 번호입니다.
  • 응답은 Label 이름으로 한다

  • 데이터 가져오기 참고



    FAQ의 Intent를 수동으로 투입하는 것은 뼈가 부러지기 때문에, 임포트 기능을 사용합니다.
    그러나 이 가져오기 기능도 불편하며 JSON 파일만 가져올 수 있습니다.
    그리고 더 불편하게도 JSON 파일을 일괄 업로드하는 기능이 없습니다.
    어쩔 수 없으므로 Agent 단위로 가져오는 방법을 취합니다.
    Agent 파일을 ZIP로 DL하면 Intent 폴더에 1Intent에 대해 메타 정보와 학습 구문이 별도의 JSON 파일로 저장됩니다.
    그래서 CSV에서이 두 JSON으로 변환하는 스크립트를 작성합니다.
    이번에는 학습 문구와 답변만 고려하므로 아래에 필요한 최소한의 필드만으로 JSON을 만듭니다.


    아니
    Response
    UserSays1
    UserSays2
    ...
    UserSays10


    1
    toilet
    화장실은 어디입니까?
    화장실이 있습니까?
    ...
    화장실은 어디


    같은 1 행 1Intent CSV 데이터에서

    name.json
    {
      "name": "No",
      "responses": [
        {
          "messages": [
            {
              "type": "message",
              "speech": [
                "Response"
              ]
            }
          ]
        }
      ]
    }
    

    그리고

    name_usersays_en.json
    [
      {
        "data": [
          {
            "text": "UserSays1"
          }
        ]
      },
      {
        "data": [
          {
            "text": "UserSays2"
          }
        ]
      }
    ]
    

    두 개의 JSON 파일을 만듭니다.

    GAS로 JSON 파일 만들기



    CSV를 스프레드시트로 가져와서 이 기사를 참고 에 JSON을 ZIP로 굳게 저장합니다.
    function toIntents() {
      const sheet = SpreadsheetApp.getActiveSheet();
      const blobs = new Array();
      for (let i = 2; i <= sheet.getLastRow(); i++) {
        const name = ('000' + (i-1)).slice(-3);
        // name.jsonの作成
        const intent = {
          "name": name,
          "responses": createResponses(sheet.getRange(i, 2).getValue()),
        }
        const intentBlob = Utilities.newBlob(JSON.stringify(intent, null, 4),'application/json',name + '.json');
        blobs.push(intentBlob);
        // name_usersays_ja.jsonの作成
        const userSays = createUserSays(sheet, i);
        const userSaysBlob = Utilities.newBlob(JSON.stringify(userSays, null, 4),'application/json',name + '_usersays_ja.json');
        blobs.push(userSaysBlob);
      }
      const folder = DriveApp.getFolderById('hogehoge');
      const zip = Utilities.zip(blobs, 'jsons.zip');
      folder.createFile(zip);
    }
    
    function createResponses(speech) {
      return [
        {
          "messages": [
            {
              "type": "message",
              "speech": [
                speech
              ]
            }
          ]
        }
      ]
    }
    
    function createUserSays(sheet, rowNo) {
      const userSays = new Array();
      for (let i = 3; i <= 12; i++) {
        userSays.push({
          "data": [
            {
              "text":sheet.getRange(rowNo, i).getValue()
            }
          ]
        })
      }
      return userSays;
    }
    

    데이터 가져오기



    데이터가 완료되면 실제로 가져옵니다.
    앞에서 언급했지만 에이전트 단위로 가져옵니다.
    우선은 Agent 파일군을 ZIP로 다운로드합니다.
    톱니바퀴 설정을 클릭합니다.

    탭의 Export and Import에서 EXPORT AS ZIP을 클릭합니다.
    그러면 Agent 파일을 ZIP로 얻을 수 있습니다.

    Anget 폴더 안의 intents 폴더에 방금 만든 JSON을 모두 저장하고 다시 ZIP로 압축합니다.

    나무
    ├── agent.json
    ├── intents
    │   ├── 001.json
    │   ├── 001_usersays_ja.json
    │   ├── 002.json
    │   ├── 002_usersays_ja.json
    │   ├── 003.json
    │   ├── 003_usersays_ja.json
    │   ├── 004.json
    │   ├── 004_usersays_ja.json
    │   ├── 005.json
    │   ├── 005_usersays_ja.json
    │   ├── 006.json
    │   ├── 006_usersays_ja.json
    │   ├── 007.json
    │   ├── 007_usersays_ja.json
    │   ├── 008.json
    │   ├── 008_usersays_ja.json
    │   ├── 009.json
    │   ├── 009_usersays_ja.json
    │   ├── 010.json
    │   ├── 010_usersays_ja.json
    │   ├── Default\ Fallback\ Intent.json
    │   ├── Default\ Welcome\ Intent.json
    │   └── Default\ Welcome\ Intent_usersays_ja.json
    └── package.json
    

    다시 압축된 ZIP을 RESTORE합니다.

    Intents를 살펴보면 무사히 캡처한 것을 확인할 수 있다고 생각합니다.

    시험에, 학습 프레이즈 그대로 말을 걸어 보면, 무사히 돌아왔습니다!

    그러나 학습 문구에는 존재하지 않고 AutoML에서는 정밀도를 내준 "니코틴 최고!"를 주어 보니 불행히도 Fallback Intent에 떨어졌습니다.


    끝에



    엑셀로 관리할 수 있는 간단한 일문일답 FAQ라면 쉽게 캡처할 수 있었습니다.
    다만, 일괄로 캡처하는 것이 슈퍼 멘도쿠사이...구글씨, 좀 더 어떻게 되나요?
    더 스마트한 캡처 방법이 있다면 알려주세요.
    또, FAQ는 여러가지 듣는 방법이 있으므로, 학습 프레이즈를 모두를 망라하는 것은 어렵지요. 조금이라도 문구에서 벗어나면 Fallback Intent에 떨어집니다. 알 수없는 단어에 관해서는 AutoML보다 약할 수 있습니까?
    그래서, 이전 기사 로 한 구문을 분할하는 것으로, 1Intent로 모든 FAQ를 대응해 버리자! 라는 구성에 침착했습니다.

    좋은 웹페이지 즐겨찾기