Kezdjük a hírekkel. Tegnap a Yandex.Cloud bejelentette a szerver nélküli számítások szolgáltatásának indulását. . Ez azt jelenti: te csak a szolgáltatásod (például webalkalmazás vagy chatbot) kódját írod, a Cloud pedig automatikusan létrehozza és fenntartja azokat a virtuális gépeket, ahol ez fut, és akár replikálja is őket, ha nő a terhelés. Valójában nem is kell semmivel foglalkozni, nagyon kényelmes. És csak a számítási időért fizetsz.
Egyesek viszont akár nem is fizethetnek. Ők a , azaz az őt integráló chatbotok. Bármilyen fejlesztő létrehozhat, hosztolhat és regisztrálhat ilyen készséget, és mától már nem is kell hosztolni a készségeket - elegendő a kódjukkal feltölteni őket a felhőbe, egyfajta .
De van néhány nüansz. Először is, a Python kódod bizonyos függőségeket igényelhet, és ezeket a Cloudba betenni nem triviális feladat. Másodszor, bármely normális chatbotnak valahol tárolnia kell a párbeszéd állapotát (stateful ezért); hogyan lehet ezt a legegyszerűbben megoldani egy szerver nélküli funkcióban? Harmadszor, hogyan lehet gyorsan és koszosan készíteni egy készséget Alice számára, vagy bármilyen bot számára valamilyen cselekménnyel? Ezek a nüanszok, igazából, a cikk témája.

Morális felkészülés
Türelmetleneknek: a szükséges függőségeket egy make-fájllal gyűjtöm össze a funkció felhőbe töltése előtt, a párbeszéd állapotát a Yandex Object Storage-ban tárolom (támogatja az S3 API-t), és a párbeszéd irányítására a saját könyvtáramat használom, . Végül kapunk egy demó készséget. Most pedig nézzük meg ezt egy kicsit részletesebben.
A némileg türelmetleneknek: mielőtt belemerülnénk az én történetembe a nehézségekről, nagyon ajánlom, hogy kezdjétek az egyszerűvel. Nevezetesen, hozz létre egy fájlban egy echo bot-díjat, regisztráld, és teszteld a Dialogs fejlesztői konzoljában; részletek a és . És csak azután kezdjétek el.
Ha azonnal szeretnéd érezni, miért küzdünk itt, mondd Alice-nak ‘‘. Körülbelül a következő párbeszédnek kellene zajlania:
Alice: Helló! Az 'IT horoszkóp' készségben vagy. Mondd, hogy 'Kezdet', ha szeretnéd tudni, mit jósolnak neked a csillagok.
Felhasználó: Kezdet
A: Kérlek, add meg a neved.
Felhasználó: Vasziszuali
A: Most mond meg az születési éved. Csak négy számot, semmi feleslegeset.
Felhasználó: második
A: Kérem, próbálja meg újra. Mondja meg születési évét — négy számjegy.
Y: 2002
A: Csodás! Most mondja meg születési hónapját.
Y: Február
A: Kitűnő! Végül pedig mondja meg születési dátumát — csak a nap, maximum egy vagy két számjegy.
Y: 18
A: Köszönöm, Vasilij! Most már tudjuk: 17 éves vagy, és Kos vagy. Ez igazán szerencsés helyzet! A csillagok azt mondják neked: a csillagok üzeneteit a készség aktiválásával ismerheted meg.
A probléma az, hogy még egy ilyen egyszerű párbeszéd fenntartásához is emlékezni kell a felhasználó nevére és születési dátumára, ami a serverless funkciók környezetében nem triviális. A kontextust nem lehet az operatív memóriában vagy fájlformátumban tárolni, mivel a Yandex.Cloud egyszerre több virtuális gépen is futhat, és véletlenszerűen válthat közöttük. Valamilyen külső tárolót kell használnunk. Az Object Storage-ra esett a választás, mint viszonylag kedvező árú és egyszerű tárolóra közvetlenül a Yandex.Cloud-ban (tehát valószínűleg gyors). Mint ingyenes alternatívát kipróbálhatjuk például a szabad MongoDB-t. És az Object Storage (ami S3 interfészt támogat) és a MongoDB számára is léteznek kényelmes Python csomagolások.
Egy másik probléma az, hogy az Object Storage és a MongoDB, valamint bármilyen más adatbázis vagy adattároló használatához külső függőségekre van szükség, amelyeket fel kell tölteni a Yandex Functions-hoz a funkció adottságaival együtt. Szeretnénk ezt kényelmesen megtenni. Teljesen kényelmesen (például mint a Heroku-n) sajnos nem fog sikerülni, de valamilyen alapvető kényelmet létrehozhatunk, ha írnánk egy környezetépítő szkriptet (make file).
Hogyan indítsuk el a horoszkóp készséget
- Készüljön fel: lépjen be egy Linux rendszert futtató gépre. Elvben Windows-on is használható, de a make file elindításához ott kicsit varázsolni kell. Mindenesetre szüksége lesz legalább 3.6-os Python telepítésére.
- Klónozza le a GitHubról .
- Regisztráljon a Y. Cloud-ra:
- Hozzon létre két tárolót a , nevezze el őket bármilyen névvel
{BUCKET NAME}éstgalice-test-cold-storage(ez a második név jelenleg hardcode-olva van amain.pypéldámba). Az első tárolóra csak a telepítéshez van szükség, a másodikra pedig a párbeszédek állapotának tárolásához. - Létrehozás , adjon neki szerepet
szerkesztő, és szerezzen hozzá statikus hitelesítő adatokat{KEY ID}és{KEY VALUE}— ezeket a párbeszéd állapotának rögzítésére fogjuk használni. Mindez szükséges ahhoz, hogy a Funkció az Y.Cloud-ból hozzáférhessen a tárolóhoz az Y.Cloud-ból. Remélem, hogy egyszer az azonosítás automatikussá válik, de addig is így. - (Nem kötelező) telepíteni
yc. Funkciót létrehozni webes felületen is lehetséges, de a CLI előnye, hogy az új fejlesztések itt gyorsabban jelennek meg. - Most már készíthetjük a függőségek összeszerelését: futtatni a parancssorban a példa készlet mappájából
make all. Számos könyvtár (főleg, ahogy az lenni szokott, haszontalanok) fog települni a mappábadist. - Kézzel feltölteni az Object Storage-ba (a tárolóba
{BUCKET NAME}) a korábban létrehozott archívumotdist.zip. Ha szeretné, ezt parancssorból is megteheti, például az alábbiak használatával . - Létrehozni egy szerver nélküli funkciót a webes interfészen vagy az eszköz használatával
yc. Az eszköz parancsa így fog kinézni:
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=3sA funkció manuális létrehozásakor minden paraméter hasonló módon van kitöltve.
Most már a létrehozott funkciót tesztelheti a fejlesztői konzolon, majd tovább fejlesztheti és publikálhatja a készséget.

Mi van a motorháztető alatt
A Make-fájl valójában egy meglehetősen egyszerű szkriptet tartalmaz a függőségek telepítésére és archiválására dist.zip, körülbelül ennyit:
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 ./*A többi — néhány egyszerű eszköz, amely könyvtárba van csomagolva tgalice. A felhasználói adatokról szóló folyamat a konfig fájlban van leírva form.yaml:
form_name: 'horoscope_form'
start:
regexp: 'kezdet|kezd(és|eni)'
suggests:
- Kezdés
fields:
- name: 'name'
question: Kérlek, mondd meg a nevedet.
- name: 'year'
question: Most mondd el nekem a születési évedet. Csak négy szám, semmi más.
validate_regexp: '^[0-9]{4}$'
validate_message: Kérlek, próbáld újra. Mondd meg a születési évedet - négy szám.
- name: 'month'
question: Kiváló! Most mondd meg a születési hónapodat.
options:
- január
...
- december
validate_message: Amit mondtál, nem tűnik hónapnak. Kérlek, mondd meg a születési hónapodat, más szavak nélkül.
- name: 'day'
question: Nagyszerű! Végül, mondj egy dátumot a születésnapodra - csak egy szám, maximum két számjegy.
validate_regexp: '[0123]?d$'
validate_message: Kérlek, próbáld újra. Meg kell mondanod a születésnapod számát (például huszadik); ez egy vagy két számjegy.A konfiguráció feldolgozását és a végső eredmény kiszámítását a Python osztály végzi
class CheckableFormFiller(tgalice.dialog_manager.form_filling.FormFillingDialogManager):
SIGNS = {
'január': 'Bak',
...
}
def handle_completed_form(self, form, user_object, ctx):
response = tgalice.dialog_manager.base.Response(
text='Köszönöm, {}! Most már tudjuk: {} éves vagy, és te {}. n'
'Ez igazán szerencsés! A csillagok azt mondják neked: {}'.format(
form['fields']['name'],
2019 - int(form['fields']['year']),
self.SIGNS[form['fields']['month']],
random.choice(FORECASTS),
),
user_object=user_object,
)
return responsePontosabban, az alap osztály FormFillingDialogManager foglalkozik a "forma" kitöltésével, míg az alosztály módszere handle_completed_form megmondja, mit kell tenni, amikor az készen áll.
Ezen alapvető felhasználói párbeszédfolyam mellett üdvözölni is kell, valamint segítséget adni a "segítség" parancsra, és ki kell lépni a készségből a "kilépés" parancsra. Ehhez tgalice szintén van sablon, így a teljes párbeszédkezelő darabokból áll:
dm = tgalice.dialog_manager.CascadeDialogManager(
tgalice.dialog_manager.GreetAndHelpDialogManager(
greeting_message=DEFAULT_MESSAGE,
help_message=DEFAULT_MESSAGE,
exit_message='Viszlát, gyere vissza az "IT Horoszkóp" készségbe még!'
),
CheckableFormFiller(`form.yaml`, default_message=DEFAULT_MESSAGE)
)CascadeDialogManager egyszerűen működik: megpróbálja alkalmazni a párbeszéd aktuális állapotára az összes alkotóelemét egymás után, és kiválasztja az első megfelelő elemet.
Hálás válaszként a párbeszédkezelő minden üzenetre Python objektumot ad vissza Válasz, amelyet aztán átkonvertálhatunk nyers szöveggé, vagy üzenetté az Aliszban vagy a Telegramon – attól függően, hol fut a bot; ebben található a párbeszéd módosított állapota is, amelyet meg kell őriznünk. Az egész feladat a továbbiakban egy másik osztályra hárul, DialogConnector, így a Yandex Functions platformon a készséget aktiváló közvetlen szkript így néz ki:
...
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_handlerAhogy látjátok, ennek a kódnak a nagy része az S3 interfészhez való csatlakozást hozza létre. Az, hogy ezt a csatlakozást közvetlenül hogyan használjuk, a .
Az utolsó sor létrehozza a alice_handler — azt a funkciót, amelyet megadtunk a Yandex Cloud-nak, amikor a paramétert adtuk meg --entrypoint=main.alice_handler.
A lényeg pedig ennyi. Make fájlok a buildhez, S3-szerű Object Storage a kontextus tárolására, és Python könyvtárak. tgaliceEzek együttesen, a serverless funkciókkal és a Python kifejezőerejével elegendőek egy egészséges ember készségeinek fejlesztéséhez.
Megkérdezheted, miért is kellett létrehozni tgalice? Весь скучный код, перекладывающий JSON’ы из запроса в ответ и из хранилища в память и обратно, лежит в ней. Там же лежит применялка регулярок, функция для понимания того, что «феврарь» похоже на «февраль», и прочее NLU для бедных. По моей задумке, этого уже должно быть достаточно, чтобы можно было набрасывать прототипы навыков в yaml-файлах, не слишком отвлекаясь на технические детали.
Ha komolyabb NLU-ra vágyunk, a készségünkhöz hozzácsatolhatunk vagy , de ennek beállításához további bonyodalmakra lesz szükség, különösen a serverless környezetben. Ha valósággal nem akarsz kódot írni, érdemes egy vizuális tervezőre támaszkodni, mint például . A tgalice létrehozásakor valami középutat kerestem. Nézzük meg, mi sül ki belőle.
Nos, most lépj be a olvass , és készíts csodálatos !
Forrás: habr.com
