
Die Chatbot-Branche boomt. Anfangs waren sie dumm genug und konnten einen Dialog mit dem Benutzer führen, führend sein und mögliche Antworten anbieten. Dann wurden die Bots etwas schlauer und forderten vom Benutzer Texteingaben, um die Antworten mit Schlüsselwörtern zu versehen. Die Entwicklung des maschinellen Lernens hat dazu geführt, dass die Fähigkeit zur Kommunikation mit dem Bot und der Stimme entstanden ist. Die meisten Lösungen gingen jedoch nicht sehr weit von der gleichen Konstruktion des Dialogdiagramms und dem Übergang zwischen seinen Knoten durch Schlüsselwörter entfernt.
Vor kurzem haben wir bei Parallels beschlossen, eine Reihe interner Prozesse zu optimieren und als Experiment einen Bot für unsere eigenen Bedürfnisse zu erstellen. Nach einer kurzen Suche beschlossen wir, unser Glück beim Open-Source-Projekt
RASA zu versuchen. Laut den Entwicklern selbst haben sie einen Chat-Bot der dritten Generation erstellt. Das heißt, dieser Bot umgeht nicht nur das Zustandsdiagramm, sondern kann den Kontext des vorherigen Dialogfelds speichern und verwenden. Bis heute sieht die beste Illustration für moderne Chat-Bots ungefähr so aus:

Das heißt, Chat-Bots sind nur eine Reihe verifizierter Regeln für den Wechsel von einem Punkt in der Grafik zu einem anderen. Wenn Sie sich die vorhandenen Lösungen der Giganten des Marktes ansehen, gibt es tatsächlich nichts, was sich von den dortigen Regeln unterscheidet. Grob gesagt sieht dieses Set ungefähr so aus:
Dialog an Punkt XXX.
Wenn der Benutzer ein Angebot mit den Worten ['Kaufen', 'Ticket'] eingegeben hat, fahren Sie mit dem Punkt „WO FRAGEN“ fort.
Wenn der Benutzer ein Angebot mit den Worten ['kaufen', 'Schnitzel'] eingegeben hat, fahren Sie mit dem Punkt „FRAGEN VON WAS“ fort.
Es ist sofort klar, dass es hier Müll ist, wenn der Benutzer eingibt: "Ich möchte ein Ticket nach Porto kaufen", wird er immer noch gefragt: "Wohin möchten Sie gehen?" Um den Dialog humaner zu gestalten, müssen Sie neue Regeln hinzufügen, was zu tun ist, wenn es einen Hinweis auf den Ort gibt.
Fügen Sie dann Regeln hinzu, was zu tun ist, wenn Ort und Zeit angegeben sind, und so weiter.
Dieses Regelwerk wird schnell genug wachsen, aber es ist nicht das Schlimmste. Alle „richtigen“ Wege können beschrieben, verbessert und geleckt werden.
Das Unangenehmste ist, dass eine Person im Gegensatz zu einem Bot eine unvorhersehbare Kreatur ist und jederzeit ganz anders fragen kann. Das heißt, in dem Moment, in dem der Bot bereits bereit ist, ein Ticket zu buchen, kann eine Person fragen: "Übrigens, was ist mit dem Wetter?" oder "obwohl nicht, möchte ich in mein Auto steigen, wie lange dauert die Straße?"
Dies kann er jedoch auch im Moment nach der Wahl einer Stadt, aber vor der Wahl einer Abfahrtszeit oder sogar der Wahl eines Ortes, an den er gehen möchte, erfragen. Der Bot, der auf Zustandsautomaten basiert, wird blockieren und seine mechanischen Pseudopoden werden traurig zucken und der Benutzer wird frustriert sein.
Hier können (und sollten) Sie maschinelles Lernen anwenden. Dann treten jedoch neue Probleme auf: Wenn Sie beispielsweise das Verstärkungstraining verwenden, um Übergänge zu Diagrammpunkten vorherzusagen, stellen sich Fragen: Woher erhalten Sie die Daten für dieses Training und wer bewertet die Qualität der Antworten?
Es ist unwahrscheinlich, dass Benutzer zustimmen, Ihren Bot zu unterrichten, und wie die Praxis zeigt, kann eine Benutzergemeinschaft einem Bot überhaupt nicht beibringen, was Sie wollen und was die Gesellschaft für anständig hält. Darüber hinaus reagiert der Bot in der Anfangsphase völlig fehl am Platz, was die Benutzer nervös macht und sich im Prinzip nicht mit dieser Unterstützung herumschlägt.
Nachdem die RASA-Entwickler alle Mängel der vorhandenen Bots analysiert und überlegt hatten, versuchten sie, die Probleme wie folgt zu lösen:
- Jede Eingabe des Benutzers erfolgt über die „Bestimmung der Absicht“, dh der durch maschinelles Lernen eingegebene Text wird einer (oder mehreren) Absichten zugeordnet. Bei Bedarf werden Entitäten auch vom Text isoliert und dem Speicher des Bots hinzugefügt.
- Dieser Prozess ähnelt anderen Bots mit Ausnahme des verwendeten Absichtsbestimmungsmodells.
- Die nächste Aktion des Bots wird mithilfe von maschinellem Lernen basierend auf dem Kontext, dh den vorherigen Aktionen, Absichten und dem Speicherstatus des Bots, vorhergesagt.
- Gleichzeitig werden für das erste Training nicht viele Daten benötigt, und der Bot kann durchaus vorhersagen, welche Aktion auch ohne bestimmte Beispiele und Regeln ausgeführt werden soll.
Betrachten Sie die Arbeitsmechanismen genauer.
RASA NLU
Beginnen wir mit dem ersten Wal, auf dem der Bot ruht. Dies ist ein Verständnis der natürlichen Sprache, das aus zwei Hauptteilen besteht: Bestimmung der Absicht und Anerkennung von Entitäten.
AbsichtserkennungDie Bestimmung der Absicht basiert auf einem modifizierten Algorithmus namens
StarSpace von Facebook, der auf Tensorflow implementiert ist. In diesem Fall werden keine vorab trainierten Modelle von Vektordarstellungen von Wörtern verwendet, sodass Sie die Einschränkungen dieser Darstellungen umgehen können.
Das Bestimmen der Absicht in RASA-Algorithmen funktioniert beispielsweise für jede Sprache sowie für bestimmte Wörter, die Sie in den Trainingsbeispielen angeben. Bei der Implementierung durch vorab trainierte Vektordarstellungen wie GloVe oder word2vec verursacht die Lokalisierung des Bots und seine Anwendung in hochspezialisierten Bereichen genügend Kopfschmerzen.
Der Algorithmus basiert auf der Vektorisierung von Sätzen durch eine Vielzahl von Wörtern und dem Vergleich ihrer „Ähnlichkeit“. Beispiele für Absichten und Absichten selbst werden unter Verwendung einer Worttasche in Vektoren umgewandelt und der Eingabe der entsprechenden neuronalen Netze zugeführt. Am Ausgang des neuronalen Netzwerks wird ein Vektor für diesen bestimmten Satz von Wörtern erhalten (dieselbe Einbettung).
Das Training findet so statt, dass die Verlustfunktion in Form der Summe paarweiser Abstände (entweder Kosinus- oder Vektorprodukte) zwischen zwei ähnlichen Vektoren und k-unterschiedlichen Vektoren minimiert wird. Somit wird nach dem Training jeder Absicht ein bestimmter Vektor zugeordnet.
Nach Erhalt der Benutzereingaben wird der Vorschlag auf ähnliche Weise vektorisiert und durch das trainierte Modell geführt. Danach wird der Abstand vom resultierenden Vektor zu allen Absichtsvektoren berechnet. Das Ergebnis wird eingestuft, wobei die wahrscheinlichsten Absichten hervorgehoben und negative Werte abgeschnitten werden, dh völlig unähnlich.
Zusätzlich zu den oben genannten Brötchen können Sie mit diesem Ansatz automatisch mehr als eine Absicht vom Vorschlag unterscheiden. Zum Beispiel: „Ja, das habe ich verstanden. Aber wie kann ich jetzt nach Hause kommen? " Wird als "intent_confirm + intent_how_to_drive" erkannt, wodurch Sie humanere Dialoge mit dem Bot erstellen können.
Übrigens können Sie vor dem Training künstliche Sätze aus Beispielen erstellen, indem Sie vorhandene mischen, um die Anzahl der Trainingsbeispiele zu erhöhen.
RASA-Entitätserkennung
Der zweite Teil der NLU ist das Extrahieren von Entitäten aus Text. Ein Benutzer schreibt beispielsweise: „Ich möchte mit zwei Freunden in ein chinesisches Restaurant gehen.“ Der Bot muss nicht nur die Absicht, sondern auch die entsprechenden Daten hervorheben. Das heißt, füllen Sie Ihr Gedächtnis aus, dass die Gerichte im Restaurant chinesisch sein sollten und dass die Anzahl der Besucher drei beträgt.
Hierfür wird ein Ansatz verwendet, der auf bedingten Zufallsfeldern basiert und bereits irgendwo im
Habré beschrieben wurde , sodass ich ihn nicht wiederholen werde. Wer dies wünscht, kann diesen Algorithmus
auf der Stanford-Website nachlesen.
Außerdem stelle ich fest, dass Sie Entitäten aus Text abrufen können, der auf Vorlagen, Texten (z. B. Städtenamen) basiert, sowie eine Verbindung zu einem separaten Facebook-Entlein-Dienst herstellen können, über den Sie auch eines Tages gerne schreiben würden.
RASA Geschichten
Der zweite Blauwal, auf dem RASA Core basiert, sind Geschichten. Das allgemeine Wesen der Geschichten sind Beispiele für echte Gespräche mit dem Bot, die als Absichtsreaktion formatiert sind. Basierend auf diesen Geschichten wird ein wiederkehrendes neuronales Netzwerk (LSTM) trainiert, das den vorherigen Nachrichtenverlauf der gewünschten Aktion zuordnet. Auf diese Weise können Sie Diagramme von Dialogen nicht starr festlegen und nicht alle möglichen Zustände und Übergänge zwischen ihnen bestimmen.
Mit einer ausreichenden Anzahl von Beispielen wird das Netzwerk den nächsten Status für den Übergang angemessen vorhersagen, unabhängig vom Vorhandensein eines bestimmten Beispiels. Leider ist die genaue Anzahl der Geschichten dafür nicht bekannt, und alles, woran man sich orientieren kann, ist der Satz der Entwickler: "Je mehr, desto besser."
Um das System zu trainieren und nicht nur einige erfundene Dialoge dort aufzuzeichnen, können Sie interaktives Training verwenden.
Es gibt zwei Möglichkeiten:
1. Lassen Sie eine Reihe von Ingenieuren Gespräche mit dem Bot führen und korrigieren Sie falsche Vorhersagen, falsche Definitionen von Entitäten und Stecker, um Aktionen für Geschichten vorherzusagen.
2. Speichern Sie Konversationen in der Datenbank und verwenden Sie dann speziell geschulte Techniker, um die Dialoge zu betrachten, in denen der Benutzer sein Problem nicht lösen konnte, dh zu einer Person gewechselt wurde oder der Bot seine Hilflosigkeit eingestand und nicht antworten konnte.
Um den Mechanismus von Geschichten zu verstehen, ist es am einfachsten, ein einfaches Beispiel zu analysieren. Angenommen, eine Tischreservierung in einem Restaurant, ein Beispiel, das von den Entwicklern im Abschnitt mit den Quellcodebeispielen bereitgestellt wurde. Zuerst bestimmen wir unsere Absichten und dann machen wir ein paar Geschichten.
Absichten und ihre Beispiele:
Intent_hello
- Hallo
- Hallo
- Aloha
- Guten Morgen
...
Absicht_Danke
...
Intent_request
Intent_inform
Als nächstes müssen Sie den Speicher des Bots festlegen, dh die Slots bestimmen, in denen aufgezeichnet wird, was der Benutzer benötigt. Definieren Sie die Slots:
Küche:
Typ: nicht funktionsfähig
auto_fill: false
num_people:
Typ: nicht funktionsfähig
auto_fill: false
Und jetzt werden wir Beispiele (einen kleinen Teil) für die oben ausgelassenen Absichten zeigen. Die Klammern in den Beispielen sind die Daten für das Training von Ner_CRF im Format [Entität] (Variablenname für die Speicherung: Was wir speichern).
intent_request_restaurant
- Ich bin auf der Suche nach einem Restaurant
- Kann ich [schwedisches] (Küchen-) Essen für [sechs Personen] bekommen (num_people: 6)?
- ein Restaurant, das [karibische] (Küche) Essen serviert
- Ich bin wie ein Restaurant
- Ich bin auf der Suche nach einem Restaurant, das [mediterrane] (Küche) Essen serviert
intent_inform
- [2] (num_people) Personen
- für [drei] (num_people: 3) Personen
- nur [eine] (num_people: 1) Person
- wie wäre es mit [asiatisch orientalisch] (Küche)
- Was ist mit [indischem] (Küchen-) Essen?
- Wie wäre es mit [türkisch] (Küche) Art von Essen
- um [englisch] (Küche)
Nun bestimmen wir die Geschichte des Hauptpfades:
* grüße
- äußern_greet
* Intent_request
- restaurant_form
- form {"name": "restaurant_form"}
- form {"name": null}
- action_book_restaurant
* Danke
- Äußerste Sorgen
Das ist der perfekte Bot für eine perfekte Welt. Wenn der Benutzer im ersten Satz sofort alle erforderlichen Daten angegeben hat, wird eine Tabelle reserviert. Zum Beispiel schreibt er: "Ich möchte einen Tisch im spanischen Restaurant für fünf Personen reservieren." In diesem Fall sind num_people 5 und cuisine - spanish, was für den Bot für weitere Aktionen auf der Reservierung ausreicht.
Wenn Sie sich jedoch die Beispiele ansehen, können Sie feststellen, dass die Daten nicht immer in der erforderlichen Menge vorhanden sind und manchmal überhaupt nicht. Es werden also nicht zum Kern gehörende Dialoge angezeigt.
Angenommen, die Anfrage enthält keine Daten zur Küche, d. H. So etwas wie dieser Dialog:
Hallo
Hallo
Ich möchte ein Restaurant für fünf Personen buchen
...
Damit es korrekt ausgefüllt werden kann, müssen Sie den Verlauf des folgenden Formulars ermitteln:
* grüße
- äußern_greet
* Intent_request
- restaurant_form
- form {"name": "restaurant_form"}
- slot {"request_slot": "num_people"}
- absolute_ask_coven
* form: inform {"cuisine": "mexican"}
- Slot {"Küche": "Mexikaner"}
- form: restaurant_form
...
Und das Beste daran ist, dass, wenn Sie Geschichten für mehrere Küchen erstellen, der Bot bei Treffen mit einem Unbekannten die nächste Aktion selbst vorhersagt, obwohl dies nicht sehr sicher ist. Wenn Sie eine ähnliche Geschichte erstellen, aber der "Cuisine" -Slot ausgefüllt ist und nicht der "num_people" -Slot, ist es dem Bot absolut egal, in welcher Reihenfolge die Informationen zu den Tabellenreservierungsparametern bereitgestellt werden.
Es gibt zwei Möglichkeiten, um Versuche zu stoppen, einen Bot vom richtigen Weg zu führen: mögliche Geschichten zu finden, um „über nichts“ zu sprechen, oder alle Versuche, ein solches Gespräch zu beginnen - antworten Sie, dass es sich lohnt, wieder ins Geschäft zurückzukehren.
Da sich unser Unternehmen am Anfang einer erstaunlichen Reise in die Welt der Chatbots befindet, besteht die Möglichkeit, dass es neue Artikel darüber gibt, welchen Rechen wir gesammelt haben und was wir getan haben. Bleib dran!
