Sådan oprettes en filmbot med SAP Conversational AI og NodeJS

Få filmanbefalinger fra Filmdatabasen ved at spørge din egen chatbot på Facebook Messenger.

Ved afslutningen af ​​denne tutorial vil du være i stand til at opbygge en fuldt funktionel filmbot, der er i stand til at fremsætte filmanbefalinger baseret på flere kriterier. Vi bruger SAP Conversational AI bot building platform (tilmeld dig her gratis) og The Movie Database for information om film.

Her er en demo-chat med Movie Bot:

Hvad bygger vi i dag?

Interaktion med tredjeparts API'er giver mulighed for meget mere interessante brugssager end enkle Q / A chatbots. Med Bot-færdigheder tilføjede vi muligheden for at kalde webhooks direkte fra bygherren, hvilket gør det endnu lettere.

Dagens bot kræver flere trin:

  1. Uddrag af vigtige oplysninger i en sætning
  2. Opbygning af botstrømmen (triggere, krav, handlinger)
  3. Oprettelse og forbindelse af et bot-API, der er i stand til at hente data fra filmdatabasen

Du har brug for en SAP Conversational AI-konto, Node.JS og potentielt Ngrok til test.

Før vi hopper ind, skal du tjekke denne guide i stedet for, hvis du leder efter en guide, der beskriver oprettelsen af ​​din første bot.

Lad os komme til det!

Trin 1: Udtræk nøgleinfo fra en sætning

Det er nyttigt at bestemme den samlede betydning af en sætning. Til vores brugssag er det ikke nok at vide, at brugeren ønsker at se på noget.

Vi er nødt til at vide, hvad brugerne vil se.

Enheder er designet til at løse dette problem: de uddrager nøgleinformation i en sætning.

Hensigter får dig til at forstå, at du skal gøre noget. Enheder hjælper dig med faktisk at gøre noget.

Lad os forestille os, at du er et teleselskab, der leverer telefon- og internetadgang. Din bot har en hensigt, der forstår, når folk klager over et strømstop:

De udvundne enheder vil hjælpe med at forstå, hvad der går galt, hvor og siden hvornår.

Til vores filmbot vil vi forsøge at udtrække 3 vigtige oplysninger:

  1. Hvad brugeren vil se (en film kontra et tv-show)
  2. Hvilken genre de leder efter
  3. På hvilket sprog

Brug af guld enheder

For at hjælpe dig med at fremskynde din udvikling udtrækker SAP Conversational AI flere enheder som standard: datoer, placeringer, telefonnumre ...

En udtømmende liste er tilgængelig her.

Den sproglige enhed vil være nyttig:

Guldenheder - Sprog

Ser du den lille stjerne ved siden af ​​enhedsnavnet? Det adskiller en guldenhed fra en brugerdefineret enhed.

Vi vil bruge det til at opfylde vores tredje krav: filmsproget.

Oprettelse af tilpassede enheder

Vi opretter tilpassede enheder til at udtrække de oplysninger, vi har brug for. Som med intentioner er træning meget vigtig: jo flere eksempler du tilføjer til din bot, jo mere præcis bliver det.

Træning af dine enheder kan ske gennem flere formål. Enheder er uafhængige af hensigter.

Til vores filmbot har vi kun brug for én intention, opdagelse og 2 enheder:

  • optagelse for at identificere, at brugeren ønsker at se en film eller et tv-show
  • genre

Åbn hensigten med at opdage og tilføje udtryk. Sørg for at dække enhver mulighed, dette betyder en sund blanding af udtryk med:

  • Ingen enheder overhovedet: "Min kæreste vil se noget i aften"
  • Én enhed: ”Jeg vil se en film”
  • Mange enheder: "Kan du anbefale mig nogle franske drama-tv-shows?"

Hvis du vil mærke dine udtryk, skal du vælge den tekst, du vil mærke, og indtaste dit enhedsnavn:

Mærkning af brugerdefinerede enheder

Du skal tilføje mange flere eksempler: 15 ville være rart, men en produktionsklar bot vil kræve mindst 50 eksempler for at fungere godt. For at fremskynde processen kan du gafle de enheder, der er bygget inden for denne bot [indspilningsenhed, genreenhed] og derefter gaffel opdage-intentionen fra denne bot.

Du kan her se, at "fransk" blev opdaget som en nationalitet, ikke et sprog, fordi det er, hvad det er i denne sammenhæng. Når vi bygger botstrømmen, sørger vi for at kontrollere for disse to enheder.

Tilføjelse af brugerdefinerede berigelser

Nu hvor vi har mærket har vores enheder, skal vi berige dem! Åbn enhedspanelet fra din bot under fanen Træning som vist nedenfor:

Enhedsafsnit

Lad os åbne genreenheden. Hvis du ser øverst til højre på panelet, skal du se en skifte, der siger fri - begrænset og indstillinger. Åbn det, så vi i detaljer kan forklare de forskellige indstillinger, du har adgang til:

Enhedspanel

I enhedspanelet har du adgang til forskellige indstillinger for din enhed:

  • Gratis vs begrænset - En gratis brugerdefineret enhed bruges, når du ikke har en streng liste over værdier og ønsker, at maskinlæring skal registrere alle mulige værdier. Mens en begrænset brugerdefineret enhed bruges, hvis du har en streng liste med ord til at opdage og ikke har brug for automatisk registrering af enheden.
  • Fuzzy matching - Fuzzy matching er et indeks mellem 0 og 1 for at indikere, hvor tæt et ord kan være fra det i din enhedsliste over værdier. Hvis ordet er over dette indeks, vil platformen mærke det som den nærmeste værdi på din liste.
  • Liste over værdier - det er her du kan tilføje alle listen over værdier for din enhed, der kan være forskellige værdier eller synonymer

For mere detaljeret information om enheder, kan du læse vores detaljerede dokumentation.

I vores tilfælde vil vores genreenhed blive begrænset, daMovie Database API kun administrerer en bestemt liste over genrer. Her er listen nedenfor:

[
{id: 28, navn: 'Handling'},
{id: 12, navn: 'Eventyr'},
{id: 16, navn: 'Animation'},
{id: 35, navn: 'Comedy'},
{id: 80, navn: 'Kriminalitet'},
{id: 99, navn: 'Dokumentar'},
{id: 18, navn: 'Drama'},
{id: 10751, navn: 'Familie'},
{id: 14, navn: 'Fantasy'},
{id: 36, navn: 'Historie'},
{id: 27, navn: 'Skrekk'},
{id: 10402, navn: 'Musik'},
{id: 9648, navn: 'Mystery'},
{id: 10749, navn: 'Romance'},
{id: 878, navn: 'Science Fiction'},
{id: 53, navn: 'Thriller'},
{id: 10752, navn: 'Krig'},
{id: 37, navn: 'Western'}
]

Føj alle de forskellige genrer til vores liste over værdier. Glem ikke at tilføje synonymer som SF, Sci-Fi til science fiction, romantisk for romantik eller animeret, tegneserie til animation. Du kan hente listen over værdier derfra.

Som du kan se fra JSON ovenfor, er der ID'er forbundet med genrene. Årsagen er, at filmdatabasen ikke kan søge efter en bestemt genre baseret på dens engelske navn, men snarere på et brugerdefineret nummer. Vi kan knytte en bestemt id til hver af genreværdierne, der returneres inden for JSON i NLP API. Vi kan videresende det til Movie Database API. Dette er formålet med brugerdefinerede berigelser. Hver gang en enhed registreres, beriges JSON, der returneres af NLP API, med yderligere oplysninger om enheden.

Inden for det brugerdefinerede berigelsespanel er vi nødt til at oprette 3 nøgler:

  • navn - for at kortlægge synonymer under den samme værdi
  • id - for at berige med id i filmdatabasen
  • artikel - for at tilføje artiklen om genren (vi bruger denne senere)

For at tilføje en brugerdefineret berigelse skal du klikke på tilføj en ny nøgle og tilføje de tre nøgler, der er anført ovenfor. For artiklen sættes standardnøgleværdien til 'a', da de fleste af genrerne ville være med 'a'. Inden for navn kan du begynde at tilføje den specifikke berigelse og kortlægge den til alle de forskellige værdier for din artikel, id og navn som nedenfor:

Tilpassede berigelser til navnTilpassede berigelser til id'erBrugerdefinerede berigelser til artiklen

Du kan gafle hele enheden fra denne side, som inkluderer berigelse. Nu når dette er gjort, lad os teste det inden for testkonsollen. Hvis du sender sætningen "Jeg vil se en animationsfilm", skal du nu se følgende brugerdefinerede berigelse:

"genre": [
      {
        "value": "animeret",
        "raw": "animeret",
        "tillid": 0,99,
        "name": "animation",
        "id": 16,
        "artikel": "en"
      }

Fantastisk, nu giver vores berigelse os det generiske navn, id og artiklen! Lad os gøre det samme for optagelsesenheden. Gå tilbage til enhedspanelet, og klik på optagelse. Derefter gøres det begrænset, og tilføj alle mulige værdier og synonymer til tv-show og film (såsom tv-shows, shows, film, film, film, film osv.). Se hele listen her. Gå nu til brugerdefinerede berigelser, tilføj nøgeltypen og tilføj 2 specifikke værdier:

  • film - til alle filmsynonymer
  • tv - til alle tv-shows synonymer

Det skal se sådan ud:

Brugerdefinerede berigelser til type

Når vi sender tilbage vores sætning “Jeg vil se en animationsfilm” har vi nu også berigelsen til optagelse:

"optagelse": [
      {
        "value": "film",
        "rå": "film",
        "tillid": 0,99,
        "type": "film"
      }
    ]

Trin 2: Opbyg din botstrøm

Da vi bare skal sikre os, at alle vores kriterier er udfyldt, før vi kalder et Node.JS API, vil build-delen være ret enkel.

Vi har bare brug for en færdighed, lad os kalde det opdage.

Du kan finde et eksempel på en konfigureret færdighed her.

triggers

Vi ønsker at udløse denne færdighed, hvis intentionen @ opdagelse er til stede:

Meddelelse udløser

Denne fane hjælper dig med at indsamle data, før du flytter til handlinger. Vi vil sikre os, at brugeren specificerer en optagelse, en genre, et sprog og en ja eller nej-intention før han går videre:

Krav

Kravene kontrolleres en efter en. De kan alle blive opfyldt ved den første meddelelse. For eksempel, hvis brugeren siger, at jeg vil se en forbrydelsesfilm på engelsk, vil handlingerne blive udløst øjeblikkeligt.

For hvert krav kan du vælge at sende en meddelelse, hvis den er komplet, eller hvis den mangler.

At sende meddelelser, når et krav er fuldført, kan gøre din bot mere livlig: En krimfilm? Jeg elsker dem også !, men er næsten obligatorisk, når kravet mangler: Du skal bede dine brugere om at udfylde det, du har brug for at vide.

For eksempel sender jeg hurtige svar med foreslåede genrer, hvis #genre mangler:

Betinget besked, hvis der mangler et krav

For bekræftelsen bruger vi hukommelsen til at vise en dynamisk meddelelse til validering af valg af bruger ved hjælp af @ yes og @no intention:

Brug af hukommelsen til dynamisk besked

Når du har konfigureret spørgsmål til de 4 grupper af enheder, skal du gå til fanen Handlinger.

Handlinger

Når kravene er opfyldt, ønsker vi at ringe til vores API for faktisk at udføre søgningen, hvis brugeren sagde ja. Ellers nulstiller vi hukommelsen og spørger igen, hvad brugeren vil se.

Hvis _memory.no er til stede - nulstil hele hukommelsen og send en meddelelse som "Lad os starte igen, hvad vil du se?"

Hvis _memory.yes er til stede, skal du oprette en CALL WEHBOOK-handling. Du kan enten indtaste en fuld URL (f.eks: https://mydomainname.com/discover-movies) eller en relativ URL (/ Discover-film). SAP Conversational AI bruger parameteren Bot base URL i dine bot indstillinger, når du skriver en relativ URL.

Derefter skal du tilføje en handling UPDATE CONVERSATION> EDIT MEMORY> RESET ALL MEMORY for at tømme hukommelsen, når opkaldet er foretaget.

Handlinger

Hvis du ikke har en offentlig server, eller hvis du vil teste din bot under udvikling, er ngrok et meget praktisk værktøj. Det opretter en offentlig URL til dig og videresender anmodninger til din computer.

Når du har installeret det, skal du køre

ngrok http 5000

Og kopier videresendelses-URL i HTTPS (https://XXX.ngrok.io) til dine botindstillinger ("Bot webhook base URL" felt). Alle anmodninger fremsat til denne URL vil blive videresendt til porten 5000 på din computer.

Alle dine botbehov nu er dens API for at få dine film!

Trin 3: Oprettelse af filmen bot API

NodeJS-delen af ​​denne bot er forholdsvis enkel: Den vil opføre sig som en HTTP-proxy mellem SAP Conversational AI og The Movie Database.

Når din ansøgning modtager en anmodning fra SAP Conversational AI, sender den en søgeforespørgsel til Movie Database med kriterierne for din bruger og formaterer JSON-svaret til SAP Conversational AI-meddelelsesformatet.

Bot API-diagram

Valgmulighed 1: den automatiske måde

Du kan klone hele projektet direkte fra vores Git-lager: https://github.com/plieb/movie-bot-skills-training

Valgmulighed 2: den manuelle måde

Trin 1 - stillads dit projekt

mkdir film-bot && cd film-bot
npm init
npm-installation - gem ekspress-krop-parser-aksier
tryk på index.js config.js
mkdir Discover-film && cd Discover-film
tryk på index.js movieApi.js
cd ..

Trin 2 - at få et TMDb API-token

Du skal bruge et token for at bruge Movie Database API, gå her for at generere en og redigere din config.js fil:

module.exports = {MOVIEDB_TOKEN: process.env.MOVIEDB_TOKEN || 'PURYOURTOKENHERE', PORT: process.env.PORT || 5000,};

Trin 3 - fylde din index.js med en Express-applikation
 
Lad os oprette en Express-applikation til at håndtere anmodningerne fra SAP Conversational AI. For bedre at organisere vores projekt, som det ses i trin 1, har vi en mappe / Discover-film / som indeholder kernen i vores bot-kode (i stedet for at placere alle vores filer i den samme mappe), og vi kalder det gennem loadMovieRoute.

const express = kræver ('express');
const bodyParser = kræver ('body-parser');

const config = kræver ('./ config');
const loadMovieRoute = kræve ('./ Discover-film');

const app = express ();
app.use (bodyParser.json ());

loadMovieRoute (app);

app.post ('/ fejl', funktion (req, res) {
  console.log (req.body);
  res.sendStatus (200);
});

const port = config.PORT;
app.listen (port, funktion () {
  console.log (`App lytter på port $ {port}`);
});

Trin 4 - udfylde Discover-films / index.js

Vi beder SAP Conversational AI om at sende en POST-anmodning til / opdage film, når en bruger har udfyldt sine søgekriterier.

Vores controller's hovedmål er at vælge og formatere præferencerne fra hukommelsen for at sende dem til Movie Database's API:

const config = kræver ('../ config'); const {DiscoverMovie} = kræve ('./ movieApi'); function loadMovieRoute (app) {app.post ('/ Discover-film', funktion (req, res) {console.log ('[GET] / Discover-films'); const kind = req.body.conversation.memory [ 'optagelse']. type; const genre = req.body.conversation.memory ['genre']. id; const language = req.body.conversation.memory ['sprog']; const nationalitet = req.body.conversation. hukommelse ['nationalitet']; const isoCode = sprog? language.short.toLowerCase (): nationalitet.short.toLowerCase (); returnere DiscoverMovie (kind, genreId, isoCode) .then (funktion (carouselle) {res.json ({ svar: carouselle, samtale: {}});}) .catch (funktion (err) {console.error ('movieApi :: DiscoverMovie error:', err);});}); } module.exports = loadMovieRoute;

Trin 5 - udfylde Discover-film / movieApi.js

Nu hvor vi har udpakket og formateret alle filtre fra anmodningen, er vi nødt til at sende anmodningen til filmdatabasen og formatere svaret:

const axios = kræver ('axios');
const config = kræver ('../ config');

funktion DiscoverMovie (art, genreId, sprog) {
  return moviedbApiCall (art, genreId, sprog) .then (svar =>
    apiResultToCarousselle (response.data.results)
  );
}

funktion moviedbApiCall (art, genreId, sprog) {
  return axios.get (`https://api.themoviedb.org/3/discover/$ {kind}`, {
    params: {
      api_key: config.MOVIEDB_TOKEN,
      sort_by: 'popularitet.desc',
      include_adult: falsk,
      with_genres: genreId,
      med_original_sprog: sprog,
    },
  });
}

funktion apiResultToCarousselle (resultater) {
  if (results.length === 0) {
    Vend tilbage [
      {
        type: 'quickReplies',
        indhold: {
          titel: 'Beklager, men jeg kunne ikke finde nogen resultater til din anmodning :(',
          knapper: [{title: 'Start forfra', værdi: 'Start over'}],
        },
      },
    ];
  }

  const cards = results.slice (0, 10) .map (e => ({
    titel: e.title || e.name,
    undertekst: e.overview,
    imageUrl: `https://image.tmdb.org/t/p/w600_and_h900_bestv2$ {e.poster_path}`,
    knapper: [
      {
        type: 'web_url',
        værdi: `https://www.themoviedb.org/movie/$ {e.id}`,
        titel: 'Se mere',
      },
    ],
  }));

  Vend tilbage [
    {
      type: 'tekst',
      indhold: "Her er hvad jeg fandt til dig!",
    },
    {type: 'karrusel', indhold: kort},
  ];
}

module.exports = {
  discoverMovie,
};

Trin 6 - Start motoren!

Det er alt! Du er klar til at teste din bot.

Start din applikation ved at køre: node index.js

Alt i alt skal du se: App startede på port 5000

Filmanbefalinger, vejr, sundhed, trafik… Med tredjeparts API'er er alt muligt! Nu hvor du er fortrolig med arbejdsgangen, kan vi ikke vente med at høre fra dig om, hvad du bygger! Og husk, du er meget velkommen til at kontakte os, hvis du har brug for hjælp, gennem kommentarsektionen nedenfor eller via Slack.

Oprindeligt offentliggjort på SAP Conversational AI blog.