Mencipta kemahiran stateful untuk Alice menggunakan fungsi tanpa pelayan Yandex.Cloud dan Python

Mari kita mulakan dengan berita. Semalam Yandex.Cloud mengumumkan pelancaran perkhidmatan pengkomputeran tanpa pelayan Fungsi Awan Yandex. Ini bermakna: anda hanya menulis kod untuk perkhidmatan anda (contohnya, aplikasi web atau chatbot), dan Cloud itu sendiri mencipta dan mengekalkan mesin maya di mana ia dijalankan, malah mereplikasinya jika beban meningkat. Anda tidak perlu berfikir sama sekali, ia sangat mudah. Dan bayaran hanya untuk masa pengiraan.

Walau bagaimanapun, sesetengah mungkin tidak membayar sama sekali. Ini adalah pemaju Kemahiran luar Alice, iaitu chatbots terbina di dalamnya. Mana-mana pembangun boleh menulis, mengehos dan mendaftar kemahiran sedemikian, dan mulai hari ini kemahiran itu tidak perlu dihoskan - cuma muat naik kod mereka ke awan dalam bentuk fungsi tanpa pelayan yang sama.

Tetapi terdapat beberapa nuansa. Pertama, kod pit anda mungkin memerlukan beberapa kebergantungan, dan menyeretnya ke dalam Awan bukanlah perkara remeh. Kedua, mana-mana chatbot biasa perlu menyimpan keadaan dialog di suatu tempat (oleh itu stateful); Apakah cara paling mudah untuk melakukan ini dalam fungsi tanpa pelayan? Ketiga, bagaimanakah anda boleh menulis kemahiran cepat dan kotor untuk Alice atau pun sejenis bot dengan plot bukan sifar? Artikel itu, sebenarnya, mengenai nuansa ini.

Mencipta kemahiran stateful untuk Alice menggunakan fungsi tanpa pelayan Yandex.Cloud dan Python

Persediaan akhlak

Bagi yang tidak sabar: Saya mengumpul kebergantungan yang diperlukan dengan makefile sebelum memuat naik fungsi ke awan, saya menyimpan keadaan dialog dalam Penyimpanan Objek Yandex (ia menyokong API S3), dan saya menggunakan perpustakaan saya sendiri untuk mengurus dialog tgalice. Akhirnya ternyata apa-apa kemahiran demo. Sekarang mari kita lihat semua ini dengan lebih terperinci.

Bagi mereka yang kurang sabar, sebelum menyelami kisah saya tentang kerumitan, saya sangat mengesyorkan bermula dengan sesuatu yang mudah. Iaitu, buat fungsi echobot satu fail, daftar dan uji dalam konsol pembangun Dialog; butiran - dalam Blog dialog и Dokumentasi awan. Dan barulah bermula.

Jika anda ingin segera merasakan apa yang kami perjuangkan di sini, tanya Alice 'dayakan kemahiran "horoskop IT".'. Dialog yang serupa dengan yang berikut harus berlaku:

Alice: Hello! Anda berada dalam kemahiran "Horoskop IT". Sebut "Mula" untuk mengetahui perkara yang dijanjikan bintang kepada anda.
Pengguna: Mula
A: Sila nyatakan nama anda
Yu: Vasisualiy
A: Sekarang beritahu saya tahun kelahiran awak. Hanya empat digit, tiada tambahan.
Yu: kedua
A: Sila cuba lagi. Masukkan tahun kelahiran anda - empat digit.
Yu: 2002
Bagus! Sekarang namakan bulan kelahiran anda.
Yu: Februari
Bagus! Akhir sekali, beritahu saya tarikh lahir anda - hanya nombor, hanya satu atau dua digit.
Yu: 18
A: Terima kasih, Vasisualiy! Sekarang kita tahu: anda berumur 17 tahun dan Aquarius. Sudah tentu, anda bertuah! Bintang memberitahu anda: а что говорят звёзды, вы узнаете, запустив навык.

Masalahnya ialah untuk mengekalkan walaupun dialog yang begitu mudah, anda perlu mengingati nama pengguna dan tarikh lahir, dan dalam persekitaran fungsi tanpa pelayan ini bukan perkara remeh. Ia tidak mungkin untuk menyimpan konteks dalam RAM atau sebagai fail pada cakera, kerana Yandex.Cloud boleh menjalankan fungsi pada beberapa mesin maya pada masa yang sama dan bertukar antara mereka sesuka hati. Anda perlu menggunakan beberapa jenis storan luaran. Storan Objek telah dipilih sebagai storan yang agak murah dan tidak rumit secara langsung dalam Yandex.Cloud (iaitu, mungkin pantas). Sebagai alternatif percuma, anda boleh mencuba, sebagai contoh, sekeping percuma Monga mendung tempat yang jauh. Terdapat pembalut Python yang mudah untuk Penyimpanan Objek (yang menyokong antara muka S3) dan Mongo.

Masalah lain ialah untuk mengakses Storan Objek, MongoDB dan mana-mana pangkalan data atau stor data lain, anda memerlukan beberapa kebergantungan luaran yang perlu dimuat naik ke Fungsi Yandex bersama-sama dengan kod fungsi anda. Dan saya ingin melakukan ini dengan mudah. Malangnya, ia tidak akan memudahkan sepenuhnya (seperti pada Heroku), tetapi beberapa keselesaan asas boleh dibuat dengan menulis skrip untuk membina persekitaran (membuat fail).

Bagaimana untuk melancarkan kemahiran horoskop

  1. Sediakan: pergi ke beberapa mesin dengan Linux. Pada dasarnya, anda mungkin boleh bekerja dengan Windows juga, tetapi kemudian anda perlu melakukan sedikit keajaiban dengan melancarkan makefile. Dan dalam apa jua keadaan, anda memerlukan sekurang-kurangnya Python 3.6 dipasang.
  2. Klonkannya daripada Github contoh kemahiran horoskop.
  3. Daftar dalam Y.Cloud: https://cloud.yandex.ru
  4. Buat diri anda dua baldi Penyimpanan Objek, panggil mereka dengan sebarang nama {BUCKET NAME} и tgalice-test-cold-storage (nama kedua ini kini dikodkan dengan keras main.py contoh saya). Baldi pertama akan diperlukan hanya untuk penggunaan, yang kedua - untuk menyimpan keadaan dialog.
  5. mewujudkan akaun perkhidmatan, berikan dia peranan editor, dan dapatkan kelayakan statik untuknya {KEY ID} и {KEY VALUE} — kami akan menggunakannya untuk merekodkan keadaan dialog. Semua ini diperlukan supaya fungsi daripada Ya.Cloud boleh mengakses storan daripada Ya.Cloud. Suatu hari nanti, saya harap, kebenaran akan menjadi automatik, tetapi buat masa ini ia seperti itu.
  6. (Pilihan) pasang antara muka baris arahan yc. Anda juga boleh mencipta fungsi melalui antara muka web, tetapi CLI bagus kerana pelbagai inovasi muncul di dalamnya dengan lebih pantas.
  7. Kini anda sebenarnya boleh menyediakan pemasangan pergantungan: jalankan pada baris arahan dari folder dengan contoh kemahiran make all. Sekumpulan perpustakaan (kebanyakannya, seperti biasa, tidak diperlukan) akan dipasang dalam folder dist.
  8. Tuangkan ke dalam Penyimpanan Objek dengan tangan (ke dalam baldi {BUCKET NAME}) arkib yang diperolehi dalam langkah sebelumnya dist.zip. Jika dikehendaki, anda boleh melakukan ini dari baris arahan, sebagai contoh, menggunakan AWS CLI.
  9. Cipta fungsi tanpa pelayan melalui antara muka web atau menggunakan utiliti yc. Untuk utiliti, arahan akan kelihatan 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

Apabila mencipta fungsi secara manual, semua parameter diisi dengan cara yang sama.

Kini fungsi yang anda buat boleh diuji melalui konsol pembangun, dan kemudian kemahiran itu boleh dipertingkatkan dan diterbitkan.

Mencipta kemahiran stateful untuk Alice menggunakan fungsi tanpa pelayan Yandex.Cloud dan Python

Apa yang ada di bawah tudung

Makefile sebenarnya mengandungi skrip yang agak mudah untuk memasang kebergantungan dan meletakkannya ke dalam arkib dist.zip, kira-kira 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 ./*

Selebihnya ialah beberapa alat mudah yang dibungkus dalam perpustakaan tgalice. Proses mengisi data pengguna diterangkan oleh konfigurasi 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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

Kerja menghuraikan konfigurasi ini dan mengira hasil akhir diambil alih oleh kelas Python

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 tepat lagi, kelas asas FormFillingDialogManager berurusan dengan mengisi "borang", dan kaedah kelas kanak-kanak handle_completed_form memberitahunya apa yang perlu dilakukan apabila dia sudah bersedia.

Sebagai tambahan kepada aliran utama dialog ini, pengguna juga mesti disambut, serta diberi bantuan menggunakan arahan "bantuan" dan dilepaskan daripada kemahiran menggunakan arahan "keluar". Untuk tujuan ini dalam tgalice Terdapat juga templat, jadi keseluruhan pengurus dialog terdiri daripada kepingan:

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 Ia berfungsi dengan mudah: ia cuba menggunakan semua komponennya pada keadaan semasa dialog secara bergilir-gilir, dan memilih yang pertama yang sesuai.

Pengurus dialog mengembalikan objek Python sebagai respons kepada setiap mesej. Response, yang kemudiannya boleh ditukar kepada teks biasa, atau menjadi mesej dalam Alice atau Telegram - bergantung pada tempat bot sedang berjalan; ia juga mengandungi keadaan berubah dialog yang perlu disimpan. Seluruh dapur ini dikendalikan oleh kelas lain, DialogConnector, jadi skrip langsung untuk melancarkan kemahiran pada Fungsi Yandex kelihatan 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, kebanyakan kod ini mencipta sambungan ke antara muka S3 Penyimpanan Objek. Anda boleh membaca bagaimana sambungan ini digunakan secara langsung dalam kod tgalice.
Baris terakhir mencipta fungsi alice_handler — yang sama yang kami suruh Yandex.Cloud tarik apabila kami menetapkan parameter --entrypoint=main.alice_handler.

Itu sahaja, sebenarnya. Makefiles untuk pemasangan, Storan Objek seperti S3 untuk menyimpan konteks dan perpustakaan Python tgalice. Digabungkan dengan fungsi tanpa pelayan dan ekspresif Python, ini sudah cukup untuk membangunkan kemahiran manusia yang sihat.

Anda mungkin bertanya mengapa perlu mencipta tgalice? Semua kod membosankan yang memindahkan JSON daripada permintaan kepada respons dan dari storan ke memori dan kembali terletak di dalamnya. Terdapat juga aplikasi kod biasa, fungsi untuk memahami bahawa "Februari" adalah serupa dengan "Februari", dan NLU lain untuk golongan miskin. Menurut idea saya, ini sepatutnya sudah mencukupi supaya anda boleh melakar prototaip kemahiran dalam fail yaml tanpa terlalu terganggu oleh butiran teknikal.

Jika anda mahukan NLU yang lebih serius, anda boleh lampirkan pada kemahiran anda Rasa atau DeepPavlov, tetapi menetapkannya akan memerlukan tarian tambahan dengan tamborin, terutamanya tanpa pelayan. Jika anda tidak berasa seperti pengekodan sama sekali, anda harus menggunakan pembina visual seperti Aimylogic. Apabila mencipta tgalice, saya memikirkan beberapa jenis laluan perantaraan. Mari lihat apa yang datang dari ini.

Nah, sekarang sertai sembang pembangun kemahiran alice, baca dokumentasi, dan cipta indah kemahiran!

Sumber: www.habr.com

Tambah komen