Membuat keterampilan stateful untuk Alice pada fungsi tanpa server Yandex.Cloud dan Python

Mari kita mulai dengan beritanya. Kemarin Yandex.Cloud mengumumkan peluncuran layanan komputasi tanpa server Fungsi Cloud Yandex. Artinya: Anda hanya menulis kode layanan Anda (misalnya, aplikasi web atau chatbot), dan Cloud sendiri yang membuat dan memelihara mesin virtual di tempat ia berjalan, dan bahkan mereplikasinya jika bebannya meningkat. Anda tidak perlu berpikir sama sekali, ini sangat nyaman. Dan pembayaran hanya berlaku pada saat perhitungan.

Namun, ada pula yang tidak membayar sama sekali. Inilah para pengembangnya Keterampilan eksternal Alice, yaitu chatbots yang terpasang di dalamnya. Pengembang mana pun dapat menulis, menghosting, dan mendaftarkan keterampilan tersebut, dan mulai saat ini keterampilan bahkan tidak perlu dihosting — cukup unggah kode mereka ke cloud dalam bentuk fungsi tanpa server yang sama.

Namun ada beberapa nuansa. Pertama, kode hewan peliharaan Anda mungkin memerlukan beberapa ketergantungan, dan tidak mudah untuk menyeretnya ke Cloud. Kedua, chatbot normal apa pun perlu menyimpan status dialog di suatu tempat (oleh karena itu stateful); bagaimana cara melakukannya dalam fungsi tanpa server dengan cara termudah? Ketiga, bagaimana Anda bisa menulis keterampilan cepat-kotor untuk Alice atau bahkan semacam bot dengan plot yang bukan nol? Sebenarnya, artikel tentang nuansa ini.

Membuat keterampilan stateful untuk Alice pada fungsi tanpa server Yandex.Cloud dan Python

persiapan moral

Bagi yang tidak sabar: Saya mengumpulkan dependensi yang diperlukan dengan makefile sebelum mengunggah fungsi ke cloud, saya menyimpan status dialog di Yandex Object Storage (mendukung API S3), dan saya menggunakan perpustakaan saya sendiri untuk mengelola dialog tgalice. Hasilnya, ternyata seperti itu keterampilan demo. Dan sekarang mari kita menganalisis semua ini lebih detail.

Bagi mereka yang tidak terlalu sabar, sebelum menyelami cerita saya yang rumit, saya sangat menyarankan untuk memulai dari yang sederhana. Yaitu, membuat fungsi echobot file tunggal, mendaftar dan mengujinya di konsol pengembang Dialog; detail - masuk Dialog Blog и dokumentasi awan. Dan baru kemudian mulai.

Jika ingin segera merasakan apa yang kita perjuangkan, tanyakan pada Alice'aktifkan keterampilan "Horoskop IT"'. Dialog berikut harus dilakukan:

Alice: Halo! Anda berada dalam keterampilan "horoskop IT". Ucapkan "Mulai" untuk mengetahui apa yang dijanjikan bintang kepada Anda.
Pengguna: Mulai
A: Silakan sebutkan nama Anda.
Yu: Vasisuali
A: Sekarang beritahu saya tahun lahirmu. Hanya empat digit, tidak lebih.
Yu: kedua
J: Silakan coba lagi. Sebutkan tahun lahir Anda - empat digit.
Yu: 2002
Besar! Sekarang beri nama bulan kelahiran Anda.
Yu: Februari
Besar! Terakhir, beri tahu saya tanggal lahir Anda - hanya sebuah angka, hanya satu atau dua digit.
Yu: 18
A: Terima kasih, Vasual! Sekarang kami tahu: Anda berusia 17 tahun dan Anda seorang Aquarius. Di sini Anda tentu saja beruntung! Bintang-bintang memberitahumu а что говорят звёзды, вы узнаете, запустив навык.

Masalahnya adalah untuk mempertahankan dialog sederhana sekalipun, Anda perlu mengingat nama dan tanggal lahir pengguna, dan dalam lingkungan tanpa server hal ini bukanlah hal yang sepele. Menyimpan konteks di RAM atau sebagai file di disk tidak akan berfungsi, karena Yandex.Cloud dapat menjalankan fungsi di beberapa mesin virtual secara bersamaan dan beralih di antara keduanya secara sewenang-wenang. Anda harus menggunakan semacam penyimpanan eksternal. Object Storage dipilih sebagai penyimpanan yang cukup murah dan sederhana langsung di Yandex.Cloud (mungkin cepat). Sebagai alternatif gratis, Anda dapat mencoba, misalnya, produk gratis Mongi mendung suatu tempat yang jauh. Baik Object Storage (mendukung antarmuka S3) dan Mongo memiliki pembungkus Python yang nyaman.

Masalah lainnya adalah untuk masuk ke Object Storage, MongoDB, dan database atau penyimpanan data lainnya, Anda memerlukan beberapa dependensi eksternal yang perlu Anda unggah ke Yandex Functions bersama dengan kode fungsi Anda. Dan saya ingin melakukannya dengan nyaman. Ini benar-benar nyaman (seperti di heroku), sayangnya, ini tidak akan berfungsi, tetapi Anda dapat menciptakan kenyamanan dasar dengan menulis skrip untuk membangun lingkungan (membuat file).

Bagaimana memulai keterampilan horoskop

  1. Bersiaplah: buka beberapa mesin dengan Linux. Pada prinsipnya, Anda mungkin dapat bekerja dengan Windows juga, tetapi kemudian Anda harus membayangkan peluncuran makefile. Dan bagaimanapun juga, Anda memerlukan setidaknya 3.6 Python yang terinstal.
  2. Klon dari github contoh keterampilan horoskop.
  3. Daftar di Ya.Cloud: https://cloud.yandex.ru
  4. Buat sendiri dua ember Penyimpanan Objek, panggil mereka dengan nama apa pun {BUCKET NAME} и tgalice-test-cold-storage (nama tengah ini sekarang di-hardcode menjadi main.py contoh saya). Bucket pertama hanya diperlukan untuk penerapan, bucket kedua untuk menyimpan status dialog.
  5. membuat akun layanan, beri dia peran editor, dan dapatkan kredensial statis untuk itu {KEY ID} и {KEY VALUE} - kami akan menggunakannya untuk merekam keadaan dialog. Semua ini diperlukan agar fungsi dari Ya.Cloud dapat mengakses penyimpanan dari Ya.Cloud. Suatu hari nanti, saya berharap, otorisasi akan menjadi otomatis, tetapi untuk saat ini - begitu.
  6. (Opsional) instal antarmuka baris perintah yc. Anda juga dapat membuat fungsi melalui antarmuka web, tetapi CLI bagus karena segala macam inovasi muncul lebih cepat.
  7. Sekarang Anda sebenarnya dapat menyiapkan perakitan dependensi: jalankan pada baris perintah dari folder dengan contoh keterampilan make all. Banyak perpustakaan (kebanyakan, seperti biasa, tidak diperlukan) akan dipasang di folder tersebut dist.
  8. Isi dengan pena ke dalam Object Storage (ke dalam ember {BUCKET NAME}) arsip yang diperoleh pada langkah sebelumnya dist.zip. Jika diinginkan, Anda juga dapat melakukan ini dari baris perintah, misalnya menggunakan AWS CLI.
  9. Buat fungsi tanpa server melalui antarmuka web atau menggunakan utilitas yc. Untuk utilitas, perintahnya akan terlihat seperti ini:

yc serverless function version create
    --function-name=horoscope
    --environment=AWS_ACCESS_KEY_ID={KEY ID},AWS_SECRET_ACCESS_KEY={KEY VALUE}
    --runtime=python37
    --package-bucket-name={BUCKET NAME}
    --package-object-name=dist.zip
    --entrypoint=main.alice_handler
    --memory=128M
    --execution-timeout=3s

Saat membuat fungsi secara manual, semua parameter diisi dengan cara yang sama.

Sekarang fungsi yang Anda buat dapat diuji melalui konsol pengembang, lalu diselesaikan dan dipublikasikan keterampilannya.

Membuat keterampilan stateful untuk Alice pada fungsi tanpa server Yandex.Cloud dan Python

Apa yang ada di balik terpal

Makefile sebenarnya berisi skrip yang cukup sederhana untuk menginstal dependensi dan memasukkannya ke dalam arsip. dist.zip, sesuatu seperti ini:

mkdir -p dist/
pip3 install -r requirements.txt --target dist/ 
cp main.py dist/main.py
cp form.yaml dist/form.yaml
cd dist && zip --exclude '*.pyc' -r ../dist.zip ./*

Sisanya adalah beberapa alat sederhana yang dibungkus dalam perpustakaan tgalice. Proses pengisian data pengguna dijelaskan oleh config form.yaml:

form_name: 'horoscope_form'
start:
  regexp: 'старт|нач(ать|ни)'
  suggests:
    - Старт
fields:
  - name: 'name'
    question: Пожалуйста, назовите своё имя.
  - name: 'year'
    question: Теперь скажите мне год вашего рождения. Только четыре цифры, ничего лишнего.
    validate_regexp: '^[0-9]{4}$'
    validate_message: Пожалуйста, попробуйте ещё раз. Назовите год вашего рождения - четыре цифры.
  - name: 'month'
    question: Замечательно! Теперь назовите месяц вашего рождения.
    options:
      - январь
     ...
      - декабрь
    validate_message: То, что вы назвали, не похоже на месяц. Пожалуйста, назовите месяц вашего рождения, без других слов.
  - name: 'day'
    question: Отлично! Наконец, назовите мне дату вашего рождения - только число, всего одна или две цифры.
    validate_regexp: '[0123]?d$'
    validate_message: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

Kelas python mengambil alih pekerjaan menguraikan konfigurasi ini dan menghitung hasil akhirnya

class CheckableFormFiller(tgalice.dialog_manager.form_filling.FormFillingDialogManager):
    SIGNS = {
        'январь': 'Козерог',
        ...
    }

    def handle_completed_form(self, form, user_object, ctx):
        response = tgalice.dialog_manager.base.Response(
            text='Спасибо, {}! Теперь мы знаем: вам {} лет, и вы {}. n'
                 'Вот это вам, конечно, повезло! Звёзды говорят вам: {}'.format(
                form['fields']['name'],
                2019 - int(form['fields']['year']),
                self.SIGNS[form['fields']['month']],
                random.choice(FORECASTS),
            ),
            user_object=user_object,
        )
        return response

Lebih tepatnya, kelas dasar FormFillingDialogManager terlibat dalam pengisian "formulir", dan metode kelas anak handle_completed_form memberitahu apa yang harus dilakukan ketika dia siap.

Selain alur utama dialog pengguna ini, perlu juga untuk menyapa pengguna, serta mengeluarkan bantuan pada perintah "bantuan" dan pelepasan dari keterampilan pada perintah "keluar". Untuk ini di tgalice ada juga templatnya, jadi keseluruhan pengelola dialog terdiri dari beberapa bagian:

dm = tgalice.dialog_manager.CascadeDialogManager(
    tgalice.dialog_manager.GreetAndHelpDialogManager(
        greeting_message=DEFAULT_MESSAGE,
        help_message=DEFAULT_MESSAGE,
        exit_message='До свидания, приходите в навык "Айтишный гороскоп" ещё!'
    ),
    CheckableFormFiller(`form.yaml`, default_message=DEFAULT_MESSAGE)
)

CascadeDialogManager cara kerjanya sederhana: ia mencoba menerapkan semua komponennya pada keadaan dialog saat ini secara bergantian, dan memilih komponen pertama yang relevan.

Sebagai respons terhadap setiap pesan, pengelola dialog mengembalikan objek python Response, yang kemudian dapat diubah menjadi teks biasa, atau menjadi pesan di Alice atau Telegram - tergantung di mana bot berjalan; itu juga berisi perubahan status dialog yang perlu disimpan. Semua dapur ini ditangani oleh kelas lain, DialogConnector, jadi skrip langsung untuk memulai keterampilan di Yandex Functions terlihat seperti ini:

...
session = boto3.session.Session()
s3 = session.client(
    service_name='s3',
    endpoint_url='https://storage.yandexcloud.net',
    aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
    aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
    region_name='ru-central1',
)
storage = tgalice.session_storage.S3BasedStorage(s3_client=s3, bucket_name='tgalice-test-cold-storage')
connector = tgalice.dialog_connector.DialogConnector(dialog_manager=dm, storage=storage)
alice_handler = connector.serverless_alice_handler

Seperti yang Anda lihat, sebagian besar kode ini membuat koneksi ke antarmuka Object Storage S3. Bagaimana koneksi ini digunakan secara langsung, dapat Anda baca dalam kode tgalice.
Baris terakhir membuat suatu fungsi alice_handler - yang kami pesan untuk menarik Yandex.Cloud saat kami mengatur parameternya --entrypoint=main.alice_handler.

Faktanya, itu saja. Makefile untuk membangun, Penyimpanan Objek seperti S3 untuk penyimpanan konteks, dan perpustakaan python tgalice. Ditambah dengan fitur tanpa server dan ekspresi python, ini cukup untuk mengembangkan keterampilan orang yang sehat.

Anda mungkin bertanya mengapa Anda perlu membuat tgalice? Semua kode membosankan yang mentransfer JSON dari permintaan ke respons dan dari penyimpanan ke memori dan sebaliknya terletak di dalamnya. Ada juga aplikasi reguler, yang berfungsi untuk memahami bahwa "Februari" mirip dengan "Februari", dan NLU lainnya untuk masyarakat miskin. Menurut ide saya, ini seharusnya sudah cukup untuk membuat sketsa prototipe keterampilan dalam file yaml tanpa terlalu terganggu oleh detail teknis.

Jika Anda menginginkan NLU yang lebih serius, Anda dapat menyesuaikannya dengan keahlian Anda Rasa или dalamPavlov, tetapi menyiapkannya memerlukan tarian tambahan dengan rebana, terutama pada mode tanpa server. Jika Anda tidak ingin membuat kode sama sekali, Anda harus menggunakan konstruktor tipe visual logika tujuan. Saat membuat tgalice, saya memikirkan semacam jalur perantara. Mari lihat apa yang terjadi.

Nah, sekarang bergabunglah Obrolan pengembang keterampilan Aliy, Baca dokumentasidan menciptakan luar biasa keterampilan!

Sumber: www.habr.com

Tambah komentar