Stvaranje vještine praćenja stanja za Alice na funkcijama Yandex.Cloud i Python bez poslužitelja

Počnimo s novostima. Yandex.Cloud je jučer najavio pokretanje računalne usluge bez poslužitelja Yandex Cloud funkcije. To znači: vi samo pišete kod svoje usluge (na primjer, web aplikacije ili chatbota), a Cloud sam stvara i održava virtualne strojeve na kojima radi, pa ih čak i replicira ako se opterećenje poveća. Ne morate uopće razmišljati, vrlo je zgodno. I plaćanje ide samo za vrijeme obračuna.

Međutim, neki ljudi možda uopće neće platiti. Ovo su programeri Aliceine vanjske vještine, odnosno u njega ugrađeni chatbotovi. Svaki razvojni programer može napisati, ugostiti i registrirati takvu vještinu, a od danas vještine ne moraju čak ni biti udomljene - samo prenesite njihov kod u oblak u obliku ista funkcija bez poslužitelja.

Ali postoji nekoliko nijansi. Prvo, kod vašeg ljubimca može zahtijevati neke ovisnosti, a nije trivijalno povući ih u oblak. Drugo, svaki normalni chatbot mora negdje pohraniti stanje dijaloga (dakle, stanje); kako to najlakše učiniti u funkciji bez poslužitelja? Treće, kako možete napisati brzu i prljavu vještinu za Alice ili čak neku vrstu bota sa zapletom koji nije nula? O tim nijansama, zapravo, članak.

Stvaranje vještine praćenja stanja za Alice na funkcijama Yandex.Cloud i Python bez poslužitelja

moralna priprema

Za nestrpljive: prikupljam potrebne ovisnosti s makefileom prije učitavanja funkcije u oblak, pohranjujem stanje dijaloškog okvira u Yandex Object Storage (podržava S3 API) i koristim vlastitu biblioteku za upravljanje dijaloškim okvirom tgalice. Kao rezultat toga, ispada takav demo vještina. A sada analizirajmo sve ovo malo detaljnije.

Za malo manje nestrpljive, prije nego što se upuste u moju priču o složenosti, toplo preporučujem da započnu s jednostavnim. Naime, izradite single-file echobot funkciju, registrirajte je i testirajte u Dialog developer konzoli; detalji - u Blog Dijalozi и dokumentacija u oblaku. I tek onda počnite.

Ako želite odmah osjetiti za što se borimo, pitajte Alice'uključi vještinu "IT horoskop"'. Trebao bi se održati sljedeći dijalog:

Alice: Bok! Vi ste u vještini "IT horoskop". Recite "Start" i saznajte što vam zvijezde obećavaju.
Korisnik: Start
O: Molimo navedite svoje ime.
Yu: Vasisualy
O: Sad mi reci godinu svog rođenja. Samo četiri znamenke, ništa više.
Yu: drugo
O: Molimo pokušajte ponovno. Navedite godinu rođenja - četiri znamenke.
Yu: 2002
O: Sjajno! Sada navedite mjesec svog rođenja.
Yu: Veljača
O: Izvrsno! Na kraju, reci mi svoj datum rođenja - samo broj, samo jedna ili dvije znamenke.
Yu: 18
O: Hvala, Vasisual! Sada znamo: imate 17 godina i Vodenjak ste. Ovdje ste, naravno, sretni! Zvijezde vam govore а что говорят звёзды, вы узнаете, запустив навык.

Problem je u tome što za održavanje čak i tako jednostavnog dijaloga morate zapamtiti ime i datum rođenja korisnika, a u okruženju bez poslužitelja to nije trivijalno. Neće uspjeti pohraniti kontekst u RAM ili kao datoteku na disku, jer Yandex.Cloud može pokrenuti funkciju na nekoliko virtualnih računala u isto vrijeme i proizvoljno se prebacivati ​​između njih. Morat ćete koristiti neku vrstu vanjske pohrane. Objektna pohrana odabrana je kao prilično jeftina i jednostavna pohrana izravno u Yandex.Cloudu (što je vjerojatno brzo). Kao besplatnu alternativu možete isprobati npr. besplatni komad Oblačno Mongi negdje daleko. I Object Storage (podržava S3 sučelje) i Mongo imaju praktične Python omote.

Još jedan problem je taj da su vam potrebne neke vanjske ovisnosti koje morate prenijeti u Yandex Functions zajedno sa svojim funkcijskim kodom da biste otišli na Object Storage, MongoDB i bilo koju drugu bazu podataka ili pohranu podataka. I želio bih to učiniti udobno. Potpuno je prikladno (kao na herokuu), nažalost, neće raditi, ali možete stvoriti neku osnovnu udobnost pisanjem skripte za izgradnju okruženja (make file).

Kako započeti vještinu horoskopa

  1. Pripremite se: idite na neki stroj s Linuxom. U principu, vjerojatno možete raditi i sa sustavom Windows, ali tada morate dočarati pokretanje makefilea. U svakom slučaju, trebat će vam barem 3.6 instalirani Python.
  2. Kloniraj s githuba primjer horoskopske vještine.
  3. Registrirajte se u Ya.Cloud: https://cloud.yandex.ru
  4. Napravite sebi dvije kante Pohrana predmeta, zovite ih bilo kojim imenom {BUCKET NAME} и tgalice-test-cold-storage (ovo srednje ime je sada tvrdo kodirano u main.py moj primjer). Prvi spremnik bit će potreban samo za implementaciju, drugi - za pohranjivanje dijaloških stanja.
  5. stvoriti servisni račun, dajte mu ulogu editor, i dobiti statičke vjerodajnice za to {KEY ID} и {KEY VALUE} - pomoću njih ćemo zabilježiti stanje dijaloga. Sve je to potrebno kako bi funkcija iz Ya.Clouda mogla pristupiti pohrani iz Ya.Clouda. Jednom će, nadam se, autorizacija postati automatska, ali za sada - tako.
  6. (Izborno) instalirajte sučelje naredbenog retka yc. Također možete kreirati funkciju putem web sučelja, ali CLI je dobar jer se u njemu brže pojavljuju sve vrste inovacija.
  7. Sada zapravo možete pripremiti sklop ovisnosti: pokrenite na naredbenom retku iz mape s primjerom vještine make all. Hrpa biblioteka (uglavnom, kao i obično, nepotrebnih) bit će instalirana u mapi dist.
  8. Napunite olovkama u Object Storage (u kantu {BUCKET NAME}) arhiva dobivena u prethodnom koraku dist.zip. Ako želite, to možete učiniti i iz naredbenog retka, na primjer, koristeći AWS CLI.
  9. Stvorite funkciju bez poslužitelja putem web sučelja ili pomoću uslužnog programa yc. Za uslužni program, naredba će izgledati ovako:

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

Prilikom ručnog kreiranja funkcije, svi parametri se popunjavaju na isti način.

Sada se funkcija koju ste izradili može testirati putem konzole za razvojne programere, a zatim finalizirati i objaviti vještinu.

Stvaranje vještine praćenja stanja za Alice na funkcijama Yandex.Cloud i Python bez poslužitelja

Što je ispod haube

Makefile zapravo sadrži prilično jednostavnu skriptu za instaliranje ovisnosti i njihovo stavljanje u arhivu. dist.zip, nešto kao ovo:

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 ./*

Ostatak je nekoliko jednostavnih alata umotanih u biblioteku tgalice. Proces popunjavanja korisničkih podataka opisuje 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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

Klasa python preuzima posao analiziranja ove konfiguracije i izračunavanja konačnog rezultata

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

Točnije, osnovna klasa FormFillingDialogManager bavi se popunjavanjem "formulara", a metodom djetetove klase handle_completed_form govori što treba učiniti kada bude spremna.

Osim ovog glavnog tijeka korisničkog dijaloga, potrebno je i pozdraviti korisnika, kao i izdati pomoć na naredbu "pomoć" i otpustiti skill na naredbu "izlaz". Za ovo u tgalice tu je i predložak, tako da je cijeli upravitelj dijaloga sastavljen od dijelova:

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 radi jednostavno: pokušava primijeniti na trenutno stanje dijaloga sve njegove komponente redom i odabire prvu relevantnu.

Kao odgovor na svaku poruku, upravitelj dijaloga vraća python objekt Response, koji se zatim može pretvoriti u običan tekst, ili u poruku u Alice ili Telegramu - ovisno o tome gdje je bot pokrenut; također sadrži promijenjeno stanje dijaloškog okvira koji treba spremiti. Cijelom ovom kuhinjom upravlja druga klasa, DialogConnector, tako da izravna skripta za pokretanje vještine na Yandex funkcijama izgleda ovako:

...
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

Kao što možete vidjeti, većina ovog koda stvara vezu sa sučeljem Object Storage S3. Kako se ova veza izravno koristi, možete pročitati u kodu tgalice.
Posljednji redak stvara funkciju alice_handler - onaj kojem smo naredili da povuče Yandex.Cloud kada smo postavili parametar --entrypoint=main.alice_handler.

To je, zapravo, sve. Makefile za izgradnju, S3-like Object Storage za kontekstnu pohranu i python knjižnica tgalice. Zajedno sa značajkama bez poslužitelja i ekspresivnošću pythona, to je dovoljno da se razvije vještina zdrave osobe.

Možete pitati zašto trebate stvarati tgalice? Sav dosadni kod koji prenosi JSON-ove od zahtjeva do odgovora i od pohrane do memorije i natrag leži u njemu. Tu je i redovita aplikacija, funkcija za razumijevanje da je "veljača" slična "veljača" i drugi NLU za siromašne. Prema mojoj ideji, ovo bi već trebalo biti dovoljno da se mogu skicirati prototipovi vještina u yaml datotekama bez da vas previše ometaju tehnički detalji.

Ako želite ozbiljniji NLU, možete ga zeznuti prema svojoj vještini Raša ili DeepPavlov, no njihovo postavljanje će zahtijevati dodatno plesanje uz tamburu, pogotovo na serverlessu. Ako vam se uopće ne da kodirati, trebali biste upotrijebiti konstruktor vizualnog tipa Aimylogic. Prilikom izrade tgalice razmišljao sam o nekakvom međuputu. Da vidimo što će se dogoditi.

Pa, sada se pridružite Chat programera Aliy vještina, čitati dokumentacijai stvarati nevjerojatne vještine!

Izvor: www.habr.com

Dodajte komentar