Crearea unei abilități de stat pentru Alice pe funcțiile fără server ale Yandex.Cloud și Python

Să începem cu știrile. Yandex.Cloud a anunțat ieri lansarea unui serviciu de calcul fără server Funcții Yandex Cloud. Aceasta înseamnă: scrii doar codul serviciului tău (de exemplu, o aplicație web sau un chatbot), iar Cloud-ul însuși creează și întreține mașini virtuale acolo unde rulează și chiar le reproduce dacă sarcina crește. Nu trebuie să te gândești deloc, este foarte convenabil. Iar plata merge doar pentru timpul calculelor.

Cu toate acestea, este posibil ca unii oameni să nu plătească deloc. Aceștia sunt dezvoltatorii Abilitățile externe ale Alicei, adică chatboți încorporați în el. Orice dezvoltator poate scrie, găzdui și înregistra o astfel de abilitate, iar de astăzi abilitățile nici nu trebuie să fie găzduite - doar încărcați codul lor în cloud sub forma aceeași funcție fără server.

Dar există câteva nuanțe. În primul rând, codul dvs. de companie poate necesita anumite dependențe și nu este trivial să le trageți în Cloud. În al doilea rând, orice chatbot normal trebuie să stocheze starea dialogului undeva (deci cu stare); cum să o faci într-o funcție fără server cel mai simplu mod? În al treilea rând, cum poți scrie o abilitate rapidă și murdară pentru Alice sau chiar un fel de bot cu un complot diferit de zero? Despre aceste nuanțe, de fapt, articolul.

Crearea unei abilități de stat pentru Alice pe funcțiile fără server ale Yandex.Cloud și Python

pregătire morală

Pentru cei nerăbdători: colectez dependențele necesare cu un makefile înainte de a încărca funcția în cloud, stochez starea dialogului în Yandex Object Storage (suportă API-ul S3) și folosesc propria bibliotecă pentru a gestiona dialogul tgalice. Ca rezultat, se dovedește astfel de abilitate demo. Și acum să analizăm toate acestea mai în detaliu.

Pentru cei puțin mai puțin nerăbdători, înainte de a se scufunda în povestea mea de complexitate, recomand cu căldură să înceapă simplu. Și anume, creați o funcție echobot cu un singur fișier, înregistrați-o și testați-o în consola pentru dezvoltatori Dialog; detalii - în Dialoguri pe blog и documentație cloud. Și abia atunci începe.

Dacă vrei să simți imediat pentru ce luptăm, întreabă-l pe Alice.activați abilitate „Horoscop IT”'. Ar trebui să aibă loc următorul dialog:

Alice: Bună! Sunteți în competența „Horoscop IT”. Spune „Începe” pentru a afla ce îți promit astrele.
Utilizator: Începeți
R: Vă rugăm să spuneți numele dvs.
Yu: Vasiual
A: Acum spune-mi anul nașterii tale. Doar patru cifre, nimic mai mult.
Yu: al doilea
R: Vă rugăm să încercați din nou. Indicați anul nașterii dumneavoastră - patru cifre.
Yu: 2002
A: Grozav! Acum numește luna nașterii tale.
Yu: Februarie
A: Grozav! În cele din urmă, spune-mi data ta de naștere - doar un număr, doar una sau două cifre.
Yu: 18
A: Mulțumesc, Vasisual! Acum știm: ai 17 ani și ești Vărsător. Aici ești, desigur, norocos! Vă spun stelele а что говорят звёзды, вы узнаете, запустив навык.

Problema este că pentru a menține chiar și un dialog atât de simplu, trebuie să vă amintiți numele și data nașterii utilizatorului, iar într-un mediu fără server acest lucru nu este banal. Nu va funcționa pentru a stoca contextul în RAM sau ca fișier pe disc, deoarece Yandex.Cloud poate rula funcția pe mai multe mașini virtuale în același timp și poate comuta între ele în mod arbitrar. Va trebui să utilizați un fel de stocare externă. Object Storage a fost aleasă ca o stocare destul de ieftină și simplă direct în Yandex.Cloud (adică, probabil rapid). Ca alternativă gratuită, puteți încerca, de exemplu, o piesă gratuită Mongi înnorat undeva departe. Atât Object Storage (acceptă interfața S3) cât și Mongo au wrapper-uri Python convenabile.

O altă problemă este că pentru a accesa Object Storage, MongoDB și orice altă bază de date sau depozit de date, aveți nevoie de unele dependențe externe pe care trebuie să le încărcați în Yandex Functions împreună cu codul funcției. Și mi-ar plăcea să o fac confortabil. Este complet convenabil (ca pe heroku), din păcate, nu va funcționa, dar puteți crea un confort de bază scriind un script pentru a construi mediul (creați fișierul).

Cum să începi abilitățile horoscopului

  1. Pregătește-te: mergi la o mașină cu Linux. În principiu, probabil că puteți lucra și cu Windows, dar apoi trebuie să vă evocați cu lansarea makefile-ului. Și, în orice caz, veți avea nevoie de cel puțin 3.6 Python instalat.
  2. Clonează din github exemplu de abilitate horoscop.
  3. Înregistrați-vă în Ya.Cloud: https://cloud.yandex.ru
  4. Creează-ți două găleți Depozitarea obiectelor, numiți-i pe orice nume {BUCKET NAME} и tgalice-test-cold-storage (Acest nume de mijloc este acum codificat în main.py exemplul meu). Prima găleată va fi necesară numai pentru implementare, a doua - pentru stocarea stărilor de dialog.
  5. crea cont de serviciu, dă-i un rol editorși obțineți acreditări statice pentru acesta {KEY ID} и {KEY VALUE} - le vom folosi pentru a înregistra starea dialogului. Toate acestea sunt necesare pentru ca funcția de la Ya.Cloud să poată accesa stocarea din Ya.Cloud. Într-o zi, sper, autorizarea va deveni automată, dar deocamdată - așa.
  6. (Opțional) instalați Linia de comandă yc. De asemenea, puteți crea o funcție prin interfața web, dar CLI-ul este bun pentru că tot felul de inovații apar mai repede în ea.
  7. Acum puteți, de fapt, să pregătiți ansamblul dependențelor: rulați pe linia de comandă din folderul cu exemplul de abilitate make all. O grămadă de biblioteci (de cele mai multe ori, ca de obicei, inutile) vor fi instalate în folder dist.
  8. Umpleți cu pixuri în depozitul de obiecte (într-o găleată {BUCKET NAME}) arhiva obtinuta la pasul anterior dist.zip. Dacă doriți, puteți face acest lucru și din linia de comandă, de exemplu, folosind AWS CLI.
  9. Creați o funcție fără server prin interfața web sau folosind utilitarul yc. Pentru utilitar, comanda va arăta astfel:

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

Când se creează manual o funcție, toți parametrii sunt completați în același mod.

Acum, funcția pe care ați creat-o poate fi testată prin consola pentru dezvoltatori și apoi abilitate finalizată și publicată.

Crearea unei abilități de stat pentru Alice pe funcțiile fără server ale Yandex.Cloud și Python

Ce este sub capotă

Makefile conține de fapt un script destul de simplu pentru a instala dependențe și a le pune într-o arhivă. dist.zip, ceva de genul:

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

Restul sunt câteva instrumente simple împachetate într-o bibliotecă tgalice. Procesul de completare a datelor utilizatorului este descris de 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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

Clasa python preia munca de analiză a acestei configurații și de calculare a rezultatului final

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

Mai exact, clasa de bază FormFillingDialogManager se angajează în completarea „formularului” și a metodei clasei de copii handle_completed_form spune ce să facă când este gata.

În plus față de acest flux principal al dialogului utilizatorului, este, de asemenea, necesar să salutați utilizatorul, precum și să acordați ajutor la comanda „ajutor” și să eliberați abilitate la comanda „ieșire”. Pentru aceasta in tgalice există și un șablon, astfel încât întregul manager de dialog este alcătuit din piese:

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 funcționează simplu: încearcă să aplice la starea curentă a dialogului toate componentele sale pe rând și o selectează pe prima relevantă.

Ca răspuns la fiecare mesaj, managerul de dialog returnează un obiect Python Response, care poate fi apoi convertit în text simplu sau într-un mesaj în Alice sau Telegram - în funcție de locul în care rulează botul; conține, de asemenea, starea schimbată a dialogului care trebuie salvat. De toată această bucătărie se ocupă o altă clasă, DialogConnector, deci scriptul direct pentru începerea unei aptitudini pe funcțiile Yandex arată astfel:

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

După cum puteți vedea, cea mai mare parte a acestui cod creează o conexiune la interfața Object Storage S3. Cum se utilizează direct această conexiune, puteți citi in cod tgalice.
Ultima linie creează o funcție alice_handler - cel pe care l-am comandat să tragem Yandex.Cloud atunci când setăm parametrul --entrypoint=main.alice_handler.

Asta, de fapt, este tot. Makefiles pentru construirea, S3-like Object Storage pentru stocarea contextului și o bibliotecă python tgalice. Împreună cu caracteristicile fără server și expresivitatea lui python, acest lucru este suficient pentru a dezvolta abilitățile unei persoane sănătoase.

Puteți întreba de ce trebuie să creați tgalice? Tot codul plictisitor care transferă JSON de la cerere la răspuns și de la stocare la memorie și înapoi se află în el. Există, de asemenea, o aplicație de expresie regulată, o funcție pentru a înțelege că „februarie” este similar cu „februarie”, și alte NLU pentru săraci. Conform ideii mele, acest lucru ar trebui să fie deja suficient pentru a putea schița prototipuri de abilități în fișiere yaml fără a fi prea distras de detalii tehnice.

Dacă doriți un NLU mai serios, îl puteți pune la îndemână Rasa sau DeepPavlov, dar configurarea lor va necesita dans suplimentar cu o tamburină, mai ales pe serverless. Dacă nu aveți chef de codificare, ar trebui să utilizați constructorul de tip vizual Aimilogic. Când am creat tgalice, m-am gândit la un fel de cale intermediară. Să vedem ce se întâmplă.

Ei bine, acum alăturați-vă Chat pentru dezvoltatori de abilități Aliy, citit documentațieși creează uimitor aptitudini!

Sursa: www.habr.com

Adauga un comentariu