Să începem cu știrile. Yandex.Cloud a anunțat ieri lansarea unui serviciu de calcul fără server . 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 , 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 .
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.

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 . Ca rezultat, se dovedește 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 и . Și abia atunci începe.
Dacă vrei să simți imediat pentru ce luptăm, întreabă-l pe Alice.'. 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ă 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
- 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.
- Clonează din github .
- Înregistrați-vă în Ya.Cloud:
- Creează-ți două găleți , numiți-i pe orice nume
{BUCKET NAME}иtgalice-test-cold-storage(Acest nume de mijloc este acum codificat înmain.pyexemplul meu). Prima găleată va fi necesară numai pentru implementare, a doua - pentru stocarea stărilor de dialog. - crea , 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. - (Opțional) instalați
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. - 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 folderdist. - Umpleți cu pixuri în depozitul de obiecte (într-o găleată
{BUCKET NAME}) arhiva obtinuta la pasul anteriordist.zip. Dacă doriți, puteți face acest lucru și din linia de comandă, de exemplu, folosind . - 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=3sCâ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ă.

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 responseMai 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_handlerDupă 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 .
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ă sau , 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 . 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ă , citit și creează uimitor !
Sursa: www.habr.com
