إنشاء مهارة ذات حالة لـ Alice على وظائف بدون خادم في Yandex.Cloud و Python

لنبدأ بالأخبار. أعلنت Yandex.Cloud أمس عن إطلاق خدمة حوسبة بدون خادم وظائف سحابة Yandex. هذا يعني أنك تكتب رمز الخدمة فقط (على سبيل المثال ، تطبيق ويب أو روبوت محادثة) ، وتقوم السحابة نفسها بإنشاء وصيانة الأجهزة الافتراضية حيث يتم تشغيلها ، بل وتكررها إذا زاد الحمل. لا داعي للتفكير على الإطلاق ، إنه أمر مريح للغاية. ويتم الدفع فقط لوقت الحسابات.

ومع ذلك ، قد لا يدفع بعض الناس على الإطلاق. هؤلاء هم المطورون مهارات أليس الخارجية، أي روبوتات المحادثة المضمنة فيها. يمكن لأي مطور كتابة واستضافة وتسجيل هذه المهارة ، ومن اليوم لا تحتاج المهارات حتى إلى الاستضافة - فقط قم بتحميل الكود الخاص بهم إلى السحابة في النموذج نفس الوظيفة بدون خادم.

ولكن هناك بعض الفروق الدقيقة. أولاً ، قد يتطلب رمز حيوانك الأليف بعض التبعيات ، وليس من التافه سحبها إلى السحابة. ثانيًا ، يحتاج أي روبوت محادثة عادي إلى تخزين حالة الحوار في مكان ما (لذلك يكون ذا الحالة) ؛ كيفية القيام بذلك في وظيفة بدون خادم بأسهل طريقة؟ ثالثًا ، كيف يمكنك كتابة مهارة سريعة وقذرة لأليس أو حتى نوع من الروبوتات بمؤامرة غير صفرية؟ حول هذه الفروق الدقيقة ، في الواقع ، المقال.

إنشاء مهارة ذات حالة لـ Alice على وظائف بدون خادم في Yandex.Cloud و Python

التحضير الأخلاقي

بالنسبة إلى نفاد الصبر: أقوم بجمع التبعيات الضرورية باستخدام ملف makefile قبل تحميل الوظيفة إلى السحابة ، وأقوم بتخزين حالة مربع الحوار في Yandex Object Storage (يدعم S3 API) ، وأستخدم مكتبتي الخاصة لإدارة مربع الحوار تجاليس. نتيجة لذلك ، اتضح مثل مهارة العرض. والآن دعونا نحلل كل هذا بمزيد من التفصيل.

بالنسبة للأشخاص الأقل صبرًا ، قبل الغوص في قصتي عن التعقيد ، أوصي بشدة بالبدء ببساطة. وبالتحديد ، قم بإنشاء وظيفة echobot ذات ملف واحد ، وقم بتسجيلها واختبارها في وحدة تحكم مطور Dialog ؛ التفاصيل - في حوارات المدونة и التوثيق السحابي. وعندها فقط تبدأ.

إذا كنت تريد أن تشعر على الفور بما نقاتل من أجله ، فاسأل أليس 'شغّل مهارة "برج تكنولوجيا المعلومات"". ينبغي إجراء الحوار التالي:

أليس: مرحبًا! أنت في مهارة "برج تكنولوجيا المعلومات". قل "ابدأ" لمعرفة ما وعدك به النجوم.
المستخدم: ابدأ
ج: يرجى ذكر اسمك.
Yu: فاسيسالي
ج: الآن أخبرني بسنة ولادتك. أربعة أرقام فقط ، لا أكثر.
يو: الثاني
ج: يرجى المحاولة مرة أخرى. اذكر سنة ميلادك - أربعة أرقام.
يو: 2002
عظيم! الآن اسم شهر ميلادك.
يو: فبراير
عظيم! أخيرًا ، أخبرني بتاريخ ميلادك - مجرد رقم ، رقم واحد أو رقمان فقط.
يو: 18
ج: شكرا لك يا فاسيسوال! الآن نحن نعلم: عمرك 17 عامًا وأنت برج الدلو. ها أنت محظوظ بالطبع! تخبرك النجوم а что говорят звёзды, вы узнаете, запустив навык.

تكمن المشكلة في أنه للحفاظ على مثل هذا الحوار البسيط ، عليك أن تتذكر اسم المستخدم وتاريخ ميلاده ، وهذا ليس بالأمر التافه في بيئة لا تحتوي على خادم. لن يعمل على تخزين السياق في ذاكرة الوصول العشوائي أو كملف على القرص ، لأن يمكن لـ Yandex.Cloud تشغيل الوظيفة على العديد من الأجهزة الافتراضية في نفس الوقت والتبديل بينها بشكل تعسفي. سيكون عليك استخدام نوع من التخزين الخارجي. تم اختيار تخزين الكائنات على أنه تخزين بسيط وغير مكلف إلى حد ما مباشرة في Yandex.Cloud (ربما يكون سريعًا). كبديل مجاني ، يمكنك تجربة قطعة مجانية على سبيل المثال منجي غائم في مكان ما بعيدًا. يحتوي كل من Object Storage (يدعم واجهة S3) و Mongo على أغلفة ملائمة من Python.

هناك مشكلة أخرى وهي أنه من أجل الانتقال إلى Object Storage و MongoDB وأي قاعدة بيانات أو مخزن بيانات آخر ، فأنت بحاجة إلى بعض التبعيات الخارجية التي تحتاج إلى تحميلها إلى وظائف Yandex جنبًا إلى جنب مع رمز الوظيفة الخاص بك. وأود أن أفعل ذلك بشكل مريح. إنه ملائم تمامًا (كما هو الحال في heroku) ، للأسف ، لن يعمل ، ولكن يمكنك إنشاء بعض الراحة الأساسية من خلال كتابة نص برمجي لبناء البيئة (إنشاء ملف).

كيف تبدأ مهارة برجك

  1. استعد: انتقل إلى بعض الأجهزة مع Linux. من حيث المبدأ ، ربما يمكنك العمل مع Windows أيضًا ، ولكن بعد ذلك عليك أن تستحضر إطلاق makefile. وعلى أي حال ، سوف تحتاج إلى تثبيت Python 3.6 على الأقل.
  2. استنساخ من جيثب مثال على مهارة برجك.
  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. املأ بالأقلام في تخزين الكائنات (في دلو {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

عند إنشاء دالة يدويًا ، يتم ملء جميع المعلمات بنفس الطريقة.

الآن يمكن اختبار الوظيفة التي قمت بإنشائها من خلال وحدة تحكم المطور ، ثم إنهاء ونشر المهارة.

إنشاء مهارة ذات حالة لـ Alice على وظائف بدون خادم في 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. يتم وصف عملية ملء بيانات المستخدم بواسطة 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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

تتولى فئة python مهمة تحليل هذا التكوين وحساب النتيجة النهائية

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 تخبر ماذا تفعل عندما تكون جاهزة.

بالإضافة إلى هذا التدفق الرئيسي لحوار المستخدم ، من الضروري أيضًا الترحيب بالمستخدم ، بالإضافة إلى إصدار المساعدة بشأن أمر "المساعدة" والإفراج عن المهارة في أمر "الخروج". لهذا في 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، والتي يمكن تحويلها بعد ذلك إلى نص عادي ، أو إلى رسالة في Alice أو Telegram - اعتمادًا على مكان تشغيل الروبوت ؛ يحتوي أيضًا على الحالة المتغيرة لمربع الحوار الذي يجب حفظه. يتم التعامل مع كل هذا المطبخ من قبل فئة أخرى ، DialogConnector، لذلك يبدو النص المباشر لبدء مهارة على وظائف Yandex كما يلي:

...
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. كيف يتم استخدام هذا الاتصال مباشرة ، يمكنك أن تقرأ في كود تجاليس.
السطر الأخير ينشئ دالة alice_handler - الذي طلبناه لسحب Yandex.Cloud عندما قمنا بتعيين المعلمة --entrypoint=main.alice_handler.

هذا ، في الواقع ، كل شيء. ملفات Makefiles للبناء ، وتخزين الكائنات على غرار S3 لتخزين السياق ، ومكتبة python tgalice. جنبًا إلى جنب مع الميزات التي لا تحتوي على خادم وتعبير Python ، هذا كافٍ لتطوير مهارة الشخص السليم.

قد تسأل لماذا تحتاج إلى إنشاء tgalice؟ كل التعليمات البرمجية المملة التي تنقل JSONs من الطلب إلى الاستجابة ومن التخزين إلى الذاكرة والعودة تكمن فيها. هناك أيضًا تطبيق منتظم ، وظيفة لفهم أن "فبراير" مشابه لـ "فبراير" ، وأخرى NLU للفقراء. وفقًا لفكرتي ، يجب أن يكون هذا كافيًا بالفعل لتكون قادرًا على رسم نماذج أولية للمهارات في ملفات yaml دون تشتيت انتباهك كثيرًا بالتفاصيل الفنية.

إذا كنت تريد NLU أكثر جدية ، فيمكنك أن تفسدها لمهاراتك راسا أو ديب بافلوف، لكن إعدادهم سيتطلب رقصًا إضافيًا مع الدف ، خاصة على الخادم. إذا كنت لا ترغب في الترميز على الإطلاق ، فيجب عليك استخدام مُنشئ النوع المرئي ايميلوجيك. عند إنشاء tgalice ، فكرت في نوع من المسار الوسيط. دعونا نرى ما سيحدث.

حسنًا ، انضم الآن مطور مهارات عاليه دردشة، اقرأ الوثائقوخلق مذهل مهارات!

المصدر: www.habr.com

إضافة تعليق