Construire un Chatbot avec PubNub et ChatGPT / OpenAI

pubnubdevrel

PubNub Developer Relations

Posted on March 11, 2024

Construire un Chatbot avec PubNub et ChatGPT / OpenAI

Jusqu'à très récemment, si vous vouliez créer un chatbot, vous utilisiez le "traitement du langage naturel" (NLP) pour comprendre et interpréter ce que l'utilisateur demandait, puis vous essayiez de répondre à cette demande en utilisant une logique d'arrière-plan, éventuellement intégrée à un service propriétaire. Des solutions telles que Dialogflow ou Microsoft Bot framework fournissent une IA conversationnelle basée sur l'apprentissage automatique et sont traditionnellement populaires auprès des développeurs qui créent des chatbots.

OpenAI et OpenAI's ChatGPT rendent plus facile que jamais la création d'un chatbot basé sur l'intelligence artificielle. Étant donné que le modèle de langage étendu (LLM) qui alimente OpenAI est basé sur un ensemble de données publiques, vous pouvez facilement améliorer l'expérience utilisateur de votre application en fournissant toute information que vous pourriez raisonnablement attendre d'une base de connaissances publique.

PubNub permet des expériences en temps réel pour un large éventail d'industries et de cas d'utilisation, y compris le support client et le chat in-appToutes ces expériences en temps réel sont alimentées par des données, qu'il s'agisse de messages lisibles par l'utilisateur ou de métadonnées sur votre solution - ne serait-il pas formidable de tirer parti de ces données existantes pour alimenter un chatbot ?

Quelques exemples de cas d'utilisation dans le monde réel :

  • Fournir des réponses aux questions les plus fréquemment posées au support client

  • Augmenter vos données existantes avec du contenu supplémentaire, par exemple en suggérant des endroits où manger à proximité d'un lieu donné.

  • Fournir des résumés de conversations basés sur l'historique des messages.

Nous avons publié un article sur ce sujet, et bien que cet ancien article soit toujours d'actualité, l'industrie évolue très rapidement, et quelques mois, c'est long.

Cet article explique comment construire un chatbot alimenté par OpenAI, similaire à celui que vous pouvez voir fonctionner dans notre PubNub showcase illustrée ci-dessous.

The showcase's AI model has been primed to mention PubNub, where appropriate

Architecture de haut niveau

Pour créer un chatbot comme ChatGPT, vous devrez utiliser l' API de chat OpenAI et vous inscrire pour créer une clé API. L'API OpenAI est accessible en tant que point de terminaison REST, elle peut donc être appelée à partir de n'importe quel langage de programmation, bien que la plupart des exemples fournis soient écrits en Python.

La meilleure façon d'extraire des données de PubNub, d'initier ou de poursuivre une conversation avec le chatbot est d'utiliser des fonctions. Les fonctions fournissent un conteneur JavaScript sans serveur qui fonctionne en Node.JS et vous permet d'exécuter une logique métier chaque fois qu'un événement se produit sur le réseau PubNub, comme la réception d'un message de chat. Les fonctions PubNub sont fréquemment utilisées pour la traduction de langue en temps réel à la volée, le filtrage des blasphèmes, ou pour invoquer un service tiers tel que OpenAI.

Cet exemple fonctionnera comme suit :

  • L'application de chat existante utilise PubNub pour envoyer et recevoir des messages en temps réel.

  • Une fonction PubNub écoute les messages envoyés à un canal spécifique.

  • En soi, un message unique ne fournit aucun contexte à ChatGPT, de sorte qu'une partie de l'historique de la conversation sera également mise en cache pour permettre un dialogue continu.

  • La fonction PubNub invoquera l'API OpenAI et récupérera la réponse

  • La réponse sera publiée sur le canal PubNub associé à votre propre chatbot.

Vous pouvez voir cela dans le diagramme de séquence ci-dessous :

Example sequence diagram for implementing a ChatGPT-like chatbot with PubNub and OpenAI

  1. L'utilisateur tape un message dans votre application de chat. Avec plus de 50 SDK, PubNub est capable de supporter la grande majorité des applications, et le message sera publié sur le canal représentant le chatbot sur le réseau PubNub.

  2. Une fonction PubNub est configurée pour être invoquée après un événement de publication sur un canal. Lorsqu'un message est reçu, l'historique du canal est récupéré pour fournir un certain contexte à la conversation, et cet historique, ainsi que l'entrée de l'utilisateur et un contexte supplémentaire, est fourni à ChatGPT via l'API Chat Completion.

  3. L'API ChatGPT génère des réponses adaptées au flux de la conversation

  4. Dans la fonction PubNub, une réponse est reçue de ChatGPT, qui est analysée et publiée dans le réseau PubNub.

  5. L'application, qui s'est préalablement abonnée pour recevoir des messages de PubNub, affichera la réponse du chatbot.

Configuration de la fonction PubNub

Créez votre fonction PubNub comme suit :

Prérequis : Si vous êtes nouveau sur PubNub, suivez notre documentation pour configurer votre compte ou visitez notre tour pour comprendre ce qu'est PubNub.

  1. Naviguez vers le tableau de bord de l'administrateur

  2. Sélectionnez les fonctions dans le menu de gauche, et sélectionnez le jeu de clés approprié dans lequel vous souhaitez créer la fonction.

  3. Sélectionnez + Créer un nouveau module.

  4. Saisissez un nom et une description de module, sélectionnez un jeu de clés, puis cliquez sur Créer.

  5. Sélectionnez le module que vous venez de créer.

  6. Sélectionnez + Créer une nouvelle fonction

  7. Donnez un nom à la fonction et sélectionnez le type d'événement After Publish ou Fire. Cette fonction sera invoquée APRES qu'un message ait été soumis à PubNub. Les fonctions peuvent être synchrones ou asynchrones, et dans ce cas, nous capturons simplement une copie du message pour l'envoyer à OpenAI. Vous pouvez trouver plus de détails sur les différents types de fonctions décrits dans notre documentation

  8. Le canal de la fonction doit correspondre au canal où vous publiez les messages que vous voulez envoyer à OpenAI. Vous pouvez utiliser un joker ici, ainsi, par exemple, chatgpt.* correspondra à tout canal qui commence par chatgpt. Puisque nous voulons que cette fonction parle à plusieurs personnes en même temps, un joker nous permet de séparer quel utilisateur est impliqué dans la conversation active afin que nous puissions répondre sur le canal approprié.Lorsque plusieurs personnes parlent à OpenAI simultanément, PubNub se charge de créer plusieurs instances de votre fonction. Par exemple, chatgpt.dave et chatgpt.simon sont deux canaux différents, mais tous deux invoqueront la fonction PubNub écoutant sur chatgpt.*. La manière dont PubNub gère les caractères génériques des canaux est expliquée plus en détail dans notre documentation.

  9. Sélectionnez Mes secrets et créez un nouveau secret pour la clé de l'API OpenAI ; le code ci-dessous suppose que ce secret s'appelle OPENAI_API_KEY.

Voici un exemple de fonction PubNub qui invoquera OpenAI / ChatGPT

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";
  });
}
Enter fullscreen mode Exit fullscreen mode

Considérations pratiques lors de l'appel à l'API OpenAI

Propriétés de l'API Chat Completion

Le code présenté dans cet article utilise l'API OpenAI Chat Completion, mais il est plus configurable que ce qui est montré ci-dessus.

Le fait de spécifier que stream est vrai renverra la réponse de l'OpenAI comme un flux de données sur les événements envoyés par le serveur. En termes pratiques, cela peut réduire la latence perçue puisque l'utilisateur verra une réponse plus immédiate, similaire à la façon dont l'interface web de ChatGPT fonctionne.

model vous permet de spécifier le modèle de langage utilisé pour générer la réponse. L'API est alimentée par une famille de modèles avec des capacités et des prix différents, avec des modèles mis à jour et de nouveaux modèles ajoutés fréquemment.

max_tokens limite le nombre de jetons que l'API utilisera pour générer des résultats. En général, plus le nombre de jetons est faible, moins le résultat est complexe et moins le contexte est pris en compte, mais les réponses seront fournies plus rapidement.

Le rôle du message vous permet de spécifier l'auteur d'un message. L'exemple de cet article utilise system pour fournir des instructions à OpenAPI, user pour les messages envoyés par l'utilisateur final, et assistant pour les réponses précédemment fournies par OpenAI.

Le modèle peut être affiné en spécifiant la température / top_p, la fréquence_pénalité et la présence_pénalité. Veuillez consulter la documentation de l'OpenAPI pour plus d'informations à ce sujet.

L'API vous permet également de définir et de spécifier des fonctions personnalisées qui augmentent les capacités du modèle, ce qui sort du cadre de ce blog. Si vous souhaitez en savoir plus, nous avons un article séparé qui illustre comment vous pouvez permettre à ChatGPT de publier sur PubNub en votre nom, ce qui vous permet de dire quelque chose comme "Envoyez un message au canal principal pour lui dire que je serai prêt dans 5 minutes"."Vous pouvez également permettre à ChatGPT d'invoquer votre propre API commerciale, en fournissant, par exemple, des informations sur les produits ou sur l'état de la commande directement au client.

Fournir un contexte à la discussion en ligne

Les requêtesHTTP sont sans état, donc pour engager une conversation de longue durée avec OpenAI, il doit y avoir un moyen de donner un certain contexte à l'API, de décrire la conversation jusqu'à présent et de fournir des métadonnées autour de cette conversation.

L'API Chat Completion accepte un tableau de messages, qui permet au modèle d'IA de déduire le sens d'une question qui, autrement, pourrait être ambiguë. Prenons l'exemple suivant :

> [Utilisateur] Quelle est la taille de la terre ?

> [OpenAI] La terre a un diamètre d'environ 12 742 kilomètres.

> [Utilisateur] Je voulais dire : quel est son poids ?

> [OpenAI] La masse de la Terre est d'environ 5,97x10^24 kg.

Il est clair que pour répondre à la question "Quel est son poids ?", l'IA doit comprendre ce qu'est "ce".

Lorsque vous construirez votre chatbot alimenté par PubNub, vous devrez décider de la quantité de contexte de conversation à fournir. Si vous utilisez les fonctions de PubNub, vous avez accès à l'historique complet des messages pour le canal, et l'exemple fournit les 10 messages précédents de la conversation. Vous pourriez bien sûr fournir beaucoup plus si nécessaire, en fonction de vos besoins :

// 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})
});
Enter fullscreen mode Exit fullscreen mode

Le*fait d'avoir le contexte du chat déjà dans PubNub rend trivial le fait de fournir ce contexte à OpenAI*. Notez que le rôle sera différent selon que le message a été envoyé à OpenAI ou reçu d' OpenAI.

Requêtes à long terme

Lorsque vous développez votre chatbot de type ChatGPT et que vous configurez les paramètres utilisés par votre modèle d'IA, tenez compte du temps de réponse attendu pour votre requête. Par défaut, les fonctions PubNub offrent un temps d'exécution maximal de 10 secondes par invocation, qui peut être augmenté en contactant le support. En général, un chatbot qui prend trop de temps pour répondre à la question d'un utilisateur sera perçu négativement par ce dernier, c'est pourquoi il est bon de régler les paramètres de votre modèle pour atteindre un équilibre entre la réactivité et les capacités, comme mentionné plus haut.

Si vous intégrez OpenAI dans votre solution PubNub et que vous vous attendez à ce que la durée de la réponse dépasse la durée d'exécution de la fonction par défaut, n'hésitez pas à nous contacter et nous pourrons vous fournir des recommandations et des conseils.

En résumé

En utilisant une combinaison de PubNub et d'OpenAI / ChatGPT, il est possible de créer rapidement des solutions en temps réel immensément puissantes pour ajouter de l'IA et du chat à n'importe quelle expérience en ligne.

Lorsque vous êtes prêt à commencer, visitez notre tableau de bord d'administration pour vous inscrire pour un ensemble gratuit de clés PubNub. Nous avons un certain nombre de tutoriels et de démonstrations couvrant tous les secteurs d'activité, ou consultez notre vitrine PubNub (également disponible sur Github) pour voir un exemple de chatbot propulsé par OpenAI.

Sommaire

Architecture de haut niveauConfigurer votre fonctionPubNubCréervotre fonction PubNub comme suit:Voici un exemple de fonction PubNub qui invoquera OpenAI / ChatGPTPConsidérationspratiqueslors de l'appel de l'APIOpenAIPropriétés de l'API de complétion de ChatFournir uncontexte auChatRequêtesde longue duréeEnrésumé

Comment PubNub peut-il vous aider ?

Cet article a été publié à l'origine sur PubNub.com

Notre plateforme aide les développeurs à construire, livrer et gérer l'interactivité en temps réel pour les applications web, les applications mobiles et les appareils IoT.

La base de notre plateforme est le réseau de messagerie en temps réel le plus grand et le plus évolutif de l'industrie. Avec plus de 15 points de présence dans le monde, 800 millions d'utilisateurs actifs mensuels et une fiabilité de 99,999 %, vous n'aurez jamais à vous soucier des pannes, des limites de concurrence ou des problèmes de latence causés par les pics de trafic.

Découvrez PubNub

Découvrez le Live Tour pour comprendre les concepts essentiels de chaque application alimentée par PubNub en moins de 5 minutes.

S'installer

Créez un compte PubNub pour un accès immédiat et gratuit aux clés PubNub.

Commencer

La documentation PubNub vous permettra de démarrer, quel que soit votre cas d'utilisation ou votre SDK.

💖 💪 🙅 🚩
pubnubdevrel
PubNub Developer Relations

Posted on March 11, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related