1. Прежде чем начать
В этом практическом занятии вы узнаете, как интегрировать простой текстовый и голосовой бот Dialogflow Essentials (ES) в приложение Flutter. Dialogflow ES — это набор инструментов для разработки разговорных пользовательских интерфейсов. Таким образом, вы можете создавать чат-боты, голосовые боты, телефонные шлюзы — все это с помощью одного инструмента, и даже поддерживать несколько каналов на более чем 20 различных языках. Dialogflow интегрируется со многими популярными платформами для общения, такими как Google Assistant, Slack и Facebook Messenger. Если вы хотите создать агента для одной из этих платформ, вам следует использовать один из множества вариантов интеграции. Однако для создания чат-бота для мобильных устройств вам потребуется создать собственную интеграцию. Вы создадите интенты, указав обучающие фразы для обучения базовой модели машинного обучения.
Данная лабораторная работа составлена таким образом, чтобы отразить типичный опыт разработчика облачных решений:
- Настройка среды
- Dialogflow: Создайте нового агента Dialogflow ES.
- Dialogflow: Настройка Dialogflow
- Google Cloud: Создание сервисной учетной записи
- Flutter: Создание приложения для чата
- Создание проекта Flutter
- Настройка параметров и разрешений
- Добавление зависимостей
- Привязка к учетной записи службы.
- Запуск приложения на виртуальном или физическом устройстве
- Flutter: Создание интерфейса чата с поддержкой преобразования речи в текст.
- Создание интерфейса чата
- Связывание интерфейса чата
- Интеграция пакета Dialogflow gRPC в приложение
- Dialogflow: Моделирование агента Dialogflow
- Настройте приветственный и резервный интенты.
- Воспользуйтесь базой знаний с часто задаваемыми вопросами (FAQ).
Предварительное условие
- Базовые навыки игры в дартс/флаттер.
- Базовый опыт работы с платформой Google Cloud Platform.
- Базовый опыт работы с Dialogflow ES.
Что вы построите
В этом практическом занятии вы узнаете, как создать мобильного бота для ответов на часто задаваемые вопросы (FAQ), который сможет ответить на большинство распространенных вопросов об инструменте Dialogflow. Пользователи могут взаимодействовать с текстовым интерфейсом или передавать голосовые сообщения через встроенный микрофон мобильного устройства, чтобы получить ответы. |
|
Что вы узнаете
- Как создать чат-бота с помощью Dialogflow Essentials
- Как интегрировать Dialogflow в приложение Flutter с помощью пакета Dialogflow gRPC
- Как распознавать текстовые намерения с помощью Dialogflow
- Как передать голосовой сигнал через микрофон в Dialogflow
- Как использовать коннектор базы знаний для импорта общедоступных часто задаваемых вопросов (FAQ)
- Протестируйте чат-бота с помощью текстового и голосового интерфейса на виртуальном или физическом устройстве.
Что вам понадобится
- Для создания агента Dialogflow вам потребуется учетная запись Google Identity / Gmail.
- Для загрузки сервисной учетной записи вам потребуется доступ к платформе Google Cloud Platform.
- Среда разработки Flutter
Настройте среду разработки Flutter.
- Выберите операционную систему, на которую вы устанавливаете Flutter.
- Для пользователей macOS: https://flutter.dev/docs/get-started/install/macos
- Windows: https://flutter.dev/docs/get-started/install/windows
- Linux: https://flutter.dev/docs/get-started/install/linux
- ChromeOS: https://flutter.dev/docs/get-started/install/chromeos
- Вы можете создавать приложения с помощью Flutter, используя любой текстовый редактор в сочетании с нашими инструментами командной строки. Однако в этом мастер-классе будет использоваться Android Studio . Плагины Flutter и Dart для Android Studio предоставляют вам автозавершение кода, подсветку синтаксиса, помощь в редактировании виджетов, поддержку запуска и отладки и многое другое. Следуйте инструкциям по адресу https://flutter.dev/docs/get-started/editor
2. Настройка среды
Dialogflow: Создайте нового агента Dialogflow ES.
- Откройте
- В левой боковой панели, прямо под логотипом, выберите в выпадающем списке « Создать нового агента ». (Обратите внимание, не нажимайте на выпадающее меню «Глобальный», нам потребуется экземпляр Dialogflow с глобальным доступом, чтобы использовать базу знаний FAQ.)
- Укажите имя агента
yourname-dialogflow(используйте своё имя) - В качестве языка по умолчанию выберите английский - en.
- В качестве часового пояса по умолчанию выберите ближайший к вам часовой пояс.
- Не выбирайте «Мега-агент». (Эта функция позволяет создать всеобъемлющего агента, который будет координировать работу «подагентских» агентов. Сейчас нам это не нужно.)
- Нажмите «Создать» .

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

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

- Перейдите на вкладку «Речь» и убедитесь, что установлен флажок «Автоматическая адаптация речи» .
- При желании вы также можете переключить первый тумблер, это улучшит работу модели речи, но эта функция доступна только при обновлении пробной версии Dialogflow.
- Нажмите «Сохранить».
Google Cloud: Получите служебный аккаунт
После создания агента в Dialogflow необходимо создать проект Google Cloud в консоли Google Cloud.
- Откройте консоль Google Cloud:
- Убедитесь, что вы вошли в систему с той же учетной записью Google, что и в Dialogflow, и выберите проект:
yourname-dialogflowв верхней синей панели. - Далее найдите
Dialogflow APIна верхней панели инструментов и выберите результат Dialogflow API в выпадающем списке.

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

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

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

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

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

Отлично, все необходимые инструменты настроены правильно. Теперь мы можем приступить к интеграции Dialogflow в наше приложение!
3. Flutter: Создание приложения для чата
Создайте шаблон приложения
- Откройте Android Studio и выберите «Создать новый проект Flutter».
- Выберите тип проекта «Flutter Application» . Затем нажмите «Далее».
- Убедитесь, что путь к Flutter SDK указывает местоположение самого SDK (если текстовое поле пустое, выберите «Установить SDK...»).
- Введите название проекта (например,
flutter_dialogflow_agent). Затем нажмите «Далее» . - Измените имя пакета и нажмите «Готово» .

Это позволит создать тестовое приложение с использованием Material Components .
Дождитесь, пока Android Studio установит SDK и создаст проект.
Настройки и разрешения
- Для используемой нами библиотеки записи звука sound_stream требуется minSdk не ниже 21. Поэтому изменим это в файле android/app/build.gradle в блоке defaultConfig. (Обратите внимание, что в папке android находятся два файла build.gradle, но правильный — тот, что находится в папке app.)
defaultConfig {
applicationId "com.myname.flutter_dialogflow_agent"
minSdkVersion 21
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
- Чтобы предоставить разрешения микрофону, а также позволить приложению взаимодействовать с агентом Dialogflow, работающим в облаке, нам необходимо добавить разрешения INTERNET и RECORD_AUDIO в файл app/src/main/AndroidManifest.xml . В вашем проекте Flutter есть несколько файлов AndroidManifest.xml, но вам понадобится тот, который находится в основной папке. Вы можете добавить эти строки прямо внутри тегов manifest.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Добавление зависимостей
Мы будем использовать пакеты sound_stream , rxdart и dialogflow_grpc .
- Добавьте зависимость
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!
- Добавьте зависимость
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!
- Добавьте зависимость
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.
- В вашем проекте создайте директорию и назовите её:
assets. - Переместите файл credentials.json , который вы скачали из консоли Google Cloud, в папку assets .
- Откройте файл pubspec.yaml и добавьте учетную запись службы в блок flutter.
flutter:
uses-material-design: true
assets:
- assets/credentials.json
Запуск приложения на физическом устройстве
Если у вас есть устройство Android, вы можете подключить телефон через USB-кабель и отлаживать его на устройстве. Следуйте этим шагам , чтобы настроить это через экран «Параметры разработчика» на вашем устройстве Android.
Запуск приложения на виртуальном устройстве
Если вы хотите запустить приложение на виртуальном устройстве, выполните следующие действия:
- Нажмите «Инструменты» > «Диспетчер AVD» . (Или выберите «Диспетчер AVD» на верхней панели инструментов; на рисунке ниже он выделен розовым цветом).

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


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

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

- Давайте попробуем функцию «Горячая перезагрузка», чтобы продемонстрировать, как быстро можно вносить изменения.
В файле lib/main.dart измените заголовок MyHomePage в классе MyApp на: Flutter Dialogflow Agent . И измените primarySwatch на Colors.orange.

Сохраните файл или нажмите на значок молнии на панели инструментов Android Studio. Вы должны увидеть изменения, внесенные непосредственно в виртуальное устройство.
4. Flutter: Создание интерфейса чата с поддержкой STT
Создание интерфейса чата
- Создайте новый файл виджета Flutter в папке lib (щелкните правой кнопкой мыши по папке lib, выберите New > Flutter Widget > Stateful widget ) и назовите этот файл:
chat.dart
Вставьте следующий код в этот файл. Этот файл 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 строку `Widget build`. Это создаст интерфейс чат-бота, который будет содержать:
- ListView , содержащий все сообщения чата от пользователя и чат-бота. Он использует класс ChatMessage, который создает сообщения чата с аватаром и текстом.
- Текстовое поле для ввода текстовых запросов.
- IconButton со значком отправки, предназначенный для отправки текстовых запросов в Dialogflow.
- IconButton со встроенным микрофоном для отправки аудиопотоков в Dialogflow, состояние которого изменяется при нажатии.
Связывание интерфейса чата
- Откройте файл 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())
);
}
}
- Запустите приложение. ( Если приложение уже запускалось ранее, остановите виртуальное устройство и перезапустите main.dart ). При первом запуске приложения с интерфейсом чата появится всплывающее окно с запросом разрешения на использование микрофона. Нажмите: Во время использования приложения .

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

Отлично, теперь мы готовы интегрировать приложение с Dialogflow!
Интеграция вашего Flutter-приложения с Dialogflow_gRPC
- Откройте файл chat.dart и добавьте следующие импорты:
import 'package:dialogflow_grpc/dialogflow_grpc.dart';
import 'package:dialogflow_grpc/generated/google/cloud/dialogflow/v2beta1/session.pb.dart';
- В верхней части файла, сразу под
// TODO DialogflowGrpcV2Beta1 class instanceдобавьте следующую строку, чтобы сохранить экземпляр класса Dialogflow:
DialogflowGrpcV2Beta1 dialogflow;
- Найдите метод 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 находится в папке assets !)
Опять же, для демонстрационных целей, показывающих, как работать с Dialogflow gRPC, это допустимо, но для производственных приложений хранить файл credentials.json в папке assets не рекомендуется, поскольку это считается небезопасным.
Выполнение вызова detectIntent
- Теперь найдите метод
handleSubmitted(), вот где начинается волшебство. Прямо под комментарием TODO добавьте следующий код. Этот код добавит введенное пользователем сообщение в ListView:
ChatMessage message = ChatMessage(
text: text,
name: "You",
type: true,
);
setState(() {
_messages.insert(0, message);
});
- Теперь, прямо под предыдущим кодом, мы вызовем detectIntent, передадим текст из поля ввода и languageCode. — Результат (внутри
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);
});
}
- Запустите виртуальное устройство и протестируйте вызов функции обнаружения намерения. Введите:
hi. Вас должно поприветствовать стандартное приветственное сообщение. Если вы введете что-то другое, вам будет возвращено стандартное резервное сообщение.
Выполнение вызова streamingDetectIntent
- Теперь найдите метод
handleStream(), вот где начинается волшебство потоковой передачи аудио. Сначала, сразу под первым TODO, создайте объект audioInputConfigV2beta1 со списком biasList для смещения голосовой модели. Поскольку мы используем телефон (виртуальное устройство), 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]
);
- Далее мы вызовем метод
streamingDetectIntentу объектаdialogflow, который содержит нашу сессию Dialogflow:
final responseStream = dialogflow.streamingDetectIntent(config, _audioStream);
- С помощью 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 различных языках. Дизайнеры пользовательского опыта Dialogflow (специалисты по моделированию агентов, лингвисты) или разработчики создают интенты, указывая обучающие фразы для обучения базовой модели машинного обучения.
Интент классифицирует намерения пользователя. Для каждого агента Dialogflow ES можно определить множество интентов, объединение которых может обеспечить полноценный диалог. Каждый интент может содержать параметры и ответы.
Сопоставление намерений также известно как классификация намерений или сопоставление намерений. Это основная концепция в Dialogflow ES. После сопоставления намерения оно может возвращать ответ, собирать параметры (извлечение сущностей) или запускать код веб-перехватчика (выполнение), например, для получения данных из базы данных.
Когда конечный пользователь что-то пишет или говорит в чат-боте (это называется пользовательским выражением или высказыванием), Dialogflow ES сопоставляет это выражение с наилучшим намерением вашего агента Dialogflow на основе обучающих фраз. Внутренняя модель машинного обучения Dialogflow ES была обучена на этих обучающих фразах.
Dialogflow ES работает с концепцией, называемой контекстом. Подобно человеку, Dialogflow ES может запоминать контекст при втором и третьем репликах. Именно так он отслеживает предыдущие высказывания пользователя.
Более подробная информация о Dialogflow Intents доступна здесь .
Изменение стандартного приветственного намерения
При создании нового агента Dialogflow автоматически создаются два намерения по умолчанию. Намерение «Приветствие по умолчанию» — это первый сценарий, который вы получаете при начале разговора с агентом. Намерение «Запасной сценарий по умолчанию» — это сценарий, который вы получаете, когда агент не может вас понять или не может сопоставить намерение с тем, что вы только что сказали.
Вот приветственное сообщение для стандартного приветственного намерения:
Пользователь | Агент |
Привет | «Привет, я бот Dialogflow FAQ, я могу ответить на ваши вопросы о Dialogflow». |
- Нажмите «Интенты» > «Интент приветствия по умолчанию»
- Прокрутите вниз до раздела «Ответы» .
- Очистить все текстовые ответы.
- На вкладке «По умолчанию» создайте следующие 2 ответа:
- Привет, я бот для ответов на часто задаваемые вопросы по Dialogflow. Я могу ответить на ваши вопросы. Что бы вы хотели узнать?
- Привет! Я — бот Dialogflow FAQ. У вас есть вопросы о Dialogflow? Чем я могу помочь?
Настройки должны быть аналогичны тем, что показаны на этом скриншоте.

- Нажмите «Сохранить».
- Давайте проверим этот интент. Сначала протестируем его в симуляторе Dialogflow.Type: Hello . Он должен вернуть одно из следующих сообщений:
- Привет, я бот для ответов на часто задаваемые вопросы по Dialogflow. Я могу ответить на ваши вопросы. Что бы вы хотели узнать?
- Привет! Я — бот Dialogflow FAQ. У вас есть вопросы о Dialogflow? Чем я могу помочь?
Изменение намерения резервного варианта по умолчанию
- Click Intents > Default Fallback Intent
- Прокрутите вниз до раздела «Ответы» .
- Очистить все текстовые ответы.
- На вкладке «По умолчанию» создайте следующий ответ:
- К сожалению, я не знаю ответа на этот вопрос. Вы проверяли наш сайт? http://www.dialogflow.com?
- Нажмите «Сохранить».
Подключение к онлайн-базе знаний
Коннекторы знаний дополняют заданные намерения. Они анализируют документы знаний для поиска автоматических ответов (например, часто задаваемые вопросы или статьи из CSV-файлов, онлайн-сайтов или даже PDF-файлов!). Для их настройки необходимо определить одну или несколько баз знаний, представляющих собой наборы документов знаний.
Узнайте больше о средствах обмена знаниями.
Давайте попробуем.
- Выберите пункт «Знания (бета-версия)» в меню.

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

- Это откроет окно.
Используйте следующую конфигурацию:
Название документа: DialogflowFAQ Тип знаний: FAQ MIME-тип: text/html
- URL-адрес, с которого мы загружаем данные, следующий:
https://www.leeboonstra.dev/faqs/
- Нажмите «Создать».
Создана база знаний:

- Прокрутите страницу вниз до раздела «Ответы» и нажмите «Добавить ответ».
Создайте следующие ответы и нажмите «Сохранить» .
$Knowledge.Answer[1]
- Нажмите «Просмотреть подробности».

- Выберите «Включить автоматическую перезагрузку» , чтобы автоматически получать изменения при обновлении страницы часто задаваемых вопросов, и нажмите «Сохранить» .
Здесь отобразятся все часто задаваемые вопросы, которые вы реализовали в Dialogflow. Это просто!
Имейте в виду, что вы также можете указать на онлайн-сайт с часто задаваемыми вопросами (FAQ), чтобы импортировать их в систему вашего агента. Можно даже загрузить PDF-файл с текстовым блоком, и Dialogflow сам сформирует вопросы.
Теперь часто задаваемые вопросы следует рассматривать как «дополнительные элементы», которые можно добавить к вашим агентам, помимо ваших сценариев намерений. Часто задаваемые вопросы из базы знаний не могут обучить модель. Поэтому, если задавать вопросы совершенно другим способом, результат может не совпадать, поскольку в этом случае не используются модели машинного обучения (понимание естественного языка). Именно поэтому иногда стоит преобразовать ваши часто задаваемые вопросы в сценарии намерений.
- Проверьте ответы на вопросы в симуляторе справа.
- Когда всё заработает, вернитесь в своё Flutter-приложение и протестируйте чат и голосового бота с этим новым контентом! Задавайте вопросы, которые вы загрузили в Dialogflow.

6. Поздравляем!
Поздравляем, вы успешно создали свое первое Flutter-приложение с интеграцией чат-бота Dialogflow! Отличная работа!
Что мы рассмотрели
- Как создать чат-бота с помощью Dialogflow Essentials
- Как интегрировать Dialogflow в приложение Flutter
- Как распознавать текстовые намерения с помощью Dialogflow
- Как передать голосовой сигнал через микрофон в Dialogflow
- Как использовать коннектор базы знаний
Что дальше?
Вам понравилась эта практическая работа по программированию? Тогда взгляните на эти замечательные практические работы по Dialogflow!
- Интеграция Dialogflow с Google Ассистентом
- Интеграция Dialogflow с Google Chat
- Создание действий для Google Ассистента с помощью Dialogflow (уровень 1)
- Понимание процесса выполнения задач путем интеграции Dialogflow с Google Calendar +. Создайте свое первое приложение Flutter.
Интересуетесь, как я разработал gRPC-пакет Dialogflow для Dart/Flutter?
- Ознакомьтесь с моей статьей в блоге «Скрытое руководство по работе с API gRPC Google Cloud».