在 Yandex.Cloud 和 Python 的無服務器功能上為 Alice 創建有狀態技能

讓我們從新聞開始。昨天,Yandex.Cloud 宣布推出無伺服器運算服務 Yandex 雲功能。這意味著您只需為您的服務(例如,Web 應用程式或聊天機器人)編寫程式碼,而雲端本身會創建並維護其運行的虛擬機,甚至在負載增加時複製它們。根本不用思考,非常方便。且費用僅針對計算時間。

然而,有些人可能根本不付錢。這些是開發人員 愛麗絲的外在技能,也就是內建聊天機器人。任何開發人員都可以編寫、託管和註冊這樣的技能,從今天起,技能甚至不需要託管——只需以 相同的無伺服器功能.

但也存在一些細微差別。首先,您的推銷程式碼可能需要一些依賴項,將它們拖入雲端並非易事。其次,任何正常的聊天機器人都需要將對話的狀態儲存在某個地方(這就是它有狀態的原因);在無伺服器功能中執行此操作的最簡單方法是什麼?第三,如何快速而粗略地為 Alice 或任何具有非零情節的機器人編寫技能?事實上,這篇文章就是關於這些細微差別的事。

在 Yandex.Cloud 和 Python 的無服務器功能上為 Alice 創建有狀態技能

道德準備

對於不耐煩的人:我在將函數上傳到雲端之前使用 makefile 編譯必要的依賴項,將對話框狀態儲存在 Yandex 物件儲存中(它支援 S3 API),並使用我自己的函式庫來管理對話框 特加利斯。結果是 這樣 演示技能。現在讓我們更詳細地看一下這一切。

對於不太有耐心的人,在深入了解我的複雜故事之前,我強烈建議先從簡單的事情開始。即創建一個單文件的echobot函數,並在Dialogs開發者控制台中進行註冊和測試;詳細信息-在 對話式部落格 и 雲端文檔。然後才開始。

如果你想立即感受到我們在這裡為之奮鬥的目標,那就問問愛麗絲吧。開啟技能“IT星座”'。應該會出現以下對話:

愛麗絲:你好!您正處於「IT 星座運勢」技能階段。說“開始”來了解星星為您準備了什麼。
使用者:開始
答:請說出您的姓名。
於:瓦西里
A:現在告訴我您的出生年份。僅四位數字,僅此而已。
餘:第二
答:請再試一次。請提供您的出生年份 - 四位數字。
年齡:2002
答:太棒了!現在說出您的出生月份。
Y:二月
答:太棒了!最後,告訴我您的出生日期——只是一個數字,只有一位或兩位數字。
年齡:18
A:謝謝你,瓦西里!現在我們知道了:你17歲,是水瓶座。你確實很幸運!星象告訴你: а что говорят звёзды, вы узнаете, запустив навык.

問題在於,即使要維持這樣簡單的對話,您也需要記住使用者的姓名和出生日期,而在無伺服器功能環境中,這並非易事。無法將上下文儲存在 RAM 中或作為磁碟上的文件,因為 Yandex.Cloud 可以在多個虛擬機器上同時運行該功能並在它們之間任意切換。您必須使用一些外部儲存。物件儲存被選為 Yandex.Cloud 中直接的一種相當便宜且簡單的儲存(即可能速度很快)。作為免費的替代方案,您可以嘗試例如免費作品 多雲的蒙吉 某個遙遠的地方。物件儲存(它支援 S3 介面)和 Mongo 都有方便的 Python 包裝器。

另一個問題是,要轉到物件儲存、MongoDB 和任何其他資料庫或資料存儲,您需要一些外部依賴項,這些依賴項需要與您的函數程式碼一起上傳到 Yandex Functions。我希望能夠方便地做到這一點。不幸的是,它不會完全方便(就像在 Heroku 上一樣),但可以透過編寫用於組裝環境的腳本(make 檔案)來創造一些基本的舒適感。

如何啟動星座技能

  1. 準備工作:登入任一台執行 Linux 的機器。基本上,只需… Windows 這或許可行,但運行 Makefile 需要一些技巧。而且無論如何,你需要安裝 Python 3.6 或更高版本。
  2. 從 GitHub 克隆 星座技巧範例.
  3. 在 Yandex.Cloud 註冊: https://cloud.yandex.ru
  4. 為自己創建兩個儲存桶 對象存儲,用任何名字稱呼他們 {BUCKET NAME} и tgalice-test-cold-storage (這個第二個名字現在被硬編碼在 main.py 我的例子)。第一個儲存桶僅用於部署,第二個儲存桶用於儲存對話狀態。
  5. 創建 服務帳戶,給他一個角色 editor並取得其靜態憑證 {KEY ID} и {KEY VALUE} — 我們將用它們來記錄對話的狀態。所有這些都是必要的,以便 Yandex.Cloud 的功能可以存取 Yandex.Cloud 的儲存。我希望有一天授權能夠自動化,但目前情況就是這樣。
  6. (可選)安裝 命令行界面 yc。您也可以透過 Web 介面建立功能,但 CLI 更好,因為各種創新可以更快出現在其中。
  7. 現在您可以實際準備依賴項建置:從包含範例技能的資料夾在命令列中執行它 make all。資料夾中將安裝一堆庫(大多數,像往常一樣,是不必要的) dist.
  8. 手動上傳到對象存儲(存儲桶) {BUCKET NAME})上一步驟取得的檔案 dist.zip。如果您願意,您可以從命令列執行此操作,例如使用 命令行界面.
  9. 透過 Web 介面或使用實用程式建立無伺服器功能 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 的無服務器功能上為 Alice 創建有狀態技能

底層原理

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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

解析此配置並計算最終結果的工作由 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 工作原理很簡單:它嘗試依序將其所有元件應用到對話的當前狀態,並選擇第一個合適的元件。

作為對每個訊息的回應,對話管理器會傳回一個 Python 物件。 Response,然後可以將其轉換為純文本,或轉換為 Alice 或 Telegram 中的消息 - 具體取決於機器人的運行位置;它還包含對話的修改狀態,需要保存。還有一門課程專門解整個廚房, 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

如您所見,大部分程式碼都會建立與 S3 物件儲存介面的連線。您可以閱讀有關如何直接使用此連接 在 tgalice 代碼中.
最後一行建立函數 alice_handler — 與我們設定參數時告訴 Yandex.Cloud 拉取的相同 --entrypoint=main.alice_handler.

嗯,事實上就是這樣。用於建置的 Makefile、用於儲存上下文的類似 S3 的物件儲存以及 Python 庫 tgalice。再加上無伺服器函數和 Python 的表現力,這足以培養一個健康人的技能。

你可能會問為什麼需要創建 tgalice?將 JSON 從請求移動到回應、從儲存移動到記憶體並返回的所有無聊代碼都包含在其中。還有一個正則表達式應用程序,一個用於理解“February”與“February”相似的函數,以及其他針對窮人的NLU。在我看來,這已經足以能夠在 yaml 檔案中勾勒出技能的原型,而不會被技術細節分散太多注意力。

如果你想要更嚴肅的 NLU,你可以將它附加到你的技能中 Rasa深巴甫洛夫,但設定它們將需要一些額外的工作,特別是在無伺服器上。如果你根本不想寫程式碼,那麼你應該使用像 艾米邏輯。當我創建 tgalice 時,我正在考慮某種中間路徑。讓我們看看結果如何。

好吧,現在加入 Alice 技能開發者聊天, 讀 文件,創造精彩 技能!

來源: www.habr.com

為具有 DDoS 保護、VPS VDS 服務器的站點購買可靠的主機 🔥 購買具備 DDoS 防護的可靠網站寄存服務,包括 VPS 和 VDS 伺服器 | ProHoster