Yandex Cloud-da serverless funksiyaları və Python istifadə edərək Aliqa üçün stateful bacarığın yaradılması

Gəlin yeniliklərlə başlayaq. Dünən Yandex. Cloud serversiz hesablama xidmətinin başladığını elan etdi. Yandex Cloud Functions. Bu, o deməkdir ki: siz yalnız xidmətinizin kodunu (məsələn, veb tətbiqi və ya chatbot) yazırsınız, və Cloud özü virtual maşınlar yaradır və idarə edir, onları işə salır və yük artdıqda hətta replika edir. Ümumiyyətlə düşünməyə ehtiyac yoxdur, çox rahatdır. Və ödəmə yalnız hesablama müddətinə görədir.

Ancaq bəziləri tamamilə ödəniş etməyə bilər. Bu, - doqquz bacarıqları olan programçılardır Alisanın, yəni ona inteqrasiya edilmiş chatbotlar. Belə bir bacarıq yaratmaq, host etmək və qeydə almaq hər bir proqramçı tərəfindən mümkündür, və bu gündən etibarən bacarıqları host etməyə ehtiyac yoxdur - sadəcə kodu buludda yerləşdirmək kifayətdir. b именно bu serversiz funksiyadır..

Amma bir neçə nüans var. Birincisi, sizin python kodu bəlkə də hansısa asılılıqlara ehtiyac duyur və onları Cloud-a gətirmək - asan deyil. İkincisi, hər bir normal chatbotun dialoq vəziyyətini bir yerdə saxlamaq lazımdır (stateful olduğu üçün); bunu serversiz funksiyada ən asan necə etmək olar? Üçüncüsü, belə bir bot üçün (müəyyən bir süjetli) bacarıq tez və çirkli necə yazılmalıdır? Bu nüanslar, əslində, bu məqalənin mövzusudur.

Yandex Cloud-da serverless funksiyaları və Python istifadə edərək Aliqa üçün stateful bacarığın yaradılması

Mənəvi hazırlıq

Təcrübəsiz olanlar üçün: mən lazımi asılılıqları buluda funksiyanı yükləməzdən əvvəl make-fayl ilə yığılır, dialoq vəziyyətini Yandex-in Object Storage-da saxlayıram (bu, S3 API-ni dəstəkləyir), və dialoqu idarə etmək üçün öz kitabxanamı istifadə edirəm tgalice. Nəticədə belə bir demo-bacarıq alırıq. İndi bu mövzunu bir az daha ətraflı müzakirə edək. Bir az daha səbirsiz olanlar üçün: mənim çətinliklərim haqqında hekayəmə girməzdən əvvəl, sadə bir şeylə başlamağı tövsiyə edirəm. Yəni, tək fayl olan bir echo-bot funksiyası yaratmaq, onu qeyd etmək və inkişaf etdirici konsolda test etmək; ətraflı məlumat -

Dialoqlar blogunda Cloud dokumentasiyasında. Və yalnız sonra başlayın.Əgər dərhal nə uğrunda mübarizə apardığımızı hiss etmək istəyirsinizsə, Alisdən ‘

‘it-şans funqiyasını aç’ deyərkən soruşun. Təxminən belə bir dialoq baş verməlidir:Alisa: Salam! Siz ‘İT Şans’ bacarığında yerləşirsiniz. ‘Başla’ deyərək, sizə ulduzların nə göstərəcəyini öyrənin.İstifadəçi: Başla

A: Zəhmət olmasa, adınızı deyin.
İ: Vasisiualiy
A: İndi doğum ilinizi deyin. Yalnız dörd rəqəm, heç bir əşya deyil.
İ: ikinci
A: Zəhmət olmasa, bir daha cəhd edin. Doğum ilinizi deyin - dörd rəqəm.
İ: 2002
A: Əla! İndi doğum ayınızı deyin.
İ: Fevral
A: Mükəmməl! Nəhayət, doğum tarixini - yalnız bir və ya iki rəqəmli bir ədəd söyləyin.
İ: 18
A: Təşəkkür edirəm, Vasisiualiy! İndi bilirik ki, siz 17 yaşındasınız və Dolça bürcüsünüz. Bu sizə əlbəttə ki, şans gətirdi! Ulduzlar sizə deyir:
Ulduzların nə dediğini, bacarığı işə saldıqdan sonra öyrənirsiniz.
А: Спасибо, Васисуалий! Теперь мы знаем: вам 17 лет, и вы Водолей. Вот это вам, конечно, повезло! Звёзды говорят вам: а что говорят звёзды, вы узнаете, запустив навык.

Problemin mənbəyi, belə sadə bir dialoqu davam etdirmək üçün istifadəçinin adını və doğum tarixini xatırlamaq lazım olmasıdır; bu isə serverless funksiyalar mühitində asan deyil. Konteksdə məlumatı yaddaşda və ya diskin bir faylında saxlamaq mümkün deyil, çünki Yandex Cloud eyni anda bir neçə virtual maşında funksiyanı işə sala bilər və aralarında sərbəst keçid edə bilər. Bunun üçün xarici bir saxlama istifadə etməlisiniz. Obraz, Yandex Cloud-da ucuz və sadə bir saxlama olaraq seçildi (yəni, sürətli olmalıdır). Pulsuz alternativ kimi, məsələn, pulsuz bir parça sınaya bilərsiniz. buludlu Mongo bir yerdə. Həm Object Storage (S3 interfeysi dəstəkləyir), həm də Mongo üçün rahat Python örtükləri var.

Digər problem isə budur ki, Object Storage-da, MongoDB-də və ya hər hansı digər verilənlər bazasında və ya saxlama düzeyinə giriş üçün xarici asılılıqlar tələb olunur; bunları Yandex Functions-a kodunuzla yükləmək lazımdır. Bunun rahat bir şəkildə edilməsini istəyirəm. Tamamilə rahat bir şəkildə (məsələn, heroku kimi) etmək mümkün olmayacaq, amma bir az əsas rahatlıq yaratmaq üçün mühitin toplanması üçün bir skript yazmaq mümkündür (make faylı).

Ulduz falını necə işə salmaq olar

  1. Hazırlıq: Linux ilə işləyən bir kompüterə daxil olun. Əslində, Windows ilə də işləmək mümkündür, amma make faylı ilə işləmə üçün bir az çətinlik çəkəcəm. Hər halda, Python 3.6-dan aşağı olmayan bir versiya quraşdırmalısınız.
  2. GitHub-dan özünə klonlamaq ulduz falı nümunəsi.
  3. Yandex Cloud-da qeydiyyatdan keçmək: https://cloud.yandex.ru
  4. İki çən yaratmalısınız seçirik, düyməyəistədiyiniz adla {BUCKET NAME}tgalice-test-cold-storage (bu ikinci ad hazırda main.py nümunəmdə saklanır). İlk çən yalnız yerləşdirmə üçün lazım olacaq, ikinci çən isə dialoq vəziyyətlərini saxlamaq üçün istifadə ediləcək.
  5. hər iki mənbə sahəsi üzrə və ya mövcud birini ikinci ilə sahələri ilə genişləndirmək. xidmət hesabı, ona redaktorrolunu vermək , və statik akreditivlərini əldə etmək{KEY ID} {KEY VALUE}
  6. — bunları dialoq vəziyyətini yazmaq üçün istifadə edəcəyik. Bütün bunlar, Yandex Cloud-dan funksiyanın Yandex Cloud-dakı saxlama ilə əlaqə qura bilməsi üçün lazımdır. Ümid edirəm ki, bir gün bu, avtomatik olacaq, amma indilik belədir. Komanda xətti interfeysi (İstəyə bağlı) quraşdırmaqyc.
  7. Bir funksiyanı veb interfeysindən yaratmaq olar, amma CLI-nin üstünlüyü ondan ibarətdir ki, burada müxtəlif yeniliklər daha tez görünür. İndi asılılıqların toplanmasını hazırlaya bilərsiniz: nümunə bacarıqından olan qovluqdan komandalar psixologiyasındamake all. dist.
  8. Əvvəlki addımda yaradılmış arxivi Object Storage-da (çən {BUCKET NAME}) əllə yükləyin. İstəsəniz, bunu komanda sətrindən də edə bilərsiniz, məsələn, istifadə edərək dist.zipAWS CLI Veb interfeysindən və ya alət istifadə edərək serverless funksiya yaradın. Alət üçün komanda belə olacakdır:.
  9. . (İstəyə bağlı) quraşdırmaq.

yc serverless function versiyası yarat
    --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

Əl ilə funksiya yaradarkən, bütün parametrlər eyni şəkildə doldurulur.

İndi yaratdığınız funksiyanı inkişaf etdirici konsol vasitəsilə sınaqdan keçirə, sonra isə bacarıq üzərində işləyə və yayımlaya bilərsiniz.

Yandex Cloud-da serverless funksiyaları və Python istifadə edərək Aliqa üçün stateful bacarığın yaradılması

Nə baş verir?

Make faylı əslində asılılıqları quraşdırmaq və arxivə yığmaq üçün olduqca sadə bir skripti ehtiva edir. dist.zip, təxminən belə:

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

Qalanı isə bir neçə sadə alətdir, kitabxanaya sarılmışdır. tgalice. İstifadəçi məlumatlarının doldurulma prosesi konfiqurasiya ilə təsvir edilir. form.yaml:

form_name: 'horoscope_form'
start:
  regexp: 'stарт|нач(ать|ни)'
  suggests:
    - Start
fields:
  - name: 'name'
    question: Zəhmət olmasa, adınızı deyin.
  - name: 'year'
    question: İndi mənə doğum ilinizin dörd rəqəmini deyin. Yalnız dörd rəqəm, başqa heç nə.
    validate_regexp: '^[0-9]{4}$'
    validate_message: Zəhmət olmasa, yenidən cəhd edin. Doğum ilinizi, dörd rəqəm deyin.
  - name: 'month'
    question: Əla! İndi doğum ayınızı deyin.
    options:
      - yanvar
     ...
      - dekabr
    validate_message: Dediyiniz şey ay kimi görünmür. Zəhmət olmasa, doğum ayınızı, əlavə sözlər olmadan, deyin.
  - name: 'day'
    question: Mükəmməl! Nəhayət, doğum gününüzün ədədini, yalnız bir və ya iki rəqəm deyin.
    validate_regexp: '[0123]?d$'
    validate_message: Zəhmət olmasa, yenidən cəhd edin. Doğum gününüzün ədədini deməlisiniz (məsələn, iyirminci); bu, bir və ya iki rəqəm olmalıdır.

Bu konfiqurasiyanı parçalamaq və yekun nəticəni hesablamaq işini Python sinifi üzərinə götürür.

class CheckableFormFiller(tgalice.dialog_manager.form_filling.FormFillingDialogManager):
    SIGNS = {
        'yanvar': 'Oğlaq',
        ...
    }

    def handle_completed_form(self, form, user_object, ctx):
        response = tgalice.dialog_manager.base.Response(
            text='Təşəkkür edirəm, {}! İndi bilirik: siz {} yaşındasınız və siz {}. n'
                 'Bu sizə əlbəttə ki, köməkçi olur! Ulduzlar sizə deyir: {}'.format(
                form['fields']['name'],
                2019 - int(form['fields']['year']),
                self.SIGNS[form['fields']['month']],
                random.choice(FORECASTS),
            ),
            user_object=user_object,
        )
        return response

Daha dəqiq desək, əsas sinif FormFillingDialogManager «formanın» doldurulması ilə məşğuldur və övlad sinifinin metodu handle_completed_form doldurulduqda nə etməli olduğunu bildirir.

Bundan əlavə, istifadəçinin dialoq axınının qarşılamağı, və «yardım» əmrinə görə kömək göstərməli, «çıxış» əmrinə görə səviyyədən ayrılması lazımdır. Bunun üçün tgalice həmçinin bir şablon var, buna görə də tam dialoq meneceri parçalardan ibarətdir:

dm = tgalice.dialog_manager.CascadeDialogManager(
    tgalice.dialog_manager.GreetAndHelpDialogManager(
        greeting_message=DEFAULT_MESSAGE,
        help_message=DEFAULT_MESSAGE,
        exit_message='Sağ olun, "IT Horoskopu" bacarığına yenidən gəlməyi unutmayın!'
    ),
    CheckableFormFiller(`form.yaml`, default_message=DEFAULT_MESSAGE)
)

CascadeDialogManager belə işləyir: dialoq menecerinin hazırkı vəziyyətinə bütün komponentləri növbə ilə tətbiq etməyə çalışır və ilk uyğun olanını seçir.

Dialoq meneceri hər mesajın cavabı olaraq Python obyekti qaytarır Cavab, bu da daha sonra düz mətinə çevrilə bilər, ya da Aliya ya da Telegramda mesaj olaraq — botun harada işlədiyindən asılı olaraq; burada dialoqun dəyişdirilmiş vəziyyətini saxlamaq lazımdır. Bütün bu işlərlə başqa bir sinif, DialogConnector, ona görə birbaşa Yandex Functions-da bacarığı işə salan skript belə görünür:

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

Gördüyünüz kimi, bu kodun əksər hissəsi S3 obyekt saxlama interfeysinə qoşulma yaradır. Bu qoşulmanın necə istifadə olunduğunu tgalice kodunda oxuya bilərsiniz.
Sonuncu sətir alice_handler — bu, biz Yandex Cloud-a çağırmağı tapşırdığımız o eyni funksiyadır, parametri qoyduqda --entrypoint=main.alice_handler.

Bax, elə budur. Yığma üçün Make-fayllar, kontekstin saxlanması üçün S3-ə bənzər obyekt saxlama və Python kitabxanası. tgaliceBunlar serverless funksiyalar və Python-un ifadəliliyi ilə birlikdə, sağlam insanların bacarığının inkişafı üçün kifayətdir.

Soruşa bilərsiniz ki, niyə bunu yaratmaq lazım idi tgalice? Весь скучный код, перекладывающий JSON’ы из запроса в ответ и из хранилища в память и обратно, лежит в ней. Там же лежит применялка регулярок, функция для понимания того, что «феврарь» похоже на «февраль», и прочее NLU для бедных. По моей задумке, этого уже должно быть достаточно, чтобы можно было набрасывать прототипы навыков в yaml-файлах, не слишком отвлекаясь на технические детали.

Daha ciddi NLU istəyirsinizsə, bacarığınıza RasaDeepPavlov, lakin onların konfiqurasiyası üçün əlavə çətinliklər lazım olacaq, xüsusən serverless-də. Əgər kod yazmaq istəyirsinizsə, Aimylogic kimi vizual quruculardan istifadə etməlisiniz. tgalice yaradarkən, hansısa bir aralıq yol düşünmüşdüm. Bunun nə olacaq, baxarıq.Bu gün isə

Ali bacarıqların inkişaf etdiriciləri sohbetə qoşulun , oxuyun, və möhtəşəm sənədbacarıqlar yaradın bacarıqlar!

Mənbə: habr.com

DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər 🔥 DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər | ProHoster