Skapa en tillståndsfull färdighet för Alice på de serverlösa funktionerna i Yandex.Cloud och Python

Låt oss börja med nyheterna. Igår tillkännagav Yandex.Cloud lanseringen av en serverlös databehandlingstjänst Yandex molnfunktioner. Det betyder att du bara skriver koden för din tjänst (till exempel en webbapplikation eller en chatbot), och molnet skapar och underhåller själva de virtuella maskinerna där det körs, och replikerar dem till och med om belastningen ökar. Du behöver inte tänka alls, det är väldigt bekvämt. Och avgiften gäller endast beräkningstiden.

Vissa personer kanske dock inte betalar alls. Dessa är utvecklarna Alices externa färdigheter, det vill säga chatbotar inbyggda i den. Vilken utvecklare som helst kan skriva, hosta och registrera en sådan färdighet, och från och med idag behöver färdigheter inte ens hostas – bara ladda upp sin kod till molnet i formuläret samma serverlösa funktion.

Men det finns ett par nyanser. För det första kan din pitchkod kräva vissa beroenden, och att dra dem till molnet är inte enkelt. För det andra behöver alla vanliga chatbotar lagra dialogens tillstånd någonstans (det är därför den är tillståndskänslig); Vad är det enklaste sättet att göra detta i en serverlös funktion? För det tredje, hur kan man snabbt och enkelt skriva en färdighet för Alice eller någon annan bot med en plot som inte är noll? Artikeln handlar faktiskt om dessa nyanser.

Skapa en tillståndsfull färdighet för Alice på de serverlösa funktionerna i Yandex.Cloud och Python

Moralisk förberedelse

För den otålige: Jag kompilerar de nödvändiga beroendena med en makefile innan jag laddar upp funktionen till molnet, jag lagrar dialogrutans tillstånd i Yandex Object Storage (det stöder S3 API), och jag använder mitt eget bibliotek för att hantera dialogrutan. tgalice. Resultatet är sådan demofärdighet. Låt oss nu titta på allt detta lite mer i detalj.

För de lite mindre otåliga, innan jag dyker in i min berättelse om komplikationer, rekommenderar jag starkt att börja med det enkla. Skapa nämligen en echobot-funktion med en enda fil, registrera och testa den i Dialogs utvecklarkonsol; detaljer - i Dialoger blogg и Molndokumentation. Och först då börja.

Om du omedelbart vill känna vad vi kämpar för här, fråga Aliceaktivera färdigheten "IT-horoskop"'. Följande dialog bör uppstå:

Alice: Hej! Du är i färdigheten "IT-horoskop". Säg "Start" för att ta reda på vad stjärnorna har i beredskap för dig.
Användare: Start
A: Vänligen ange ditt namn.
Yu: Vassily
A: Säg mig nu vilket år du är född. Bara fyra siffror, inget mer.
Yu: andra
A: Försök igen. Ange ditt födelseår – fyra siffror.
År: 2002
A: Underbart! Nämn nu din födelsemånad.
Å: Februari
A: Utmärkt! Slutligen, berätta ditt födelsedatum – bara en siffra, bara en eller två siffror.
År: 18
A: Tack så mycket, Vasilij! Nu vet vi: du är 17 år gammal och du är Vattumannen. Du har sannerligen tur! Stjärnorna säger dig: а что говорят звёзды, вы узнаете, запустив навык.

Problemet är att för att upprätthålla även en så enkel dialog måste man komma ihåg användarens namn och födelsedatum, och i en serverlös funktionsmiljö är detta inte trivialt. Det är inte möjligt att lagra kontexten i RAM eller som en fil på disk, eftersom Yandex.Cloud kan köra funktionen på flera virtuella maskiner samtidigt och växla mellan dem godtyckligt. Du måste använda extern lagring. Objektlagring valdes som en ganska billig och enkel lagring direkt i Yandex.Cloud (dvs. förmodligen snabb). Som ett gratisalternativ kan du till exempel prova ett gratis exemplar molnmongie någonstans långt borta. Det finns praktiska Python-omslag för både Object Storage (det stöder S3-gränssnittet) och Mongo.

Ett annat problem är att för att gå till Object Storage, MongoDB och alla andra databaser eller datalagringar behöver du vissa externa beroenden som måste laddas upp till Yandex Functions tillsammans med koden för din funktion. Och jag skulle vilja göra detta bekvämt. Tyvärr kommer det inte att vara helt bekvämt (som på Heroku), men viss grundläggande bekvämlighet kan skapas genom att skriva ett skript för att montera miljön (make file).

Hur man startar horoskopfärdigheten

  1. Förbered: logga in på valfri maskin som kör Linux. I grund och botten, med Windows Detta skulle förmodligen också kunna fungera, men att köra makefilen skulle kräva lite magi. Och i vilket fall som helst behöver du Python 3.6 eller senare installerat.
  2. Klona det från GitHub exempel på horoskopfärdighet.
  3. Registrera dig i Yandex.Cloud: https://cloud.yandex.ru
  4. Skapa två hinkar åt dig själv Objektförvaring, kalla dem vid vilket namn som helst {BUCKET NAME} и tgalice-test-cold-storage (detta andra namn är nu hårdkodat i main.py mitt exempel). Den första hinken behövs endast för distribution, den andra - för att lagra dialogtillstånd.
  5. skapa servicekonto, ge honom en roll editoroch hämta statiska autentiseringsuppgifter för det {KEY ID} и {KEY VALUE} — vi kommer att använda dem för att registrera dialogens tillstånd. Allt detta är nödvändigt så att funktionen från Yandex.Cloud kan komma åt lagringen från Yandex.Cloud. Någon gång hoppas jag att auktoriseringen blir automatisk, men för tillfället är det så.
  6. (Valfritt) installera kommandoradsgränssnitt yc. Du kan också skapa en funktion via webbgränssnittet, men CLI är bra eftersom alla möjliga innovationer dyker upp i det snabbare.
  7. Nu kan du faktiskt förbereda beroendebygget: kör det i kommandoraden från mappen med exempelfärdigheten. make all. Ett gäng bibliotek (mestadels, som vanligt, onödiga) kommer att installeras i mappen dist.
  8. Ladda upp manuellt till objektlagring (till en bucket) {BUCKET NAME}) arkivet som erhölls i föregående steg dist.zip. Om du vill kan du göra detta från kommandoraden, till exempel med hjälp av AWS CLI.
  9. Skapa en serverlös funktion via webbgränssnittet eller med hjälp av ett verktyg yc. För verktyget kommer kommandot att se ut så här:

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

När man skapar en funktion manuellt fylls alla parametrar i på samma sätt.

Nu kan du testa funktionen du skapade via utvecklarkonsolen och sedan förfina och publicera färdigheten.

Skapa en tillståndsfull färdighet för Alice på de serverlösa funktionerna i Yandex.Cloud och Python

Vad finns under huven

Makefile innehåller faktiskt ett ganska enkelt skript för att installera beroenden och lägga dem i arkivet. dist.zip, något liknande detta:

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

Resten är några enkla verktyg inslagna i ett bibliotek. tgalice. Processen för att fylla i användardata beskrivs av konfigurationsfilen 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: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

Arbetet med att analysera denna konfiguration och beräkna det slutliga resultatet tas över av Python-klassen.

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

Mer exakt, basklassen FormFillingDialogManager är engagerad i att fylla i "formuläret", och metoden för barnklassen handle_completed_form säger åt henne vad hon ska göra när hon är redo.

Utöver detta huvudsakliga dialogflöde måste användaren också hälsas välkommen och få hjälp via kommandot ”help”, och avslutas med ”exit”. För detta ändamål, tgalice Det finns också en mall, så hela dialoghanteraren är uppbyggd av delar:

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 fungerar enkelt: den försöker tillämpa alla dess komponenter på dialogens aktuella tillstånd i tur och ordning och väljer den första lämpliga.

Som svar på varje meddelande returnerar dialoghanteraren ett Python-objekt. Response, som sedan kan konverteras till vanlig text, eller till ett meddelande i Alice eller Telegram – beroende på var boten körs; den innehåller också dialogens modifierade tillstånd, vilket behöver sparas. Det finns en annan kurs som handlar om hela köket, DialogConnector, så det direkta skriptet för att köra färdigheten på Yandex Functions ser ut så här:

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

Som du kan se skapar det mesta av den här koden en anslutning till S3 Object Storage-gränssnittet. Du kan läsa om hur den här anslutningen används direkt i tgalice-kod.
Den sista raden skapar funktionen alice_handler — samma som vi bad Yandex.Cloud att hämta när vi ställde in parametern --entrypoint=main.alice_handler.

Det är faktiskt allt. Makefiles för att bygga, S3-liknande objektlagring för att lagra kontext och ett Python-bibliotek tgalice. Tillsammans med serverlösa funktioner och Pythons uttrycksförmåga är detta tillräckligt för att utveckla en frisk persons färdighet.

Du kanske undrar varför det var nödvändigt att skapa tgalice? All tråkig kod som flyttar JSON:er från förfrågan till svar och från lagring till minne och tillbaka ligger i den. Det finns också en app för reguljära uttryck, en funktion för att förstå att "februari" liknar "februari", och andra NLU för de fattiga. Enligt min mening borde detta redan vara tillräckligt för att kunna skissa prototyper av färdigheter i yaml-filer utan att bli alltför distraherad av tekniska detaljer.

Om du vill ha en mer seriös NLU kan du koppla det till din skicklighet rasa eller DeepPavlov, men att sätta upp dem kommer att kräva lite extra dans med en tamburin, särskilt på serverlösa enheter. Om du inte alls känner för att koda, bör du använda en visuell designer som Aimylogiskt. När jag skapade tgalice tänkte jag på någon slags mellanväg. Låt oss se vad det blir av detta.

Nå, var med nu Alice Skills-utvecklare chatt, läs dokumentationoch skapa underbara Kompetens!

Källa: will.com

Köp pålitlig hosting för webbplatser med DDoS-skydd, VPS VDS-servrar 🔥 Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster