Создавайте голосовых ботов для Android с помощью Dialogflow Essentials & трепетать

1. Прежде чем начать

В этой лаборатории вы узнаете, как интегрировать простого текстового и голосового бота Dialogflow Essentials (ES) в приложение Flutter. Dialogflow ES — это пакет разработки для создания диалоговых пользовательских интерфейсов. Таким образом, чат-боты, голосовые боты, телефонные шлюзы. Вы можете создать его с помощью одного и того же инструмента и даже поддерживать несколько каналов на более чем 20 разных языках. Dialogflow интегрируется со многими популярными платформами общения, такими как Google Assistant, Slack и Facebook Messenger. Если вы хотите создать агент для одной из этих платформ, вам следует использовать один из многих вариантов интеграции. Однако, чтобы создать чат-бота для мобильных устройств, вам придется создать собственную интеграцию. Вы создадите намерения, указав обучающие фразы для обучения базовой модели машинного обучения.

Эта лабораторная работа призвана отразить общий опыт облачных разработчиков:

  1. Настройка среды
  • Dialogflow: создание нового агента Dialogflow ES
  • Dialogflow: настройка Dialogflow
  • Google Cloud: создайте учетную запись службы
  1. Flutter: создание приложения для чата
  • Создание проекта Flutter
  • Настройка параметров и разрешений
  • Добавление зависимостей
  • Привязка к аккаунту сервиса.
  • Запуск приложения на виртуальном или физическом устройстве
  1. Flutter: создание интерфейса чата с поддержкой преобразования речи в текст
  • Создание интерфейса чата
  • Подключение интерфейса чата
  • Интеграция пакета Dialogflow gRPC в приложение
  1. Dialogflow: моделирование агента Dialogflow
  • Настройте намерения приветствия и отступления
  • Используйте базу знаний FAQ

Предварительное условие

  • Базовый опыт работы с Dart/Flutter
  • Базовый опыт работы с Google Cloud Platform
  • Базовый опыт работы с Dialogflow ES.

Что ты построишь

Эта лаборатория покажет вам, как создать мобильного бота для часто задаваемых вопросов, который может ответить на наиболее распространенные вопросы об инструменте Dialogflow. Конечные пользователи могут взаимодействовать с текстовым интерфейсом или передавать голос через встроенный микрофон мобильного устройства, чтобы получить ответы.

Что вы узнаете

  • Как создать чат-бота с помощью Dialogflow Essentials
  • Как интегрировать Dialogflow в приложение Flutter с помощью пакета Dialogflow gRPC
  • Как определить намерения текста с помощью Dialogflow
  • Как передать голос через микрофон в Dialogflow
  • Как использовать соединитель базы знаний для импорта общедоступных часто задаваемых вопросов
  • Протестируйте чат-бота через текстовый и голосовой интерфейс на виртуальном или физическом устройстве.

Что вам понадобится

  • Для создания агента Dialogflow вам понадобится Google Identity/адрес Gmail.
  • Чтобы загрузить сервисный аккаунт, вам понадобится доступ к Google Cloud Platform.
  • Среда разработки Flutter

Настройте среду разработки Flutter

  1. Выберите операционную систему, в которой вы устанавливаете Flutter.
  1. Вы можете создавать приложения с помощью Flutter, используя любой текстовый редактор в сочетании с нашими инструментами командной строки. Однако в этом семинаре будет использоваться Android Studio . Плагины Flutter и Dart для Android Studio предоставляют вам возможность завершения кода, подсветку синтаксиса, помощь в редактировании виджетов, поддержку запуска и отладки и многое другое. Следуйте инструкциям на странице https://flutter.dev/docs/get-started/editor.

2. Настройка среды

Dialogflow: создание нового агента Dialogflow ES

  1. Открыть
  2. На левой панели, прямо под логотипом, в раскрывающемся списке выберите « Создать нового агента ». (Обратите внимание: не нажимайте раскрывающийся список с надписью «Глобальный», нам понадобится экземпляр Dialogflow, который является глобальным, чтобы использовать базу знаний часто задаваемых вопросов.)
  3. Укажите имя агента yourname-dialogflow (используйте свое имя)
  4. В качестве языка по умолчанию выберите английский – ru.
  5. В качестве часового пояса по умолчанию выберите ближайший к вам часовой пояс.
  6. Не выбирайте Mega Agent. (С помощью этой функции вы можете создать всеобъемлющего агента, который сможет организовывать работу между «дополнительными» агентами. Сейчас нам это не нужно.)
  7. Нажмите Создать .

Экран создания нового проекта

Настроить диалоговый поток

  1. Нажмите на значок шестеренки в левом меню рядом с названием вашего проекта.

Раскрывающийся список «Создать новый проект»

  1. Введите следующее описание агента: Часто задаваемые вопросы по Dialogflow Чат-бот
  2. Включите бета-функции , нажмите переключатель.

Dialogflow Essentials V2Beta1

  1. Перейдите на вкладку «Речь» и убедитесь, что флажок «Автоматическая адаптация речи» активен.
  2. При желании вы также можете щелкнуть первый переключатель, это улучшит модель речи, но это доступно только при обновлении пробной версии Dialogflow.
  3. Нажмите « Сохранить».

Google Cloud: получите сервисный аккаунт

После создания агента в Dialogflow проект Google Cloud должен быть создан в консоли Google Cloud.

  1. Откройте консоль Google Cloud:
  2. Убедитесь, что вы вошли в систему с той же учетной записью Google, что и в Dialogflow, и выберите проект: yourname-dialogflow на верхней синей панели.
  3. Затем найдите Dialogflow API на верхней панели инструментов и щелкните результат Dialogflow API в раскрывающемся списке.

Включить API диалогового потока

  1. Нажмите синюю кнопку «Управление» и выберите «Учетные данные» в левой строке меню. (Если Dialogflow еще не включен, сначала нажмите «Включить» )

Консоль GCP для учетных данных

  1. Нажмите «Создать учетные данные» (вверху экрана) и выберите «Учетная запись службы» .

Создать учетные данные

  1. Укажите имя учетной записи службы: flutter_dialogflow , идентификатор и описание и нажмите «Создать» .

Создать учетную запись службы

  1. На шаге 2 вам нужно будет выбрать роль: Dialogflow API Admin , нажать «Продолжить» и «Готово» .
  2. Нажмите на учетную запись службы flutter_dialogflow , перейдите на вкладку «Ключи» и нажмите « Добавить ключ» > «Создать новый ключ».

Создать ключ

  1. Создайте ключ JSON . Переименуйте его в credentials.json и сохраните в безопасном месте на жестком диске. Мы воспользуемся им позже.

JSON-ключ

Отлично, все необходимые нам инструменты настроены правильно. Теперь мы можем начать с интеграции Dialogflow в наше приложение!

3. Flutter: создание приложения для чата

Создайте шаблонное приложение

  1. Откройте Android Studio и выберите «Начать новый проект Flutter».
  2. Выберите Приложение Flutter в качестве типа проекта. Затем нажмите «Далее».
  3. Убедитесь, что путь Flutter SDK указывает местоположение SDK (выберите «Установить SDK...», если текстовое поле пусто).
  4. Введите имя проекта (например, flutter_dialogflow_agent ). Затем нажмите Далее .
  5. Измените имя пакета и нажмите «Готово» .

Создать новое приложение Flutter

Это создаст пример приложения с Material Components .

Подождите, пока Android Studio установит SDK и создаст проект.

Настройки и разрешения

  1. Библиотека звукозаписи sound_stream , которую мы будем использовать, требует minSdk не ниже 21 . Итак, давайте изменим это в android/app/build.gradle в блоке defaultConfig. (Обратите внимание: в папке Android есть 2 файла build.gradle, но тот, который находится в папке приложения, является правильным.)
defaultConfig {
   applicationId "com.myname.flutter_dialogflow_agent"
   minSdkVersion 21
   targetSdkVersion 30
   versionCode flutterVersionCode.toInteger()
   versionName flutterVersionName
}
  1. Чтобы предоставить разрешения для микрофона, а также позволить приложению обращаться к агенту Dialogflow, который работает в облаке, нам нужно будет добавить разрешения INTERNET и RECORD_AUDIO в файл app/src/main/AndroidManifest.xml . В вашем проекте Flutter есть несколько файлов AndroidManifest.xml, но вам понадобится тот, который находится в основной папке. Вы можете добавить строки прямо внутри тегов манифеста.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />

Добавление зависимостей

Мы будем использовать пакеты sound_stream , rxdart и Dialogflow_grpc .

  1. Добавьте зависимость 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. Добавьте зависимость 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. Добавьте зависимость 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!

Загрузка сервисного аккаунта и информации о проекте Google Cloud

  1. В вашем проекте создайте каталог и назовите его: assets .
  2. Переместите файл Credentials.json , который вы скачали из консоли Google Cloud, в папку с ресурсами .
  3. Откройте pubspec.yaml и добавьте учетную запись службы в блок флаттера.
flutter:
  uses-material-design: true
  assets:
    - assets/credentials.json

Запуск приложения на физическом устройстве

Если у вас есть устройство Android, вы можете подключить телефон через USB-кабель и выполнить отладку на устройстве. Выполните следующие действия , чтобы настроить это на экране «Параметры разработчика» на вашем устройстве Android.

Запуск приложения на виртуальном устройстве

Если вы хотите запустить приложение на виртуальном устройстве, выполните следующие действия:

  1. Нажмите «Инструменты» > «Диспетчер AVD» . (Или выберите AVD Manager на верхней панели инструментов, на рисунке ниже он выделен розовым цветом)

Верхняя панель инструментов Android Studio

  1. Мы создадим целевое виртуальное устройство Android, чтобы можно было протестировать наше приложение без физического устройства. Подробности см. в разделе «Управление AVD» . Выбрав новое виртуальное устройство, вы можете дважды щелкнуть его, чтобы запустить.

Управление AVD

Виртуальное устройство

  1. На главной панели инструментов Android Studio выберите в раскрывающемся списке устройство Android в качестве целевого и убедитесь, что выбран файл main.dart . Затем нажмите кнопку «Выполнить» (зеленый треугольник).

В нижней части IDE вы увидите журналы в консоли. Вы заметите, что происходит установка Android и вашего стартового приложения Flutter. Это займет минуту: как только виртуальное устройство будет готово, внесение изменений произойдет очень быстро. Когда вы все закончите, откроется стартовое приложение Flutter.

Шаблонное приложение

  1. Давайте включим микрофон для нашего приложения чат-бота. Нажмите кнопку параметров виртуального устройства, чтобы открыть параметры. На вкладке «Микрофон» включите все три переключателя.

Варианты АВД

  1. Давайте попробуем горячую перезагрузку, чтобы продемонстрировать, насколько быстро можно вносить изменения.

В lib/main.dart измените заголовок MyHomePage в классе MyApp на Flutter Dialogflow Agent . И измените основной образец на Colors.orange.

Первый код

Сохраните файл или щелкните значок болта на панели инструментов Android Studio. Вы должны увидеть изменения, внесенные непосредственно в виртуальное устройство.

4. Flutter: создание интерфейса чата с поддержкой STT.

Создание интерфейса чата

  1. Создайте новый файл виджета Flutter в папке lib . (щелкните правой кнопкой мыши папку lib, выберите «Создать» > «Виджет Flutter» > «Виджет с состоянием» ), назовите этот файл: chat.dart

Вставьте следующий код в этот файл. Этот файл дартс создает интерфейс чата. Dialogflow пока не будет работать, это просто расположение всех компонентов и интеграция компонента микрофона для обеспечения потоковой передачи. В комментариях в файле будет указано, куда мы позже интегрируем 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),
      ),
    );
  }
}

Найдите в файле Chat.dart сборку виджета. При этом создается интерфейс чат-бота, который содержит:

  • ListView , который содержит все всплывающие сообщения чата пользователя и чат-бота. Он использует класс ChatMessage, который создает сообщения чата с аватаром и текстом.
  • TextField для ввода текстовых запросов
  • IconButton со значком отправки для отправки текстовых запросов в Dialogflow.
  • IconButton с микрофоном для отправки аудиопотоков в Dialogflow, который меняет состояние при нажатии.

Подключение интерфейса чата

  1. Откройте main.dart и измените Widget build , чтобы он создавал только экземпляр интерфейса Chat() . Все остальные демо-коды можно удалить.
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. Запустите приложение. ( Если приложение было запущено ранее. Остановите виртуальное устройство и перезапустите main.dart ). Когда вы впервые запускаете приложение с интерфейсом чата. Вы получите всплывающее окно с вопросом, хотите ли вы разрешить использование микрофона. Нажмите: Во время использования приложения .

Разрешения

  1. Поиграйте с текстовой областью и кнопками. Когда вы вводите текстовый запрос и нажимаете Enter или нажимаете кнопку «Отправить», вы увидите текстовый запрос, зарегистрированный на вкладке «Выполнить» в Android Studio. Когда вы нажмете кнопку микрофона и остановите его, вы увидите аудиопоток, зарегистрированный на вкладке «Выполнить» .

Журнал аудиопотока

Отлично, теперь мы готовы интегрировать приложение с Dialogflow!

Интеграция вашего приложения Flutter с Dialogflow_gRPC

  1. Откройте Chat.dart и добавьте следующий импорт:
import 'package:dialogflow_grpc/dialogflow_grpc.dart';
import 'package:dialogflow_grpc/generated/google/cloud/dialogflow/v2beta1/session.pb.dart';
  1. В верхней части файла, прямо под // TODO DialogflowGrpcV2Beta1 class instance добавьте следующую строку для хранения экземпляра класса Dialogflow:
DialogflowGrpcV2Beta1 dialogflow;
  1. Найдите метод initPlugin() и добавьте следующий код прямо под комментарием TODO:
    // Get a Service account
    final serviceAccount = ServiceAccount.fromString(
        '${(await rootBundle.loadString('assets/credentials.json'))}');
    // Create a DialogflowGrpc Instance
    dialogflow = DialogflowGrpcV2Beta1.viaServiceAccount(serviceAccount);

Это создаст экземпляр Dialogflow, авторизованный для вашего проекта Google Cloud с учетной записью службы. (Убедитесь, что у вас есть файл Credentials.json в папке с ресурсами !)

Опять же, для демонстрационных целей работы с Dialogflow gRPC это нормально, но для рабочих приложений вы не хотите хранить файл Credentials.json в папке ресурсов, поскольку это не считается безопасным.

Выполнение вызова обнаружения намерения

  1. Теперь найдите метод handleSubmitted() , и вот здесь-то и начинается волшебство. Прямо под комментарием TODO добавьте следующий код. Этот код добавит введенное пользователем сообщение в ListView:
ChatMessage message = ChatMessage(
 text: text,
 name: "You",
 type: true,
);

setState(() {
 _messages.insert(0, message);
});
  1. Теперь, прямо под предыдущим кодом, мы выполним вызов детектора Intent, передадим текст из входных данных и языковой код. — Результат (внутри data.queryResult.fulfillment ) будет напечатан в ListView:
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. Запустите виртуальное устройство и проверьте вызов обнаружения намерения. Типа: hi . Он должен приветствовать вас стандартным приветственным сообщением. Когда вы вводите что-то еще, он вернет вам резервную копию по умолчанию.

Выполнение вызова StreamingDetectIntent

  1. Теперь найдите метод handleStream() , здесь и проявляется магия потоковой передачи звука. Сначала прямо под первым TODO создайте аудио InputConfigV2beta1 со списком смещений, чтобы сместить модель голоса. Поскольку мы используем телефон (виртуальное устройство), значение sampleHertz будет 16000, а кодировка — Linear 16. Это зависит от аппаратного обеспечения вашего компьютера/микрофона, который вы используете. Для моего внутреннего микрофона Macbook 16000 было достаточно. (См. информацию о пакете 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. Далее мы вызовем streamingDetectIntent объекта dialogflow , который содержит наш сеанс Dialogflow:
final responseStream = dialogflow.streamingDetectIntent(config, _audioStream);
  1. С помощью responseStream мы наконец можем прослушать входящий транскрипт, обнаруженный пользовательский запрос и обнаруженный ответ с совпадающим намерением. Мы напечатаем это в 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');
});

Вот и все, запустите свое приложение и протестируйте его на виртуальном устройстве, нажмите кнопку микрофона и скажите: «Привет» .

Это вызовет приветственное намерение Dialogflow по умолчанию. Результаты будут распечатаны на экране. Теперь, когда Flutter отлично работает с интеграцией Dialogflow, мы можем начать работу над разговором с нашим чат-ботом.

5. Dialogflow: моделирование агента Dialogflow

Dialogflow Essentials — это пакет разработки для создания диалоговых пользовательских интерфейсов. Таким образом, чат-боты, голосовые боты, телефонные шлюзы. Вы можете создать его с помощью одного и того же инструмента и даже поддерживать несколько каналов на более чем 20 разных языках. UX-дизайнеры Dialogflow (разработчики моделей агентов, лингвисты) или разработчики создают намерения, указывая обучающие фразы для обучения базовой модели машинного обучения.

Намерение классифицирует намерение пользователя. Для каждого агента Dialogflow ES вы можете определить множество намерений, где ваши объединенные намерения могут обрабатывать весь разговор. Каждое намерение может содержать параметры и ответы.

Соответствие намерению также известно как классификация намерений или сопоставление намерений. Это основная концепция Dialogflow ES. Как только намерение сопоставлено, оно может вернуть ответ, собрать параметры (извлечение сущности) или запустить код веб-перехватчика (выполнение), например, для получения данных из базы данных.

Когда конечный пользователь пишет или говорит что-то в чат-боте, что называется выражением или высказыванием пользователя, Dialogflow ES сопоставляет это выражение с наилучшими намерениями вашего агента Dialogflow на основе обучающих фраз. На основе этих обучающих фраз была обучена внутренняя модель машинного обучения Dialogflow ES.

Dialogflow ES работает с концепцией, называемой контекстом. Как и человек, Dialogflow ES может запоминать контекст во 2-м и 3-м поворотах. Таким образом он может отслеживать предыдущие высказывания пользователя.

Вот дополнительная информация о намерениях Dialogflow .

Изменение намерения приветствия по умолчанию

Когда вы создаете новый агент Dialogflow, два намерения по умолчанию будут созданы автоматически. Приветственное намерение по умолчанию — это первый поток, который вы получаете, когда начинаете разговор с агентом. Резервное намерение по умолчанию — это поток, который вы получите, если агент не сможет вас понять или не сможет сопоставить намерение с тем, что вы только что сказали.

Вот приветственное сообщение для намерения приветствия по умолчанию:

Пользователь

Агент

Привет

«Привет, я бот FAQ по Dialogflow, я могу отвечать на вопросы по Dialogflow».

«Что бы вы хотели знать?»

  1. Нажмите «Намерения» > «Намерение приветствия по умолчанию».
  2. Прокрутите вниз до «Ответы» .
  3. Очистить все текстовые ответы.
  4. На вкладке по умолчанию создайте следующие 2 ответа:
  • Привет, я бот FAQ по Dialogflow, я могу отвечать на вопросы по Dialogflow. Что бы вы хотели знать?
  • Привет, я бот по вопросам и вопросам Dialogflow. У вас есть вопросы о Dialogflow? Как я могу помочь?

Конфигурация должна быть похожа на этот скриншот.

Изменить намерение приветствия по умолчанию

  1. Нажмите « Сохранить».
  2. Давайте проверим это намерение. Во-первых, мы можем протестировать его в симуляторе Dialogflow. Введите: Hello . Он должен вернуть одно из этих сообщений:
  • Привет, я бот FAQ по Dialogflow, я могу отвечать на вопросы по Dialogflow. Что бы вы хотели знать?
  • Привет, я бот по вопросам и вопросам Dialogflow. У вас есть вопросы о Dialogflow? Как я могу помочь?

Изменение резервного намерения по умолчанию

  1. Нажмите «Намерения» > «Запасное намерение по умолчанию».
  2. Прокрутите вниз до «Ответы» .
  3. Очистить все текстовые ответы.
  4. На вкладке по умолчанию создайте следующий ответ:
  • К сожалению, я не знаю ответа на этот вопрос. Вы проверили наш сайт? http://www.dialogflow.com?
  1. Нажмите « Сохранить».

Подключение к онлайн-базе знаний

Соединители знаний дополняют определенные намерения. Они анализируют документы знаний , чтобы найти автоматические ответы. (например, часто задаваемые вопросы или статьи из файлов CSV, веб-сайтов или даже файлов PDF!) Для их настройки вы определяете одну или несколько баз знаний, которые представляют собой коллекции документов знаний.

Узнайте больше о соединителях знаний.

Давайте попробуем это.

  1. В меню выберите Знания (бета).

База знаний

  1. Нажмите правую синюю кнопку: Создать базу знаний.
  2. Введите имя базы знаний; Dialogflow FAQ и нажмите «Сохранить» .
  3. Нажмите Создать первую ссылку.

База знаний первая

  1. Это откроет окно.

Используйте следующую конфигурацию:

Название документа: DialogflowFAQ Тип знаний: FAQ Тип MIME: text/html

  1. URL-адрес, с которого мы загружаем данные:

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

  1. Нажмите Создать

Создана база знаний:

База знаний создана

  1. Прокрутите вниз до раздела «Ответы» и нажмите «Добавить ответ».

Создайте следующие ответы и нажмите «Сохранить» .

$Knowledge.Answer[1]
  1. Нажмите « Просмотреть подробности».

Посмотреть детали

  1. Выберите « Включить автоматическую перезагрузку» , чтобы автоматически получать изменения при обновлении веб-страницы часто задаваемых вопросов, и нажмите « Сохранить» .

Здесь отобразятся все часто задаваемые вопросы, которые вы реализовали в Dialogflow. Это просто!

Помните, что вы также можете указать онлайн-сайт HTML с часто задаваемыми вопросами, чтобы импортировать часто задаваемые вопросы в свой агент. Можно даже загрузить PDF-файл с блоком текста, и Dialogflow сам предложит вопросы.

Теперь часто задаваемые вопросы следует рассматривать как «дополнительные материалы», которые можно добавить к вашим агентам, рядом с вашими потоками намерений. Часто задаваемые вопросы базы знаний не могут обучать модель. Таким образом, задавая вопросы совершенно другим способом, вы можете не получить совпадения, потому что при этом не используется понимание естественного языка (модели машинного обучения). Вот почему иногда стоит преобразовать часто задаваемые вопросы в намерения.

  1. Проверьте вопросы в симуляторе справа.
  2. Когда все заработает, вернитесь в свое приложение Flutter и протестируйте свой чат и голосового бота с этим новым контентом! Задайте вопросы, которые вы загрузили в Dialogflow.

Результат

6. Поздравления

Поздравляем, вы успешно создали свое первое приложение Flutter с интеграцией чат-бота Dialogflow, молодцы!

Что мы рассмотрели

  • Как создать чат-бота с помощью Dialogflow Essentials
  • Как интегрировать Dialogflow в приложение Flutter
  • Как определить намерения текста с помощью Dialogflow
  • Как передать голос через микрофон в Dialogflow
  • Как использовать коннектор базы знаний

Что дальше?

Понравилась эта лаборатория кода? Взгляните на эти великолепные лаборатории Dialogflow!

Хотите узнать, как я создал пакет Dialogflow gRPC для Dart/Flutter?