Pengenalan ucapan (selanjutnya - ASR, Pengenalan Ucapan Otomatis) digunakan untuk membuat bot dan / atau IVR, serta untuk jajak pendapat otomatis. Voximplant menggunakan ASR yang disediakan oleh Good Corporation - Pengakuan Google bekerja dengan cepat dan dengan akurasi tinggi, tetapi ... Seperti biasa, ada satu peringatan. Seseorang dapat berhenti bahkan dalam kalimat pendek, dan kami membutuhkan jaminan bahwa ASR tidak akan mengambil jeda sebagai akhir dari jawaban. Jika ASR berpikir bahwa orang tersebut telah selesai berbicara, maka setelah "jawaban" skrip dapat memasukkan sintesis suara dengan pertanyaan berikut - pada saat yang sama orang tersebut akan terus berbicara dan mendapatkan pengalaman pengguna yang buruk: bot / IVR mengganggu orang tersebut. Hari ini kami akan memberi tahu Anda cara menangani hal ini agar pengguna Anda tidak kesal saat berkomunikasi dengan asisten besi.
Konsep
Tujuannya adalah untuk mengajukan pertanyaan dan mendengarkan seseorang tanpa mengganggu dan menunggu akhir jawabannya. ASR diwakili oleh
modul terpisah , di mana ada acara
ASR. Hasil - dipicu ketika seseorang telah selesai berbicara. Kekhususan ASR Google adalah bahwa ASR. Hasil dengan teks yang dikenali akan kembali segera setelah seseorang berhenti sebentar setidaknya dan Google memutuskan bahwa frasa tersebut dikenali dan diselesaikan.
Untuk memberi seseorang kesempatan untuk berhenti, Anda dapat menggunakan acara
ASR.InterimResult . Di dalamnya, ASR dalam proses pengakuan mengembalikan semua teks "mentah", mengoreksi dan mengubahnya tergantung pada konteksnya - dan seterusnya, hingga ASR. Hasil dipicu. Dengan demikian, acara ASR.InterimResult
adalah indikator bahwa seseorang saat ini mengatakan sesuatu . Kami akan fokus hanya padanya dan melihat berapa lama itu tidak datang. Dan teks-teks yang diakui antara diterima dari ASR.Hasil - untuk menambahkan.
Secara umum, akan terlihat seperti ini:
asr.addEventListener(ASREvents.InterimResult, e => { clearTimeout(timer) timer = setTimeout(stop, 3000) }) asr.addEventListener(ASREvents.Result, e => { answer += " " + e.text }) function stop(){
Kami mengungkapkan esensinya. Pengatur waktu
Untuk bekerja dengan benar dengan jeda, Anda dapat membuat objek khusus:
timeouts = { silence: null, pause: null, duration: null }
Setelah mengajukan pertanyaan, seseorang sering berpikir selama beberapa detik. Lebih baik mengatur penghitung waktu hening di awal 6-8 detik, kami akan menyimpan ID penghitung waktu di
timeouts.silence parameter.
Jeda di tengah jawaban optimal dalam 3-4 detik, sehingga seseorang dapat berpikir, tetapi tidak menderita dengan harapan ketika ia selesai. Ini adalah parameter
timeouts.pause .
Pengatur waktu umum untuk seluruh jawaban -
timeouts.duration - berguna jika kita tidak ingin orang itu berbicara terlalu lama. Ini juga melindungi kita dari kasus ketika seseorang berada di ruangan yang bising dengan suara latar belakang yang akan diambil oleh kita untuk pidato klien. Dan juga dari kasus ketika kami sampai ke robot lain yang berbicara dengan robot kami dalam lingkaran.
Jadi, di awal skrip, kita pasang modul ASR, deklarasikan variabelnya, dan buat objek
timeout :
require(Modules.ASR) let call, asr, speech = "" timeouts = { silence: null, pause: null, duration: null }
Panggilan masuk
Ketika panggilan masuk tiba di skrip, acara
AppEvents.CallAlerting menyala . Mari kita membuat penangan untuk acara ini: menjawab panggilan, menyapa klien, memulai pengakuan setelah sambutan. Dan mari kita biarkan seseorang mengganggu robot dari tengah pertanyaan yang diajukan (detail - sedikit lebih jauh).
handler AppEvents.CallAlerting VoxEngine.addEventListener(AppEvents.CallAlerting, e => { call = e.call
Dapat dilihat bahwa fungsi
startASR dan
startSilenceAndDurationTimeouts disebut -
mari kita lihat apa ini dan mengapa.
Pengakuan dan batas waktu
Pengakuan diimplementasikan dalam fungsi
startASR . Ini membuat instance ASR dan mengarahkan suara orang ke instance ini, tetapi juga berisi pengendali acara untuk
ASREvents.InterimResult dan
ASREvents.Result events . Seperti yang kami katakan di atas, di sini kami memperlakukan ASR.InterimResult sebagai tanda bahwa seseorang sedang berbicara. Pawang acara ini membersihkan batas waktu yang dibuat sebelumnya, menetapkan nilai baru untuk
batas waktu. Jeda, dan akhirnya menghentikan suara yang disintesis (ini adalah bagaimana seseorang dapat mengganggu bot). ASREvents.Result handler hanya menggabungkan semua respons yang dihasilkan dalam variabel
pidato . Secara khusus, dalam skenario ini,
ucapan tidak digunakan dengan cara apa pun, tetapi Anda dapat
mentransfernya ke backend Anda, misalnya, jika Anda mau.
mulaiASR function startASR() { asr = VoxEngine.createASR({ lang: ASRLanguage.RUSSIAN_RU, interimResults: true }) asr.addEventListener(ASREvents.InterimResult, e => { clearTimeout(timeouts.pause) clearTimeout(timeouts.silence) timeouts.pause = setTimeout(speechAnalysis, 3000) call.stopPlayback() }) asr.addEventListener(ASREvents.Result, e => {
Fungsi
startSilenceAndDurationTimeouts ... Menulis nilai dari penghitung waktu yang sesuai:
function startSilenceAndDurationTimeouts() { timeouts.silence = setTimeout(speechAnalysis, 8000) timeouts.duration = setTimeout(speechAnalysis, 30000) }
Dan beberapa fitur lainnya
speechAnalysis menghentikan pengenalan dan mem-parsing teks dari
ucapan (yang diperoleh dari
ASREvents.Result ). Jika tidak ada teks, maka kami ulangi pertanyaannya; jika ada teks, maka dengan sopan mengucapkan selamat tinggal dan menutup telepon.
Analisis pidato function speechAnalysis() {
HandleSilence bertanggung jawab untuk mengulangi pertanyaan:
function handleSilence() { call.say(", . , , ?", Language.RU_RUSSIAN_FEMALE)
Akhirnya, fungsi pembantu untuk menghentikan ASR:
function stopASR() { asr.stop() call.removeEventListener(CallEvents.PlaybackFinished) clearTimeout(timeouts.duration) }
Semuanya bersama
daftar skrip | require(Modules.ASR) |
| |
| let call, |
| asr, |
| speech = "" |
| |
| timeouts = { |
| silence: null, |
| pause: null, |
| duration: null |
| } |
| |
| // CallAlerting , |
| VoxEngine.addEventListener(AppEvents.CallAlerting, e => { |
| |
| call = e.call |
| |
| // . Connected |
| call.answer() |
| call.addEventListener(CallEvents.Connected, e => { |
| call.say(", . , , ?", Language.RU_RUSSIAN_FEMALE) |
| |
| // 4 |
| setTimeout(startASR, 4000) |
| // |
| call.addEventListener(CallEvents.PlaybackFinished, startSilenceAndDurationTimeouts) |
| }); |
| call.addEventListener(CallEvents.Disconnected, e => { |
| VoxEngine.terminate() |
| }) |
| }) |
| |
| function startASR() { |
| asr = VoxEngine.createASR({ |
| lang: ASRLanguage.RUSSIAN_RU, |
| interimResults: true |
| }) |
| |
| asr.addEventListener(ASREvents.InterimResult, e => { |
| clearTimeout(timeouts.pause) |
| clearTimeout(timeouts.silence) |
| |
| timeouts.pause = setTimeout(speechAnalysis, 3000) |
| call.stopPlayback() |
| }) |
| |
| asr.addEventListener(ASREvents.Result, e => { |
| // |
| speech += " " + e.text |
| }) |
| |
| // ASR |
| call.sendMediaTo(asr) |
| } |
| |
| function startSilenceAndDurationTimeouts() { |
| timeouts.silence = setTimeout(speechAnalysis, 8000) |
| timeouts.duration = setTimeout(speechAnalysis, 30000) |
| } |
| |
| function speechAnalysis() { |
| // ASR |
| stopASR() |
| const cleanText = speech.trim().toLowerCase() |
| |
| if (!cleanText.length) { |
| // , , |
| // .. , , , |
| handleSilence() |
| } else { |
| call.say( |
| " ! !", |
| Language.RU_RUSSIAN_FEMALE |
| ) |
| call.addEventListener(CallEvents.PlaybackFinished, () => { |
| call.removeEventListener(CallEvents.PlaybackFinished) |
| call.hangup() |
| }) |
| } |
| } |
| |
| function handleSilence() { |
| call.say(", . , , ?", Language.RU_RUSSIAN_FEMALE) |
| |
| // 3 |
| setTimeout(startASR, 3000) |
| call.addEventListener(CallEvents.PlaybackFinished, startSilenceAndDurationTimeouts) |
| } |
| |
| function stopASR() { |
| asr.stop() |
| call.removeEventListener(CallEvents.PlaybackFinished) |
| clearTimeout(timeouts.duration) |
| } |
Skenario terakhir menunjukkan bagaimana Anda dapat "memuliakan" robot bujursangkar, menambahkan sedikit kebijaksanaan dan perhatian padanya. Tentunya metode ini bukan satu-satunya yang mungkin, jadi jika Anda memiliki pemikiran tentang bagaimana Anda dapat dengan elegan menyelesaikan interaksi yang biasa antara bot dan seseorang, bagikan dalam komentar. Bagi mereka yang menginginkan sesuatu yang lebih maju dan tiba-tiba tidak membaca tutorial kami tentang DialogFlow - kami
sarankan Anda membiasakan diri .