Zbuduj chatbota za pomocą PubNub i ChatGPT / OpenAI
Published: 2024-03-11 14:27:56

Jeszcze do niedawna, jeśli chciałeś zbudować chatbota, używałeś "przetwarzania języka naturalnego" (NLP), aby zrozumieć i zinterpretować to, o co prosił użytkownik, a następnie próbowałeś spełnić to żądanie za pomocą logiki zaplecza, potencjalnie zintegrowanej z zastrzeżoną usługą. Rozwiązania takie jak Dialogflow lub Microsoft Bot framework zapewniają konwersacyjną sztuczną inteligencję opartą na uczeniu maszynowym i tradycyjnie są popularne wśród programistów tworzących chatboty.

OpenAI i ChatGPT OpenAI sprawiają, że tworzenie chatbota opartego na sztucznej inteligencji jest łatwiejsze niż kiedykolwiek. Ponieważ duży model językowy (LLM), który zasila OpenAI, opiera się na publicznym zbiorze danych, możesz łatwo poprawić wrażenia użytkownika z aplikacji, dostarczając wszelkie informacje, których można oczekiwać w publicznej bazie wiedzy.

PubNub obsługuje doświadczenia w czasie rzeczywistym dla wielu branż i przypadków użycia, w tym [obsługa klienta](https://www.pubnub.com/solutions/communications/) i [czat w aplikacji.](https://www.pubnub.com/solutions/chat/)Wszystkie te doświadczenia w czasie rzeczywistym są zasilane danymi, zarówno wiadomościami czytelnymi dla użytkownika, jak i metadanymi dotyczącymi rozwiązania - czy nie byłoby **wspaniale wykorzystać te istniejące dane do zasilania chatbota?**

_Kilka przykładowych zastosowań w świecie rzeczywistym:_

-   Udzielanie odpowiedzi na najczęściej zadawane pytania dotyczące **obsługi** klienta
    
-   **Rozszerzanie** istniejących danych o dodatkowe treści, na przykład sugerowanie miejsc, w których można zjeść w pobliżu podanej lokalizacji.
    
-   Dostarczanie **podsumowań konwersacji** na podstawie historii wiadomości.
    

Opublikowaliśmy [artykuł](https://www.pubnub.com/blog/building-a-chatbot-with-openai-gpt3-and-pubnub/) na ten temat i chociaż ten starszy artykuł jest nadal poprawny, branża rozwija się bardzo szybko, a kilka miesięcy to dużo czasu.

W tym artykule omówimy, jak zbudować chatbota opartego na OpenAI, podobnego do tego, który można zobaczyć w naszej prezentacji [PubNub showcase](http://pubnub-showcase.netlify.app/) pokazanej poniżej.

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

**Architektura wysokiego poziomu**
----------------------------------

Aby stworzyć chatbota podobnego do ChatGPT, należy skorzystać z interfejsu [API OpenAI Chat](https://platform.openai.com/docs/api-reference/chat) i założyć konto w celu utworzenia [klucza API](https://platform.openai.com/account/api-keys). Interfejs API OpenAI jest dostępny jako punkt końcowy REST, więc można go wywołać z praktycznie dowolnego języka programowania, chociaż większość dostarczonych przykładów jest napisana w Pythonie.

Najlepszym sposobem na wyodrębnienie danych z PubNub, aby zainicjować lub kontynuować rozmowę z chatbotem, jest użycie [funkcji](https://www.pubnub.com/products/functions/). Funkcje zapewniają bezserwerowy kontener [JavaScript](https://www.pubnub.com/guides/javascript/), który działa w Node.JS i umożliwia wykonywanie logiki biznesowej za każdym razem, gdy zdarzenie wystąpi w sieci PubNub, takie jak otrzymanie wiadomości czatu. Funkcje PubNub są często używane do tłumaczenia języków w czasie rzeczywistym, filtrowania wulgaryzmów lub wywoływania usług innych firm, takich jak OpenAI.

Ten przykład będzie działał w następujący sposób:

-   Istniejąca aplikacja czatu używa PubNub do wysyłania i odbierania wiadomości w czasie rzeczywistym.
    
-   Funkcja PubNub będzie nasłuchiwać wiadomości wysyłanych do określonego kanału.
    
-   Pojedyncza wiadomość sama w sobie nie zapewnia żadnego kontekstu dla ChatGPT, więc część historii konwersacji będzie również buforowana, aby umożliwić ciągły dialog.
    
-   Funkcja PubNub wywoła API OpenAI i pobierze odpowiedź
    
-   Odpowiedź zostanie opublikowana na kanale PubNub powiązanym z Twoim chatbotem
    

Można to zobaczyć na poniższym diagramie sekwencji:

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

1.  Użytkownik wpisuje wiadomość w aplikacji czatu. Dzięki ponad 50 zestawom SDK PubNub jest w stanie obsługiwać zdecydowaną większość aplikacji, a wiadomość zostanie [opublikowana](https://www.pubnub.com/docs/general/messages/publish) na kanale reprezentującym chatbota w sieci PubNub.
    
2.  Funkcja PubNub jest skonfigurowana tak, aby była wywoływana po wystąpieniu [zdarzenia publikacji](https://www.pubnub.com/docs/general/serverless/functions/overview#after-publish-or-fire-functions) na kanale. Po otrzymaniu wiadomości pobierana jest historia kanału, aby zapewnić pewien kontekst rozmowy, a ta historia, wraz z danymi wejściowymi użytkownika i dodatkowym kontekstem, jest dostarczana do ChatGPT za pośrednictwem interfejsu [API Chat Completion](https://platform.openai.com/docs/api-reference/chat/create).
    
3.  Interfejs API ChatGPT wygeneruje odpowiedzi dostosowane do przebiegu konwersacji
    
4.  W ramach funkcji PubNub odbierana jest odpowiedź od ChatGPT, która jest analizowana i [publikowana](https://www.pubnub.com/docs/general/messages/publish) z powrotem w sieci PubNub.
    
5.  Aplikacja, która wcześniej [zasubskrybowała](https://www.pubnub.com/docs/general/channels/subscribe) otrzymywanie wiadomości z PubNub, wyświetli odpowiedź chatbota.
    

**Konfiguracja funkcji PubNub**
-------------------------------

### Utwórz funkcję PubNub w następujący sposób:

Wymagania wstępne: Jeśli jesteś nowy w PubNub, postępuj zgodnie z naszą [dokumentacją](https://www.pubnub.com/docs/general/basics/set-up-your-account), aby skonfigurować swoje konto lub odwiedź naszą [wycieczkę](https://www.pubnub.com/tour/introduction/), aby zrozumieć, na czym polega PubNub.

1.  Przejdź do [panelu administratora](http://admin.pubnub.com/)
    
2.  Wybierz `funkcje` z menu po lewej stronie i wybierz odpowiedni zestaw klawiszy, w którym chcesz utworzyć funkcję.
    
3.  Wybierz `+ Utwórz nowy moduł`.
    
4.  Wprowadź nazwę i opis modułu, wybierz zestaw klawiszy, a następnie naciśnij przycisk `Utwórz`.
    
5.  Wybierz właśnie utworzony moduł
    
6.  Wybierz + Utwórz nową `funkcję`
    
7.  Nadaj funkcji nazwę i wybierz typ zdarzenia `After Publish lub Fire`. Ta funkcja zostanie wywołana PO przesłaniu wiadomości do PubNub. Funkcje mogą być synchroniczne lub asynchroniczne, a w tym przypadku po prostu przechwytujemy kopię wiadomości do wysłania do OpenAI. Więcej szczegółów na temat [różnych typów funkcji](https://www.pubnub.com/docs/general/serverless/functions/overview#before-publish-or-fire-functions) można znaleźć w naszej dokumentacji
    
8.  Kanał funkcji powinien odpowiadać kanałowi, na którym [publikujesz](https://www.pubnub.com/docs/general/messages/publish) wiadomości, które chcesz wysłać do OpenAI. Możesz użyć tutaj symbolu wieloznacznego, więc na przykład `chatgpt.` \* będzie pasował do każdego kanału, który rozpoczyna się od chatgpt. Ponieważ chcemy, aby ta funkcja rozmawiała z wieloma osobami jednocześnie, symbol wieloznaczny pozwala nam oddzielić, który użytkownik jest zaangażowany w aktywną rozmowę, abyśmy mogli odpowiedzieć na odpowiednim kanale.Tam, gdzie wiele osób jednocześnie rozmawia z OpenAI, PubNub zajmuje się tworzeniem wielu instancji funkcji. Na przykład chatgpt. `dave` i `chatgpt.simon` to dwa różne kanały, ale oba będą wywoływać funkcję PubNub nasłuchującą na `chatgpt.*`. Sposób, w jaki [PubNub obsługuje symbole wieloznaczne kanałów](https://support.pubnub.com/hc/en-us/articles/360051495072-How-do-I-subscribe-to-a-wildcard-channel-), wyjaśniono bardziej szczegółowo w naszej dokumentacji.
    
9.  Wybierz `Moje sekrety` i utwórz nowy sekret dla [klucza API](https://platform.openai.com/account/api-keys) OpenAI; poniższy kod zakłada, że ten sekret nazywa się `OPENAI_API_KEY`.
    

### **Oto przykładowa funkcja PubNub, która wywoła OpenAI / ChatGPT**

```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";
  });
}
```

**Praktyczne uwagi dotyczące wywoływania interfejsu API OpenAI**
----------------------------------------------------------------

### **Właściwości interfejsu API uzupełniania czatu**

Kod przedstawiony w tym artykule wykorzystuje OpenAI Chat Completion [API](https://platform.openai.com/docs/api-reference/chat/create), ale jest bardziej konfigurowalny niż pokazano powyżej.

Określenie wartości `stream` jako true spowoduje zwrócenie odpowiedzi OpenAI jako strumienia danych ponad [zdarzeniami wysyłanymi przez serwer](https://www.pubnub.com/guides/server-sent-events/). W praktyce może to zmniejszyć postrzegane opóźnienie, ponieważ użytkownik zobaczy bardziej natychmiastową odpowiedź, podobnie jak działa interfejs sieciowy ChatGPT.

`model` pozwala określić model językowy używany do generowania odpowiedzi. API jest zasilane przez rodzinę modeli o różnych możliwościach i cenach, przy czym modele są często aktualizowane i dodawane są nowe modele.

`max_tokens` ogranicza liczbę [tokenów](https://platform.openai.com/tokenizer), których API użyje do wygenerowania danych wyjściowych. Ogólnie rzecz biorąc, im mniejsza liczba tokenów, tym mniej złożone dane wyjściowe i tym mniej kontekstu jest śledzone, ale odpowiedzi będą dostarczane szybciej.

`Rola` wiadomości pozwala określić autora wiadomości. Przykład w tym artykule wykorzystuje `system` do dostarczenia pewnych instrukcji do OpenAPI, `użytkownika` do wiadomości wysyłanych przez użytkownika końcowego i `asystenta` do odpowiedzi wcześniej dostarczonych przez OpenAI.

Model można dodatkowo dostosować, określając `temperature` / `top_p`, `frequency_penality` i `presence_penalty`. Więcej informacji na ten temat można znaleźć w [dokumentacji OpenAPI](https://platform.openai.com/docs/api-reference/chat/create).

Interfejs API umożliwia również definiowanie i określanie niestandardowych funkcji, które rozszerzają możliwości modelu, co wykracza poza zakres tego bloga. Jeśli chcesz dowiedzieć się więcej, mamy [osobny post](https://gist.github.com/stephenlb/de558e9802a6f950951eb0939ab71bcd), który ilustruje, w jaki sposób możesz zezwolić ChatGPT na publikowanie w PubNub w Twoim imieniu, umożliwiając Ci powiedzenie czegoś w rodzaju: "Wyślij wiadomość do głównego kanału, informując ich, że będę gotowy za 5 minut"."Można również zezwolić ChatGPT na wywoływanie własnego API biznesowego, dostarczając na przykład informacje o produkcie lub informacje o statusie zamówienia bezpośrednio do klienta.

### **Dostarczanie kontekstu do czatu**

Żądania[HTTP](https://www.pubnub.com/guides/http/) są bezstanowe, więc aby zaangażować się w długotrwałą rozmowę z OpenAI, musi istnieć sposób na nadanie pewnego kontekstu API, opisanie dotychczasowej rozmowy i dostarczenie metadanych wokół tej rozmowy.

Interfejs [API uzupełniania cz](https://platform.openai.com/docs/api-reference/chat/create) atu akceptuje tablicę `wiadomości`, które pozwalają modelowi sztucznej inteligencji wywnioskować znaczenie z tego, co w przeciwnym razie mogłoby być niejednoznacznym pytaniem. Rozważmy ten przykład:

\> \[Użytkownik\] Jak duża jest Ziemia?

\> \[OpenAI\] Ziemia ma średnicę około 12 742 kilometrów.

\> \[Użytkownik\] Chodziło **mi o to, jak ciężka jest** Ziemia?

\> Ziemia ma masę około 5,97x10^24 kg.

Oczywiście, aby odpowiedzieć na pytanie "Jak ciężka jest", sztuczna inteligencja musiała zrozumieć, czym jest "to".

Budując chatbota opartego na PubNub, będziesz musiał zdecydować, ile kontekstu konwersacji należy zapewnić. Jeśli korzystasz z funkcji PubNub, masz dostęp do całej historii wiadomości dla kanału, a przykład zawiera 10 poprzednich wiadomości w rozmowie. Oczywiście możesz zapewnić znacznie więcej, jeśli zajdzie taka potrzeba, w zależności od potrzeb:

```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})
});
```

**Posiadanie kontekstu czatu już w PubNub sprawia, że dostarczenie tego kontekstu do OpenAI jest banalnie** proste. Należy pamiętać, że `rola` będzie się różnić w zależności od tego, czy wiadomość została wysłana do OpenAI, czy odebrana z OpenAI.

### **Długotrwałe zapytania**

Podczas opracowywania chatbota podobnego do ChatGPT i konfigurowania parametrów używanych przez model sztucznej inteligencji należy wziąć pod uwagę oczekiwany czas odpowiedzi na zapytanie. Domyślnie funkcje PubNub oferują maksymalny czas działania wynoszący 10 sekund na wywołanie, który można zwiększyć, kontaktując się z pomocą techniczną. Ogólnie rzecz biorąc, chatbot, który zbyt długo odpowiada na pytanie użytkownika, będzie postrzegany przez niego negatywnie, dlatego dobrą praktyką jest wybranie parametrów modelu, aby osiągnąć równowagę między szybkością reakcji a możliwościami, jak wspomniano wcześniej.

Niektóre przypadki użycia OpenAI mogą oczekiwać odpowiedzi mierzonych w minutach, a nie sekundach. Jeśli integrujesz OpenAI ze swoim rozwiązaniem PubNub i spodziewasz się, że czas trwania odpowiedzi przekroczy domyślny czas działania funkcji, [skontaktuj](https://www.pubnub.com/company/contact-us/) się z nami, a my udzielimy Ci zaleceń i porad.

**Podsumowując**
----------------

Korzystając z połączenia PubNub i OpenAI / ChatGPT, możliwe jest szybkie tworzenie niezwykle potężnych rozwiązań czasu rzeczywistego w celu dodania sztucznej inteligencji i czatu do dowolnego doświadczenia online.

Gdy będziesz gotowy, aby rozpocząć, odwiedź nasz [panel administracyjny](http://admin.pubnub.com/), aby zarejestrować się w celu uzyskania bezpłatnego zestawu kluczy PubNub. Mamy wiele [samouczków](https://www.pubnub.com/tutorials/) i [wersji demonstracyjnych](https://www.pubnub.com/demos/) obejmujących każdą branżę lub sprawdź naszą [wizytówkę PubNub](http://pubnub-showcase.netlify.app/) (dostępną również na [Github](https://github.com/PubNubDevelopers/PubNub-Showcase)), aby zobaczyć przykładowego chatbota obsługiwanego przez OpenAI.

#### Spis treści

[Architektura wysokiego poziomuKonfiguracja](#h-0)[funkcji PubNubUtwórz](#h-1)[funkcję PubNub w następujący sposób:](#h-2)[Oto przykładowa funkcja PubNub, która wywoła OpenAI / ChatGPTPraktyczne](#h-3)[rozważania podczas wywoływania OpenAI APIChat](#h-4)[Completion API PropertiesProviding](#h-5)[Context to ChatLong-Running](#h-6)[QueriesPodsumowanie](#h-8)

Jak PubNub może ci pomóc?
=========================

Ten artykuł został pierwotnie opublikowany na [PubNub.com](https://www.pubnub.com/blog/build-a-chatbot-with-pubnub-and-chatgpt-openai/)

Nasza platforma pomaga programistom tworzyć, dostarczać i zarządzać interaktywnością w czasie rzeczywistym dla aplikacji internetowych, aplikacji mobilnych i urządzeń IoT.

Fundamentem naszej platformy jest największa w branży i najbardziej skalowalna sieć przesyłania wiadomości w czasie rzeczywistym. Dzięki ponad 15 punktom obecności na całym świecie obsługującym 800 milionów aktywnych użytkowników miesięcznie i niezawodności na poziomie 99,999%, nigdy nie będziesz musiał martwić się o przestoje, limity współbieżności lub jakiekolwiek opóźnienia spowodowane skokami ruchu.

Poznaj PubNub
-------------

Sprawdź [Live Tour](https://www.pubnub.com/tour/introduction/), aby zrozumieć podstawowe koncepcje każdej aplikacji opartej na PubNub w mniej niż 5 minut.

Rozpocznij konfigurację
-----------------------

Załóż [konto](https://admin.pubnub.com/signup/) PubNub, aby uzyskać natychmiastowy i bezpłatny dostęp do kluczy PubNub.

Rozpocznij
----------

[Dokumenty](https://www.pubnub.com/docs) PubNub pozwolą Ci rozpocząć pracę, niezależnie od przypadku użycia lub [zestawu SDK](https://www.pubnub.com/docs).