Tworzenie botów głosowych na Androida z użyciem Dialogflow Essentials i Skrzydełko

1. Zanim zaczniesz

Z tego ćwiczenia z programowania dowiesz się, jak zintegrować prosty bot tekstowy i głosowy Dialogflow Essentials (ES) z aplikacją Flutter. Dialogflow ES to pakiet programistyczny do tworzenia konwersacyjnych interfejsów użytkownika. Dlatego czatboty, boty głosowe, bramy telefoniczne. Możesz tworzyć je za pomocą tego samego narzędzia. Możesz też obsługiwać wiele kanałów w ponad 20 różnych językach. Dialogflow integruje się z wieloma popularnymi platformami do prowadzenia rozmów, takimi jak Asystent Google, Slack czy Facebook Messenger. Jeśli chcesz utworzyć agenta dla jednej z tych platform, musisz użyć jednej z wielu opcji integracji. Aby jednak utworzyć czatbota na urządzenia mobilne, musisz utworzyć integrację niestandardową. Musisz utworzyć intencje, określając wyrażenia do trenowania, aby wytrenować bazowy model systemów uczących się.

Moduł został ułożony w taki sposób, aby odzwierciedlać typowe czynności podejmowane przez programistów poruszających się w chmurze:

  1. Konfiguracja środowiska
  • Dialogflow: tworzenie nowego agenta Dialogflow ES
  • Dialogflow: konfigurowanie Dialogflow
  • Google Cloud: tworzenie konta usługi
  1. Flutter: tworzenie aplikacji do obsługi czatu
  • Tworzenie projektu Flutter
  • Konfigurowanie ustawień i uprawnień
  • Dodawanie zależności
  • Łączę z kontem usługi.
  • uruchamianie aplikacji na urządzeniu wirtualnym lub fizycznym,
  1. Flutter: tworzenie interfejsu czatu z obsługą zamiany mowy na tekst
  • Tworzenie interfejsu czatu
  • Łączenie interfejsu czatu
  • Integracja pakietu Dialogflow gRPC z aplikacją
  1. Dialogflow: Modelowanie agenta Dialogflow
  • Skonfiguruj powitanie i intencje zastępcze
  • Korzystanie z bazy wiedzy z najczęstszymi pytaniami

Warunek wstępny

  • Podstawowa obsługa gry w rzutki i Flutter
  • Podstawowe funkcje Google Cloud Platform
  • Podstawowe informacje o Dialogflow ES

Co utworzysz

Dzięki temu ćwiczeniu w Codelabs dowiesz się, jak utworzyć bota z najczęstszymi pytaniami na temat urządzeń mobilnych, który odpowie na najczęstsze pytania dotyczące narzędzia Dialogflow. Użytkownicy mogą korzystać z interfejsu tekstowego lub przesyłać strumieniowo głos przez wbudowany mikrofon urządzenia mobilnego, aby uzyskać odpowiedzi.

Czego się nauczysz

  • Jak utworzyć czatbota w Dialogflow Essentials
  • Jak zintegrować Dialogflow z aplikacją Flutter przy użyciu pakietu Dialogflow gRPC
  • Jak wykrywać intencje tekstowe przy użyciu Dialogflow
  • Jak transmitować głos przez mikrofon do Dialogflow
  • Jak korzystać z oprogramowania sprzęgającego bazy wiedzy do importowania publicznych najczęstszych pytań
  • Przetestuj czatbota za pomocą interfejsu tekstowego i głosowego na urządzeniu wirtualnym lub fizycznym

Czego potrzebujesz

  • Aby utworzyć agenta Dialogflow, musisz mieć tożsamość Google lub adres Gmail.
  • Aby pobrać konto usługi, musisz mieć dostęp do Google Cloud Platform
  • Środowisko programistyczne Flutter

Konfigurowanie środowiska programistycznego Flutter

  1. Wybierz system operacyjny, w którym instalujesz Flutter.
  1. Aplikacje możesz tworzyć za pomocą dowolnego edytora tekstu w połączeniu z naszymi narzędziami wiersza poleceń. W warsztatach będziemy jednak korzystać z Android Studio. Wtyczki Flutter i Dart do Android Studio umożliwiają uzupełnianie kodu, podświetlanie składni, wspomaganie edytowania widżetów, uruchamianie obsługę debugowania itp. Wykonaj czynności opisane na stronie https://flutter.dev/docs/get-started/editor.

2. Konfiguracja środowiska

Dialogflow: tworzenie nowego agenta Dialogflow ES

  1. Otwórz
  2. Na lewym pasku, tuż pod logo, kliknij „Create New Agent” (Utwórz nowego agenta). w menu. Nie klikaj menu z tekstem „Global” (Globalne). Aby skorzystać z bazy wiedzy z odpowiedziami na najczęstsze pytania, potrzebujemy instancji Dialogflow w wersji globalnej.
  3. Podaj nazwę agenta yourname-dialogflow (użyj własnej nazwy)
  4. Jako język domyślny wybierz English – en.
  5. Jako domyślną strefę czasową wybierz najbliższą strefę czasową.
  6. Nie wybieraj Mega Agent. Dzięki tej funkcji możesz utworzyć agenta nadrzędnego, którego można administrować agentami „sub”. nie są one teraz potrzebne).
  7. Kliknij Utwórz.

Ekran tworzenia nowego projektu

Konfigurowanie Dialogflow

  1. W menu po lewej stronie kliknij ikonę koła zębatego obok nazwy projektu.

Menu tworzenia nowego projektu

  1. Wpisz następujący opis agenta: Czatbot Dialogflow FAQ
  2. Włącz funkcje beta – użyj przełącznika.

Dialogflow Essentials V2 (beta) 1

  1. Kliknij kartę Mowa i upewnij się, że jest zaznaczone pole Automatyczne dostosowywanie mowy.
  2. Opcjonalnie możesz też przełączyć pierwszy przełącznik, aby ulepszyć model mowy, ale ta funkcja jest dostępna tylko po przejściu na wersję próbną Dialogflow.
  3. Kliknij Zapisz.

Google Cloud: uzyskiwanie konta usługi

Po utworzeniu agenta w Dialogflow należy utworzyć projekt Google Cloud w konsoli Google Cloud.

  1. Otwórz konsolę Google Cloud: .
  2. Zaloguj się na to samo konto Google co w Dialogflow i wybierz projekt yourname-dialogflow na niebieskim pasku u góry.
  3. Następnie na górnym pasku narzędzi wyszukaj Dialogflow API i w menu kliknij wynik Dialogflow API.

Włączanie interfejsu Dialogflow API

  1. Kliknij niebieski przycisk Zarządzaj i Dane logowania na pasku menu po lewej stronie. Jeśli usługa Dialogflow nie jest jeszcze włączona, najpierw kliknij Włącz.

Dane logowania w konsoli GCP

  1. Kliknij Utwórz dane logowania (u góry ekranu) i wybierz Konto usługi.

Utwórz dane logowania

  1. Podaj nazwę konta usługi: flutter_dialogflow, identyfikator i opis, a następnie kliknij Utwórz.

Tworzenie konta usługi

  1. W kroku 2 musisz wybrać rolę Dialogflow API Admin, a następnie kliknąć Dalej i Gotowe.
  2. Kliknij konto usługi flutter_dialogflow, kliknij kartę Keys (Klucze) i wybierz Add Key > (Dodaj klucz) Utwórz nowy klucz

Utwórz klucz

  1. Utwórz klucz JSON. Zmień nazwę na credentials.json i zapisz w bezpiecznym miejscu na dysku twardym. Użyjemy ich później.

Klucz JSON

Doskonale. Wszystkie potrzebne narzędzia są poprawnie skonfigurowane. Możemy teraz zacząć od integracji Dialogflow z naszą aplikacją.

3. Flutter: tworzenie aplikacji do obsługi czatu

Tworzenie aplikacji Boilerplate

  1. Otwórz Android Studio i wybierz Rozpocznij nowy projekt Flutter.
  2. Jako typ projektu wybierz Flutter Application (Aplikacja Flutter). Następnie kliknij Dalej.
  3. Sprawdź, czy ścieżka Flutter SDK określa lokalizację pakietu SDK (jeśli pole tekstowe jest puste, wybierz Zainstaluj SDK...).
  4. Wpisz nazwę projektu (np. flutter_dialogflow_agent). Następnie kliknij Dalej.
  5. Zmień nazwę pakietu i kliknij Zakończ.

Utwórz nową aplikację Flutter

Spowoduje to utworzenie przykładowej aplikacji z komponentami Material Komponenty.

Poczekaj, aż Android Studio zainstaluje pakiet SDK i utworzy projekt.

Ustawienia Uprawnienia

  1. Używana przez nas biblioteka dyktafonu sound_stream wymaga parametru minSdk o wartości co najmniej 21. Zmieńmy to polecenie android/app/build.gradle w bloku defaultConfig. Pamiętaj, że w folderze Androida są 2 pliki build.gradle, a w folderze aplikacji jest ten właściwy.
defaultConfig {
   applicationId "com.myname.flutter_dialogflow_agent"
   minSdkVersion 21
   targetSdkVersion 30
   versionCode flutterVersionCode.toInteger()
   versionName flutterVersionName
}
  1. Aby przyznać uprawnienia do mikrofonu i umożliwić aplikacji skontaktowanie się z agentem Dialogflow, który działa w chmurze, musimy dodać uprawnienia INTERNET i RECORD_AUDIO do pliku app/src/main/AndroidManifest.xml. W projekcie Flutter jest wiele plików AndroidManifest.xml, ale musisz mieć ten plik w folderze głównym. Możesz dodać te wiersze bezpośrednio w tagach manifestu.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />

Dodawanie zależności

Wykorzystamy pakiety sound_stream, rxdart i dialogflow_grpc.

  1. Dodaj zależność sound_stream
$ flutter pub add sound_stream
Resolving dependencies...
  async 2.8.1 (2.8.2 available)
  characters 1.1.0 (1.2.0 available)
  matcher 0.12.10 (0.12.11 available)
+ sound_stream 0.3.0
  test_api 0.4.2 (0.4.5 available)
  vector_math 2.1.0 (2.1.1 available)
Downloading sound_stream 0.3.0...
Changed 1 dependency!
  1. Dodaj zależność dialogflow_grpc
flutter pub add dialogflow_grpc
Resolving dependencies...
+ archive 3.1.5
  async 2.8.1 (2.8.2 available)
  characters 1.1.0 (1.2.0 available)
+ crypto 3.0.1
+ dialogflow_grpc 0.2.9
+ fixnum 1.0.0
+ googleapis_auth 1.1.0
+ grpc 3.0.2
+ http 0.13.4
+ http2 2.0.0
+ http_parser 4.0.0
  matcher 0.12.10 (0.12.11 available)
+ protobuf 2.0.0
  test_api 0.4.2 (0.4.5 available)
+ uuid 3.0.4
  vector_math 2.1.0 (2.1.1 available)
Downloading dialogflow_grpc 0.2.9...
Downloading grpc 3.0.2...
Downloading http 0.13.4...
Downloading archive 3.1.5...
Changed 11 dependencies!
  1. Dodaj zależność rxdart
$ flutter pub add rxdart
Resolving dependencies...
  async 2.8.1 (2.8.2 available)
  characters 1.1.0 (1.2.0 available)
  matcher 0.12.10 (0.12.11 available)
+ rxdart 0.27.2
  test_api 0.4.2 (0.4.5 available)
  vector_math 2.1.0 (2.1.1 available)
Downloading rxdart 0.27.2...
Changed 1 dependency!

Wczytuję informacje o koncie usługi i projekcie Google Cloud

  1. Utwórz w projekcie katalog i nazwij go: assets.
  2. Przenieś plik credentials.json pobrany z konsoli Google Cloud do folderu assets.
  3. Otwórz plik pubspec.yaml i dodaj konto usługi do bloku Flutter.
flutter:
  uses-material-design: true
  assets:
    - assets/credentials.json

Uruchamianie aplikacji na urządzeniu fizycznym

Jeśli masz urządzenie z Androidem, możesz podłączyć telefon kablem USB i debugować na urządzeniu. Wykonaj te czynności, aby skonfigurować tę funkcję na ekranie Opcje programisty na urządzeniu z Androidem.

Uruchamianie aplikacji na urządzeniu wirtualnym

Jeśli chcesz uruchomić aplikację na urządzeniu wirtualnym, wykonaj te czynności:

  1. Kliknij Narzędzia> AVD Manager. Możesz też wybrać Menedżera AVD na górnym pasku narzędzi – na ilustracji poniżej jest on wyróżniony różowym kolorem.

Górny pasek narzędzi Android Studio

  1. Stworzymy docelowe urządzenie wirtualne z Androidem, abyśmy mogli przetestować naszą aplikację bez fizycznego urządzenia. Więcej informacji znajdziesz w artykule Zarządzanie urządzeniami AVD. Po wybraniu nowego urządzenia wirtualnego, możesz je kliknąć dwukrotnie, aby je uruchomić.

Zarządzaj reklamami AVD

Urządzenie wirtualne

  1. Na głównym pasku narzędzi Android Studio wybierz z menu urządzenie z Androidem jako docelowe i upewnij się, że wybrany jest plik main.dart. Następnie naciśnij przycisk Uruchom (zielony trójkąt).

U dołu IDE zobaczysz logi w konsoli. Zauważysz, że trwa instalowanie Androida i aplikacji startowej Flutter. Zajmie to tylko chwilę, gdy urządzenie wirtualne będzie gotowe, a wprowadzanie zmian będzie bardzo szybkie. Gdy skończysz, otworzy się aplikacja startowa Flutter.

Aplikacja Boilerplate

  1. Włączmy mikrofon naszej aplikacji czatbot. Kliknij przycisk Opcje na urządzeniu wirtualnym, aby otworzyć opcje. Na karcie Mikrofon włącz wszystkie 3 przełączniki.

Opcje AVD

  1. Przetestujmy ponowne załadowanie „gorące”, aby pokazać, jak szybko można wprowadzać zmiany.

W lib/main.dart zmień tytuł mojej strony głównej w klasie MyApp na: Flutter Dialogflow Agent. Zmień wartość primarySwatch na Colors.orange.

Pierwszy kod

Zapisz plik lub kliknij ikonę śrubki na pasku narzędzi Android Studio. Zmiana powinna być widoczna bezpośrednio na urządzeniu wirtualnym.

4. Flutter: tworzenie interfejsu czatu z obsługą STT

Tworzenie interfejsu czatu

  1. Utwórz nowy plik widżetu Flutter w folderze lib. (kliknij prawym przyciskiem folder lib, New > Flutter Widget > Stateful Widget), nazwij ten plik: chat.dart

Wklej do tego pliku ten kod. Ten plik dart tworzy interfejs czatu. Dialogflow jeszcze nie będzie działać. Jedynym wyjątkiem jest układ wszystkich komponentów i integracja mikrofonu z mikrofonem, która umożliwia przesyłanie strumieniowe. Znajdziesz tam komentarze w pliku, gdzie później zintegrujemy Dialogflow.

// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rxdart/rxdart.dart';
import 'package:sound_stream/sound_stream.dart';

// TODO import Dialogflow


class Chat extends StatefulWidget {
  Chat({Key key}) : super(key: key);

  @override
  _ChatState createState() => _ChatState();
}

class _ChatState extends State<Chat> {
  final List<ChatMessage> _messages = <ChatMessage>[];
  final TextEditingController _textController = TextEditingController();

  bool _isRecording = false;

  RecorderStream _recorder = RecorderStream();
  StreamSubscription _recorderStatus;
  StreamSubscription<List<int>> _audioStreamSubscription;
  BehaviorSubject<List<int>> _audioStream;

  // TODO DialogflowGrpc class instance

  @override
  void initState() {
    super.initState();
    initPlugin();
  }

  @override
  void dispose() {
    _recorderStatus?.cancel();
    _audioStreamSubscription?.cancel();
    super.dispose();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlugin() async {
    _recorderStatus = _recorder.status.listen((status) {
      if (mounted)
        setState(() {
          _isRecording = status == SoundStreamStatus.Playing;
        });
    });

    await Future.wait([
      _recorder.initialize()
    ]);



    // TODO Get a Service account

  }

  void stopStream() async {
    await _recorder.stop();
    await _audioStreamSubscription?.cancel();
    await _audioStream?.close();
  }

  void handleSubmitted(text) async {
    print(text);
    _textController.clear();

    //TODO Dialogflow Code

  }

  void handleStream() async {
    _recorder.start();

    _audioStream = BehaviorSubject<List<int>>();
    _audioStreamSubscription = _recorder.audioStream.listen((data) {
      print(data);
      _audioStream.add(data);
    });


    // TODO Create SpeechContexts
    // Create an audio InputConfig

    // TODO Make the streamingDetectIntent call, with the InputConfig and the audioStream
    // TODO Get the transcript and detectedIntent and show on screen

  }

  // The chat interface
  //
  //------------------------------------------------------------------------------------
  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
      Flexible(
          child: ListView.builder(
            padding: EdgeInsets.all(8.0),
            reverse: true,
            itemBuilder: (_, int index) => _messages[index],
            itemCount: _messages.length,
          )),
      Divider(height: 1.0),
      Container(
          decoration: BoxDecoration(color: Theme.of(context).cardColor),
          child: IconTheme(
            data: IconThemeData(color: Theme.of(context).accentColor),
            child: Container(
              margin: const EdgeInsets.symmetric(horizontal: 8.0),
              child: Row(
                children: <Widget>[
                  Flexible(
                    child: TextField(
                      controller: _textController,
                      onSubmitted: handleSubmitted,
                      decoration: InputDecoration.collapsed(hintText: "Send a message"),
                    ),
                  ),
                  Container(
                    margin: EdgeInsets.symmetric(horizontal: 4.0),
                    child: IconButton(
                      icon: Icon(Icons.send),
                      onPressed: () => handleSubmitted(_textController.text),
                    ),
                  ),
                  IconButton(
                    iconSize: 30.0,
                    icon: Icon(_isRecording ? Icons.mic_off : Icons.mic),
                    onPressed: _isRecording ? stopStream : handleStream,
                  ),
                ],
              ),
            ),
          )
      ),
    ]);
  }
}


//------------------------------------------------------------------------------------
// The chat message balloon
//
//------------------------------------------------------------------------------------
class ChatMessage extends StatelessWidget {
  ChatMessage({this.text, this.name, this.type});

  final String text;
  final String name;
  final bool type;

  List<Widget> otherMessage(context) {
    return <Widget>[
      new Container(
        margin: const EdgeInsets.only(right: 16.0),
        child: CircleAvatar(child: new Text('B')),
      ),
      new Expanded(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(this.name,
                style: TextStyle(fontWeight: FontWeight.bold)),
            Container(
              margin: const EdgeInsets.only(top: 5.0),
              child: Text(text),
            ),
          ],
        ),
      ),
    ];
  }

  List<Widget> myMessage(context) {
    return <Widget>[
      Expanded(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.end,
          children: <Widget>[
            Text(this.name, style: Theme.of(context).textTheme.subtitle1),
            Container(
              margin: const EdgeInsets.only(top: 5.0),
              child: Text(text),
            ),
          ],
        ),
      ),
      Container(
        margin: const EdgeInsets.only(left: 16.0),
        child: CircleAvatar(
            child: Text(
              this.name[0],
              style: TextStyle(fontWeight: FontWeight.bold),
            )),
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.symmetric(vertical: 10.0),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: this.type ? myMessage(context) : otherMessage(context),
      ),
    );
  }
}

Wyszukiwanie kompilacji widżetu w pliku chat.dart. Tworzy to interfejs czatbota, który zawiera:

  • ListView, który zawiera wszystkie dymki czatu użytkownika i czatbota. Wykorzystuje klasę ChatMessage do tworzenia wiadomości czatu z awatarem i tekstem.
  • TextField do wpisywania zapytań tekstowych.
  • IconButton z ikoną wysyłania do wysyłania zapytań tekstowych do Dialogflow
  • Przycisk IconButton z mikrofonem do wysyłania strumieni audio do Dialogflow, który zmienia stan po naciśnięciu.

Łączenie interfejsu czatu

  1. Otwórz plik main.dart i zmień Widget build, aby utworzyć tylko instancję interfejsu Chat(). Pozostałe kody demonstracyjne można usunąć.
import 'package:flutter/material.dart';
import 'chat.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.orange,
      ),
      home: MyHomePage(title: 'Flutter Dialogflow Agent'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Chat())
    );
  }
}
  1. Uruchom aplikację. (Jeśli aplikacja została uruchomiona wcześniej. Zatrzymaj urządzenie wirtualne i ponownie uruchom plik main.dart. Pierwsze uruchomienie aplikacji z interfejsem czatu. Pojawi się wyskakujące okienko z pytaniem, czy chcesz zezwolić na dostęp do mikrofonu. Kliknij: Podczas używania aplikacji.

Uprawnienia

  1. Poeksperymentuj z obszarem tekstowym i przyciskami. Gdy wpiszesz zapytanie tekstowe i naciśniesz Enter lub klikniesz przycisk wysyłania, zobaczysz zapytanie zapisane na karcie Uruchom w Android Studio. Gdy naciśniesz przycisk mikrofonu i go zatrzymasz, strumień audio zostanie zapisany na karcie Uruchom.

Dziennik strumienia audio

Świetnie, jesteśmy już gotowi do zintegrowania tej aplikacji z Dialogflow.

Integracja aplikacji Flutter z Dialogflow_gRPC

  1. Otwórz chat.dart i dodaj następujące importy:
import 'package:dialogflow_grpc/dialogflow_grpc.dart';
import 'package:dialogflow_grpc/generated/google/cloud/dialogflow/v2beta1/session.pb.dart';
  1. W górnej części pliku, tuż pod nagłówkiem // TODO DialogflowGrpcV2Beta1 class instance, dodaj ten wiersz, aby przytrzymać instancję klasy Dialogflow:
DialogflowGrpcV2Beta1 dialogflow;
  1. Wyszukaj metodę initPlugin() i dodaj następujący kod tuż pod komentarzem TODO:
    // Get a Service account
    final serviceAccount = ServiceAccount.fromString(
        '${(await rootBundle.loadString('assets/credentials.json'))}');
    // Create a DialogflowGrpc Instance
    dialogflow = DialogflowGrpcV2Beta1.viaServiceAccount(serviceAccount);

Spowoduje to utworzenie instancji Dialogflow autoryzowanej w ramach projektu Google Cloud przy użyciu konta usługi. Sprawdź, czy w folderze assets znajduje się plik credentials.json.

Z kolei w celach demonstracyjnych dotyczących korzystania z Dialogu gRPC Dialogflow jest w porządku, ale w przypadku aplikacji produkcyjnych nie warto przechowywać plikucredential.json w folderze zasobów, ponieważ nie jest on uważany za bezpieczny.

Wykonywanie wywołania DetectionIntent

  1. Teraz znajdź metodę handleSubmitted(). Oto, co z niej wynika. Bezpośrednio pod komentarzem TODO dodaj następujący kod.Ten kod spowoduje dodanie wiadomości wpisywanej przez użytkownika do widoku listy:
ChatMessage message = ChatMessage(
 text: text,
 name: "You",
 type: true,
);

setState(() {
 _messages.insert(0, message);
});
  1. Teraz, bezpośrednio pod poprzednim kodem, wywołamy metodę DetectionIntent, przekażemy tekst z danych wejściowych i dodamy wartość languageCode. - Wynik (w ciągu data.queryResult.fulfillment) zostanie wydrukowany w widoku listy:
DetectIntentResponse data = await dialogflow.detectIntent(text, 'en-US');
String fulfillmentText = data.queryResult.fulfillmentText;
if(fulfillmentText.isNotEmpty) {
  ChatMessage botMessage = ChatMessage(
    text: fulfillmentText,
    name: "Bot",
    type: false,
  );

  setState(() {
    _messages.insert(0, botMessage);
  });
}
  1. Uruchom urządzenie wirtualne i przetestuj wywołanie intencji. Typ: hi. Powinno wyświetlić się domyślna wiadomość powitalna. Gdy wpiszesz coś innego, wyświetli się domyślna kreacja zastępcza.

Wykonywanie wywołania StreamingDetectIntent

  1. Teraz znajdź metodę handleStream(). Oto, co pomoże w odtwarzaniu strumieni audio. Bezpośrednio pod pierwszym zadaniem do wykonania utwórz plik audio InputConfigV2beta1 z parametrem biasList, aby uprzedzić model głosu. Ponieważ korzystamy z telefonu (urządzenia wirtualnego), przykładowym Hertz będzie 16000, a kodowanie Linear 16. Zależy to od używanego sprzętu lub mikrofonu. Dla mojego wewnętrznego mikrofonu Macbooka 16000 to dobry wynik. Zobacz informacje o pakiecie https://pub.dev/packages/sound_stream.
var biasList = SpeechContextV2Beta1(
    phrases: [
      'Dialogflow CX',
      'Dialogflow Essentials',
      'Action Builder',
      'HIPAA'
    ],
    boost: 20.0
);

    // See: https://cloud.google.com/dialogflow/es/docs/reference/rpc/google.cloud.dialogflow.v2#google.cloud.dialogflow.v2.InputAudioConfig
var config = InputConfigV2beta1(
    encoding: 'AUDIO_ENCODING_LINEAR_16',
    languageCode: 'en-US',
    sampleRateHertz: 16000,
    singleUtterance: false,
    speechContexts: [biasList]
);
  1. Następnie wywołamy metodę streamingDetectIntent w obiekcie dialogflow, w którym trwa sesja Dialogflow:
final responseStream = dialogflow.streamingDetectIntent(config, _audioStream);
  1. Dzięki strumieniowi odpowiedzi możemy w końcu odsłuchiwać przychodzącą transkrypcję, wykryte zapytanie użytkownika i wykrytą dopasowaną odpowiedź intencji. Wydrukujemy to w formacie ChatMessage na ekranie:
// Get the transcript and detectedIntent and show on screen
responseStream.listen((data) {
  //print('----');
  setState(() {
    //print(data);
    String transcript = data.recognitionResult.transcript;
    String queryText = data.queryResult.queryText;
    String fulfillmentText = data.queryResult.fulfillmentText;

    if(fulfillmentText.isNotEmpty) {

      ChatMessage message = new ChatMessage(
        text: queryText,
        name: "You",
        type: true,
      );

      ChatMessage botMessage = new ChatMessage(
        text: fulfillmentText,
        name: "Bot",
        type: false,
      );

      _messages.insert(0, message);
      _textController.clear();
      _messages.insert(0, botMessage);

    }
    if(transcript.isNotEmpty) {
      _textController.text = transcript;
    }

  });
},onError: (e){
  //print(e);
},onDone: () {
  //print('done');
});

To wszystko, uruchom aplikację i przetestuj ją na urządzeniu wirtualnym, naciśnij przycisk mikrofonu i powiedz „Cześć”.

Spowoduje to aktywowanie domyślnej intencji powitalnej Dialogflow. Wyniki zostaną wydrukowane na ekranie. Teraz, gdy platforma Flutter doskonale współpracuje z integracją Dialogflow, możemy zacząć pracę nad rozmową z czatbotem.

5. Dialogflow: modelowanie agenta Dialogflow

Dialogflow Essentials to pakiet dla programistów do tworzenia konwersacyjnych interfejsów użytkownika. Dlatego czatboty, boty głosowe, bramy telefoniczne. Możesz tworzyć je za pomocą tego samego narzędzia. Możesz też obsługiwać wiele kanałów w ponad 20 różnych językach. Projektanci UX Dialogflow (modelerzy agentów, lingwiści) i deweloperzy tworzą intencje, określając wyrażenia do trenowania, aby wytrenować bazowy model systemów uczących się.

Intencja kategoryzuje zamiar użytkownika. W przypadku każdego agenta Dialogflow ES możesz zdefiniować wiele intencji, dla których połączone intencje mogą zapewnić obsługę pełnej rozmowy. Każda intencja może zawierać parametry i odpowiedzi.

Dopasowanie intencji to tzw. klasyfikacja intencji lub dopasowywanie intencji. To główne zagadnienie używane w Dialogflow ES. Po dopasowaniu intencji może zwracać odpowiedź, zbierać parametry (wyodrębnianie encji) lub aktywować kod webhooka (realizację), np. aby pobrać dane z bazy danych.

Gdy użytkownik napisze lub powie coś w czatbocie, zwanym wyrażeniem lub wypowiedzią użytkownika, Dialogflow ES dopasuje wyrażenie do najlepszej intencji agenta Dialogflow na podstawie wyrażeń treningowych. Działający od podstaw model systemów uczących się Dialogflow ES został wytrenowany z wykorzystaniem tych wyrażeń do trenowania.

W Dialogflow ES korzysta się z koncepcji kontekstu. Tak jak człowiek, Dialogflow ES zapamiętuje kontekst w drugiej i trzeciej turze. W ten sposób może śledzić wypowiedzi użytkowników w przeszłości.

Więcej informacji o intencjach Dialogflow

Modyfikowanie domyślnej intencji powitalnej

Gdy utworzysz nowego agenta Dialogflow, automatycznie zostaną utworzone 2 domyślne intencje. Domyślna intencja powitalna to pierwszy proces, który pojawia się po rozpoczęciu rozmowy z agentem. Domyślna intencja kreacji zastępczej to proces, który pojawia się, gdy agent nie jest w stanie Cię zrozumieć lub nie może dopasować intencji do Twojej wypowiedzi.

Oto wiadomość powitalna dla domyślnej intencji powitalnej:

Użytkownik

Przedstawiciel

Cześć

„Cześć, jestem botem najczęściej zadawanych pytań Dialogflow. Mogę odpowiadać na pytania w Dialogflow”.

„Co chcesz wiedzieć?”

  1. Kliknij Intents (Intencje) > „Intents” (Intencje). Domyślna intencja powitalna
  2. Przewiń w dół do sekcji Odpowiedzi.
  3. Usuń wszystkie odpowiedzi tekstowe.
  4. Na karcie domyślnej utwórz 2 takie odpowiedzi:
  • Cześć, jestem botem najczęściej zadawanych pytań Dialogflow. Mogę odpowiadać na pytania dotyczące Dialogflow. Co chcesz wiedzieć?
  • Jestem botem najczęściej zadawanych pytań Dialogflow. Czy masz jakieś pytania na temat Dialogflow? W czym mogę pomóc?

Konfiguracja powinna być podobna do tej na zrzucie ekranu.

Edytuj domyślną intencję powitalną

  1. Kliknij Zapisz.
  2. Przetestujmy tę intencję. Najpierw możemy przetestować to narzędzie w Dialogflow Simulator.Type: Hello. Powinien wyświetlić się jeden z tych komunikatów:
  • Cześć, jestem botem najczęściej zadawanych pytań Dialogflow. Mogę odpowiadać na pytania dotyczące Dialogflow. Co chcesz wiedzieć?
  • Jestem botem najczęściej zadawanych pytań Dialogflow. Czy masz jakieś pytania na temat Dialogflow? W czym mogę pomóc?

Modyfikowanie domyślnej intencji kreacji zastępczej

  1. Kliknij Intents (Intencje) > „Intents” (Intencje). Domyślna intencja zastępcza
  2. Przewiń w dół do sekcji Odpowiedzi.
  3. Usuń wszystkie odpowiedzi tekstowe.
  4. Na karcie domyślnej utwórz tę odpowiedź:
  • Nie znam odpowiedzi na to pytanie. Czy odwiedziłeś(-aś) naszą stronę internetową? http://www.dialogflow.com?
  1. Kliknij Zapisz.

Łączenie się z bazą wiedzy online

Oprogramowanie sprzęgające wiedzy uzupełnia zdefiniowane intencje. Analizują dokumenty wiedzy, aby znaleźć automatyczne odpowiedzi. (np. najczęstsze pytania lub artykuły z plików CSV, witryn internetowych, a nawet plików PDF!) Aby je skonfigurować, należy zdefiniować co najmniej 1 bazę wiedzy, która jest zbiorem dokumentów wiedzy.

Więcej informacji o usłudze Knowledge Connectors

Wypróbujmy to.

  1. W menu wybierz Wiedza (beta).

Baza wiedzy

  1. Kliknij niebieski przycisk po prawej stronie: Utwórz bazę wiedzy.
  2. Wpisz nazwę bazy wiedzy; Dialogflow FAQ i kliknij Save (Zapisz).
  3. Kliknij link Utwórz pierwszy.

Pierwsza baza wiedzy

  1. Otworzy się okno.

Użyj tej konfiguracji:

Nazwa dokumentu: DialogflowFAQ Typ wiedzy: FAQ Typ MIME: text/html

  1. Adres URL strony, z której wczytujemy dane, to:

https://www.leeboonstra.dev/faqs/

  1. Kliknij Utwórz.

Utworzono bazę wiedzy:

Utworzono bazę wiedzy

  1. Przewiń w dół do sekcji „Odpowiedzi” i kliknij Dodaj odpowiedź.

Utwórz poniższe odpowiedzi i kliknij Zapisz.

$Knowledge.Answer[1]
  1. Kliknij Wyświetl szczegóły.

Wyświetl szczegóły

  1. Wybierz Włącz automatyczne odświeżanie, by automatycznie pobierać zmiany po zaktualizowaniu strony z najczęstszymi pytaniami, a potem kliknij Zapisz.

Zostaną wyświetlone wszystkie najczęstsze pytania wdrożone przez Ciebie w Dialogflow. To proste.

Możesz też wskazać stronę internetową HTML z odpowiedziami na najczęstsze pytania, aby zaimportować je do pracownika obsługi klienta. Możesz nawet przesłać plik PDF z blokiem tekstu, a Dialogflow zasugeruje Ci kilka pytań.

Najczęstsze pytania należy traktować jako dodatkowe który chcesz dodać do agentów, obok przepływów intencji. Najczęstsze pytania dotyczące bazy wiedzy nie mogą wytrenować modelu. Dlatego zadawanie pytań w zupełnie inny sposób może nie uzyskać dopasowania, ponieważ w ich przypadku nie jest wykorzystywane rozumienie języka naturalnego (modele systemów uczących się). Dlatego czasami warto przekształcić najczęstsze pytania w zamiary na zamiar.

  1. Odpowiedz na pytania w symulatorze po prawej stronie.
  2. Gdy wszystko będzie działać, wróć do aplikacji Flutter i przetestuj czat oraz bota głosowego z nowymi treściami. Zadaj pytania wczytane do Dialogflow.

Wynik

6. Gratulacje

Gratulujemy. Udało Ci się utworzyć pierwszą aplikację Flutter z integracją z czatbotem Dialogflow. Dobra robota!

Omówione zagadnienia

  • Jak utworzyć czatbota w Dialogflow Essentials
  • Jak zintegrować Dialogflow z aplikacją Flutter
  • Jak wykrywać intencje tekstowe przy użyciu Dialogflow
  • Jak transmitować głos przez mikrofon do Dialogflow
  • Jak korzystać z oprogramowania sprzęgającego bazy wiedzy

Co dalej?

Podobał Ci się ten moduł związany z kodowaniem? Zapoznaj się z tymi wspaniałymi modułami Dialogflow.

Chcesz dowiedzieć się, jak udało mi się utworzyć pakiet Dialogflow gRPC na potrzeby Dart/Flutter?