讓我們從新聞開始。昨天,Yandex.Cloud 宣布推出無伺服器運算服務 。這意味著您只需為您的服務(例如,Web 應用程式或聊天機器人)編寫程式碼,而雲端本身會創建並維護其運行的虛擬機,甚至在負載增加時複製它們。根本不用思考,非常方便。且費用僅針對計算時間。
然而,有些人可能根本不付錢。這些是開發人員 ,也就是內建聊天機器人。任何開發人員都可以編寫、託管和註冊這樣的技能,從今天起,技能甚至不需要託管——只需以 .
但也存在一些細微差別。首先,您的推銷程式碼可能需要一些依賴項,將它們拖入雲端並非易事。其次,任何正常的聊天機器人都需要將對話的狀態儲存在某個地方(這就是它有狀態的原因);在無伺服器功能中執行此操作的最簡單方法是什麼?第三,如何快速而粗略地為 Alice 或任何具有非零情節的機器人編寫技能?事實上,這篇文章就是關於這些細微差別的事。

道德準備
對於不耐煩的人:我在將函數上傳到雲端之前使用 makefile 編譯必要的依賴項,將對話框狀態儲存在 Yandex 物件儲存中(它支援 S3 API),並使用我自己的函式庫來管理對話框 。結果是 演示技能。現在讓我們更詳細地看一下這一切。
對於不太有耐心的人,在深入了解我的複雜故事之前,我強烈建議先從簡單的事情開始。即創建一個單文件的echobot函數,並在Dialogs開發者控制台中進行註冊和測試;詳細信息-在 и 。然後才開始。
如果你想立即感受到我們在這裡為之奮鬥的目標,那就問問愛麗絲吧。'。應該會出現以下對話:
愛麗絲:你好!您正處於「IT 星座運勢」技能階段。說“開始”來了解星星為您準備了什麼。
使用者:開始
答:請說出您的姓名。
於:瓦西里
A:現在告訴我您的出生年份。僅四位數字,僅此而已。
餘:第二
答:請再試一次。請提供您的出生年份 - 四位數字。
年齡:2002
答:太棒了!現在說出您的出生月份。
Y:二月
答:太棒了!最後,告訴我您的出生日期——只是一個數字,只有一位或兩位數字。
年齡:18
A:謝謝你,瓦西里!現在我們知道了:你17歲,是水瓶座。你確實很幸運!星象告訴你: а что говорят звёзды, вы узнаете, запустив навык.
問題在於,即使要維持這樣簡單的對話,您也需要記住使用者的姓名和出生日期,而在無伺服器功能環境中,這並非易事。無法將上下文儲存在 RAM 中或作為磁碟上的文件,因為 Yandex.Cloud 可以在多個虛擬機器上同時運行該功能並在它們之間任意切換。您必須使用一些外部儲存。物件儲存被選為 Yandex.Cloud 中直接的一種相當便宜且簡單的儲存(即可能速度很快)。作為免費的替代方案,您可以嘗試例如免費作品 某個遙遠的地方。物件儲存(它支援 S3 介面)和 Mongo 都有方便的 Python 包裝器。
另一個問題是,要轉到物件儲存、MongoDB 和任何其他資料庫或資料存儲,您需要一些外部依賴項,這些依賴項需要與您的函數程式碼一起上傳到 Yandex Functions。我希望能夠方便地做到這一點。不幸的是,它不會完全方便(就像在 Heroku 上一樣),但可以透過編寫用於組裝環境的腳本(make 檔案)來創造一些基本的舒適感。
如何啟動星座技能
- 準備工作:登入任一台執行 Linux 的機器。基本上,只需… Windows 這或許可行,但運行 Makefile 需要一些技巧。而且無論如何,你需要安裝 Python 3.6 或更高版本。
- 從 GitHub 克隆 .
- 在 Yandex.Cloud 註冊:
- 為自己創建兩個儲存桶 ,用任何名字稱呼他們
{BUCKET NAME}иtgalice-test-cold-storage(這個第二個名字現在被硬編碼在main.py我的例子)。第一個儲存桶僅用於部署,第二個儲存桶用於儲存對話狀態。 - 創建 ,給他一個角色
editor並取得其靜態憑證{KEY ID}и{KEY VALUE}— 我們將用它們來記錄對話的狀態。所有這些都是必要的,以便 Yandex.Cloud 的功能可以存取 Yandex.Cloud 的儲存。我希望有一天授權能夠自動化,但目前情況就是這樣。 - (可選)安裝
yc。您也可以透過 Web 介面建立功能,但 CLI 更好,因為各種創新可以更快出現在其中。 - 現在您可以實際準備依賴項建置:從包含範例技能的資料夾在命令列中執行它
make all。資料夾中將安裝一堆庫(大多數,像往常一樣,是不必要的)dist. - 手動上傳到對象存儲(存儲桶)
{BUCKET NAME})上一步驟取得的檔案dist.zip。如果您願意,您可以從命令列執行此操作,例如使用 . - 透過 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手動建立函數時,所有參數都以相同的方式填寫。
現在您可以透過開發者控制台測試您創建的功能,然後完善和發布該技能。

底層原理
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 物件儲存介面的連線。您可以閱讀有關如何直接使用此連接 .
最後一行建立函數 alice_handler — 與我們設定參數時告訴 Yandex.Cloud 拉取的相同 --entrypoint=main.alice_handler.
嗯,事實上就是這樣。用於建置的 Makefile、用於儲存上下文的類似 S3 的物件儲存以及 Python 庫 tgalice。再加上無伺服器函數和 Python 的表現力,這足以培養一個健康人的技能。
你可能會問為什麼需要創建 tgalice?將 JSON 從請求移動到回應、從儲存移動到記憶體並返回的所有無聊代碼都包含在其中。還有一個正則表達式應用程序,一個用於理解“February”與“February”相似的函數,以及其他針對窮人的NLU。在我看來,這已經足以能夠在 yaml 檔案中勾勒出技能的原型,而不會被技術細節分散太多注意力。
如果你想要更嚴肅的 NLU,你可以將它附加到你的技能中 或 ,但設定它們將需要一些額外的工作,特別是在無伺服器上。如果你根本不想寫程式碼,那麼你應該使用像 。當我創建 tgalice 時,我正在考慮某種中間路徑。讓我們看看結果如何。
好吧,現在加入 , 讀 ,創造精彩 !
來源: www.habr.com
