Krei ŝtatan kapablon por Alice pri la senservilaj funkcioj de Yandex.Cloud kaj Python

Ni komencu per la novaĵoj. Hieraŭ Yandex.Cloud anoncis la lanĉon de senservila komputika servo Yandex Nubaj Funkcioj. Ĉi tio signifas: vi nur skribas la kodon de via servo (ekzemple, TTT-aplikaĵo aŭ babilejo), kaj la Nubo mem kreas kaj konservas virtualajn maŝinojn kie ĝi funkcias, kaj eĉ reproduktas ilin se la ŝarĝo pliiĝas. Vi tute ne devas pensi, ĝi estas tre oportuna. Kaj la pago iras nur por la tempo de kalkuloj.

Tamen iuj homoj eble tute ne pagas. Ĉi tiuj estas la programistoj La eksteraj kapabloj de Alice, tio estas, babilrotoj enkonstruitaj en ĝi. Ajna programisto povas skribi, gastigi kaj registri tian kapablon, kaj ekde hodiaŭ kapabloj eĉ ne bezonas esti gastigitaj - nur alŝutu sian kodon al la nubo en la formo la sama senservila funkcio.

Sed estas kelkaj nuancoj. Unue, via dorlotbesta kodo povas postuli iujn dependecojn, kaj ne estas facile treni ilin en la Nubon. Due, ĉiu normala babilejo bezonas stoki la staton de la dialogo ie (ŝtata do); kiel fari ĝin en senservila funkcio la plej facila maniero? Trie, kiel vi povas skribi rapidan kaj malpuran kapablon por Alico aŭ eĉ ian bot kun ne-nula intrigo? Pri ĉi tiuj nuancoj, fakte, la artikolo.

Krei ŝtatan kapablon por Alice pri la senservilaj funkcioj de Yandex.Cloud kaj Python

morala preparo

Por senpacienculoj: mi kolektas la necesajn dependecojn per makedosiero antaŭ ol alŝuti la funkcion al la nubo, mi konservas la staton de la dialogo en Yandex Object Storage (ĝi subtenas la S3 API), kaj mi uzas mian propran bibliotekon por administri la dialogon. tgalice. Kiel rezulto, ĝi rezultas tia demo-kapablo. Kaj nun ni analizu ĉion ĉi iom pli detale.

Por la iomete malpli malpaciencaj, antaŭ ol plonĝi en mian rakonton pri komplekseco, mi tre rekomendas komenci simple. Nome, kreu unudosieran eĥobotfunkcion, registriĝu kaj provu ĝin en la Dialog-programkonzolo; detaloj - en Blogaj Dialogoj и nuba dokumentado. Kaj nur tiam komencu.

Se vi volas tuj senti, por kio ni batalas, demandu al Alicio.ŝaltu la kapablon "IT-horoskopo"'. La sekva dialogo devus okazi:

Alico: Saluton! Vi estas en la kapablo "IT horoskopo". Diru "Komencu" por ekscii, kion la steloj promesas al vi.
Uzanto: Komencu
A: Bonvolu indiki vian nomon.
Yu: Vasuly
A: Nun diru al mi la jaron de via naskiĝo. Nur kvar ciferoj, nenio pli.
Yu: due
A: Bonvolu provi denove. Indiku la jaron de via naskiĝo - kvar ciferoj.
Ju: 2002
Granda! Nun nomu la monaton de via naskiĝo.
Yu: februaro
Granda! Fine, diru al mi vian naskiĝdaton - nur nombron, nur unu aŭ du ciferojn.
Ju: 18
A: Dankon, Vasisual! Nun ni scias: vi estas 17-jara kaj vi estas Akvisto. Jen vi estas, kompreneble, bonŝanca! La steloj diras al vi а что говорят звёзды, вы узнаете, запустив навык.

La problemo estas, ke por konservi eĉ tian simplan dialogon, vi devas memori la nomon kaj daton de naskiĝo de la uzanto, kaj en senservila medio tio ne estas bagatela. Ne funkcios stoki la kuntekston en RAM aŭ kiel dosiero sur disko, ĉar Yandex.Cloud povas ruli la funkcion sur pluraj virtualaj maŝinoj samtempe kaj ŝanĝi inter ili arbitre. Vi devos uzi ian eksteran stokadon. Objekta Stokado estis elektita kiel sufiĉe malmultekosta kaj simpla stokado rekte en Yandex.Cloud (tio estas, verŝajne rapida). Kiel senpaga alternativo, vi povas provi, ekzemple, senpagan pecon Nuba Mongi ie malproksime. Ambaŭ Object Storage (ĝi subtenas la S3-interfacon) kaj Mongo havas oportunajn Python-envolvaĵojn.

Alia problemo estas, ke por iri al Object Storage, MongoDB, kaj ajna alia datumbazo aŭ datumvendejo, vi bezonas iujn eksterajn dependecojn, kiujn vi devas alŝuti al Yandex Functions kune kun via funkcia kodo. Kaj mi ŝatus fari ĝin komforte. Ĝi estas tute oportuna (kiel ĉe heroku), ve, ĝi ne funkcios, sed vi povas krei iom da baza komforto skribante skripton por konstrui la medion (fari dosieron).

Kiel komenci la horoskopan kapablon

  1. Preparu: iru al iu maŝino kun Linukso. Principe, vi verŝajne ankaŭ povas labori kun Vindozo, sed tiam vi devas elvoki kun la lanĉo de la makedosiero. Kaj ĉiukaze, vi bezonos almenaŭ 3.6 instalitan Python.
  2. Klonu el github ekzemplo de horoskopa kapablo.
  3. Registriĝi en Ya.Cloud: https://cloud.yandex.ru
  4. Kreu al vi du sitelojn enen Stokado de Objektoj, voku ilin per iu ajn nomo {BUCKET NAME} и tgalice-test-cold-storage (ĉi tiu meza nomo nun estas malmola kodita en main.py mia ekzemplo). La unua sitelo estos bezonata nur por deplojo, la dua - por stoki dialogŝtatojn.
  5. krei servo konto, donu al li rolon editor, kaj ricevu senmovajn akreditaĵojn por ĝi {KEY ID} и {KEY VALUE} - ni uzos ilin por registri la staton de la dialogo. Ĉio ĉi estas necesa por ke la funkcio de Ya.Cloud povu aliri la stokadon de Ya.Cloud. Iam, mi esperas, rajtigo fariĝos aŭtomata, sed nuntempe — tiel.
  6. (Laŭvola) instali komandlinia interfaco yc. Vi ankaŭ povas krei funkcion per la retinterfaco, sed la CLI estas bona ĉar ĉiaj novigoj aperas en ĝi pli rapide.
  7. Nun vi povas, fakte, prepari la aron de dependecoj: rulu sur la komandlinio de la dosierujo kun la lerta ekzemplo make all. Aro da bibliotekoj (plejparte, kiel kutime, nenecesaj) estos instalitaj en la dosierujo dist.
  8. Plenigu per plumoj en Objektan Stokadon (en sitelon {BUCKET NAME}) la arkivo akirita ĉe la antaŭa paŝo dist.zip. Se vi volas, vi ankaŭ povas fari tion de la komandlinio, ekzemple, uzante AWS CLI.
  9. Kreu senservilan funkcion per la retinterfaco aŭ uzante la ilon yc. Por la utileco, la komando aspektos jene:

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

Dum permane kreado de funkcio, ĉiuj parametroj estas plenigitaj en la sama maniero.

Nun la funkcio, kiun vi kreis, povas esti provita per la programisto-konzolo, kaj poste finpretigita kaj publikigita lerteco.

Krei ŝtatan kapablon por Alice pri la senservilaj funkcioj de Yandex.Cloud kaj Python

Kio estas sub la kapuĉo

La makedosiero fakte enhavas sufiĉe simplan skripton por instali dependecojn kaj meti ilin en arkivon. dist.zip, io kiel ĉi tio:

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

La resto estas kelkaj simplaj iloj envolvitaj en biblioteko tgalice. La procezo de plenigado de uzantdatenoj estas priskribita per la agordo 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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

La python-klaso transprenas la laboron analizi ĉi tiun agordon kaj kalkuli la finan rezulton

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

Pli precize, la baza klaso FormFillingDialogManager okupiĝas pri plenigo de la "formularo", kaj la metodo de la infana klaso handle_completed_form diras kion fari kiam ŝi estas preta.

Krom ĉi tiu ĉefa fluo de dialogo, la uzanto ankaŭ devas esti salutita, kaj ankaŭ doni helpon pri la "helpo" komando kaj liberigi de la kapablo sur la "eliro" komando. Por ĉi tio en tgalice ekzistas ankaŭ ŝablono, do la tuta dialogadministrilo konsistas el pecoj:

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 funkcias simple: ĝi provas apliki al la nuna stato de la dialogo ĉiujn ĝiajn komponantojn laŭvice, kaj elektas la unuan koncernan.

Kiel respondo al ĉiu mesaĝo, la dialogmanaĝero resendas pitonan objekton Response, kiu tiam povas esti konvertita en simplan tekston, aŭ en mesaĝon en Alico aŭ Telegramo - depende de kie la roboto funkcias; ĝi ankaŭ enhavas la ŝanĝitan staton de la dialogo, kiu devas esti konservita. Ĉio ĉi kuirejo estas pritraktata de alia klaso, DialogConnector, do la rekta skripto por komenci lertecon en Yandex Functions aspektas jene:

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

Kiel vi povas vidi, la plej granda parto de ĉi tiu kodo kreas konekton al la interfaco Object Storage S3. Kiel ĉi tiu rilato estas rekte uzata, vi povas legi en tgalice kodo.
La lasta linio kreas funkcion alice_handler - tiu, kiun ni ordonis tiri Yandex.Cloud kiam ni fiksas la parametron --entrypoint=main.alice_handler.

Tio, fakte, estas ĉio. Makefiles por konstruado, S3-simila Object Storage por kunteksta stokado, kaj python-biblioteko tgalice. Kune kun la senservilaj trajtoj kaj esprimkapablo de python, ĉi tio sufiĉas por disvolvi la lertecon de sana homo.

Vi povas demandi kial vi bezonas krei tgalice? Ĉiu enuiga kodo, kiu transdonas JSONojn de peto al respondo kaj de stokado al memoro kaj reen kuŝas en ĝi. Ekzistas ankaŭ regula aplikaĵo, funkcio por kompreni ke "februaro" similas al "februaro", kaj aliaj NLU por malriĉuloj. Laŭ mia ideo, ĉi tio jam sufiĉu por povi skizi lertajn prototipojn en yaml-dosieroj sen esti tro distrita de teknikaj detaloj.

Se vi volas pli seriozan NLU, vi povas ŝraŭbi ĝin al via kapablo ĜustoProfundePavlov, sed starigi ilin postulos plian dancadon per tamburino, precipe ĉe senservilo. Se vi tute ne emas kodi, vi devus uzi la vidan tipkonstruktilon Aimylogic. Kreante tgalice, mi pensis pri ia meza vojo. Ni vidu kio okazas.

Nu, nun aliĝu Aliy-kapabloj babilejo por programistoj, legi dokumentadokaj kreu mirindan kapabloj!

fonto: www.habr.com

Aldoni komenton