カスタムナレッジベースでLLMチャットボットを構築する
Published: 2024-02-01 21:09:34

これらのLLMやChatGPTが注目されるにつれ、"Garbage in, garbage out "という新しい原則が浮かび上がってきました。GPT-4やGPT-3.5、あるいは他の大きな言語モデルを使うとき、この概念は次の2つの場所に当てはまります。 [プロンプトエンジニアリング](https://en.wikipedia.org/wiki/Prompt_engineering#:~:text=Prompt%20engineering%20(also%20known%20as,of%20it%20being%20explicitly%20given.)そして [微調整](https://en.wikipedia.org/wiki/Fine-tuning_(deep_learning)).また、これらのモデルがいつ学習されたかを考慮し、提供されるデータが古いか新しいかを検証する必要があります。

今日、ほとんどのビジネスは、ファイアウォールの内側や外部にある企業データ・ソースの中にあり、パブリック・ドメインのインターネット上にはない。もしこのデータにLLMを活用できれば、新たな可能性が生まれる。

この記事では、30分でカスタムナレッジベースとチャットボットを構築し、AIにデータに関する質問に答えさせる方法について説明する。

![](/cdn/3prze68gbwl1/3qYPBDJSpSd5oecj2fUDae/f2a980695856b249c645e7ea774b87fe/Screenshot_2023-07-20_at_10.17.38_PM.png)

ナレッジボット作成の前提条件
--------------

カスタムナレッジベースを作成するためには、どれだけのデータがあるかを考慮する必要があります。このブログでは、PubNubのドキュメントを使ってアシスタントを作成します。ドキュメントはたくさんあるので、以下のようなプロダクション・サービスの利用を検討する必要があります。 [Vectara](https://vectara.com/), [Pinecone](https://www.pinecone.io/)または [Weaviate](https://weaviate.io/)などを使用してベクトル埋め込みを管理することができます。LangChainを使えば、少量のデータ用にローカルベクターデータベースを作成することができます。LangChainはまた、意味検索や類似検索を通して、カスタム埋め込みをLLMモデルにマッピングすることもサポートしています。

このブログでは、Vectaraでベクターデータベースをセットアップする方法を説明します。Vectaraとやりとりする最良の方法は [PubNub Functions](https://www.pubnub.com/docs/general/serverless/functions/overview#:~:text=PubNub%20provides%20Functions%20to%20capture,filter%2C%20and%20even%20aggregate%20data.)これは、事前に定義されたイベントが発生するたびに実行されるサーバーレスJavaScriptコンテナを提供します。ファンクションが実行されるタイミングをカスタマイズできるため、AIナレッジボットがどのように動作するかを調整することができます。

Vectaraはあなたのデータセットを使って、データを複数のエンベッディングにインデックス化します。テキスト入力またはユーザー入力を渡すと、Vectaraはあなたのデータでセマンティック検索を実行し、見つかった結果を要約して、あなたのカスタムデータを使って質問に対する答えを提供します。これにより、必要な関連情報を得ることができます。ベクトラでは、TXT、HTML、PDF、ワードファイルなど複数のファイル形式をサポートしています。アップロードしたい文書をすべて集め、個別のフォルダに追加してください。

### ベクタラの設定方法

ベクタラの設定方法は以下の通りです：

1.  [サインアップ](https://console.vectara.com/login)またはVectaraにログイン
    
2.  ダッシュボードで、`コーパスの`作成をクリックします。
    
3.  コーパスに名前と説明をつけたら、`データ取り込み`ヘッダーの下にある`ファイルのアップロードセクションに`、LLMに知らせたいファイルをドラッグ＆ドロップします。ファイルのアップロードが完了したら、ウェブページの上部にあるコーパスIDを確認してください。
    
4.  右上のEメールをクリックし、`お客様IDを`保存してください。
    
5.  `APIキーを`選択し、ドロップダウンメニューからコーパスを選択してAPIキーを作成します。APIキーを保存します。
    

### ハイレベル・アーキテクチャ

アーキテクチャは以下のように構成される：

1.  チャットアプリケーションはPubNubを使ってメッセージを送受信する。
    
2.  PubNub Functionが特定のチャネルでこれらのメッセージをリッスンする。
    
3.  PubNubシグナルが発せられ、AIがいつ考え、いつ終わったかをユーザーに知らせる。
    
4.  メッセージはVectara Rest APIを使ってVectaraに転送される。
    
5.  PubNubファンクションはVectaraからのレスポンスの中から1つの結果をパースする。
    
6.  レスポンスはチャットボットに関連付けられたチャンネルに公開されます。
    

PubNub関数を設定する
-------------

1.  管理画面の [管理ダッシュボード](https://admin.pubnub.com/)
    
2.  左側のメニューから`ファンクションを`選択し、使用したいキーセットをクリックします。
    
3.  `モジュールの作成`\]を選択し、モジュールの名前と説明を入力します。
    
4.  作成したモジュールを選択し、`+ 関数を作成`をクリックします。
    
5.  ファンクションに「`Vectara Query`」などの名前を付け、ドロップダウンメニューで「`After Publish」または「Fire`」を選択します。この関数は、メッセージが関連チャネル（この場合は`docs-pubnub-ai` ）に公開された後に起動します。
    
6.  チャンネル名を`docs-pubnub-aiに`設定します。
    
7.  `My Secrets`をクリックし、`VECTARA_API_KEY`と`CUSTOMER_ID`という名前のシークレットを作成します。
    

以下はPubNub関数からベクトラデータベースに問い合わせるコードです。
------------------------------------

PubNubファンクションのコードスニペットは以下のように定義されています：

```js
const Promise = require('promise');

//
// API Key For OpenAI
// **Add your Vectara API Key and Customer ID to MY SECRETS (Left Panel)**
//
let VECTARA_API_KEY = null;
let CUSTOMER_ID = null;
let channel = "docs-pubnub-ai-response";
function getVectaraKey() {
   // Use cached key
   if (VECTARA_API_KEY && CUSTOMER_ID) {
       return new Promise(resolve => resolve(VECTARA_API_KEY));
   }
   // Fetch key from vault
   return vault.get("VECTARA_API_KEY").then(apikey => {
       return vault.get("CUSTOMER_ID").then(customer_id => {
            VECTARA_API_KEY = apikey;
            CUSTOMER_ID = customer_id;
           return new Promise(resolve => resolve(VECTARA_API_KEY));
       });
   });
}

//
// Import Modules
//
const xhr = require('xhr');
const vault = require('vault');
const pubnub = require('pubnub');

//
// Main
//
export default (request) => {
   // Input data for Vectara
   let message = request.message.text;
   let signalMessage = { message: { type: "typing_on" }, channel: channel };
   return pubnub.signal(signalMessage).then((_) => {
       return getVectaraKey().then(_ => {
           return vectara(message).then(response => {
               return pubnub.publish({
                   channel: channel,
                   message: {
                       id: "PubNubAI",
                       type: "default",
                       text: response
                   },
               }).then((publishResponse) => {
                   console.log(publishResponse);
                   message = { message: { type: "typing_off" }, channel: channel };
                   return pubnub.signal(message).then((signalOffResponse) => {
                       console.log(signalOffResponse);
                       return request.ok();
                   });
               }).catch((err) => {
                   console.error(err);
               });
           });
       });
   });
};

//
// API Call to Vectara asking the AI a question
//
async function vectara(question) {
   console.log("SENDING REQUEST TO VECTARA");
   const url = "https://api.vectara.io/v1/query";
   const body = JSON.stringify({
       "query": [
           {
           "query": question,
           "start": 0,
           "numResults": 10,
           "contextConfig": {
               "charsBefore": 0,
               "charsAfter": 0,
               "sentencesBefore": 2,
               "sentencesAfter": 2,
               "startTag": "<b>",
               "endTag": "</b>"
           },
           "corpusKey": [
               {
               "customerId": CUSTOMER_ID,
               "corpusId": 1,
               "semantics": "DEFAULT",
               "dim": [
                   {
                   "name": "string",
                   "weight": 0
                   }
               ],
               "lexicalInterpolationConfig": {
                   "lambda": 0.025
               }
               }
           ],
           "rerankingConfig": {
               "rerankerId": 272725717
           },
           "summary": [
               {
               "summarizerPromptName": "",
               "maxSummarizedResults": 5,
               "responseLang": "eng",
               "summarizerPromptId": 1,
               "debug": false,
               "responseChars": 0
               }
           ]
           }
       ]
   });

   const http_options = {
       'method': 'POST',
       'timeout': 20000,
       'headers': {
           'Content-Type': 'application/json',
           'customer-id': CUSTOMER_ID,
           'x-api-key': VECTARA_API_KEY
        },
       'body': body
   };

   xhr.timeout = 100000;

   // Send API Request to OpenAI GPT Model
   const response = await xhr.fetch(url, http_options).then(res => res.json());

   // Parse the response and get the summary
   const summary = response.responseSet[0].summary[0].text;

   return summary;
}
```

PubNubファンクションをUIに接続する
---------------------

PubNub関数をUIに接続するには、多くの [SDK](https://www.pubnub.com/docs/sdks)PubNubが提供する [パブリッシュ/サブスクライブ](https://www.pubnub.com/docs/sdks/javascript/api-reference/publish-and-subscribe)をチャンネル`pubnub-docs-aiに`登録し、上記のPubNub関数を利用した後、Vectaraクエリの実行が終了するのを待ちます。接続 [タイピングインジケーター](https://www.pubnub.com/docs/chat/sdks/messages/typing)を接続してチャンネル`pubnub-docs-ai`のPubNubシグナルをリッスンすることで、ユーザーはPubNubナレッジボットがいつ考えているのかを確認することができ、よりスムーズなエンドユーザー体験を追加することができます。

ReactでPubNub機能を接続するコード：

```js
const pubnub = new PubNub({
   publishKey: process.env.NEXT_PUBLIC_PUBLISH_KEY!,
   subscribeKey: process.env.NEXT_PUBLIC_SUBSCRIBE_KEY!,
   userId: "You",
 });

 const publishChannel = "docs-pubnub-ai";

 const sendMessage = (message: string) => {
   if (message) {
     pubnub.publish({
         channel: publishChannel, message: {
           text: message
       }});
   }
 };
```

まとめ
---

任意のベクターデータベースまたはベクターストアとともにPubNub関数を使用することは、独自のAIナレッジボットを作成するための非常に迅速かつ生産可能な方法です。Vectaraだけでなく、PineconeやWeaviate、その他のプロダクション用Vector Databaseを利用することもできます。PubNub Functionsを使えば、メッセージの送信方法と送信タイミングを簡単にホストして制御し、ベクターデータベースの機能を強化することができます。

私たちの [管理ダッシュボード](https://admin.pubnub.com/#/register)にサインアップしてPubNubキーセットの設定を開始してください。また [チュートリアル](https://www.pubnub.com/tutorials/)と [ブログ](https://www.pubnub.com/blog/)をご覧ください。 [ユースケース](https://www.pubnub.com/use-case/).

PubNubはあなたのお役に立ちますか？
====================

この記事は[PubNub.comに](https://www.pubnub.com/blog/build-chatbot-with-custom-knowledge-base/)掲載されたものです。

PubNubのプラットフォームは、開発者がWebアプリ、モバイルアプリ、IoTデバイス向けにリアルタイムのインタラクティブ機能を構築、提供、管理できるよう支援します。

私たちのプラットフォームの基盤は、業界最大かつ最もスケーラブルなリアルタイムエッジメッセージングネットワークです。世界15か所以上で8億人の月間アクティブユーザーをサポートし、99.999%の信頼性を誇るため、停電や同時実行数の制限、トラフィックの急増による遅延の問題を心配する必要はありません。

PubNubを体験
---------

[ライブツアーを](https://www.pubnub.com/tour/introduction/)チェックして、5分以内にすべてのPubNub搭載アプリの背後にある本質的な概念を理解する

セットアップ
------

[PubNubアカウントに](https://admin.pubnub.com/signup/)サインアップすると、PubNubキーに無料ですぐにアクセスできます。

始める
---

[PubNubのドキュメントは](https://www.pubnub.com/docs)、ユースケースや[SDKに](https://www.pubnub.com/docs)関係なく、あなたを立ち上げ、実行することができます。