ایجاد یک مهارت حالتی برای آلیس در توابع بدون سرور Yandex.Cloud و Python

بیایید با اخبار شروع کنیم. دیروز Yandex.Cloud راه اندازی یک سرویس محاسباتی بدون سرور را اعلام کرد توابع ابر یاندکس. این به این معنی است که: شما فقط کد سرویس خود را می نویسید (مثلاً یک برنامه وب یا یک ربات چت)، و Cloud خودش ماشین های مجازی را در جایی که اجرا می کند ایجاد و نگهداری می کند و حتی در صورت افزایش بار آنها را تکرار می کند. اصلا نیازی نیست فکر کنید، خیلی راحت است. و پرداخت فقط برای زمان محاسبه است.

با این حال، برخی ممکن است اصلاً پرداخت نکنند. اینها توسعه دهندگان هستند مهارت های بیرونی آلیس، یعنی چت ربات های ساخته شده در آن. هر توسعه‌دهنده‌ای می‌تواند چنین مهارتی را بنویسد، میزبانی کند و ثبت کند، و از امروز مهارت‌ها حتی نیازی به میزبانی ندارند - فقط کد آنها را به شکل ابری در فضای ابری آپلود کنید. همان عملکرد بدون سرور.

اما چند تفاوت ظریف وجود دارد. اولاً، ممکن است کد حیوان خانگی شما به برخی وابستگی‌ها نیاز داشته باشد و کشیدن آن‌ها به داخل Cloud بی‌اهمیت نیست. ثانیاً، هر چت بات معمولی باید وضعیت گفتگو را در جایی ذخیره کند (بنابراین حالتی). چگونه می توان آن را در یک عملکرد بدون سرور به ساده ترین راه انجام داد؟ ثالثاً، چگونه می توان یک مهارت سریع و کثیف برای آلیس یا حتی نوعی ربات با طرح غیر صفر نوشت؟ در مورد این تفاوت های ظریف، در واقع، مقاله.

ایجاد یک مهارت حالتی برای آلیس در توابع بدون سرور Yandex.Cloud و Python

آمادگی اخلاقی

برای افراد کم حوصله: من قبل از آپلود تابع در ابر، وابستگی های لازم را با یک فایل ساخت جمع آوری می کنم، وضعیت گفتگو را در Yandex Object Storage ذخیره می کنم (این برنامه از S3 API پشتیبانی می کند) و از کتابخانه خودم برای مدیریت گفتگو استفاده می کنم. tgalice. در پایان معلوم می شود چنین مهارت دمو و اکنون بیایید همه اینها را با جزئیات بیشتری تجزیه و تحلیل کنیم.

برای کسانی که کمی کم حوصله هستند، قبل از غوطه ور شدن در داستان من در مورد پیچیدگی، به شدت توصیه می کنم با چیز ساده شروع کنند. یعنی یک تابع echobot تک فایلی ایجاد کنید، آن را در کنسول توسعه دهنده Dialogs ثبت و آزمایش کنید. جزئیات - در وبلاگ دیالوگ и اسناد ابری. و تنها پس از آن شروع کنید.

اگر می خواهید بلافاصله احساس کنید که ما برای چه چیزی می جنگیم، از آلیس بپرسید.مهارت "فال IT" را فعال کنید'. دیالوگی شبیه به زیر باید رخ دهد:

آلیس: سلام! شما در مهارت "فال IT" هستید. بگویید «شروع کن» تا بدانید ستاره‌ها چه قولی به شما می‌دهند.
کاربر: شروع کنید
پاسخ: لطفا نام خود را ذکر کنید.
یو: واسیسوالی
ج: حالا سال تولدت را بگو. فقط چهار رقمی، هیچ چیز اضافی.
یو: دوم
پاسخ: لطفا دوباره امتحان کنید. سال تولد خود را ذکر کنید - چهار رقمی.
یو: 2002
ج: عالی! اکنون ماه تولد خود را نام ببرید.
یو: فوریه
ج: عالی! در نهایت، تاریخ تولد خود را به من بگویید - فقط یک عدد، فقط یک یا دو رقم.
یو: 18
پاسخ: متشکرم، واسیسوالی! اکنون می دانیم: شما 17 ساله و دلو هستید. خوب، البته، شما خوش شانس هستید! ستاره ها به شما می گویند: а что говорят звёзды, вы узнаете, запустив навык.

مشکل این است که برای حفظ چنین دیالوگ ساده ای، باید نام و تاریخ تولد کاربر را به خاطر بسپارید، و در یک محیط عملکرد بدون سرور این امر بی اهمیت است. ذخیره متن در RAM یا به صورت فایل روی دیسک امکان پذیر نخواهد بود، زیرا Yandex.Cloud می تواند یک عملکرد را همزمان روی چندین ماشین مجازی اجرا کند و به دلخواه بین آنها سوئیچ کند. شما باید از نوعی حافظه خارجی استفاده کنید. Object Storage به عنوان یک ذخیره سازی نسبتاً ارزان و بدون عارضه مستقیماً در Yandex.Cloud (یعنی احتمالاً سریع) انتخاب شد. به عنوان یک جایگزین رایگان، می توانید به عنوان مثال، یک قطعه رایگان را امتحان کنید مونگا ابری جایی دور هم Object Storage (از رابط S3 پشتیبانی می‌کند) و هم Mongo دارای پوشش‌های مناسب پایتون هستند.

مشکل دیگر این است که برای دسترسی به Object Storage، MongoDB، و هر پایگاه داده یا ذخیره داده دیگری، به برخی وابستگی های خارجی نیاز دارید که باید به همراه کد تابع شما در Yandex Functions آپلود شوند. و من می خواهم این کار را به راحتی انجام دهم. متأسفانه، کاملاً راحت نخواهد بود (مانند هروکو)، اما می توان با نوشتن یک اسکریپت برای ساخت محیط (فایل ساخت) مقداری راحتی اولیه ایجاد کرد.

چگونه یک مهارت فال را راه اندازی کنیم

  1. آماده شوید: به دستگاهی با لینوکس بروید. در اصل، احتمالاً می‌توانید با ویندوز هم کار کنید، اما پس از آن باید با راه‌اندازی makefile تداعی کنید. و در هر صورت حداقل به 3.6 پایتون نصب شده نیاز دارید.
  2. کلون از github نمونه ای از مهارت طالع بینی.
  3. ثبت نام در Ya.Cloud: https://cloud.yandex.ru
  4. برای خودت دو سطل درست کن ذخیره سازی شی، آنها را با هر نامی صدا کنید {BUCKET NAME} и tgalice-test-cold-storage (این نام دوم اکنون کدگذاری شده است main.py مثال من). سطل اول فقط برای استقرار مورد نیاز است، دومی - برای ذخیره حالت های گفتگو.
  5. ساختن حساب خدمات، به او نقش بدهید editorو برای آن اعتبار ثابت دریافت کنید {KEY ID} и {KEY VALUE} - ما از آنها برای ضبط وضعیت گفتگو استفاده خواهیم کرد. همه اینها برای اینکه تابعی از Ya.Cloud بتواند از Ya.Cloud به فضای ذخیره‌سازی دسترسی پیدا کند، نیاز است. من امیدوارم که روزی مجوز به طور خودکار تبدیل شود، اما در حال حاضر اینطور است.
  6. (اختیاری) نصب کنید رابط خط فرمان yc. شما همچنین می توانید یک تابع از طریق رابط وب ایجاد کنید، اما CLI خوب است زیرا انواع نوآوری ها در آن سریعتر ظاهر می شوند.
  7. اکنون می توانید اسمبلی وابستگی را آماده کنید: آن را در خط فرمان از پوشه با مثال مهارت اجرا کنید. make all. مجموعه ای از کتابخانه ها (عمدتاً، طبق معمول، غیر ضروری) در پوشه نصب می شوند dist.
  8. با قلم در Object Storage (در یک سطل) پر کنید {BUCKET NAME}) آرشیو به دست آمده در مرحله قبل dist.zip. در صورت تمایل، می توانید این کار را از طریق خط فرمان انجام دهید، به عنوان مثال، با استفاده از AWS CLI.
  9. یک عملکرد بدون سرور از طریق رابط وب یا با استفاده از یک ابزار کاربردی ایجاد کنید yc. برای ابزار، دستور به شکل زیر خواهد بود:

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

هنگام ایجاد یک تابع به صورت دستی، تمام پارامترها به یک شکل پر می شوند.

اکنون عملکردی که ایجاد کرده اید می تواند از طریق کنسول توسعه دهنده آزمایش شود و سپس مهارت نهایی و منتشر شود.

ایجاد یک مهارت حالتی برای آلیس در توابع بدون سرور Yandex.Cloud و Python

زیر کاپوت چیه

makefile در واقع حاوی یک اسکریپت نسبتاً ساده برای نصب وابستگی ها و قرار دادن آنها در یک آرشیو است. dist.zip، تقریباً به این صورت است:

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

بقیه چند ابزار ساده است که در یک کتابخانه پیچیده شده اند tgalice. فرآیند پر کردن اطلاعات کاربر توسط پیکربندی توضیح داده شده است 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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

کار تجزیه این پیکربندی و محاسبه نتیجه نهایی توسط کلاس پایتون انجام می شود

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

به طور دقیق تر، کلاس پایه FormFillingDialogManager با پر کردن "فرم" و روش کلاس فرزند سروکار دارد handle_completed_form به او می گوید وقتی آماده شد چه کاری انجام دهد.

علاوه بر این جریان اصلی دیالوگ، باید به کاربر خوشامد گفت و همچنین در دستور "help" کمک کرد و در دستور "خروج" از مهارت رهایی یافت. برای این منظور در tgalice یک الگو نیز وجود دارد، بنابراین کل مدیر گفتگو از قطعات تشکیل شده است:

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 به سادگی کار می کند: سعی می کند تمام اجزای آن را به نوبه خود در وضعیت فعلی گفتگو اعمال کند و اولین مورد مرتبط را انتخاب کند.

مدیر گفتگو یک شی پایتون را به عنوان پاسخ به هر پیام برمی گرداند. Response، که سپس می تواند به متن ساده یا به پیامی در آلیس یا تلگرام تبدیل شود - بسته به جایی که ربات در حال اجرا است. همچنین شامل حالت تغییر یافته دیالوگ است که باید ذخیره شود. کل این آشپزخانه توسط کلاس دیگری اداره می شود، DialogConnector، بنابراین اسکریپت مستقیم برای راه اندازی یک مهارت در Yandex Functions به شکل زیر است:

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

همانطور که می بینید، بیشتر این کد یک اتصال به رابط Object Storage S3 ایجاد می کند. نحوه استفاده مستقیم از این اتصال را می توانید بخوانید در کد tgalice.
خط آخر تابع را ایجاد می کند alice_handler - همان چیزی که به Yandex.Cloud گفتیم وقتی پارامتر را تنظیم می کنیم بکشد --entrypoint=main.alice_handler.

این همه، در واقع. Make-files برای اسمبلی، S3-مانند Object Storage برای ذخیره سازی زمینه، و کتابخانه Python tgalice. همراه با ویژگی های بدون سرور و بیانی پایتون، این برای توسعه مهارت یک فرد سالم کافی است.

ممکن است بپرسید که چرا باید ایجاد کنید tgalice? تمام کدهای خسته کننده ای که JSON ها را از درخواست به پاسخ و از ذخیره سازی به حافظه و برگشت منتقل می کند در آن قرار دارد. همچنین یک برنامه کد معمولی وجود دارد، تابعی برای درک اینکه "فوریه" مشابه "فوریه" است و سایر NLU برای فقرا. طبق ایده من، این باید از قبل کافی باشد تا بتوانید نمونه های اولیه مهارت ها را در فایل های yaml ترسیم کنید، بدون اینکه حواس شما به جزئیات فنی پرت شود.

اگر NLU جدی تری می خواهید، می توانید آن را به مهارت خود متصل کنید رسا یا دیپ پاولوف، اما تنظیم آنها نیاز به رقص اضافی با تنبور دارد، به خصوص در حالت بدون سرور. اگر اصلاً تمایلی به کدنویسی ندارید، باید از یک سازنده بصری مانند استفاده کنید آیمیلوژیک. هنگام ایجاد tgalice، به نوعی مسیر میانی فکر کردم. بذار ببینیم چه اتفاقی میافتد.

خب حالا وارد شوید چت توسعه دهنده مهارت های Aliy، خواندن مستندات، و فوق العاده خلق کنید مهارت ها!

منبع: www.habr.com

اضافه کردن نظر