It meitsjen fan in stateful feardigens foar Alice mei help fan serverless funksjes fan Yandex.Cloud en Python

Litte wy begjinne mei it nijs. Yandex.Cloud kundige juster de lansearring fan in serverless computing tsjinst oan Yandex Cloud Funksjes. Dit betsjut: jo skriuwe allinich de koade foar jo tsjinst (bgl Jo moatte hielendal net tinke, it is heul handich. En de betelling is allinich foar de berekkeningstiid.

Guon kinne lykwols hielendal net betelje. Dit binne de ûntwikkelders Alice syn eksterne feardichheden, dat wol sizze, ynboude chatbots. Elke ûntwikkelder kin sa'n feardigens skriuwe, hostje en registrearje, en fan hjoed ôf hoege de feardichheden net iens te hostjen - upload gewoan har koade nei de wolk yn 'e foarm deselde serverless funksje.

Mar der binne in pear nuânses. As earste kin jo pitkoade wat ôfhinklikens fereaskje, en it slepen nei de wolk is net-trivial. Twads, elke normale chatbot moat de steat fan 'e dialooch earne opslaan (stateful dus); Wat is de maklikste manier om dit te dwaan yn in serverleaze funksje? Tredde, hoe kinne jo in flugge en smoarge feardigens skriuwe foar Alice of sels in soarte fan bot mei in plot net nul? It artikel giet yn feite oer dizze nuânses.

It meitsjen fan in stateful feardigens foar Alice mei help fan serverless funksjes fan Yandex.Cloud en Python

Morele tarieding

Foar de ûngeduldige: ik sammelje de nedige ôfhinklikens mei in makefile foardat ik de funksje upload nei de wolk, ik bewarje de tastân fan it dialooch yn Yandex Object Storage (it stipet de S3 API), en ik brûk myn eigen bibleteek om it dialooch te behearjen tgalice. Uteinlik docht it bliken sa'n demo feardigens. No litte wy dit alles yn in bytsje mear detail besjen.

Foar dyjingen dy't in bytsje minder ûngeduldich binne, foardat ik yn myn ferhaal oer kompleksiteit dûke, ried ik tige oan om te begjinnen mei wat ienfâldich. Meitsje nammentlik in single-bestân echobot-funksje, registrearje en test it yn 'e Dialogs-ûntwikkelderskonsole; details - yn Dialogen blog и Cloud dokumintaasje. En pas dan begjinne.

As jo ​​daliks fiele wolle wêr't wy hjir foar stride, freegje dan Alice 'ynskeakelje de feardigens "IT horoscope".'. In dialooch fergelykber mei de folgjende moat foarkomme:

Alice: Hallo! Jo binne yn 'e feardigens "IT Horoscope". Sis "Begjin" om út te finen wat de stjerren jo belibje.
Brûker: Start
A: Jou asjebleaft jo namme
Yu: Vasisualiy
A: No fertel my it jier fan jo berte. Allinnich fjouwer sifers, neat ekstra.
jo: twadde
A: Besykje it nochris. Fier it jier fan jo berte yn - fjouwer sifers.
Jo: 2002
In grutte! No neam jo bertemoanne.
Yu: febrewaris
In grutte! As lêste, fertel my jo bertedatum - gewoan in nûmer, mar ien of twa sifers.
Jo: 18
A: Tankewol, Vasisualiy! No witte wy: do bist 17 jier âld en in Aquarius. No, fansels, do bist gelok! De stjerren fertelle jo: а что говорят звёзды, вы узнаете, запустив навык.

It probleem is dat om sels sa'n ienfâldige dialooch te behâlden, jo de namme en bertedatum fan 'e brûker moatte ûnthâlde, en yn in serverless funksje-omjouwing is dit net-trivial. It sil net mooglik wêze om de kontekst op te slaan yn RAM of as in bestân op skiif, om't Yandex.Cloud kin in funksje útfiere op ferskate firtuele masines tagelyk en wikselje tusken har nei wille. Jo moatte in soarte fan eksterne opslach brûke. Objekt Storage waard keazen as in frij goedkeape en uncomplicated opslach direkt yn Yandex.Cloud (dat wol sizze, wierskynlik fluch). As fergees alternatyf kinne jo bygelyks in fergees stik besykje Bewolkt Monga earne fier fuort. D'r binne handige Python-wrappers foar sawol Object Storage (dy't de S3-ynterface stipet) as Mongo.

In oar probleem is dat om tagong te krijen ta Object Storage, MongoDB, en elke oare databank of gegevenswinkel, jo moatte wat eksterne ôfhinklikens nedich hawwe dy't moatte wurde uploade nei Yandex Functions tegearre mei jo funksjekoade. En ik soe dit graach dwaan wolle. Spitigernôch sil it net folslein handich wêze (lykas op Heroku), mar wat basiskomfort kin makke wurde troch it skriuwen fan in skript om de omjouwing te bouwen (bestân meitsje).

Hoe kinne jo in horoskoopfeardigens lansearje

  1. Tariede: gean nei guon masine mei Linux. Yn prinsipe kinne jo wierskynlik ek mei Windows wurkje, mar dan moatte jo wat magy dwaan mei it lansearjen fan it makefile. En yn alle gefallen sille jo op syn minst Python 3.6 moatte ynstalleare.
  2. Kloon it fan Github Foarbyld fan horoscope feardigens.
  3. Registrearje yn Y.Cloud: https://cloud.yandex.ru
  4. Meitsje dysels twa bakken yn Objekt opslach, neam se by hokker namme {BUCKET NAME} и tgalice-test-cold-storage (dizze twadde namme is no hardcoded yn main.py myn foarbyld). De earste bak sil allinich nedich wêze foar ynset, de twadde - om dialoochsteaten op te slaan.
  5. oanmeitsje tsjinst account, jou him in rol editor, en krije statyske bewiisbrieven foar it {KEY ID} и {KEY VALUE} - wy sille se brûke om de steat fan 'e dialooch op te nimmen. Dit alles is nedich sadat in funksje fan Ya.Cloud tagong kin ta de opslach fan Ya.Cloud. Ienris wurdt, hoopje ik, autorisaasje automatysk, mar no is it sa.
  6. (Opsjoneel) ynstallearje kommandorigel ynterface yc. Jo kinne ek in funksje meitsje fia de webynterface, mar de CLI is goed om't allerhanne ynnovaasjes der flugger yn ferskine.
  7. No kinne jo de ôfhinklikensgearstalling eins tariede: rinne it op 'e kommandorigel út' e map mei it feardigensfoarbyld make all. In boskje bibleteken (meast, lykas gewoanlik, net nedich) sil ynstalleare wurde yn 'e map dist.
  8. Giet mei de hân yn Object Storage (yn 'e emmer {BUCKET NAME}) argyf krigen yn 'e foarige stap dist.zip. As jo ​​​​wolle, kinne jo dit dwaan fanút de kommandorigel, bygelyks mei AWS CLI.
  9. Meitsje in serverleaze funksje fia de webynterface of mei help fan in hulpprogramma yc. Foar it hulpprogramma sil it kommando der sa útsjen:

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

By it manuell oanmeitsjen fan in funksje, wurde alle parameters op deselde wize ynfolle.

No kin de funksje dy't jo makke hawwe wurde hifke fia de ûntwikkelderskonsole, en dan kin de feardigens wurde ferbettere en publisearre.

It meitsjen fan in stateful feardigens foar Alice mei help fan serverless funksjes fan Yandex.Cloud en Python

Wat is ûnder de motorkap

It makefile befettet eins in frij ienfâldich skript foar it ynstallearjen fan ôfhinklikens en it pleatsen yn in argyf dist.zip, sawat sa:

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

De rest is in pear ienfâldige ark ferpakt yn in bibleteek tgalice. It proses fan it ynfoljen fan brûkersgegevens wurdt beskreaun troch de konfiguraasje 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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

It wurk fan it parsearjen fan dizze konfiguraasje en it berekkenjen fan it einresultaat wurdt oernommen troch de Python-klasse

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

Mear krekter, de basisklasse FormFillingDialogManager giet it om it ynfoljen fan it "formulier", en de metoade foar bernklasse handle_completed_form fertelt har wat te dwaan as se klear is.

Njonken dizze haadstream fan dialooch moat de brûker ek begroet wurde, lykas help mei it kommando "help" en frijlitten fan 'e feardigens mei it kommando "útgong". Foar dit doel yn tgalice D'r is ek in sjabloan, sadat de heule dialoochbehearder bestiet út stikken:

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 It wurket gewoan: it besiket op syn beurt al syn komponinten oan te passen oan 'e hjoeddeistige steat fan' e dialooch, en selekteart de earste passende.

De dialoochbehearder jout in Python-objekt werom as antwurd op elk berjocht. Response, dy't dan omset wurde kin yn platte tekst, of yn in berjocht yn Alice of Telegram - ôfhinklik fan wêr't de bot draait; it befettet ek de feroare tastân fan 'e dialooch dy't bewarre wurde moat. Dizze hiele keuken wurdt behannele troch in oare klasse, DialogConnector, dus it direkte skript foar it starten fan in feardigens op Yandex Functions sjocht der sa út:

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

Sa't jo sjen kinne, makket de measte fan dizze koade in ferbining mei de S3-ynterface fan Object Storage. Jo kinne lêze hoe't dizze ferbining direkt brûkt wurdt yn tgalice koade.
De lêste rigel makket de funksje alice_handler - deselde dy't wy Yandex.Cloud fertelden om te lûken as wy de parameter ynstelle --entrypoint=main.alice_handler.

Dat is alles, eins. Meitsje bestannen foar gearstalling, S3-like Object Storage foar it opslaan fan kontekst, en in Python-bibleteek tgalice. Kombinearre mei de serverless funksjes en ekspressiviteit fan Python, is dit genôch om in sûne minsklike feardigens te ûntwikkeljen.

Jo kinne freegje wêrom't it nedich wie om te meitsjen tgalice? Alle saaie koade dy't JSONs oerbringt fan fersyk nei antwurd en fan opslach nei ûnthâld en werom leit deryn. D'r is ek in reguliere koadeapplikaasje, in funksje om te begripen dat "febrewaris" fergelykber is mei "febrewaris", en oare NLU foar de earmen. Neffens myn idee soe dit al genôch wêze moatte, sadat jo prototypen fan feardichheden yn yaml-bestannen sketse kinne sûnder te ôfliede te wurden troch technyske details.

As jo ​​​​in mear serieuze NLU wolle, kinne jo it hechtsje oan jo feardigens Smaak of DeepPavlov, mar it opsetten fan harren sil fereaskje ekstra dûnsen mei in tamboerine, benammen op serverless. As jo ​​​​gjin kodearring fiele, moatte jo in fisuele konstruktor brûke lykas Aimylogic. By it meitsjen fan tgalice tocht ik oer in soarte fan tuskenpaad. Litte wy sjen wat der fan komt.

No, doch no mei alice feardichheden ûntwikkelder petear, lêze dokumintaasje, en meitsje prachtich feardichheden!

Boarne: www.habr.com

Add a comment