Sprachbots für Android mit Dialogflow Essentials erstellen & Flattern

1. Hinweis

In diesem Codelab erfahren Sie, wie Sie einen einfachen Dialogflow ES-Text- und ‑Voicebot in eine Flutter-App einbinden. Dialogflow ES ist eine Entwicklersuite zum Erstellen von Kommunikations-UIs. Dazu gehören Chatbots, Voicebots und Telefon-Gateways. Sie können alle mit demselben Tool erstellt werden und Sie können sogar mehrere Kanäle in über 20 verschiedenen Sprachen unterstützen. Dialogflow lässt sich in viele beliebte Unterhaltungsplattformen wie Google Assistant, Slack und Facebook Messenger einbinden. Wenn Sie einen Agent für eine der Plattformen erstellen möchten, sollten Sie eine der vielen Integrationsoptionen verwenden. Wenn Sie einen Chatbot für Mobilgeräte erstellen möchten, müssen Sie jedoch eine benutzerdefinierte Integration erstellen. Sie erstellen Intents, indem Sie Trainingsformulierungen angeben, um ein zugrunde liegendes Modell für maschinelles Lernen zu trainieren.

Die Reihenfolge der Übungen in diesem Lab entspricht der üblichen Vorgehensweise eines Cloud-Entwicklers:

  1. Umgebung einrichten
  • Dialogflow: Neuen Dialogflow ES-Agent erstellen
  • Dialogflow: Dialogflow konfigurieren
  • Google Cloud: Dienstkonto erstellen
  1. Flutter: Building a chat application
  • Flutter-Projekt erstellen
  • Einstellungen und Berechtigungen konfigurieren
  • Abhängigkeiten hinzufügen
  • Verknüpfung mit dem Dienstkonto
  • Anwendung auf einem virtuellen oder physischen Gerät ausführen
  1. Flutter: Building the chat interface with Speech to Text support
  • Chatoberfläche erstellen
  • Chatoberfläche verknüpfen
  • Dialogflow-gRPC-Paket in die App einbinden
  1. Dialogflow: Dialogflow-Agent modellieren
  • Begrüßungs- und Fallback-Intents konfigurieren
  • FAQ-Wissensdatenbank verwenden

Voraussetzungen

  • Grundlegende Kenntnisse in Dart/Flutter
  • Grundlegende Erfahrung mit der Google Cloud Platform
  • Grundlegende Erfahrung mit Dialogflow ES

Aufgaben

In diesem Codelab erfahren Sie, wie Sie einen mobilen FAQ-Bot erstellen, der die häufigsten Fragen zum Tool Dialogflow beantworten kann. Endnutzer können über die Textoberfläche interagieren oder eine Stimme über das integrierte Mikrofon eines Mobilgeräts streamen, um Antworten zu erhalten.

Lerninhalte

  • Chatbot mit Dialogflow Essentials erstellen
  • Dialogflow mit dem Dialogflow-gRPC-Paket in eine Flutter-App einbinden
  • Text-Intents mit Dialogflow erkennen
  • Sprache über das Mikrofon an Dialogflow streamen
  • Wissensdatenbank-Connector verwenden, um öffentliche FAQs zu importieren
  • Chatbot über die Text- und Sprachschnittstelle auf einem virtuellen oder physischen Gerät testen

Voraussetzungen

  • Sie benötigen eine Google-Identität bzw. eine Gmail-Adresse, um einen Dialogflow-Agent zu erstellen.
  • Sie benötigen Zugriff auf die Google Cloud Platform, um ein Dienstkonto herunterzuladen.
  • Eine Flutter-Entwicklungsumgebung

Flutter-Entwicklungsumgebung einrichten

  1. Wählen Sie das Betriebssystem aus, auf dem Sie Flutter installieren.
  1. Sie können Apps mit Flutter erstellen, indem Sie einen beliebigen Texteditor in Kombination mit unseren Befehlszeilentools verwenden. In diesem Workshop wird jedoch Android Studio verwendet. Die Flutter- und Dart-Plug-ins für Android Studio bieten Ihnen unter anderem Codevervollständigung, Syntaxhervorhebung, Unterstützung beim Bearbeiten von Widgets sowie Unterstützung für das Ausführen und Debuggen. Folgen Sie der Anleitung unter https://flutter.dev/docs/get-started/editor.

2. Umgebung einrichten

Dialogflow: Neuen Dialogflow ES-Agent erstellen

  1. Öffnen Sie die .
  2. Wählen Sie in der linken Leiste direkt unter dem Logo im Drop-down-Menü die Option Create New Agent (Neuen Agent erstellen) aus. Klicken Sie nicht auf das Drop-down-Menü mit der Aufschrift „Global“. Wir benötigen eine globale Dialogflow-Instanz, um die FAQ-Wissensdatenbank zu verwenden.
  3. Geben Sie einen Agent-Namen yourname-dialogflow an (verwenden Sie Ihren eigenen Namen).
  4. Wählen Sie Englisch – en als Standardsprache aus.
  5. Wählen Sie als Standardzeitzone die Zeitzone aus, die Ihnen am nächsten ist.
  6. Wählen Sie nicht „Mega Agent“ aus. Mit dieser Funktion können Sie einen übergeordneten Agent erstellen, der die Kommunikation zwischen „Unter“-Agents koordinieren kann. Wir benötigen diese Informationen jetzt nicht.)
  7. Klicken Sie auf Erstellen.

Bildschirm zum Erstellen eines neuen Projekts

Dialogflow konfigurieren

  1. Klicken Sie im linken Menü neben dem Namen Ihres Projekts auf das Zahnradsymbol.

Neues Drop-down-Menü für Projekte erstellen

  1. Geben Sie die folgende Beschreibung für den Agenten ein: Dialogflow FAQ Chatbot
  2. Aktivieren Sie die Beta-Features, indem Sie den Schalter umlegen.

Dialogflow Essentials V2Beta1

  1. Klicken Sie auf den Tab Sprache und prüfen Sie, ob das Kästchen Automatische Sprachanpassung aktiviert ist.
  2. Optional können Sie auch den ersten Schalter umlegen. Dadurch wird das Sprachmodell verbessert. Diese Option ist jedoch nur verfügbar, wenn Sie das Dialogflow-Probeabo upgraden.
  3. Klicken Sie auf Speichern.

Google Cloud: Dienstkonto abrufen

Nachdem Sie einen Agent in Dialogflow erstellt haben, sollte in der Google Cloud Console ein Google Cloud-Projekt erstellt werden.

  1. Öffnen Sie die Google Cloud Console:
  2. Achten Sie darauf, dass Sie mit demselben Google-Konto wie in Dialogflow angemeldet sind, und wählen Sie in der blauen Leiste oben das Projekt yourname-dialogflow aus.
  3. Suchen Sie als Nächstes in der oberen Symbolleiste nach Dialogflow API und klicken Sie im Drop-down-Menü auf das Ergebnis Dialogflow API.

Dialogflow API aktivieren

  1. Klicken Sie auf die blaue Schaltfläche Verwalten und dann in der linken Menüleiste auf Anmeldedaten. Wenn Dialogflow noch nicht aktiviert ist, klicken Sie zuerst auf Aktivieren.

Anmeldedaten für die GCP Console

  1. Klicken Sie oben auf dem Bildschirm auf Anmeldedaten erstellen und wählen Sie Dienstkonto aus.

Anmeldedaten erstellen

  1. Geben Sie einen Namen für das Dienstkonto an: flutter_dialogflow, eine ID und eine Beschreibung und klicken Sie auf Erstellen.

Dienstkonto erstellen

  1. Wählen Sie in Schritt 2 die Rolle aus: Dialogflow API Admin, klicken Sie auf Weiter und dann auf Fertig.
  2. Klicken Sie auf das flutter_dialogflow-Dienstkonto, dann auf den Tab Schlüssel und auf Schlüssel hinzufügen > Neuen Schlüssel erstellen.

Schlüssel erstellen

  1. Erstellen Sie einen JSON-Schlüssel. Benennen Sie sie in credentials.json um und speichern Sie sie an einem sicheren Ort auf Ihrer Festplatte. Wir werden ihn später verwenden.

JSON-Schlüssel

Perfekt, alle erforderlichen Tools sind richtig eingerichtet. Wir können jetzt mit der Integration von Dialogflow in unsere App beginnen.

3. Flutter: Chat-Anwendung erstellen

Boilerplate-App erstellen

  1. Öffnen Sie Android Studio und wählen Sie Start a new Flutter project (Neues Flutter-Projekt starten) aus.
  2. Wählen Sie Flutter Application (Flutter-Anwendung) als Projekttyp aus. Klicken Sie auf „Weiter“.
  3. Prüfen Sie, ob der Flutter SDK-Pfad den Speicherort des SDK angibt. Wählen Sie „SDK installieren…“ aus, wenn das Textfeld leer ist.
  4. Geben Sie einen Projektnamen ein, z. B. flutter_dialogflow_agent, und klicken Sie auf Weiter.
  5. Ändern Sie den Paketnamen und klicken Sie auf Fertigstellen.

Neue Flutter-Anwendung erstellen

Dadurch wird eine Beispielanwendung mit Material Components erstellt.

Warten Sie, bis das SDK in Android Studio installiert und das Projekt erstellt wurde.

Einstellungen und Berechtigungen

  1. Die Audio-Rekorder-Bibliothek sound_stream, die wir verwenden werden, erfordert ein minSdk von mindestens 21. Wir ändern das jetzt in android/app/build.gradle im Block „defaultConfig“. Hinweis: Im Ordner „android“ gibt es zwei build.gradle-Dateien. Die Datei im Ordner „app“ ist die richtige.
defaultConfig {
   applicationId "com.myname.flutter_dialogflow_agent"
   minSdkVersion 21
   targetSdkVersion 30
   versionCode flutterVersionCode.toInteger()
   versionName flutterVersionName
}
  1. Damit wir dem Mikrofon Berechtigungen erteilen und die App den Dialogflow-Agent in der Cloud erreichen kann, müssen wir der Datei app/src/main/AndroidManifest.xml die Berechtigungen INTERNET und RECORD_AUDIO hinzufügen. Ihr Flutter-Projekt enthält mehrere AndroidManifest.xml-Dateien. Sie benötigen jedoch die Datei im Hauptordner. Sie können die Zeilen direkt in die Manifest-Tags einfügen.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />

Abhängigkeiten hinzufügen

Wir verwenden die Pakete sound_stream, rxdart und dialogflow_grpc.

  1. sound_stream-Abhängigkeit hinzufügen
$ 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. dialogflow_grpc-Abhängigkeit hinzufügen
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. rxdart-Abhängigkeit hinzufügen
$ 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!

Dienstkonto- und Google Cloud-Projektinformationen werden geladen

  1. Erstellen Sie in Ihrem Projekt ein Verzeichnis mit dem Namen assets.
  2. Verschieben Sie die Datei credentials.json, die Sie aus der Google Cloud Console heruntergeladen haben, in den Ordner assets.
  3. Öffnen Sie pubspec.yaml und fügen Sie das Dienstkonto dem Flutter-Block hinzu.
flutter:
  uses-material-design: true
  assets:
    - assets/credentials.json

Anwendung auf einem physischen Gerät ausführen

Wenn Sie ein Android-Gerät haben, können Sie Ihr Smartphone über ein USB-Kabel anschließen und auf dem Gerät debuggen. Folgen Sie dieser Anleitung, um die Funktion über den Bildschirm Entwickleroptionen auf Ihrem Android-Gerät einzurichten.

Anwendung auf einem virtuellen Gerät ausführen

Wenn Sie die Anwendung auf einem virtuellen Gerät ausführen möchten, gehen Sie so vor:

  1. Klicken Sie auf Tools> AVD Manager. Alternativ können Sie den AVD Manager auch über die obere Symbolleiste aufrufen (in der Abbildung unten rosa hervorgehoben).

Obere Symbolleiste von Android Studio

  1. Wir erstellen ein virtuelles Android-Zielgerät, damit wir unsere Anwendung ohne physisches Gerät testen können. Weitere Informationen finden Sie unter AVDs verwalten. Nachdem Sie ein neues virtuelles Gerät ausgewählt haben, können Sie es durch Doppelklicken starten.

AVDs verwalten

Virtuelles Gerät

  1. Wählen Sie in der Hauptsymbolleiste von Android Studio über das Drop-down-Menü ein Android-Gerät als Ziel aus und achten Sie darauf, dass main.dart ausgewählt ist. Drücken Sie dann die Schaltfläche Ausführen (grünes Dreieck).

Unten in der IDE werden die Logs in der Konsole angezeigt. Sie werden feststellen, dass Android und Ihre Flutter-Starter-App installiert werden. Das dauert eine Minute. Sobald das virtuelle Gerät bereit ist, können Sie Änderungen sehr schnell vornehmen. Wenn Sie fertig sind, wird die Flutter-Start-App geöffnet.

Boilerplate-App

  1. Aktivieren wir das Mikrofon für unsere Chatbot-App. Klicken Sie auf die Schaltfläche Optionen des virtuellen Geräts, um die Optionen zu öffnen. Aktivieren Sie auf dem Tab „Mikrofon“ alle drei Schalter.

AVD-Optionen

  1. Wir probieren Hot Reload aus, um zu zeigen, wie schnell Änderungen vorgenommen werden können.

Ändern Sie in lib/main.dart den MyHomePage-Titel in der MyApp-Klasse zu: Flutter Dialogflow Agent. Ändern Sie primarySwatch in „Colors.orange“.

Erster Code

Speichern Sie die Datei oder klicken Sie in der Android Studio-Symbolleiste auf das Blitzsymbol. Die Änderung sollte direkt auf dem virtuellen Gerät zu sehen sein.

4. Flutter: Chat-Oberfläche mit STT-Unterstützung erstellen

Chatoberfläche erstellen

  1. Erstellen Sie im Ordner lib eine neue Flutter-Widget-Datei. Klicken Sie mit der rechten Maustaste auf den Ordner „lib“ und wählen Sie Neu > Flutter-Widget > Stateful Widget aus. Nennen Sie die Datei chat.dart.

Fügen Sie den folgenden Code in diese Datei ein. Mit dieser Dart-Datei wird die Chat-Oberfläche erstellt. Dialogflow funktioniert noch nicht. Es geht nur um das Layout aller Komponenten und die Integration der Mikrofonkomponente, um Streams zu ermöglichen. Die Kommentare in der Datei geben an, wo wir Dialogflow später einbinden werden.

// 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),
      ),
    );
  }
}

Suchen Sie in der Datei „chat.dart“ nach „Widget build“. Damit wird die Chatbot-Oberfläche erstellt, die Folgendes enthält:

  • ListView mit allen Chatblasen des Nutzers und des Chatbots. Dazu wird die Klasse „ChatMessage“ verwendet, mit der Chatnachrichten mit einem Avatar und Text erstellt werden.
  • TextField zum Eingeben von Textanfragen
  • IconButton mit dem Symbol „Senden“ zum Senden von Textanfragen an Dialogflow
  • IconButton mit einem Mikrofon zum Senden von Audio-Streams an Dialogflow, das den Status ändert, sobald es gedrückt wird.

Chatoberfläche verknüpfen

  1. Öffnen Sie main.dart und ändern Sie Widget build so, dass nur die Chat()-Schnittstelle instanziiert wird. Alle anderen Democodes können entfernt werden.
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. Führen Sie die Anwendung aus: Wenn die App bereits gestartet wurde. Beenden Sie das virtuelle Gerät und führen Sie „main.dart“ noch einmal aus. Wenn Sie Ihre App zum ersten Mal mit der Chat-Oberfläche ausführen. Sie werden in einem Pop-up-Fenster gefragt, ob Sie den Zugriff auf das Mikrofon erlauben möchten. Klicken Sie auf Bei Nutzung der App.

Berechtigungen

  1. Probieren Sie das Textfeld und die Schaltflächen aus. Wenn Sie eine Textanfrage eingeben und die Eingabetaste drücken oder auf die Schaltfläche „Senden“ tippen, wird die Textanfrage auf dem Tab Ausführen in Android Studio protokolliert. Wenn Sie auf die Mikrofonschaltfläche tippen und die Aufnahme beenden, wird der Audio-Stream auf dem Tab Laufen protokolliert.

Audiostream-Log

Wir können die Anwendung jetzt in Dialogflow einbinden.

Flutter-App in Dialogflow_gRPC einbinden

  1. Öffnen Sie chat.dart und fügen Sie die folgenden Importe hinzu:
import 'package:dialogflow_grpc/dialogflow_grpc.dart';
import 'package:dialogflow_grpc/generated/google/cloud/dialogflow/v2beta1/session.pb.dart';
  1. Fügen Sie oben in der Datei direkt unter // TODO DialogflowGrpcV2Beta1 class instance die folgende Zeile ein, um die Dialogflow-Klasseninstanz zu speichern:
DialogflowGrpcV2Beta1 dialogflow;
  1. Suchen Sie nach der Methode initPlugin() und fügen Sie den folgenden Code direkt unter dem TODO-Kommentar ein:
    // Get a Service account
    final serviceAccount = ServiceAccount.fromString(
        '${(await rootBundle.loadString('assets/credentials.json'))}');
    // Create a DialogflowGrpc Instance
    dialogflow = DialogflowGrpcV2Beta1.viaServiceAccount(serviceAccount);

Dadurch wird eine Dialogflow-Instanz erstellt, die mit dem Dienstkonto für Ihr Google Cloud-Projekt autorisiert ist. Achten Sie darauf, dass sich die Datei credentials.json im Ordner assets befindet.

Für Demozwecke ist das in Ordnung, aber für Produktions-Apps sollten Sie die Datei „credentials.json“ nicht im Ordner „assets“ speichern, da dies nicht als sicher gilt.

detectIntent-Aufruf ausführen

  1. Suchen Sie nun nach der handleSubmitted()-Methode. Hier passiert die eigentliche Arbeit. Fügen Sie direkt unter dem TODO-Kommentar den folgenden Code ein.Dadurch wird die vom Nutzer eingegebene Nachricht der ListView hinzugefügt:
ChatMessage message = ChatMessage(
 text: text,
 name: "You",
 type: true,
);

setState(() {
 _messages.insert(0, message);
});
  1. Direkt unter dem vorherigen Code rufen wir jetzt „detectIntent“ auf. Wir übergeben den Text aus der Eingabe und einen „languageCode“. – Das Ergebnis (innerhalb von data.queryResult.fulfillment) wird in der ListView ausgegeben:
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. Starten Sie das virtuelle Gerät und testen Sie den Aufruf von „detect intent“. Typ: hi. Sie sollten mit der standardmäßigen Willkommensnachricht begrüßt werden. Wenn Sie etwas anderes eingeben, wird der Standard-Fallback zurückgegeben.

StreamingDetectIntent-Aufruf durchführen

  1. Suchen Sie nun nach der Methode handleStream(). Hier kommt die Magie für das Audio-Streaming ins Spiel. Erstellen Sie zuerst direkt unter dem ersten TODO eine Audio-InputConfigV2beta1 mit einer biasList, um das Sprachmodell zu optimieren. Da wir ein Smartphone (virtuelles Gerät) verwenden, ist „sampleHertz“ 16.000 und die Codierung „Linear 16“. Das hängt von der Hardware Ihres Geräts und dem verwendeten Mikrofon ab. Für das interne Mikrofon meines MacBooks war 16.000 gut. Weitere Informationen finden Sie unter 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. Als Nächstes rufen wir die Methode streamingDetectIntent für das dialogflow-Objekt auf, das unsere Dialogflow-Sitzung enthält:
final responseStream = dialogflow.streamingDetectIntent(config, _audioStream);
  1. Mit dem responseStream können wir uns schließlich die eingehende Transkription, die erkannte Nutzeranfrage und die erkannte übereinstimmende Intent-Antwort ansehen. Wir geben Folgendes auf dem Bildschirm aus:ChatMessage
// 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');
});

Das war's. Starten Sie Ihre Anwendung, testen Sie sie auf dem virtuellen Gerät, drücken Sie die Mikrofontaste und sagen Sie „Hallo“.

Dadurch wird der Standard-Begrüßungs-Intent von Dialogflow ausgelöst. Die Ergebnisse werden auf dem Bildschirm angezeigt. Da Flutter jetzt gut mit der Dialogflow-Integration funktioniert, können wir mit der Chatbot-Unterhaltung beginnen.

5. Dialogflow: Dialogflow-Agent modellieren

Dialogflow Essentials ist eine Suite für die Entwicklung von dialogorientierten Benutzeroberflächen. Dazu gehören Chatbots, Voicebots und Telefon-Gateways. Sie können alle mit demselben Tool erstellt werden und Sie können sogar mehrere Kanäle in über 20 verschiedenen Sprachen unterstützen. Dialogflow-UX-Designer (Agent-Modellierer, Linguisten) oder Entwickler erstellen Intents, indem sie Trainingsformulierungen angeben, um ein zugrunde liegendes Modell für maschinelles Lernen zu trainieren.

Ein Intent kategorisiert die Absicht eines Nutzers. Für jeden Dialogflow ES-Agent können Sie eine Vielzahl von Intents definieren, damit die kombinierten Intents eine vollständige Unterhaltung verarbeiten können. Jeder Intent kann Parameter und Antworten enthalten.

Die Zuordnung eines Intents wird auch als Intent-Klassifizierung oder Intent-Abgleich bezeichnet. Dies ist das Hauptkonzept in Dialogflow ES. Wenn ein Intent zugeordnet wird, kann er eine Antwort zurückgeben, Parameter erfassen (Entitätsextraktion) oder Webhook-Code (Auftragsausführung) auslösen, um beispielsweise Daten aus einer Datenbank abzurufen.

Wenn ein Endnutzer in einem Chatbot etwas schreibt oder sagt, was als Nutzerausdruck oder Äußerung bezeichnet wird, ordnet Dialogflow ES den Ausdruck anhand der Trainingsformulierungen dem besten Intent Ihres Dialogflow-Agents zu. Das zugrunde liegende Dialogflow ES-Modell für maschinelles Lernen wurde mit diesen Trainingsformulierungen trainiert.

Dialogflow ES verwendet das Konzept des Kontexts. Genau wie ein Mensch kann sich Dialogflow ES den Kontext in einem zweiten und dritten Turn merken. So kann es frühere Äußerungen von Nutzern nachvollziehen.

Weitere Informationen zu Dialogflow-Intents

Standard-Begrüßungs-Intent ändern

Wenn Sie einen neuen Dialogflow-Agent erstellen, werden automatisch zwei Standard-Intents erstellt. Der Standard-Begrüßungs-Intent ist der erste Ablauf, den Sie sehen, wenn Sie eine Unterhaltung mit dem Agent beginnen. Der Standard-Fallback-Intent ist der Ablauf, den Sie erhalten, wenn der Agent Sie nicht versteht oder keinen Intent mit dem, was Sie gerade gesagt haben, abgleichen kann.

Dies ist die Begrüßungsnachricht für den Standard-Begrüßungs-Intent:

Nutzer

Agentenmodus

Hallo

„Hallo, ich bin der Dialogflow-FAQ-Bot. Ich kann Fragen zu Dialogflow beantworten.“

„Was möchten Sie wissen?“

  1. Klicken Sie auf Intents > Default Welcome Intent (Intents > Standard-Begrüßungs-Intent).
  2. Scrollen Sie nach unten zu Antworten.
  3. Alle Textantworten löschen
  4. Erstellen Sie auf dem Standardtab die folgenden zwei Antworten:
  • Hallo, ich bin der Dialogflow-FAQ-Bot und kann Fragen zu Dialogflow beantworten. Was möchten Sie wissen?
  • Hallo, ich bin der Dialogflow-FAQ-Bot. Hast du Fragen zu Dialogflow? Wie kann ich Ihnen helfen?

Die Konfiguration sollte ähnlich wie in diesem Screenshot aussehen.

Standard-Begrüßungs-Intent bearbeiten

  1. Klicken Sie auf Speichern.
  2. Testen wir diesen Intent. Zuerst können wir es im Dialogflow-Simulator testen.Geben Sie Hallo ein. Es sollte eine der folgenden Meldungen zurückgegeben werden:
  • Hallo, ich bin der Dialogflow-FAQ-Bot und kann Fragen zu Dialogflow beantworten. Was möchten Sie wissen?
  • Hallo, ich bin der Dialogflow-FAQ-Bot. Hast du Fragen zu Dialogflow? Wie kann ich Ihnen helfen?

Standard-Fallback-Intent ändern

  1. Klicken Sie auf Intents > Default Fallback Intent (Intents > Standard-Fallback-Intent).
  2. Scrollen Sie nach unten zu Antworten.
  3. Alle Textantworten löschen
  4. Erstellen Sie auf dem Standardtab die folgende Antwort:
  • Leider weiß ich die Antwort auf diese Frage nicht. Haben Sie unsere Website unter http://www.dialogflow.com besucht?
  1. Klicken Sie auf Speichern.

Verbindung zu einer Online-Wissensdatenbank herstellen

Wissensconnectors ergänzen definierte Intents. Sie parsen Wissensdokumente, um automatisierte Antworten zu finden. (z. B. FAQs oder Artikel aus CSV-Dateien, Online-Websites oder sogar PDF-Dateien) Zum Konfigurieren von Wissensconnectors definieren Sie eine oder mehrere Wissensdatenbanken, d. h. Sammlungen von Wissensdokumenten.

Weitere Informationen zu Wissensconnectors

Probieren wir es aus.

  1. Wählen Sie im Menü Knowledge (Beta) aus.

Knowledge Base

  1. Klicken Sie auf die rechte blaue Schaltfläche: Create Knowledge Base (Wissensdatenbank erstellen).
  2. Geben Sie Dialogflow FAQ als Namen der Wissensdatenbank ein und klicken Sie auf Speichern.
  3. Klicken Sie auf den Link Ersten erstellen.

Erster Wissensdatenbank-Artikel

  1. Dadurch wird ein Fenster geöffnet.

Verwenden Sie die folgende Konfiguration:

Dokumentname: DialogflowFAQ Wissenstyp: FAQ MIME-Typ: text/html

  1. Die URL, von der wir die Daten laden, lautet:

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

  1. Klicken Sie auf Erstellen.

Eine Wissensdatenbank wurde erstellt:

Wissensdatenbank erstellt

  1. Scrollen Sie nach unten zum Abschnitt „Antworten“ und klicken Sie auf Antwort hinzufügen.

Erstellen Sie die folgenden Antworten und klicken Sie auf Speichern.

$Knowledge.Answer[1]
  1. Klicken Sie auf Details ansehen.

Details ansehen

  1. Wählen Sie Automatisches Neuladen aktivieren aus, um Änderungen automatisch abzurufen, wenn die FAQ-Webseite aktualisiert wird, und klicken Sie auf Speichern.

Hier werden alle FAQs angezeigt, die Sie in Dialogflow implementiert haben. Das ist ganz einfach.

Sie können auch auf eine Online-HTML-Website mit FAQs verweisen, um FAQs in Ihren Agent zu importieren. Sie können sogar eine PDF-Datei mit einem Textblock hochladen und Dialogflow generiert selbst Fragen.

FAQs sollten jetzt als „Extras“ betrachtet werden, die Sie Ihren Agents neben Ihren Intent-Abläufen hinzufügen können. FAQs in der Wissensdatenbank können nicht zum Trainieren des Modells verwendet werden. Wenn Sie Fragen auf eine völlig andere Art und Weise stellen, erhalten Sie möglicherweise keine Übereinstimmung, da kein Natural Language Understanding (Modelle für maschinelles Lernen) verwendet wird. Deshalb kann es sich manchmal lohnen, Ihre FAQs in Intentionen zu konvertieren.

  1. Testen Sie die Fragen im Simulator auf der rechten Seite.
  2. Wenn alles funktioniert, kehren Sie zu Ihrer Flutter-App zurück und testen Sie Ihren Chat- und Sprachbot mit diesen neuen Inhalten. Stellen Sie die Fragen, die Sie in Dialogflow geladen haben.

Ergebnis

6. Glückwunsch

Herzlichen Glückwunsch! Sie haben Ihre erste Flutter-App mit einer Dialogflow-Chatbot-Integration erstellt.

Behandelte Themen

  • Chatbot mit Dialogflow Essentials erstellen
  • Dialogflow in eine Flutter-App einbinden
  • Text-Intents mit Dialogflow erkennen
  • Sprache über das Mikrofon an Dialogflow streamen
  • Wissensdatenbank-Connector verwenden

Nächste Schritte

Hat Ihnen dieses Codelab gefallen? Sehen Sie sich diese tollen Dialogflow-Labs an.

Möchten Sie wissen, wie ich das Dialogflow-gRPC-Paket für Dart/Flutter erstellt habe?