Petunjuk pencarian (sjest) tidak hanya layanan pengguna, tetapi juga model bahasa yang sangat kuat yang menyimpan miliaran permintaan pencarian, mendukung pencarian fuzzy, personalisasi, dan banyak lagi. Kami belajar cara menggunakan sujest untuk memprediksi permintaan akhir pengguna dan memuat hasil pencarian sebelum mengklik tombol "Temukan".
Pengenalan teknologi ini - pre-renderer - membutuhkan banyak solusi menarik dalam pengembangan ponsel, pengembangan runtime pencarian, log, metrik. Dan, tentu saja, kami membutuhkan penggolong keren yang menentukan apakah akan memuat permintaan pencarian di muka: penggolong ini harus mencapai keseimbangan antara akselerasi unduhan, lalu lintas tambahan, dan beban pencarian. Hari ini saya akan berbicara tentang bagaimana kami berhasil membuat classifier seperti itu.

1. Apakah idenya akan berhasil?
Dalam tugas-tugas penelitian, jarang jelas sebelumnya bahwa ada solusi yang baik. Dan dalam kasus kami, kami juga awalnya tidak tahu data apa yang dibutuhkan untuk membangun penggolong yang cukup baik. Dalam situasi seperti itu, akan bermanfaat untuk memulai dengan beberapa model yang sangat sederhana yang akan memungkinkan Anda untuk mengevaluasi manfaat potensial dari pengembangan.
Gagasan paling sederhana ternyata sebagai berikut: kami akan memuat hasil pencarian pada prompt pertama dari saran pencarian; ketika prompt berubah, kami membuang unduhan sebelumnya dan mulai mengunduh kandidat baru. Ternyata algoritma seperti itu berfungsi dengan baik dan hampir semua permintaan dapat dimuat sebelumnya, namun, beban pada pencarian backend meningkat sesuai dan lalu lintas pengguna meningkat sesuai. Jelas bahwa solusi semacam itu tidak dapat diimplementasikan.
Gagasan berikut ini juga cukup sederhana: perlu memuat petunjuk pencarian yang mungkin tidak dalam semua kasus, tetapi hanya ketika kami cukup yakin bahwa mereka benar-benar diperlukan. Solusi paling sederhana adalah classifier yang bekerja secara langsung di runtime sesuai dengan data yang sudah dimiliki sajest.
Klasifikasi pertama dibangun hanya menggunakan sepuluh faktor. Faktor-faktor ini tergantung pada distribusi probabilitas pada set prompt (ide: semakin besar "bobot" dari prompt pertama, semakin besar kemungkinan akan dimasukkan) dan panjang input (ide: semakin sedikit huruf yang harus dimasukkan pengguna, semakin aman untuk memuat sebelumnya). Keindahan penggolong ini juga adalah bahwa untuk membangunnya, tidak perlu melepaskan apa pun. Faktor-faktor yang diperlukan untuk kandidat dapat dikumpulkan dengan membuat satu permintaan http di daemon sajest, dan target didasarkan pada log yang paling sederhana: kandidat dianggap "baik" jika total permintaan pengguna benar-benar cocok dengan itu. Dimungkinkan untuk mengumpulkan kumpulan seperti itu, melatih beberapa regresi logistik dan membangun diagram pencar hanya dalam beberapa jam.
Metrik untuk pre-renderer tidak sepenuhnya diatur seperti dalam klasifikasi biner yang biasa. Hanya dua parameter yang penting, tetapi ini bukan akurasi atau kelengkapan.
Biarkan - jumlah total permintaan, - jumlah total semua prerender, - jumlah total prerender yang berhasil, mis. yang akhirnya cocok dengan input pengguna. Kemudian dua karakteristik menarik dihitung sebagai berikut:
Misalnya, jika tepat satu prerender per permintaan dibuat, dan setengah dari prerender berhasil, maka efisiensi prerender akan menjadi 50%, dan ini berarti bahwa mungkin untuk mempercepat pemuatan setengah dari permintaan. Pada saat yang sama, untuk permintaan di mana prerender bekerja dengan sukses, lalu lintas tambahan tidak dibuat; untuk permintaan di mana prerender gagal, satu permintaan tambahan harus ditetapkan; jadi jumlah total permintaan satu setengah kali lebih besar dari yang asli, "ekstra" meminta 50% dari jumlah aslinya, oleh karena itu .
Dalam koordinat ini, saya menggambar plot pencar pertama. Dia terlihat seperti ini:

Nilai-nilai ini mengandung sejumlah asumsi yang wajar, tetapi setidaknya sudah jelas bahwa, kemungkinan besar, penggolong yang baik akan berhasil: mempercepat pemuatan beberapa puluh persen permintaan, meningkatkan beban beberapa puluh persen merupakan pertukaran yang menarik.
Sangat menarik untuk menyaksikan bagaimana classifier bekerja. Memang, ternyata panjang permintaan ternyata menjadi faktor yang sangat kuat: jika pengguna sudah hampir memasukkan petunjuk pertama, dan itu sangat mungkin pada saat yang sama, Anda dapat mengambilnya. Jadi prediksi penggolong meningkat tajam menjelang akhir permintaan.
margin prefix candidate -180.424 -96.096 -67.425 -198.641 -138.851 -123.803 -109.841 -96.805 -146.568 -135.725 -125.448 -58.615 31.414 -66.754 1.716
Prerender akan berguna bahkan jika itu terjadi pada saat memasukkan surat permintaan terakhir. Faktanya adalah bahwa pengguna masih menghabiskan waktu mengklik tombol "Temukan" setelah memasukkan permintaan. Waktu ini juga dapat disimpan.
2. Implementasi pertama
Setelah beberapa waktu, dimungkinkan untuk merakit desain yang berfungsi penuh: aplikasi mencari petunjuk ke dalam iblis sajest. Dia mengirim, antara lain, informasi tentang apakah akan memuat petunjuk pertama. Aplikasi, setelah menerima bendera yang sesuai, mengunduh hasilnya dan, jika input pengguna akhirnya sesuai dengan kandidat, memberikan hasilnya.
Pada saat itu, pengklasifikasi memperoleh faktor-faktor baru, dan model itu tidak lagi regresi logistik, tetapi cukup CatBoost . Awalnya, kami meluncurkan ambang yang cukup konservatif untuk penggolong, tetapi bahkan mereka memungkinkan kami untuk memuat hampir 10% hasil pencarian secara instan. Itu adalah rilis yang sangat sukses, karena kami berhasil secara signifikan menggeser kuantil minor kecepatan pencarian, dan pengguna memperhatikan ini dan mulai secara signifikan kembali ke pencarian: percepatan pencarian yang signifikan mempengaruhi frekuensi pengguna yang melakukan sesi pencarian!
3. Perbaikan lebih lanjut
Meskipun implementasinya berhasil, solusinya masih sangat tidak sempurna. Sebuah studi yang cermat terhadap log operasi menunjukkan bahwa ada beberapa masalah.
Pengklasifikasi tidak stabil. Misalnya, mungkin ternyata dengan awalan Yandex ia memprediksi permintaan Yandex, oleh awalan Yandex itu tidak memprediksi apa pun, dan oleh awalan Yandex itu lagi memprediksi permintaan Yandex. Kemudian implementasi langsung pertama kami membuat dua permintaan, meskipun bisa dikelola dengan satu.
Prerender tidak tahu bagaimana memproses petunjuk kata demi kata. Mengklik kata-kata-kata meminta mengarah ke munculnya ruang tambahan dalam permintaan. Misalnya, jika pengguna memasukkan Yandex, permintaan pertamanya adalah Yandex; tetapi jika pengguna menggunakan petunjuk kata-demi-kata, input sudah akan menjadi string "Yandex", dan prompt pertama adalah "kartu Yandex". Ini akan membawa konsekuensi yang membahayakan: permintaan Yandex yang sudah diunduh akan dibuang, sebaliknya permintaan kartu Yandex akan dimuat. Setelah itu, pengguna mengklik tombol "Temukan" dan ... akan menunggu pengiriman penuh dari penerbitan atas permintaan Yandex.
Dalam beberapa kasus, kandidat tidak memiliki peluang untuk menjadi sukses. Pencarian untuk kebetulan yang tidak akurat bekerja di sujest, sehingga kandidat dapat, misalnya, hanya berisi satu kata dari yang dimasukkan oleh pengguna; atau pengguna dapat membuat kesalahan ketik, dan prompt pertama tidak akan pernah sama persis dengan inputnya.
Tentu saja, meninggalkan seorang prerender dengan ketidaksempurnaan seperti itu memalukan, bahkan jika itu berguna. Saya terutama tersinggung oleh masalah dengan kata-kata petunjuk. Saya menganggap pengenalan tips kata-kata dalam pencarian mobile Yandex menjadi salah satu implementasi terbaik saya selama saya bekerja di perusahaan, tetapi di sini prerender tidak tahu bagaimana bekerja dengan mereka! Malu, bukan sebaliknya.
Pertama-tama, kami memperbaiki masalah ketidakstabilan classifier. Solusinya dipilih sangat sederhana: bahkan jika classifier mengembalikan prediksi negatif, kami tidak berhenti memuat kandidat sebelumnya. Ini membantu untuk menyimpan permintaan tambahan, karena ketika kandidat yang sama kembali lain kali, Anda tidak perlu mengunduh masalah yang terkait lagi. Pada saat yang sama, ini memungkinkan Anda untuk memuat hasil lebih cepat, karena kandidat diunduh pada saat penggolong pertama kali bekerja untuknya.
Kemudian tibalah giliran petunjuk pepatah. Server sagest adalah daemon tanpa kewarganegaraan, jadi sulit untuk mengimplementasikan logika yang terkait dengan pemrosesan kandidat sebelumnya untuk pengguna yang sama. Untuk mencari prompt secara bersamaan untuk permintaan pengguna dan permintaan pengguna tanpa spasi tambahan berarti sebenarnya menggandakan RPS dengan daemon sajest, jadi ini juga bukan pilihan yang baik. Akibatnya, kami melakukan ini: klien mengirimkan parameter khusus pada teks kandidat, yang sedang memuat sekarang; jika kandidat ini, hingga spasi, mirip dengan input pengguna, kami memberikannya, bahkan jika kandidat untuk input saat ini telah berubah.
Setelah rilis ini, akhirnya menjadi mungkin untuk memasukkan pertanyaan menggunakan kata-demi-kata dan menikmati prefetch! Cukup lucu bahwa sebelum rilis ini, hanya pengguna yang selesai memasukkan permintaan mereka menggunakan keyboard, tanpa sjest, menggunakan prefetch.
Akhirnya, kami menyelesaikan masalah ketiga dengan bantuan ML: faktor tambahan tentang sumber petunjuk, kebetulan dengan input pengguna; selain itu, berkat peluncuran pertama, kami dapat mengumpulkan lebih banyak statistik dan belajar dari data bulanan.
4. Apa hasilnya?
Masing-masing rilis ini menghasilkan peningkatan unduhan instan puluhan persen. Bagian terbaiknya adalah kami mampu meningkatkan kinerja prerender lebih dari dua kali, praktis tanpa menyentuh bagian tentang pembelajaran mesin, tetapi hanya meningkatkan fisika proses. Ini adalah pelajaran penting: seringkali kualitas classifier bukan hambatan dalam produk, tetapi peningkatannya adalah tugas yang paling menarik dan oleh karena itu pengembangan terganggu olehnya.
Sayangnya, SERP yang dimuat secara instan bukan merupakan keberhasilan yang lengkap; output yang dimuat masih perlu dirender , yang tidak terjadi secara instan. Jadi kami masih harus bekerja untuk lebih baik mengonversi unduhan data instan ke rendering instan hasil pencarian.
Untungnya, implementasi yang diterapkan sudah memungkinkan kita untuk berbicara tentang pre-renderer sebagai fitur yang cukup stabil; kami juga menguji implementasi yang dijelaskan dalam klausa 2: semuanya bersama-sama juga mengarah pada fakta bahwa pengguna sendiri mulai membuat sesi pencarian lebih sering. Ini adalah pelajaran lain yang bermanfaat: peningkatan signifikan dalam kecepatan layanan secara statistik dapat secara signifikan mempengaruhi retensi layanan.
Dalam video di bawah ini Anda dapat melihat bagaimana prerender sekarang bekerja di ponsel saya.