Začněme s novinkami. Včera Yandex.Cloud oznámil spuštění služby bezserverového výpočtu. To znamená: píšete pouze kód svého serveru (například webové aplikace nebo chatbotu) a Cloud sám vytváří a spravuje virtuální stroje, na kterých se spouští, a dokonce je replikují, pokud vzroste zátěž. Nemusíte se o nic starat, je to velmi praktické. A platíte pouze za čas výpočtů.
Někteří však mohou vůbec neplatit. To jsou vývojáři , tedy integrovaných chatbotů. Napsat, hostit a zaregistrovat takovou dovednost může každý vývojář, a od dnešního dne není potřeba dovednosti ani hostit - stačí nahrát jejich kód do cloudu jako .
Ale existuje pár nuancí. Za prvé, váš Python kód může vyžadovat nějaké závislosti, a přenášení je do Cloudu není jednoduché. Za druhé, každému normálnímu chatbotu je potřeba někde uchovávat stav dialogu (stateful proto); jak to udělat v bezserverové funkci co nejjednodušeji? A za třetí, jak rychle a jednoduše napsat dovednost pro Alisu nebo jakéhokoli bota s nějakým příběhem? O těchto nuancích vlastně článek je.

Morální příprava
Pro netrpělivé: potřebné závislosti shromažďuji makefilem před nahráním funkce do cloudu, stav dialogu uchovávám v Yandex Object Storage (ten podporuje API S3), a pro řízení dialogu používám svou vlastní knihovnu Ve výsledku vzniká demo-dovednost. A teď si to rozebereme trochu podrobněji.
Pro trochu méně netrpělivé: než se ponoříte do mého příběhu o potížích, velmi doporučuji začít s jednoduchým. A to totiž vytvořit jednofilovou funkci-echo bota, zaregistrovat ji a otestovat ji v konzoli vývojářů Dialogů; podrobnosti najdete v a A teprve potom se pustit do další práce.
Pokud chcete hned pocítit, o co zde bojujeme, požádejte Alisu '' Mělo by proběhnout přibližně následující dialog:
Alisa: Ahoj! Jste v dovednosti „IT horoskop“. Řekněte „Start“, abyste zjistili, co vám hvězdy slibují.
Uživatel: Start
A: Prosím, řekněte mi své jméno.
U: Vasisauliy
A: Nyní mi řekněte svůj rok narození. Pouze čtyři číslice, nic víc.
U: druhý
A: Prosím, zkuste to ještě jednou. Uveďte rok svého narození — čtyři číslice.
J: 2002
A: Skvěle! Nyní uveďte měsíc svého narození.
J: Únor
A: Výborně! A nakonec mi uveďte datum vašeho narození — pouze číslo, maximálně dvě číslice.
J: 18
A: Děkujeme, Vasisuáli! Nyní víme, že vám je 17 let a jste Vodnář. To je štěstí! Hvězdy vám říkají: co říkají hvězdy, se dozvíte spuštěním dovednosti.
Problém je v tom, že pro udržení i tak jednoduchého dialogu je třeba si pamatovat jméno a datum narození uživatele, což není v prostředí serverless funkcí triviální. Kontext nelze uchovávat v operační paměti nebo v souboru na disku, protože Yandex.Cloud může spustit funkci na více virtuálních strojích současně a libovolně přepínat mezi nimi. Bude třeba využít nějaké externí úložiště. Bylo zvoleno Object Storage, jakožto relativně levné a jednoduché úložiště přímo v Yandex.Cloud (tedy patrně rychlé). Jako bezplatnou alternativu můžete vyzkoušet například kousek někde daleko. A pro Object Storage (ten podporuje rozhraní S3) i pro Mongo existují pohodlné Python obálky.
Další problém je, že pro přístup jak k Object Storage, tak k MongoDB, i k jakékoli jiné databázi nebo úložišti dat jsou potřeba nějaké externí závislosti, které je třeba nahrát na Yandex Functions spolu s kódem vaší funkce. A chtělo by se to dělat pohodlně. Úplně pohodlně (třeba jako na heroku) to, bohužel, nebude možné, ale nějaký základní komfort lze vytvořit napsáním skriptu pro sestavení prostředí (make-file).
Jak spustit dovednost-horoskop
- Připravte se: přihlaste se na nějaký stroj s Linuxem. V zásadě by šlo pracovat i s Windows, ale při spuštění make-file byste museli trošku zaexperimentovat. A v každém případě budete potřebovat nainstalovaný Python verze 3.6 nebo vyšší.
- Naklonovat si z GitHubu .
- Registrovat se v Y. Cloudu:
- Vytvořit si dva bucket přístupné v , pojmenovat je libovolně
{BUCKET NAME}atgalice-test-cold-storage(to druhé jméno je v současnosti pevně zakódováno vmain.pymém příkladu). První bucket bude potřebný pouze pro nasazení, druhý — pro uchovávání stavů dialogu. - Vytvořit , přiřadit mu roli
editor, a získat k němu statické údaje o přihlášení{KEY ID}a{KEY VALUE}— budeme je používat k nahrávání stavu dialogu. To vše je potřeba, aby funkce z Y.Cloud mohla získat přístup k úložišti z Y.Cloud. Doufám, že se jednou autorizace stane automatickou, ale zatím je to tak. - (Nepovinné) nainstalovat
yc. Funkci můžete vytvořit i přes webové rozhraní, ale CLI je dobré v tom, že různé novinky se objevují rychleji. - Teď můžeme vlastně připravit sestavení závislostí: spustit v příkazovém řádku z adresáře s příkladem dovednosti
make all. Nainstaluje se spousta knihoven (většinou, jak je obvyklé, zbytečných) do adresáředist. - Ručně nahrát do Object Storage (do bucketu
{BUCKET NAME}) vytvořený v předchozím kroku archívdist.zip. Pokud byste chtěli, můžete to udělat i z příkazového řádku, například pomocí . - Vytvořit serverless funkci přes webové rozhraní nebo pomocí utilitky
yc. Pro utilitku bude příkaz vypadat takto:
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=3sPři ručním vytváření funkce se všechny parametry vyplňují obdobně.
Teď můžete svou funkci testovat přes konzolu vývojáře, poté ji upravit a publikovat dovednost.

Co se tam skrývá
Makefile obsahuje vlastně docela jednoduchý skript pro instalaci závislostí a jejich uložení do archivu dist.zip, přibližně takto:
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 ./Zbytek - několik jednoduchých nástrojů zabaleno v knihovně tgalice.. Proces vyplnění údajů o uživateli je popsán v konfiguraci form.yaml:
form_name: 'horoscope_form'
start:
regexp: 'start|begin'
suggests:
- Start
fields:
- name: 'name'
question: Prosím, uveďte své jméno.
- name: 'year'
question: Nyní mi řekněte rok vašeho narození. Pouze čtyři číslice, nic víc.
validate_regexp: '^[0-9]{4}$'
validate_message: Prosím, zkuste to znovu. Uveďte rok vašeho narození - čtyři číslice.
- name: 'month'
question: Skvělé! Nyní uveďte měsíc vašeho narození.
options:
- leden
...
- prosinec
validate_message: To, co jste uvedli, se nezdá být měsícem. Prosím, uveďte měsíc vašeho narození, bez dalších slov.
- name: 'day'
question: Výborně! Nakonec mi uveďte datum vašeho narození - pouze číslo, maximálně dvě číslice.
validate_regexp: '[0123]?d$'
validate_message: Prosím, zkuste to znovu. Musíte uvést číslo svého narození (např. dvacáté); to jsou jedna nebo dvě číslice.Práci na rozboru tohoto konfiguračního souboru a výpočtu konečného výsledku přebírá pythoní třída
class CheckableFormFiller(tgalice.dialog_manager.form_filling.FormFillingDialogManager):
SIGNS = {
'leden': 'Kozoroh',
...
}
def handle_completed_form(self, form, user_object, ctx):
response = tgalice.dialog_manager.base.Response(
text='Děkujeme, {}! Nyní víme: je vám {} let, a jste {}. n'
'To se vám, samozřejmě, podařilo! Hvězdy vám říkají: {}'.format(
form['fields']['name'],
2019 - int(form['fields']['year']),
self.SIGNS[form['fields']['month']],
random.choice(FORECASTS),
),
user_object=user_object,
)
return responsePřesněji řečeno, základní třída FormFillingDialogManager se zabývá vyplněním „formuláře“, a metoda odvozené třídy handle_completed_form určuje, co dělat, když je připravena.
Kromě tohoto hlavního toku dialogu s uživateli je třeba je také přivítat, a navíc poskytnout radu na příkaz „nápověda“ a ukončit dovednost na příkaz „konečně“. K tomu v tgalice. existuje také šablona, takže celý dialogový manažer je složen z kousků:
dm = tgalice.dialog_manager.CascadeDialogManager(
tgalice.dialog_manager.GreetAndHelpDialogManager(
greeting_message=DEFAULT_MESSAGE,
help_message=DEFAULT_MESSAGE,
exit_message='Na shledanou, přijďte do dovednosti "IT Horoskop" znovu!'
),
CheckableFormFiller(`form.yaml`, default_message=DEFAULT_MESSAGE)
)CascadeDialogManager funguje jednoduše: snaží se aplikovat na aktuální stav dialogu všechny své složky po sobě a vybere první relevantní.
Jako odpověď na každou zprávu dialogový manažer vrací pythoní objekt Odpověď, který lze dále převést na čistý text nebo na zprávu v Alici nebo Telegramu - podle toho, kde je bot spuštěn; zde je také obsažený měněný stav dialogu, který je třeba uchovat. Celým tímto zpracováním se zabývá jiná třída, DialogConnector, proto přímo skript pro spuštění dovednosti na Yandex Functions vypadá takto:
...
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_handlerJak vidíte, většina tohoto kódu vytváří spojení s S3 rozhraním Object Storage. Jak se toto spojení opravdu používá, si můžete přečíst .
Poslední řádek vytváří funkci alice_handler — tu, kterou jsme požádali Yandex.Cloud, když jsme nastavovali parametr --entrypoint=main.alice_handler.
To je vlastně vše. Make soubory pro sestavení, S3 podobné Object Storage pro uložení kontextu a pythoní knihovna tgalice.. Spolu s bezserverovými funkcemi a výstižnostmi Pythona je to dostatečné pro vývoj dovednosti pro normálního člověka.
Můžete se zeptat, proč bylo třeba vytvořit tgalice.? Весь скучный код, перекладывающий JSON’ы из запроса в ответ и из хранилища в память и обратно, лежит в ней. Там же лежит применялка регулярок, функция для понимания того, что «феврарь» похоже на «февраль», и прочее NLU для бедных. По моей задумке, этого уже должно быть достаточно, чтобы можно было набрасывать прототипы навыков в yaml-файлах, не слишком отвлекаясь на технические детали.
Pokud toužíte po serióznějším NLU, můžete k své dovednosti přidat nebo , ale pro jejich nastavení budou potřeba další tanečky, zejména na serverless. Pokud se vůbec nechcete programovat, stojí za to využít vizuálního konstruktoru jako . Když jsem vytvářel tgalice, myslel jsem na nějakou střední cestu. Uvidíme, co z toho vzejde.
No a nyní se zapojte do , čtěte , a vytvářejte skvělé !
Zdroj: habr.com
