Zacznijmy od wiadomości. Wczoraj Yandex.Cloud ogłosił uruchomienie usługi przetwarzania bezserwerowego . Oznacza to: piszesz tylko kod swojej usługi (na przykład aplikacji internetowej lub chatbota), a Chmura sama tworzy i utrzymuje maszyny wirtualne, na których działa, a nawet replikuje je w przypadku wzrostu obciążenia. Nie musisz w ogóle o tym myśleć, jest to bardzo wygodne. A płatność dotyczy tylko czasu obliczeń.
Niektórzy jednak mogą w ogóle nie płacić. To są deweloperzy , czyli wbudowane w niego chatboty. Każdy programista może napisać, hostować i zarejestrować taką umiejętność, a od dziś umiejętności nie muszą nawet być hostowane — wystarczy przesłać swój kod do chmury w formularzu .
Ale jest kilka niuansów. Po pierwsze, Twój kod pit może wymagać pewnych zależności, a przeciągnięcie ich do chmury nie jest trywialne. Po drugie, każdy normalny chatbot musi gdzieś przechowywać stan dialogu (a zatem stanowy); Jak najłatwiej to zrobić w funkcji bezserwerowej? Po trzecie, jak można napisać szybką umiejętność dla Alicji lub nawet jakiegoś bota z niezerową fabułą? Artykuł dotyczy w rzeczywistości tych niuansów.

przygotowanie moralne
Dla niecierpliwych: zbieram niezbędne zależności za pomocą pliku makefile przed przesłaniem funkcji do chmury, przechowuję stan okna dialogowego w Yandex Object Storage (obsługuje API S3), a do zarządzania oknem wykorzystuję własną bibliotekę . W rezultacie okazuje się umiejętność demonstracyjna. A teraz przeanalizujmy to wszystko bardziej szczegółowo.
Tym, którzy są mniej niecierpliwi, zanim zagłębią się w moją historię o złożoności, gorąco polecam zacząć od czegoś prostego. Mianowicie utwórz jednoplikową funkcję echobota, zarejestruj ją i przetestuj w konsoli programisty Dialogs; szczegóły - w и . I dopiero wtedy zacznij.
Jeśli chcesz od razu poczuć o co tu walczymy, zapytaj Alicję”'. Powinien nastąpić następujący dialog:
Alicja: Cześć! Jesteś w umiejętności „Horoskop IT”. Powiedz „Start”, aby dowiedzieć się, co obiecują Ci gwiazdy.
Użytkownik: Zacznij
O: Proszę podać swoje imię i nazwisko
Yu: Wasilij
Odp.: Teraz podaj mi rok swoich urodzin. Tylko cztery cyfry, nic więcej.
Yu: drugi
O: Spróbuj ponownie. Podaj rok urodzenia – cztery cyfry.
Yu: 2002
Wspaniały! Teraz podaj miesiąc swoich urodzin.
Yu: Luty
Wspaniały! Na koniec podaj swoją datę urodzenia – tylko liczbę, jedną lub dwie cyfry.
Yu: 18
O: Dziękuję, Vasisualy! Teraz już wiemy: masz 17 lat i jesteś Wodnikiem. Cóż, oczywiście, masz szczęście! Gwiazdy mówią Ci: а что говорят звёзды, вы узнаете, запустив навык.
Problem w tym, że aby utrzymać nawet tak prosty dialog, trzeba pamiętać imię i nazwisko oraz datę urodzenia użytkownika, a w środowisku bezserwerowym nie jest to trywialne. Nie będzie działać przechowywanie kontekstu w pamięci RAM lub jako plik na dysku, ponieważ Yandex.Cloud może uruchomić tę funkcję na kilku maszynach wirtualnych jednocześnie i dowolnie przełączać się między nimi. Będziesz musiał użyć jakiejś zewnętrznej pamięci masowej. Object Storage został wybrany jako dość niedrogi i prosty magazyn bezpośrednio w Yandex.Cloud (czyli prawdopodobnie szybki). Jako bezpłatną alternatywę możesz wypróbować na przykład darmowy kawałek gdzieś daleko stąd. Zarówno Object Storage (obsługuje interfejs S3), jak i Mongo mają wygodne opakowania Pythona.
Innym problemem jest to, że aby przejść do Object Storage, MongoDB i dowolnej innej bazy danych lub magazynu danych, potrzebujesz zewnętrznych zależności, które musisz przesłać do Yandex Functions wraz z kodem funkcji. A chciałbym to zrobić wygodnie. Jest to całkowicie wygodne (jak na Heroku), niestety nie zadziała, ale możesz stworzyć sobie pewien podstawowy komfort pisząc skrypt budujący środowisko (tworzący plik).
Jak rozpocząć umiejętność horoskopu
- Przygotuj się: idź na jakąś maszynę z Linuksem. W zasadzie pewnie też da się pracować z Windowsem, ale wtedy trzeba się wyczarować z uruchomieniem pliku makefile. W każdym razie będziesz potrzebować co najmniej zainstalowanego Pythona w wersji 3.6.
- Klon z githuba .
- Zarejestruj się w Ya.Cloud:
- Stwórz sobie dwa wiadra , nazywaj ich dowolnym imieniem
{BUCKET NAME}иtgalice-test-cold-storage(to drugie imię jest teraz zakodowane na stałe wmain.pymój przykład). Pierwszy segment będzie potrzebny tylko do wdrożenia, drugi - do przechowywania stanów dialogowych. - Utworzyć , daj mu rolę
editori uzyskaj dla niego poświadczenia statyczne{KEY ID}и{KEY VALUE}- wykorzystamy je do zarejestrowania stanu dialogu. Wszystko to jest potrzebne, aby funkcja Ya.Cloud mogła uzyskać dostęp do pamięci Ya.Cloud. Mam nadzieję, że kiedyś autoryzacja stanie się automatyczna, ale na razie – tak. - (Opcjonalnie) zainstaluj
yc. Funkcję można też stworzyć poprzez interfejs WWW, jednak CLI jest dobre, bo szybciej pojawiają się w nim wszelkiego rodzaju innowacje. - Teraz możesz już właściwie przygotować zestaw zależności: uruchom go w wierszu poleceń z folderu z przykładem umiejętności
make all. W folderze zostanie zainstalowanych kilka bibliotek (w większości jak zwykle niepotrzebnych).dist. - Wypełnij długopisami magazyn obiektów (do wiadra
{BUCKET NAME}) archiwum uzyskane w poprzednim krokudist.zip. W razie potrzeby możesz to również zrobić z wiersza poleceń, na przykład za pomocą . - Utwórz funkcję bezserwerową za pośrednictwem interfejsu internetowego lub narzędzia
yc. W przypadku narzędzia polecenie będzie wyglądać następująco:
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=3sPodczas ręcznego tworzenia funkcji wszystkie parametry wypełniane są w ten sam sposób.
Teraz utworzoną funkcję można przetestować za pomocą konsoli programisty, a następnie sfinalizować i opublikować umiejętności.

Co kryje się pod maską
Plik makefile faktycznie zawiera dość prosty skrypt do instalowania zależności i umieszczania ich w archiwum. dist.zip, coś takiego:
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 ./*Reszta to kilka prostych narzędzi zamkniętych w bibliotece tgalice. Proces uzupełniania danych użytkownika opisuje konfiguracja 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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.Pracę związaną z analizą tej konfiguracji i obliczeniem końcowego wyniku przejmuje klasa Pythona
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 responseDokładniej, klasa bazowa FormFillingDialogManager zajmuje się wypełnianiem „formularza” i metody klasy podrzędnej handle_completed_form mówi, co ma zrobić, gdy będzie gotowa.
Oprócz tego głównego toku dialogu należy także przywitać użytkownika, udzielić mu pomocy komendą „pomoc” i zwolnić go z umiejętności komendą „wyjdź”. W tym celu w tgalice istnieje również szablon, więc cały menedżer okien dialogowych składa się z elementów:
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 działa po prostu: stara się zastosować do aktualnego stanu dialogu po kolei wszystkie jego elementy i wybiera pierwszy odpowiedni.
W odpowiedzi na każdą wiadomość menedżer okna dialogowego zwraca obiekt Pythona Response, który można następnie zamienić na zwykły tekst lub na wiadomość w Alicji lub Telegramie – w zależności od tego, gdzie bot działa; zawiera także zmieniony stan okna dialogowego, który należy zapisać. Całą tą kuchnią zajmuje się inna klasa, DialogConnector, więc bezpośredni skrypt uruchamiania umiejętności w Yandex Functions wygląda następująco:
...
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_handlerJak widać, większość tego kodu tworzy połączenie z interfejsem Object Storage S3. Jak to połączenie jest bezpośrednio wykorzystywane, możesz przeczytać .
Ostatnia linia tworzy funkcję alice_handler - ten, który zleciliśmy pobranie Yandex.Cloud, gdy ustawimy parametr --entrypoint=main.alice_handler.
Właściwie to wszystko. Pliki Makefile do montażu, obiektowa pamięć masowa podobna do S3 do przechowywania kontekstu i biblioteka Pythona tgalice. W połączeniu z funkcjami bezserwerowymi i ekspresją Pythona wystarczy to, aby rozwinąć umiejętności zdrowej osoby.
Możesz zapytać, dlaczego musisz tworzyć tgalice? Cały nudny kod, który przenosi JSON z żądania do odpowiedzi oraz z pamięci do pamięci i z powrotem, leży w nim. Istnieje również regularna aplikacja, funkcja zrozumienia, że „luty” jest podobny do „lutego” i inne NLU dla biednych. Według mojego pomysłu powinno to już wystarczyć, aby móc szkicować prototypy umiejętności w plikach yaml bez nadmiernego rozpraszania się szczegółami technicznymi.
Jeśli chcesz poważniejszego NLU, możesz to przykręcić do swoich umiejętności lub , ale ich ustawienie będzie wymagało dodatkowych tańców z tamburynem, zwłaszcza na serwerze bez serwera. Jeśli w ogóle nie masz ochoty na kodowanie, powinieneś użyć konstruktora wizualnego, takiego jak . Tworząc tgalice myślałem o jakiejś pośredniej ścieżce. Zobaczmy co się stanie.
Cóż, teraz dołącz , czytać i twórz niesamowite !
Źródło: www.habr.com
