Erstellen eines Chatbots mit PubNub und ChatGPT / OpenAI
Published: 2024-03-11 14:53:20

Wenn man bis vor kurzem einen Chatbot entwickeln wollte, musste man die "natürliche Sprachverarbeitung" (NLP) nutzen, um die Fragen des Benutzers zu verstehen und zu interpretieren, und dann versuchen, diese Anfrage mit Hilfe einer Backend-Logik zu erfüllen, die möglicherweise in einen proprietären Dienst integriert war. Lösungen wie Dialogflow oder das Bot-Framework von Microsoft bieten Konversations-KI auf der Grundlage von maschinellem Lernen und sind bei Entwicklern, die Chatbots erstellen, traditionell beliebt.

OpenAI und ChatGPT von OpenAI machen es einfacher denn je, einen KI-Chatbot zu erstellen, der auf künstlicher Intelligenz basiert. Da das große Sprachmodell (LLM), das OpenAI antreibt, auf einem öffentlichen Datensatz basiert, können Sie die Benutzererfahrung Ihrer App ganz einfach verbessern, indem Sie alle Informationen bereitstellen, von denen Sie erwarten, dass sie in einer öffentlichen Wissensdatenbank vorhanden sind.

PubNub ermöglicht Echtzeit-Erlebnisse für ein breites Spektrum von Branchen und Anwendungsfällen, darunter [Kundensupport](https://www.pubnub.com/solutions/communications/) und [In-App-Chat](https://www.pubnub.com/solutions/chat/)All diese Echtzeit-Erlebnisse werden durch Daten angetrieben, entweder durch vom Benutzer lesbare Nachrichten oder durch Metadaten über Ihre Lösung - **wäre es nicht großartig, diese vorhandenen Daten zu nutzen, um einen Chatbot zu betreiben?**

_Einige Anwendungsbeispiele aus der Praxis:_

-   Antworten auf häufig gestellte Fragen des **Kundensupports** bereitstellen
    
-   **Anreicherung** Ihrer vorhandenen Daten mit zusätzlichen Inhalten, z. B. mit Vorschlägen für Restaurants in der Nähe eines angegebenen Standorts
    
-   Erstellen Sie **Zusammenfassungen von Unterhaltungen** auf der Grundlage des Nachrichtenverlaufs.
    

Wir veröffentlichten einen [Artikel](https://www.pubnub.com/blog/building-a-chatbot-with-openai-gpt3-and-pubnub/) zu diesem Thema veröffentlicht, und obwohl dieser ältere Artikel immer noch richtig ist, entwickelt sich die Branche sehr schnell, und ein paar Monate sind eine lange Zeit.

In diesem Artikel geht es darum, wie man einen Chatbot auf Basis von OpenAI erstellt, ähnlich dem, den Sie in unserem [PubNub Schaufenster](http://pubnub-showcase.netlify.app/) Anwendung läuft, wie unten gezeigt.

![The showcase's AI model has been primed to mention PubNub, where appropriate](https://www.pubnub.com/cdn/3prze68gbwl1/6G6aZfuXXtSqh9aBDyA7fw/5c416e9b87a4c0de5070271669bd13dd/showcase_app.png)

**High-Level Architektur**
--------------------------

Um einen Chatbot wie ChatGPT zu erstellen, müssen Sie die [OpenAI-Chat-API](https://platform.openai.com/docs/api-reference/chat) verwenden und sich für ein Konto anmelden, um einen [API-Schlüssel](https://platform.openai.com/account/api-keys) zu erstellen. Die OpenAI-API ist als REST-Endpunkt zugänglich, so dass sie von so ziemlich jeder Programmiersprache aus aufgerufen werden kann, obwohl die meisten der bereitgestellten Beispiele in Python geschrieben sind.

Der beste Weg, Daten aus PubNub zu extrahieren, um eine Konversation mit dem Chatbot zu beginnen oder fortzusetzen, ist die Verwendung von [Funktionen](https://www.pubnub.com/products/functions/). Funktionen bieten einen serverlosen [JavaScript-Container](https://www.pubnub.com/guides/javascript/), der in Node.JS läuft und es Ihnen ermöglicht, Geschäftslogik auszuführen, sobald ein Ereignis im PubNub-Netzwerk eintritt, wie z. B. der Empfang einer Chat-Nachricht. PubNub-Funktionen werden häufig für Echtzeit-Sprachübersetzung, Profanity-Filterung oder zum Aufrufen eines Drittanbieterdienstes wie OpenAI verwendet.

Dieses Beispiel wird wie folgt funktionieren:

-   Die bestehende Chat-Anwendung nutzt PubNub, um Nachrichten in Echtzeit zu senden und zu empfangen.
    
-   Eine PubNub-Funktion wartet auf Nachrichten, die an einen bestimmten Kanal gesendet werden.
    
-   Eine einzelne Nachricht allein bietet keinen Kontext für ChatGPT, daher wird auch ein Teil des Gesprächsverlaufs zwischengespeichert, um einen fortlaufenden Dialog zu ermöglichen.
    
-   Die PubNub-Funktion ruft die OpenAI-API auf und holt die Antwort ab
    
-   Die Antwort wird auf dem PubNub-Kanal veröffentlicht, der mit Ihrem eigenen Chatbot verbunden ist.
    

Sie können dies in dem folgenden Sequenzdiagramm sehen:

![Example sequence diagram for implementing a ChatGPT-like chatbot with PubNub and OpenAI](https://www.pubnub.com/cdn/3prze68gbwl1/64ZjHOSpoWo5vfykIpNPVU/44eb69443493a131043d8142133b234c/architecture.png)

1.  Der Benutzer tippt eine Nachricht in Ihrer Chat-App. Mit über 50 SDKs kann PubNub die meisten Anwendungen unterstützen, und die Nachricht wird in dem Kanal [veröffentlicht](https://www.pubnub.com/docs/general/messages/publish), der den Chatbot im PubNub-Netzwerk repräsentiert.
    
2.  Eine PubNub-Funktion wird so konfiguriert, dass sie [nach einem Veröffentlichungsereignis](https://www.pubnub.com/docs/general/serverless/functions/overview#after-publish-or-fire-functions) auf einem Kanal aufgerufen wird. Wenn eine Nachricht empfangen wird, wird der Kanalverlauf abgerufen, um einen Kontext für die Konversation zu liefern, und dieser Verlauf wird zusammen mit den Benutzereingaben und zusätzlichem Kontext über die Chat [Completion API](https://platform.openai.com/docs/api-reference/chat/create) an ChatGPT übermittelt.
    
3.  Die ChatGPT-API generiert Antworten, die an den Gesprächsverlauf angepasst sind
    
4.  Innerhalb der PubNub-Funktion wird eine Antwort von ChatGPT empfangen, die geparst und wieder im PubNub-Netzwerk [veröffentlicht](https://www.pubnub.com/docs/general/messages/publish) wird.
    
5.  Die Anwendung, die zuvor den Empfang von Nachrichten von PubNub [abonniert](https://www.pubnub.com/docs/general/channels/subscribe) hat, wird die Antwort des Chatbots anzeigen.
    

**Konfigurieren Ihrer PubNub-Funktion**
---------------------------------------

### Erstellen Sie Ihre PubNub-Funktion wie folgt:

Voraussetzungen: Wenn Sie neu bei PubNub sind, folgen Sie unserer [Dokumentation](https://www.pubnub.com/docs/general/basics/set-up-your-account), um Ihr Konto einzurichten oder besuchen Sie unsere [Tour](https://www.pubnub.com/tour/introduction/), um zu verstehen, worum es bei PubNub geht.

1.  Navigieren Sie zum [Admin-Dashboard](http://admin.pubnub.com/)
    
2.  Wählen Sie `Funktionen` aus dem linken Menü und wählen Sie das entsprechende Keyset, in dem Sie die Funktion erstellen möchten.
    
3.  Wählen Sie `+ Neues Modul erstellen`.
    
4.  Geben Sie einen Modulnamen und eine Modulbeschreibung ein, wählen Sie ein Keyset aus und klicken Sie dann auf `Erstellen`
    
5.  Wählen Sie das soeben erstellte Modul aus
    
6.  Wählen Sie `+ Neue Funktion erstellen`
    
7.  Geben Sie der Funktion einen Namen und wählen Sie den Ereignistyp `After Publish oder Fire`. Diese Funktion wird aufgerufen, NACHDEM eine Nachricht an PubNub übermittelt wurde. Funktionen können synchron oder asynchron sein. In diesem Fall erfassen wir nur eine Kopie der Nachricht, um sie an OpenAI zu senden. Weitere Einzelheiten zu den [verschiedenen Arten von Funktionen](https://www.pubnub.com/docs/general/serverless/functions/overview#before-publish-or-fire-functions) finden Sie in unserer Dokumentation
    
8.  Der Funktionskanal sollte mit dem Kanal übereinstimmen, in dem Sie Nachrichten [veröffentlichen](https://www.pubnub.com/docs/general/messages/publish), die Sie an OpenAI senden wollen. Sie können hier einen Platzhalter verwenden, so dass z.B. `chatgpt.` \* mit jedem Kanal übereinstimmt, der mit chatgpt beginnt. Da wir mit dieser Funktion mit mehreren Personen gleichzeitig sprechen wollen, ermöglicht uns ein Platzhalter zu unterscheiden, welcher Benutzer an der aktiven Konversation beteiligt ist, so dass wir auf dem entsprechenden Kanal antworten können.Wenn mehrere Personen gleichzeitig mit OpenAI sprechen, kümmert sich PubNub um die Erstellung mehrerer Instanzen Ihrer Funktion. `chatgpt.dave` und `chatgpt.simon` sind zum Beispiel zwei verschiedene Kanäle, aber beide rufen die PubNub-Funktion auf, die auf `chatgpt.*` hört. [Wie PubNub mit Channel-Wildcards umgeht](https://support.pubnub.com/hc/en-us/articles/360051495072-How-do-I-subscribe-to-a-wildcard-channel-), wird in unserer Dokumentation genauer erklärt.
    
9.  Wählen Sie `My Secrets` und erstellen Sie ein neues Geheimnis für den [OpenAI-API-Schlüssel](https://platform.openai.com/account/api-keys); der folgende Code setzt voraus, dass dieses Geheimnis `OPENAI_API_KEY` heißt.
    

### **Hier ist ein Beispiel für eine PubNub-Funktion, die OpenAI / ChatGPT aufruft**

```js
const pubnub = require('pubnub');
const xhr = require('xhr');
const vault = require('vault');

// Process all messages posted to the private ChatGPT channel
// This will be unique for each user, so chat is 1:1 with ChatGPT
export default request => {
  const inboundChannel = request.channels[0];
  if (request.message.content.type == "text" && request.message.sender != "OpenAI")
  {
    //  user’s query
    let naturalCommand = request.message.content.text;
   // Always provide OpenAI with some context of how you want questions answered
    let historicalMsgs = 
      [{"role": "system", "content": "You are a helpful assistant, expert in PubNub"}];
    return getOpenaiApiKey().then(apikey => {
      // Read the last messages from the conversation to provide conversation context
      return pubnub.history({
        channel: inboundChannel,
        count: 10
        }).then((response) => {
          response['messages'].forEach((value, index) => {
            // The message role will vary depending on whether it was sent or received 
            if (value.entry.sender && value.entry.sender == "OpenAI")
              historicalMsgs.push({"role": "assistant", 
                "content": value.entry.content.text})
            else
              historicalMsgs.push({"role": "user", 
                "content": value.entry.content.text})
          });

          // Depending on timing, last published message may or may not yet be stored
          if (historicalMsgs[historicalMsgs.length - 1].content != naturalCommand)
          {
            historicalMsgs.push({"role": "user", 
              "content": naturalCommand});
          }
          return openAI(naturalCommand, historicalMsgs).then(aiResponse => {
            // Respond back by publishing the message to PubNub
            pubnub.publish({
              channel: inboundChannel,	//  In the showcase, this is unique per user
              message: {
                content: {
                  type: "text",
                  text: aiResponse
                },
                sender: "OpenAI",
              },
            });
            return request.ok();
          });
        })
      });
    }
    return request.ok();
  };


  // Get API Key for OpenAI
  // Key is populated via Vault Secret Manager  
  let OPENAI_API_KEY = null;
  function getOpenaiApiKey() {
    // Use cached key
    if (OPENAI_API_KEY) {
      return new Promise(resolve => resolve(OPENAI_API_KEY));
    }
    // Fetch key from vault
    return vault.get("OPENAI_API_KEY").then(apikey => {
      OPENAI_API_KEY = apikey;
      return new Promise(resolve => resolve(OPENAI_API_KEY));
    });  
  }

  // API Call to OpenAI asking the AI to run functions if it thinks it needs to
  function openAI(naturalCommand, msgs) {
    // Generate Function Instructions for the AI
    const url = 'https://api.openai.com/v1/chat/completions';
    const http_options = {
      'method': 'POST',
      'headers': {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${OPENAI_API_KEY}`,
      },
    'body': JSON.stringify({
      "model": "gpt-3.5-turbo",
      "messages": msgs,
      "max_tokens": 300
    }),
    timeout: 9500, // PubNub functions timeout limit can be raised if needed
    retries: 0
  };

  return xhr.fetch(url, http_options).then((resp) => {
    const body = JSON.parse(resp.body);
    return body.choices[0].message.content;
  })
  .catch((err) => {
    console.log(err);
    return "Timed out. Please try again or ask a simpler question";
  });
}
```

**Praktische Überlegungen beim Aufrufen der OpenAI API**
--------------------------------------------------------

### **Eigenschaften der Chat Completion API**

Der in diesem Artikel vorgestellte Code verwendet die [OpenAI Chat Completion API](https://platform.openai.com/docs/api-reference/chat/create), aber sie ist besser konfigurierbar als oben gezeigt.

Wenn Sie `stream` als true angeben, wird die OpenAI-Antwort als Datenstrom über [vom Server gesendete Ereignisse](https://www.pubnub.com/guides/server-sent-events/) zurückgegeben. In der Praxis kann dies die wahrgenommene Latenz verringern, da der Benutzer eine unmittelbarere Antwort sieht, ähnlich wie die ChatGPT-Webschnittstelle funktioniert.

`model` ermöglicht die Angabe des Sprachmodells, das zur Generierung der Antwort verwendet wird. Die API wird von einer Familie von Modellen mit unterschiedlichen Fähigkeiten und Preispunkten angetrieben, wobei die Modelle regelmäßig aktualisiert und neue Modelle hinzugefügt werden.

`max_tokens` schränkt die Anzahl der [Token](https://platform.openai.com/tokenizer) ein, die die API zur Generierung der Ausgabe verwendet. Im Allgemeinen gilt: Je geringer die Anzahl der Token, desto weniger komplex ist die Ausgabe und desto weniger Kontext wird verfolgt, aber die Antworten werden schneller geliefert.

`Das` Beispiel in diesem Artikel verwendet `system`, um einige Anweisungen an OpenAPI zu übermitteln, `user` für Nachrichten, die vom Endbenutzer gesendet werden, und `assistant` für Antworten, die zuvor von OpenAI geliefert wurden.

Das Modell kann durch die Angabe von `temperature` / `top_p`, `frequency_penality` und `presence_penalty` weiter angepasst werden. Weitere Informationen hierzu finden Sie in der [OpenAPI-Dokumentation](https://platform.openai.com/docs/api-reference/chat/create).

Die API erlaubt es Ihnen auch, benutzerdefinierte Funktionen zu definieren und zu spezifizieren, die die Fähigkeiten des Modells erweitern, was aber außerhalb des Rahmens dieses Blogs liegt. Wenn Sie mehr darüber erfahren möchten, haben wir einen [separaten Beitrag](https://gist.github.com/stephenlb/de558e9802a6f950951eb0939ab71bcd), der zeigt, wie Sie ChatGPT erlauben können, in Ihrem Namen auf PubNub zu veröffentlichen, was es Ihnen ermöglicht, etwas zu sagen wie: "Sende eine Nachricht an den Hauptkanal, die besagt, dass ich in 5 Minuten bereit bin."Sie können ChatGPT auch erlauben, Ihre eigene Geschäfts-API aufzurufen, um z.B. Produktinformationen oder Informationen zum Bestellstatus direkt an den Kunden zu übermitteln.

### **Kontext für den Chat bereitstellen**

[HTTP-Anfragen](https://www.pubnub.com/guides/http/) sind zustandslos. Um also eine lang andauernde Konversation mit OpenAI zu führen, muss es eine Möglichkeit geben, der API einen gewissen Kontext zu geben, die bisherige Konversation zu beschreiben und Metadaten zu dieser Konversation bereitzustellen.

Die [Chat Completion API](https://platform.openai.com/docs/api-reference/chat/create) akzeptiert ein Array von `Nachrichten`, die es dem KI-Modell ermöglichen, aus einer ansonsten mehrdeutigen Frage eine Bedeutung abzuleiten. Betrachten Sie dieses Beispiel:

\> \[Benutzer\] Wie groß ist die Erde?

\> \[OpenAI\] Die Erde hat einen Durchmesser von etwa 12.742 Kilometern

\> \[Benutzer\] **Ich meinte, wie schwer ist sie?**

\> \[OpenAI\] Die Erde hat eine Masse von etwa 5,97x10^24 kg

Um die Frage "Wie schwer ist sie?" zu beantworten, musste die KI natürlich wissen, was "sie" ist.

Wenn Sie Ihren Chatbot auf PubNub-Basis aufbauen, müssen Sie entscheiden, wie viel Gesprächskontext zur Verfügung gestellt werden soll. Wenn Sie PubNub-Funktionen verwenden, haben Sie Zugriff auf den gesamten Nachrichtenverlauf des Channels, und das Beispiel liefert die letzten 10 Nachrichten der Unterhaltung. Sie könnten natürlich viel mehr zur Verfügung stellen, je nach Ihren Bedürfnissen:

```js
// Read in the last messages from the conversation to provide some context to Chat GPT
pubnub.history({
  channel: inboundChannel,
  count: 10
}).then((response) => {
  response['messages'].forEach((value, index) => {
    if (value.entry.sender && value.entry.sender == "ChatGPT")
      historicalMsgs.push({"role": "assistant", "content": value.entry.content.text})
    else
      historicalMsgs.push({"role": "user", "content": value.entry.content.text})
});
```

**Da der Chat-Kontext bereits in PubNub vorhanden ist, ist es trivial, diesen Kontext OpenAI zur Verfügung zu stellen**. Beachten Sie, dass die `Rolle` unterschiedlich ist, je nachdem ob die Nachricht an OpenAI gesendet oder von OpenAI empfangen wurde.

### **Langlaufende Abfragen**

Bei der Entwicklung Ihres ChatGPT-ähnlichen Chatbots und der Konfiguration der Parameter, die von Ihrem KI-Modell verwendet werden, sollten Sie die erwartete Antwortzeit auf Ihre Anfrage berücksichtigen. Standardmäßig bieten PubNub-Funktionen eine maximale Laufzeit von 10 Sekunden pro Aufruf, die durch Kontaktaufnahme mit dem Support erhöht werden kann. Im Allgemeinen wird ein Chatbot, der zu lange braucht, um auf die Frage eines Benutzers zu antworten, vom Benutzer negativ wahrgenommen, daher ist es eine gute Praxis, die Parameter Ihres Modells zu wählen, um ein Gleichgewicht zwischen Reaktionsfähigkeit und Fähigkeiten zu erreichen, wie bereits erwähnt.

Wenn Sie OpenAI in Ihre PubNub-Lösung integrieren und erwarten, dass die Dauer der Antwort die Standardlaufzeit der Funktion überschreitet, setzen Sie sich bitte mit uns in [Verbindung](https://www.pubnub.com/company/contact-us/), damit wir Ihnen Empfehlungen und Ratschläge geben können.

**Zusammenfassung**
-------------------

Mit einer Kombination aus PubNub und OpenAI / ChatGPT ist es möglich, schnell sehr leistungsfähige Echtzeitlösungen zu erstellen, um KI und Chat zu jedem Online-Erlebnis hinzuzufügen.

Wenn Sie bereit sind, loszulegen, besuchen Sie unser [Admin-Dashboard](http://admin.pubnub.com/), um sich für ein kostenloses Set von PubNub-Schlüsseln anzumelden. Wir haben eine Reihe von [Tutorials](https://www.pubnub.com/tutorials/) und [Demos](https://www.pubnub.com/demos/), die jede Branche abdecken, oder schauen Sie sich unseren [PubNub-Showcase](http://pubnub-showcase.netlify.app/) (auch auf [Github](https://github.com/PubNubDevelopers/PubNub-Showcase) verfügbar) an, um einen Beispiel-Chatbot zu sehen, der von OpenAI betrieben wird.

#### Inhalt

[High-Level-ArchitekturKonfiguration](#h-0)[Ihrer PubNub-FunktionErstellen](#h-1) Sie[Ihre PubNub-Funktion wie folgt:](#h-2)[Hier ist ein Beispiel für eine PubNub-Funktion, die OpenAI / ChatGPTP aufruftPraktische](#h-3)[Überlegungen beim Aufrufen der OpenAI APIChat](#h-4)[Completion API PropertiesBereitstellung von](#h-5)[Kontext für ChatLanglaufende](#h-6)[AbfragenZusammenfassung](#h-8)

Wie kann PubNub Ihnen helfen?
=============================

Dieser Artikel wurde ursprünglich auf [PubNub.com](https://www.pubnub.com/blog/build-a-chatbot-with-pubnub-and-chatgpt-openai/) veröffentlicht.

Unsere Plattform unterstützt Entwickler bei der Erstellung, Bereitstellung und Verwaltung von Echtzeit-Interaktivität für Webanwendungen, mobile Anwendungen und IoT-Geräte.

Die Grundlage unserer Plattform ist das größte und am besten skalierbare Echtzeit-Edge-Messaging-Netzwerk der Branche. Mit über 15 Points-of-Presence weltweit, die 800 Millionen monatlich aktive Nutzer unterstützen, und einer Zuverlässigkeit von 99,999 % müssen Sie sich keine Sorgen über Ausfälle, Gleichzeitigkeitsgrenzen oder Latenzprobleme aufgrund von Verkehrsspitzen machen.

PubNub erleben
--------------

Sehen Sie sich die [Live Tour](https://www.pubnub.com/tour/introduction/) an, um in weniger als 5 Minuten die grundlegenden Konzepte hinter jeder PubNub-gestützten App zu verstehen

Einrichten
----------

Melden Sie sich für einen [PubNub-Account](https://admin.pubnub.com/signup/) an und erhalten Sie sofort kostenlosen Zugang zu den PubNub-Schlüsseln

Beginnen Sie
------------

Mit den [PubNub-Dokumenten](https://www.pubnub.com/docs) können Sie sofort loslegen, unabhängig von Ihrem Anwendungsfall oder [SDK](https://www.pubnub.com/docs)