Vytvoření stavové dovednosti pro Alici na bezserverových funkcích Yandex.Cloud a Python

Začněme novinkami. Včera Yandex.Cloud oznámil spuštění bezserverové výpočetní služby Funkce cloudu Yandex. To znamená: napíšete pouze kód své služby (například webové aplikace nebo chatbota) a samotný Cloud vytváří a udržuje virtuální stroje, kde běží, a dokonce je replikuje, pokud se zatížení zvýší. Nemusíte vůbec přemýšlet, je to velmi pohodlné. A platba jde pouze po dobu výpočtů.

Někteří lidé však nemusí platit vůbec. To jsou vývojáři Aliciny vnější dovednosti, tedy chatboty zabudované v něm. Každý vývojář může takovou dovednost napsat, hostovat a zaregistrovat a ode dneška tyto dovednosti ani nemusí být hostovány – stačí nahrát jejich kód do cloudu ve formě stejná funkce bez serveru.

Ale je tu pár nuancí. Za prvé, váš kód pro domácí mazlíčky může vyžadovat určité závislosti a není triviální je přetáhnout do cloudu. Za druhé, každý normální chatbot potřebuje někde uložit stav dialogu (proto stavový); jak to udělat v bezserverové funkci nejjednodušším způsobem? Zatřetí, jak můžete napsat rychlou a špinavou dovednost pro Alici nebo dokonce nějakého robota s nenulovou zápletkou? O těchto nuancích ve skutečnosti článek.

Vytvoření stavové dovednosti pro Alici na bezserverových funkcích Yandex.Cloud a Python

Morální příprava

Pro netrpělivé: Před nahráním funkce do cloudu shromažďuji potřebné závislosti pomocí makefile, stav dialogu ukládám do Yandex Object Storage (podporuje S3 API) a ke správě dialogu používám vlastní knihovnu tgalice. Ve výsledku se ukazuje takový demo dovednost. A teď si to vše rozeberme trochu podrobněji.

Pro méně netrpělivé, než se ponořím do mého příběhu o složitosti, vřele doporučuji začít jednoduše. Konkrétně vytvořte jednosouborovou funkci echobot, zaregistrujte ji a otestujte ji ve vývojářské konzoli Dialog; podrobnosti - v Blogové dialogy и cloudová dokumentace. A teprve potom začít.

Pokud chceš okamžitě cítit, za co bojujeme, zeptej se Alice'zapněte dovednost "IT horoskop"'. Měl by proběhnout následující dialog:

Alice: Ahoj! Jste v dovednosti „IT horoskop“. Řekněte „Start“, abyste zjistili, co vám hvězdy slibují.
Uživatel: Start
A: Uveďte prosím své jméno.
Yu: Vasivizuálně
A: Teď mi řekni rok svého narození. Pouze čtyři číslice, nic víc.
Yu: za druhé
A: Zkuste to prosím znovu. Uveďte rok svého narození – čtyři číslice.
Yu: 2002
Velký! Nyní pojmenujte měsíc svého narození.
Yu: února
Velký! Nakonec mi řekněte své datum narození - jen číslo, jen jedna nebo dvě číslice.
Yu: 18
A: Děkuji, Vasisual! Nyní víme: je vám 17 let a jste Vodnář. Tady máte samozřejmě štěstí! Hvězdy vám říkají а что говорят звёзды, вы узнаете, запустив навык.

Problém je v tom, že pro udržení i tak jednoduchého dialogu si musíte zapamatovat jméno a datum narození uživatele a v prostředí bez serveru to není triviální. Uložení kontextu do RAM nebo jako soubor na disk nebude fungovat, protože Yandex.Cloud může funkci spouštět na několika virtuálních strojích současně a libovolně mezi nimi přepínat. Budete muset použít nějaký druh externího úložiště. Object Storage bylo zvoleno jako celkem levné a jednoduché úložiště přímo v Yandex.Cloud (tedy asi rychlé). Jako bezplatnou alternativu můžete vyzkoušet například volný kousek Zataženo Mongi někde daleko. Jak Object Storage (podporuje rozhraní S3), tak Mongo mají pohodlné obaly Pythonu.

Dalším problémem je, že abyste mohli přejít do Object Storage, MongoDB a jakékoli jiné databáze nebo úložiště dat, potřebujete nějaké externí závislosti, které musíte nahrát do funkcí Yandex spolu s kódem funkce. A chtěl bych to dělat pohodlně. Je to naprosto pohodlné (jako na heroku), bohužel to nebude fungovat, ale můžete vytvořit základní pohodlí napsáním skriptu pro vytvoření prostředí (make file).

Jak začít s dovedností horoskopu

  1. Připravte se: přejděte na nějaký počítač s Linuxem. V principu asi umíte pracovat i s Windows, ale pak musíte kouzlit se spuštěním makefile. A v každém případě budete potřebovat nainstalovaný Python alespoň 3.6.
  2. Klonovat z githubu příklad dovednosti horoskopu.
  3. Zaregistrujte se na Ya.Cloud: https://cloud.yandex.ru
  4. Vytvořte si dva kbelíky Uložení objektů, říkejte jim libovolným jménem {BUCKET NAME} и tgalice-test-cold-storage (toto prostřední jméno je nyní pevně zakódováno do main.py můj příklad). První kbelík bude potřeba pouze pro nasazení, druhý - pro ukládání stavů dialogu.
  5. vytvořit servisní účet, dát mu roli editora získejte pro něj statické přihlašovací údaje {KEY ID} и {KEY VALUE} - použijeme je k záznamu stavu dialogu. To vše je potřeba k tomu, aby funkce z Ya.Cloud měla přístup k úložišti z Ya.Cloud. Doufám, že jednoho dne se autorizace stane automatickou, ale zatím - ano.
  6. (Volitelné) nainstalovat rozhraní příkazového řádku yc. Funkci vytvoříte i přes webové rozhraní, ale CLI je dobré, protože se v něm rychleji objevují nejrůznější inovace.
  7. Nyní můžete ve skutečnosti připravit sestavení závislostí: spusťte na příkazovém řádku ze složky s příkladem dovednosti make all. Do složky se nainstaluje hromada knihoven (většinou jako obvykle nepotřebných). dist.
  8. Naplňte pery do úložiště objektů (do kbelíku {BUCKET NAME}) archiv získaný v předchozím kroku dist.zip. V případě potřeby to můžete provést také z příkazového řádku, například pomocí AWS CLI.
  9. Vytvořte funkci bez serveru přes webové rozhraní nebo pomocí utility yc. Pro obslužný program 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=3s

Při ručním vytváření funkce se všechny parametry vyplňují stejným způsobem.

Nyní lze funkci, kterou jste vytvořili, otestovat prostřednictvím vývojářské konzole a poté dokončit a publikovat dovednost.

Vytvoření stavové dovednosti pro Alici na bezserverových funkcích Yandex.Cloud a Python

Co je pod kapotou

Makefile ve skutečnosti obsahuje poměrně jednoduchý skript pro instalaci závislostí a jejich uložení do archivu. dist.zip, něco takového:

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 je několik jednoduchých nástrojů zabalených v knihovně tgalice. Proces vyplňování uživatelských údajů popisuje 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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

Třída python přebírá práci na analýze této konfigurace a výpočtu konečného výsledku

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

Přesněji základní třída FormFillingDialogManager se zabývá vyplňováním "formuláře" a metodou dětské třídy handle_completed_form říká, co má dělat, když je připravená.

Kromě tohoto hlavního toku uživatelského dialogu je také nutné uživatele pozdravit, stejně jako vydat nápovědu k příkazu „help“ a uvolnit dovednost na příkaz „exit“. Pro toto v tgalice existuje také šablona, ​​takže celý správce dialogů se skládá z částí:

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 funguje jednoduše: pokusí se aplikovat na aktuální stav dialogu postupně všechny jeho součásti a vybere první relevantní.

Jako odpověď na každou zprávu vrátí správce dialogu objekt python Response, který lze následně převést na prostý text nebo na zprávu v Alice nebo Telegramu – v závislosti na tom, kde robot běží; obsahuje také změněný stav dialogu, který je třeba uložit. Celou tuhle kuchyni má na starosti jiná třída, DialogConnector, takže přímý skript pro spuštění dovednosti ve funkcích Yandex 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_handler

Jak vidíte, většina tohoto kódu vytváří připojení k rozhraní Object Storage S3. Jak se toto spojení přímo používá, si můžete přečíst v kódu tgalice.
Poslední řádek vytváří funkci alice_handler - ten, který jsme nařídili stáhnout Yandex.Cloud, když jsme nastavili parametr --entrypoint=main.alice_handler.

To je ve skutečnosti vše. Makefiles pro vytváření, S3 Object Storage pro kontextové úložiště a python knihovnu tgalice. Spolu s funkcemi bez serveru a výrazností pythonu to stačí k rozvoji dovedností zdravého člověka.

Můžete se zeptat, proč potřebujete tvořit tgalice? V něm leží veškerý nudný kód, který přenáší JSON z požadavku na odpověď a z úložiště do paměti a zpět. Existuje také aplikace regulárních výrazů, funkce pro pochopení, že „únor“ je podobný „únoru“, a další NLU pro chudé. Podle mé představy by to již mělo stačit na to, aby bylo možné načrtnout prototypy dovedností v yaml souborech, aniž by se příliš rozptylovaly technickými detaily.

Pokud chcete serióznější NLU, můžete to přidělat podle svých schopností Rasa nebo DeepPavlov, ale jejich nastavení bude vyžadovat další tanec s tamburínou, zvláště na serverless. Pokud se vůbec necítíte na kódování, měli byste použít konstruktor vizuálního typu Aimylogic. Při tvorbě tgalice jsem přemýšlel o nějaké mezicestě. Pojďme se podívat, co se stane.

Tak a teď se přidejte Chat vývojářů dovedností Aliy, číst dokumentacea vytvořit úžasné dovednosti!

Zdroj: www.habr.com

Přidat komentář