Kreiranje vještine za Alice pomoću funkcija Yandex.Cloud i Python bez servera

Počnimo s vijestima. Jučer je Yandex.Cloud najavio pokretanje računarske usluge bez servera Yandex Cloud funkcije. To znači: pišete samo kod za svoju uslugu (na primjer, web aplikaciju ili chatbot), a sam Cloud kreira i održava virtuelne mašine na kojima radi, pa čak ih i replicira ako se opterećenje poveća. Ne morate uopšte razmišljati, veoma je zgodno. A plaćanje je samo za obračunsko vrijeme.

Međutim, neki možda uopće neće platiti. Ovo su programeri Alisine vanjske vještine, odnosno chatbotovi ugrađeni u njega. Svaki programer može napisati, ugostiti i registrirati takvu vještinu, a od danas te vještine ne moraju ni biti hostirane - samo prenesite njihov kod u oblak u obliku istu funkciju bez servera.

Ali postoji nekoliko nijansi. Prvo, vaš pit kod može zahtijevati neke ovisnosti, a njihovo prevlačenje u Cloud nije trivijalno. Drugo, svaki normalan chatbot mora negdje pohraniti stanje dijaloga (zato ima status); Koji je najlakši način da to učinite u funkciji bez servera? Treće, kako možete napisati brzu i prljavu vještinu za Alice ili čak neku vrstu bota sa zapletom koji nije nula? Članak je, zapravo, o ovim nijansama.

Kreiranje vještine za Alice pomoću funkcija Yandex.Cloud i Python bez servera

Moralna priprema

Za nestrpljive: prikupljam potrebne zavisnosti pomoću makefile-a prije postavljanja funkcije u oblak, pohranjujem stanje dijaloga u Yandex Object Storage (podržava S3 API) i koristim vlastitu biblioteku za upravljanje dijalogom tgalice. Na kraju se ispostavilo takav demo vještina. Pogledajmo sada sve ovo malo detaljnije.

Za one malo manje nestrpljive, prije nego što se upuste u moju priču o složenosti, toplo preporučujem da počnu s nečim jednostavnim. Naime, kreirajte funkciju echobot sa jednom datotekom, registrirajte je i testirajte je u Dialogs developer konzoli; detalji - in Dialogues blog и Dokumentacija u oblaku. I tek onda počnite.

Ako želite odmah osjetiti za šta se ovdje borimo, pitajte Alice'omogućiti vještinu “IT horoskop”.'. Trebalo bi da se desi dijalog sličan sledećem:

Alice: Zdravo! Nalazite se u vještini “IT horoskop”. Recite "Počni" da saznate šta vam zvezde obećavaju.
Korisnik: Start
O: Molimo navedite svoje ime
Yu: Vasisualiy
O: Sada mi reci godinu svog rođenja. Samo četiri cifre, ništa dodatno.
Yu: drugo
O: Molimo pokušajte ponovo. Unesite godinu svog rođenja - četiri cifre.
Yu: 2002
O: Odlično! Sada navedite svoj mjesec rođenja.
Yu: Februar
O: Odlično! Na kraju, recite mi svoj datum rođenja - samo broj, samo jednu ili dvije cifre.
Yu: 18
O: Hvala, Vasisualiy! Sada znamo: imate 17 godina i Vodolija. Pa, naravno, imate sreće! zvijezde ti govore: а что говорят звёзды, вы узнаете, запустив навык.

Problem je u tome što da biste održali čak i tako jednostavan dijalog, morate zapamtiti ime korisnika i datum rođenja, a u okruženju funkcija bez servera to nije trivijalno. Neće biti moguće pohraniti kontekst u RAM ili kao datoteku na disku, jer Yandex.Cloud može pokrenuti funkciju na nekoliko virtuelnih mašina u isto vrijeme i prebacivati ​​se između njih po želji. Morat ćete koristiti neku vrstu eksterne memorije. Skladište objekata odabrano je kao prilično jeftino i nekomplikovano skladište direktno u Yandex.Cloud (tj., vjerovatno brzo). Kao besplatnu alternativu, možete isprobati, na primjer, besplatni komad Oblačno Monga negde daleko. Postoje praktični omoti za Python i za Object Storage (koji podržava S3 interfejs) i za Mongo.

Drugi problem je taj što da biste pristupili Skladištu objekata, MongoDB-u i bilo kojoj drugoj bazi podataka ili skladištu podataka, potrebne su vam neke eksterne zavisnosti koje je potrebno učitati u Yandex funkcije zajedno sa kodom funkcije. I želio bih to učiniti na zgodan način. Nažalost, to neće biti potpuno zgodno (kao na Herokuu), ali neki osnovni komfor se može stvoriti pisanjem skripte za izgradnju okruženja (napravi datoteku).

Kako pokrenuti vještinu horoskopa

  1. Pripremite se: idite na neku mašinu sa Linuxom. U principu, vjerovatno možete raditi i sa Windowsom, ali tada ćete morati učiniti neku magiju s pokretanjem makefile-a. U svakom slučaju, trebat će vam instaliran barem Python 3.6.
  2. Klonirajte ga sa Githuba primjer vještine horoskopa.
  3. Registrirajte se u Y.Cloud: https://cloud.yandex.ru
  4. Napravite sebi dvije kante Object Storage, nazovite ih bilo kojim imenom {BUCKET NAME} и tgalice-test-cold-storage (ovo drugo ime je sada tvrdo kodirano u main.py moj primjer). Prva kantica će biti potrebna samo za implementaciju, druga - za pohranjivanje stanja dijaloga.
  5. stvoriti servisni račun, daj mu ulogu editor, i dobiti statičke vjerodajnice za to {KEY ID} и {KEY VALUE} — koristićemo ih za snimanje stanja dijaloga. Sve ovo je potrebno kako bi funkcija iz Ya.Clouda mogla pristupiti skladištu iz Ya.Clouda. Jednog dana, nadam se, autorizacija će postati automatska, ali za sada je tako.
  6. (Opcionalno) instalirajte interfejs komandne linije yc. Funkciju možete kreirati i preko web sučelja, ali CLI je dobar jer se u njemu brže pojavljuju sve vrste inovacija.
  7. Sada zapravo možete pripremiti sklop zavisnosti: pokrenite ga na komandnoj liniji iz fascikle sa primjerom vještine make all. Gomila biblioteka (uglavnom, kao i obično, nepotrebnih) će biti instalirana u folder dist.
  8. Ručno sipajte u skladište objekata (u kantu {BUCKET NAME}) arhiva dobijena u prethodnom koraku dist.zip. Ako želite, to možete učiniti iz komandne linije, na primjer, koristeći AWS CLI.
  9. Kreirajte funkciju bez servera 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 kreirali može testirati preko razvojne konzole, a zatim se vještina može poboljšati i objaviti.

Kreiranje vještine za Alice pomoću funkcija Yandex.Cloud i Python bez servera

Šta je ispod haube

Makefile zapravo sadrži prilično jednostavnu skriptu za instaliranje zavisnosti i njihovo stavljanje u arhivu dist.zip, otprilike ovako:

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

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

Posao raščlanjivanja ove konfiguracije i izračunavanja konačnog rezultata preuzima klasa 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

Tačnije, bazna klasa FormFillingDialogManager bavi se popunjavanjem „obrasca“ i metodom dječje klase handle_completed_form govori joj šta da radi kada bude spremna.

Pored ovog glavnog toka dijaloga, korisnika se takođe mora pozdraviti, kao i pružiti pomoć pomoću komande “help” i osloboditi se veštine pomoću komande “exit”. U tu svrhu u tgalice Postoji i predložak, tako da je cijeli menadžer 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 sve svoje komponente naizmjenično primijeniti na trenutno stanje dijaloga i bira prvu odgovarajuću.

Menadžer dijaloga vraća Python objekat kao odgovor na svaku poruku. Response, koji se zatim može pretvoriti u običan tekst, ili u poruku u Alice ili Telegramu - ovisno o tome gdje bot radi; takođe sadrži promenjeno stanje dijaloga koje treba sačuvati. Celom ovom kuhinjom upravlja druga klasa, DialogConnector, pa direktna 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 vidite, većina ovog koda stvara vezu sa S3 interfejsom Object Storage-a. Možete pročitati kako se ova veza direktno koristi kod tgalice.
Zadnji red kreira funkciju alice_handler — isti onaj za koji smo rekli Yandex.Cloud da povuče kada postavimo parametar --entrypoint=main.alice_handler.

To je sve, zapravo. Makefile za sklapanje, S3-ličnu Skladište objekata za pohranjivanje konteksta i Python biblioteku tgalice. U kombinaciji sa funkcijama bez servera i izražajnošću Pythona, ovo je dovoljno da se razvije zdrava ljudska vještina.

Možete pitati zašto je bilo potrebno kreirati tgalice? Sav dosadan kod koji prenosi JSON-ove sa zahtjeva na odgovor i iz skladišta u memoriju i natrag leži u njemu. Postoji i obična aplikacija koda, funkcija za razumijevanje da je “februar” sličan “februaru” i drugi NLU za siromašne. Prema mojoj zamisli, ovo bi već trebalo biti dovoljno da možete skicirati prototipove vještina u yaml datotekama bez da vas previše ometaju tehnički detalji.

Ako želite ozbiljniji NLU, možete ga povezati sa svojom vještinom Okusi ili DeepPavlov, ali njihovo postavljanje će zahtijevati dodatne plesove s tamburom, posebno na serveru bez servera. Ako vam se uopće ne sviđa kodiranje, trebali biste koristiti vizualni konstruktor poput Aimylogic. Kada sam stvarao tgalice, razmišljao sam o nekoj vrsti međuputa. Hajde da vidimo šta će biti od ovoga.

Pa, sad se pridruži alice skills programer chat, čitaj dokumentaciju, i kreirajte divno vještine!

izvor: www.habr.com

Dodajte komentar