1. לפני שמתחילים
ב-codelab הזה תלמדו איך לשלב בתוך אפליקציית Flutter בוט פשוט של טקסט וקול ב-Dialogflow Essentials (ES). Dialogflow ES הוא חבילת פיתוח ליצירת ממשקי משתמש שיש בהם אפשרות לנהל שיחות. לכן יש צ'אט בוטים, בוטים קוליים ושערי טלפון. כולם יכולים ליצור אותו באמצעות אותו כלי, ואפשר אפילו לתמוך בכמה ערוצים ביותר מ-20 שפות שונות. Dialogflow משתלב עם פלטפורמות פופולריות רבות לשיחות, כמו Google Assistant, Slack ו-Facebook Messenger. אם אתם רוצים ליצור סוכן לאחת מהפלטפורמות האלה, כדאי להשתמש באחת מאפשרויות השילוב הרבות. עם זאת, כדי ליצור צ'אטבוט למכשירים ניידים, תצטרכו ליצור שילוב בהתאמה אישית. תצרו כוונות על ידי ציון של ביטויי אימון לאימון מודל בסיסי של למידת מכונה.
ה-Lab הזה מסודר לפי סדר שמשקף חוויה נפוצה של מפתחים בענן:
- הגדרת הסביבה
- Dialogflow: יצירת סוכן חדש ב-Dialogflow ES
- Dialogflow: הגדרת Dialogflow
- Google Cloud: יצירת חשבון שירות
- Flutter: Building a chat application
- יצירת פרויקט Flutter
- הגדרת ההגדרות וההרשאות
- הוספת יחסי התלות
- קישור לחשבון השירות.
- הפעלת האפליקציה במכשיר וירטואלי או במכשיר פיזי
- Flutter: פיתוח ממשק הצ'אט עם תמיכה בהמרת דיבור לטקסט
- יצירת ממשק הצ'אט
- קישור לממשק הצ'אט
- שילוב חבילת Dialogflow gRPC באפליקציה
- Dialogflow: Modeling the Dialogflow agent
- הגדרת כוונות ההודעה הראשונית והחזרה למצב ראשוני
- שימוש במאגר ידע של שאלות נפוצות
דרישות מוקדמות
- ניסיון בסיסי ב-Dart/Flutter
- ניסיון בסיסי ב-Google Cloud Platform
- ניסיון בסיסי ב-Dialogflow ES
מה תפַתחו
ב-Codelab הזה תלמדו איך לבנות בוט לשאלות נפוצות לנייד, שיכול לענות על רוב השאלות הנפוצות לגבי הכלי Dialogflow. משתמשי קצה יכולים להקליד הנחיות בממשק הטקסט או להזרים קול באמצעות המיקרופון המובנה של מכשיר נייד כדי לקבל תשובות. |
|
מה תלמדו
- איך יוצרים צ'אטבוט באמצעות Dialogflow Essentials
- איך משלבים את Dialogflow באפליקציית Flutter באמצעות חבילת Dialogflow gRPC
- איך לזהות כוונות טקסט באמצעות Dialogflow
- איך מעבירים סטרימינג של קול דרך המיקרופון אל Dialogflow
- איך משתמשים במחבר של מאגר הידע כדי לייבא שאלות נפוצות ציבוריות
- בדיקת הצ'אטבוט באמצעות ממשק הטקסט והקול במכשיר וירטואלי או פיזי
הדרישות
- כדי ליצור סוכן Dialogflow, צריך כתובת Gmail או זהות Google.
- כדי להוריד חשבון שירות, תצטרכו גישה ל-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
- פותחים את .
- בסרגל הימני, מתחת ללוגו, בוחרים באפשרות יצירת סוכן חדש בתפריט הנפתח. (הערה: אל תלחצו על התפריט הנפתח עם הכיתוב Global (גלובלי). נצטרך מופע של Dialogflow שהוא גלובלי כדי להשתמש במאגר הידע של שאלות נפוצות).
- מציינים שם לסוכן
yourname-dialogflow(צריך להשתמש בשם שלכם) - בוחרים באפשרות English - en כשפת ברירת המחדל.
- כאזור זמן שמוגדר כברירת מחדל, בוחרים את אזור הזמן שהכי קרוב למיקום שלכם.
- לא בוחרים באפשרות Mega Agent. (בעזרת התכונה הזו אפשר ליצור סוכן ראשי שיכול לתאם בין סוכנים משניים. אנחנו לא צריכים את זה עכשיו).
- לוחצים על יצירה.

הגדרת Dialogflow
- בתפריט הימני, לוחצים על סמל גלגל השיניים לצד שם הפרויקט.

- מזינים את תיאור הסוכן הבא: Dialogflow FAQ Chatbot
- מפעילים את האפשרות הפעלת תכונות בטא.

- לוחצים על הכרטיסייה דיבור ומוודאים שהתיבה התאמה אוטומטית של דיבור פעילה.
- אפשר גם להפוך את המתג הראשון, כדי לשפר את מודל הדיבור, אבל האפשרות הזו זמינה רק כשמשדרגים את תקופת הניסיון של Dialogflow.
- לוחצים על שמירה.
Google Cloud: קבלת חשבון שירות
אחרי שיוצרים סוכן ב-Dialogflow, אמור להיווצר פרויקט בענן ב-Google Cloud במסוף Google Cloud.
- פותחים את מסוף Google Cloud:
- מוודאים שאתם מחוברים לאותו חשבון Google שבו אתם משתמשים ב-Dialogflow ובוחרים פרויקט:
yourname-dialogflowבסרגל הכחול העליון. - בסרגל הכלים העליון, מחפשים את
Dialogflow APIובתפריט הנפתח לוחצים על התוצאה Dialogflow API.

- לוחצים על הלחצן הכחול ניהול ואז על פרטי כניסה בסרגל התפריטים הימני. (אם Dialogflow עדיין לא מופעל, צריך ללחוץ קודם על הפעלה)

- לוחצים על Create credentials (בחלק העליון של המסך) ובוחרים באפשרות Service account.

- מציינים שם לחשבון השירות:
flutter_dialogflow, מזהה ותיאור, ולוחצים על יצירה.

- בשלב 2, בוחרים את התפקיד:
Dialogflow API Admin, לוחצים על המשך ואז על סיום. - לוחצים על
flutter_dialogflowחשבון שירות, לוחצים על הכרטיסייה מפתחות ואז על הוספת מפתח > יצירת מפתח חדש.

- יוצרים מפתח JSON. משנים את השם שלו ל-
credentials.jsonושומרים אותו במקום מאובטח בכונן הקשיח. נשתמש בו בהמשך.

מעולה, כל הכלים שדרושים לנו מוגדרים בצורה נכונה. עכשיו אפשר להתחיל לשלב את Dialogflow באפליקציה שלנו.
3. Flutter: פיתוח אפליקציית Chat
יצירת אפליקציית Boilerplate
- פותחים את Android Studio ובוחרים באפשרות Start a new Flutter project (התחלת פרויקט Flutter חדש).
- בוחרים באפשרות Flutter Application (אפליקציית Flutter) כסוג הפרויקט. אחר כך לוחצים על 'הבא'.
- מוודאים שנתיב Flutter SDK מציין את המיקום של ה-SDK (אם שדה הטקסט ריק, בוחרים באפשרות Install SDK...).
- מזינים שם לפרויקט (לדוגמה,
flutter_dialogflow_agent) ולוחצים על הבא. - משנים את שם החבילה ולוחצים על סיום.

הפעולה הזו תיצור אפליקציה לדוגמה עם רכיבי Material.
מחכים עד ש-Android Studio יתקין את ה-SDK וייצור את הפרויקט.
הגדרות והרשאות
- ספריית הקלטת האודיו sound_stream שבה נשתמש דורשת minSdk של 21 לפחות. לכן, נשנה את זה ב-android/app/build.gradle בבלוק defaultConfig. (הערה: יש 2 קבצים בשם build.gradle בתיקיית android, אבל הקובץ הנכון הוא זה שבתיקיית 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. יש כמה קובצי AndroidManifest.xml בפרויקט Flutter, אבל צריך את הקובץ שנמצא בתיקייה הראשית. אפשר להוסיף את השורות ישירות בתוך תגי המניפסט.
<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, פועלים לפי השלבים האלה.
הפעלת האפליקציה במכשיר וירטואלי
אם רוצים להריץ את האפליקציה במכשיר וירטואלי, פועלים לפי השלבים הבאים:
- לוחצים על Tools> AVD Manager (כלים > מנהל מכשירים וירטואליים). (או בוחרים את AVD Manager מסרגל הכלים העליון, באיור שלמטה הוא מסומן בוורוד)

- ניצור מכשיר וירטואלי של Android כמטרה, כדי שנוכל לבדוק את האפליקציה שלנו בלי מכשיר פיזי. פרטים נוספים זמינים במאמר בנושא ניהול מכשירי AVD. אחרי שבוחרים מכשיר וירטואלי חדש, אפשר ללחוץ עליו לחיצה כפולה כדי להפעיל אותו.


- בסרגל הכלים הראשי של Android Studio, בוחרים מכשיר Android כיעד דרך התפריט הנפתח ומוודאים שקובץ main.dart נבחר. לוחצים על הלחצן Run (משולש ירוק).
בתחתית סביבת הפיתוח המשולבת, היומנים יופיעו במסוף. תוכלו לראות שמערכת Android מתקינה את אפליקציית Flutter הראשונית שלכם. התהליך יימשך דקה. אחרי שהמכשיר הווירטואלי יהיה מוכן, תוכלו לבצע שינויים במהירות רבה. בסיום, אפליקציית Flutter הראשונית תיפתח.

- נפעיל את המיקרופון באפליקציית הצ'אטבוט. לוחצים על לחצן האפשרויות של המכשיר הווירטואלי כדי לפתוח את האפשרויות. בכרטיסייה 'מיקרופון', מפעילים את כל 3 המתגים.

- כדי להמחיש כמה מהר אפשר לבצע שינויים, ננסה את התכונה 'טעינה חמה'.
ב-lib/main.dart, משנים את הכותרת של MyHomePage בכיתה MyApp ל: Flutter Dialogflow Agent. משנים את primarySwatch ל-Colors.orange.

שומרים את הקובץ או לוחצים על סמל הברק בסרגל הכלים של Android Studio. השינוי אמור להופיע ישירות במכשיר הווירטואלי.
4. Flutter: בניית ממשק הצ'אט עם תמיכה ב-STT
יצירת ממשק הצ'אט
- יוצרים קובץ חדש של Flutter widget בתיקייה 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, שיוצרת הודעות צ'אט עם אווטאר וטקסט.
- TextField להזנת שאילתות טקסט
- 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 או על לחצן השליחה, שאילתת הטקסט מתועדת בכרטיסייה Run ב-Android Studio. כשמקישים על לחצן המיקרופון ומפסיקים אותו, זרם האודיו מתועד בכרטיסייה Run (הרצה).

מצוין, עכשיו אפשר לשלב את האפליקציה עם 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 עם הרשאה לפרויקט בענן שלכם באמצעות חשבון השירות. (חשוב לוודא שקובץ credentials.json נמצא בתיקייה assets!)
שוב, למטרות הדגמה של אופן העבודה עם Dialogflow gRPC, זה בסדר, אבל באפליקציות שמוכנות להפצה, לא מומלץ לאחסן את הקובץ credentials.json בתיקיית הנכסים, כי זה לא נחשב מאובטח.
ביצוע שיחה ל-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(). כאן מתרחש הקסם של סטרימינג אודיו. מימין למשימה הראשונה, יוצרים קובץ שמע InputConfigV2beta1 עם biasList כדי להטות את תבנית הקול. מכיוון שאנחנו משתמשים בטלפון (מכשיר וירטואלי), הערך של sampleHertz יהיה 16000 והקידוד יהיה Linear 16. זה תלוי בחומרה של המחשב ובמיקרופון שבו אתם משתמשים. במיקרופון הפנימי של ה-MacBook שלי, הערך 16,000 היה טוב. (ראו את המידע על החבילה 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 שפות שונות. מעצבי UX של Dialogflow (יוצרי מודלים של סוכנים, בלשנים) או מפתחים יוצרים כוונות על ידי ציון של ביטויי אימון לאימון מודל בסיסי של למידת מכונה.
כוונה מסווגת את הכוונה של המשתמש. לכל סוכן Dialogflow ES אפשר להגדיר הרבה כוונות, והשילוב של הכוונות יכול לנהל שיחה מלאה. כל כוונת משתמש יכולה להכיל פרמטרים ותשובות.
התאמה של כוונות נקראת גם סיווג כוונות או התאמה לכוונות. זהו המושג העיקרי ב-Dialogflow ES. אחרי שמזוהה כוונה, אפשר להחזיר תגובה, לאסוף פרמטרים (חילוץ ישויות) או להפעיל קוד של webhook (ביצוע), למשל כדי לאחזר נתונים ממסד נתונים.
כשמשתמש קצה כותב או אומר משהו בצ'אטבוט, שנקרא ביטוי או אמירה של משתמש, מערכת Dialogflow ES מתאימה את הביטוי לכוונת המשתמש הטובה ביותר של נציג Dialogflow, על סמך משפטי האימון. מודל למידת המכונה של Dialogflow ES מאומן על הביטויים האלה לאימון.
Dialogflow ES פועל עם קונספט שנקרא 'הקשר'. בדומה לבני אדם, מערכת Dialogflow ES יכולה לזכור את ההקשר בתור השני והשלישי של חילופי הדברים. כך הוא יכול לעקוב אחרי אמירות קודמות של המשתמש.
מידע נוסף על כוונות ב-Dialogflow
שינוי כוונת הפתיחה שמוגדרת כברירת מחדל
כשיוצרים סוכן חדש ב-Dialogflow, שתי כוונות ברירת מחדל נוצרות באופן אוטומטי. כוונת הפתיחה שמוגדרת כברירת מחדל היא התהליך הראשון שמתחיל כשמתחילים שיחה עם הסוכן. Default Fallback Intent הוא הרצף שתקבלו אם הסוכן לא יבין אתכם או לא יתאים כוונה למה שאמרתם.
זו הודעת הפתיחה של כוונת הפתיחה שמוגדרת כברירת מחדל:
משתמש | Agent |
שלום | "שלום, אני בוט השאלות הנפוצות של Dialogflow. אני יכול לענות על שאלות בנושא Dialogflow". |
- לוחצים על Intents > Default Welcome Intent (כוונות > כוונת ברירת המחדל של הודעת הפתיחה)
- גוללים למטה אל תגובות.
- מחיקת כל התשובות הטקסטואליות.
- בכרטיסיית ברירת המחדל, יוצרים את 2 התשובות הבאות:
- היי, אני הבוט של שאלות נפוצות ב-Dialogflow, ואני יכול לענות על שאלות בנושא Dialogflow. מה היית רוצה לדעת?
- היי, אני הבוט של שאלות נפוצות בנושא Dialogflow. יש לך שאלות לגבי Dialogflow? איך אוכל לעזור?
ההגדרה צריכה להיות דומה לזו שבצילום המסך.

- לוחצים על שמירה.
- בוא נבדוק את הכוונה הזו. קודם כל, אפשר לבדוק את זה בסימולטור של Dialogflow.מקלידים: Hello. הפונקציה צריכה להחזיר אחת מההודעות הבאות:
- היי, אני הבוט של שאלות נפוצות ב-Dialogflow, ואני יכול לענות על שאלות בנושא Dialogflow. מה היית רוצה לדעת?
- היי, אני הבוט של שאלות נפוצות בנושא Dialogflow. יש לך שאלות לגבי Dialogflow? איך אוכל לעזור?
שינוי כוונת ברירת המחדל לחזרה
- לוחצים על Intents > Default Fallback Intent (כוונה > כוונת ברירת מחדל לחזרה למצב הקודם)
- גוללים למטה אל תגובות.
- מחיקת כל התשובות הטקסטואליות.
- בכרטיסיית ברירת המחדל, יוצרים את התגובה הבאה:
- לצערי, אין לי תשובה לשאלה הזו. האם בדקת באתר שלנו? http://www.dialogflow.com?
- לוחצים על שמירה.
התחברות למאגר ידע באינטרנט
מחברי ידע משלימים את הכוונות המוגדרות. הם מנתחים מסמכי ידע כדי למצוא תשובות אוטומטיות. (לדוגמה, שאלות נפוצות או מאמרים מקובצי CSV, מאתרים באינטרנט או אפילו מקובצי PDF!) כדי להגדיר אותם, מגדירים מאגר ידע אחד או יותר, שהם אוספים של מסמכי ידע.
בואו ננסה.
- בתפריט, בוחרים באפשרות ידע (בטא).

- לוחצים על הלחצן הכחול השמאלי: יצירת מאגר ידע.
- מקלידים שם למאגר הידע, למשל שאלות נפוצות של Dialogflow, ולוחצים על שמירה.
- לוחצים על הקישור יצירת הקישור הראשון.

- ייפתח חלון.
משתמשים בהגדרות הבאות:
שם המסמך: DialogflowFAQ סוג הידע: FAQ סוג MIME: text/html
- כתובת ה-URL שממנה אנחנו טוענים את הנתונים היא:
https://www.leeboonstra.dev/faqs/
- לחץ על צור.
נוצר מאגר ידע:

- גוללים למטה לקטע 'תשובות' ולוחצים על הוספת תשובה.
יוצרים את התשובות הבאות ולוחצים על שמירה.
$Knowledge.Answer[1]
- לוחצים על הצגת פרטים.

- בוחרים באפשרות הפעלה של טעינה אוטומטית כדי לאחזר שינויים באופן אוטומטי כשדף השאלות הנפוצות מתעדכן, ולוחצים על שמירה.
יוצגו כל השאלות הנפוצות שהטמעתם ב-Dialogflow.זה קל!
חשוב לדעת שאפשר גם להפנות לאתר HTML באינטרנט עם שאלות נפוצות כדי לייבא שאלות נפוצות לסוכן. אפשר אפילו להעלות קובץ PDF עם בלוק טקסט, ו-Dialogflow יציע שאלות בעצמו.
שאלות נפוצות הן עכשיו תוספות שאפשר להוסיף לנציגים, לצד תהליכי ההפניה לכוונות. אי אפשר לאמן את המודל באמצעות שאלות נפוצות במאגר ידע. לכן, אם תשנו את הניסוח של השאלה באופן משמעותי, יכול להיות שלא תהיה התאמה כי המערכת לא משתמשת בהבנת שפה טבעית (מודלים של למידת מכונה). לכן לפעמים כדאי להמיר את השאלות הנפוצות לכוונות.
- בודקים את השאלות בסימולטור שמשמאל.
- אחרי שמוודאים שהכל עובד, חוזרים לאפליקציית Flutter ובודקים את הצ'אטבוט ואת הבוט הקולי עם התוכן החדש. לשאול את השאלות שטענתם ל-Dialogflow.

6. מזל טוב
מזל טוב, הצלחת ליצור את אפליקציית Flutter הראשונה שלך עם שילוב של צ'אטבוט של Dialogflow. כל הכבוד!
מה נכלל
- איך יוצרים צ'אטבוט באמצעות Dialogflow Essentials
- איך משלבים את Dialogflow באפליקציית Flutter
- איך לזהות כוונות טקסט באמצעות Dialogflow
- איך מעבירים סטרימינג של קול דרך המיקרופון אל Dialogflow
- איך משתמשים במחבר של מאגר הידע
מה השלב הבא?
נהניתם מה-Code Lab הזה? כדאי לעיין במעבדות Dialogflow המעולות האלה.
- שילוב של Dialogflow עם Google Assistant
- שילוב של Dialogflow עם Google Chat
- יצירת פעולות ל-Google Assistant באמצעות Dialogflow (רמה 1)
- הסבר על ביצוע פעולות באמצעות שילוב של Dialogflow עם יומן Google + יצירת אפליקציית Flutter ראשונה
רוצה לדעת איך בניתי את חבילת gRPC של Dialogflow ל-Dart/Flutter?
- מומלץ לקרוא את מאמר הבלוג שלי בנושא המדריך הנסתר לעבודה עם ממשקי ה-API של Google Cloud gRPC