2023年7月5日水曜日

ChatGPT Plugin : ベクトルデータベースに挑戦 その1

 ChatGPTを使う上でモデルが学習していない情報(特に最新情報[2021年9月以降])や特定分野の情報)をどうインプットさせるか? は当初の課題でした。それが(有償ユーザーに限りますが) WebブラウジングやPlugin機能が解放されることでピンポイントで情報を取得する事ができ、ChatGPT上で出来る事が飛躍的に増えました。

私の立場としてはGeneXusの技術情報に関する問合せ(セルフトレーニング)やコーディングなどをChatGPTで実現する事ができるか? というのが直近の目標だったりするのですが、JavaScriptやPythonといった十分にモデルが学習済みの技術であればそれも容易なのですが、いかんせんGeneXusというマイナー技術では、なかなか思う様な結果を得ることが出来ないのが現実です。

という事で、次に考えたのは、GeneXus技術情報に特化したプラグインで、問合せの内容を元に文脈的に近い情報をwikiページから取得しモデルに返すことで、より精度の高い回答をChatGPTが出来ないか? というものでした。

問合せの内容から独自のデータを利用してモデルに検討させるのは、最近ではAzure OpenAI サービスにてAdd your dataという機能があります。まだプレビュー版でありますが、これを使うと例えば自社のドキュメントをインプットしておく事で、とり業務に特化した質問に対する回答を得られることができるというものです。

今後も次々にこういった機能やサービスがリリースされてくるでしょうから、自前で作る事にあまり意味はないのかもしれませんが、エンジニアとしては早期に取り組むという事と、実際の技術的なポイントを押さえておきたくてトライしてみました。

その中で情報収集・検討・トライ&エラーした結果として要約したポイントです。

  • 検索対象となる文書のデータベース化
    • GeneXusの技術情報をデータベース化するので、英語版wikiを対象に考えます。
    • データベースはRDBではなく、以下の理由でベクトルデータベースを使用したいのですが、私もビギナーなのでまずはNoSQLであるAzure Cosmos DBを使用し、ベクトル化は自前で行う事にします。(このあたり、正式なベクトルデータベースではベクトル化機能自体備わっているのか?といった事もよくわかっていません(笑)
    • GeneXusもバージョン18U3からCosmos DBをサポートしてきていますので、今後の技術取得の意味も含めて選択しました。
  • 質問の文脈に沿った検索方法
    • 一般的なデータベース(RDB)ではキーワードを元にした部分一致検索などがありますが、ユーザーがどんな質問をするかわらかないChatGPT上では、文脈的に一致するか? という観点での検索が必要になります。
    • この検索を実現するのがベクトルデータベースです。ベクトルデータベースとは、対象となる文章を元にベクトル計算を行い数値化し、データベースに保存しておきます。
    • 一方、問合せ時の質問文もベクトル計算を行い数値化し、ベクトルデータベースに格納されているベクトル値と比較する事で、文脈的に近しい文書を見つける。というものです。
    • 今回はベクトル値同士をコサイン類似性(Cosine Similarity)計算をしてレーティング値を出し、そのレーティング値の高い値を文脈の近い文章として捉えます。
    • コサイン類似性では値が-1~1の間で表され、
      • 1は同じベクトル(0度)で完全に似ている
      • 0は直交(90度)で似ている・似ていないのどちらも無関係
      • -1は逆向き(180度)で似ていない
    • と判断します。
  • ChatGPTに返すデータの量
    • モデルに精度高く考えさせるには多くのデータを渡す方が良いですが、現在はトークン数に限りがあり、より多くのトークンが利用出来るモデルはその分コストも高くなっています。
    • 長い文章の場合は、モデルに要約させる事も可能ですが、技術的な情報では予約によって切り捨てられてしまうと不都合になる情報もあります。
    • この様にどの程度の量の情報を渡せばコストや制限に引っかからず、且つ、精度が高い処理を行って貰うことが出来るのか? は今すぐ答えが出てくる問題ではありません。
では、実装です。今回はかなりトライ&エラーが必要だと思っていたので、GeneXusではなくPythonを使って開発しました。私自身PythonはChatGPTを使うようになってから勉強し始めた言語です。文法やライブラリの調査、使い方のレクチャー、実行時エラーの原因解析と対処などなど、ChatGPTのお陰で短期で作る事が出来るようになりました。が、まだまだマスタしたというレベルではありません。超ビギナーですが、新しい言語に触れるのは幾つになっても楽しいです。(笑)

まずはデータベースの準備です。AzureでCosmos DBアカウントを作成し、データベース→コンテナと順番に作成します。


次にPythonプログラムです。最初はベクトルデータベースを構築する処理です。wikiサイトからhtmlを取得し、テキストを抜き出し、文章を元にベクトル計算をし、Cosmos DBに保存します。インプットとしてはURLを記載したjsonファイルを用意しました。

Pythonのソースコードを書きますが、超ビギナーのコーディングなので掲載はやめておきます(一部だけ掲載)。代わりにソースコードをChatGTP経由で解説してもらった内容を掲載します。

このPythonコードは、ウェブ上のドキュメントを取得し、それらをAzure Cosmos DBに保存するものです。具体的には、Wikipediaの記事を取得し、それらの記事をOpenAIのAPIを使用してベクトル化し、その結果をAzure Cosmos DBに保存します。以下に、コードの主要な部分を段階的に解説します。
  1. 環境変数の設定: このコードは、.envファイルから環境変数を読み込みます。これにはOpenAIのAPIキーとAzure Cosmos DBのURLとキーが含まれます
  2. WikiDocumentsクラスの定義: このクラスは、Wikipediaのドキュメントを取得し、それらをベクトル化し、結果をJSONファイルに保存するためのメソッドを提供します。
    • split_textメソッド: このメソッドは、テキストを単語に分割し、それらを指定された最大トークン数を超えないようにチャンクに分割します。
    • getWikiDocumentsメソッド: このメソッドは、指定されたURLからWikipediaのドキュメントを取得し、それらのドキュメントをOpenAIのAPIを使用してベクトル化します。結果はJSONファイルに保存されます。
    • compute_hashメソッド: このメソッドは、指定されたURLからハッシュ値を計算します。これは、Cosmos DBに保存する際のパーティションキーとして使用されます。
    • saveCosmosDBメソッド: このメソッドは、JSONファイルからドキュメントを読み込み、それらをAzure Cosmos DBに保存します。
  3. Mainクラスの定義: このクラスは、WikiDocumentsクラスのインスタンスを使用して、ドキュメントの取得と保存のプロセスを制御します。
  4. メインの実行部分: ここでは、WikiDocumentsクラスとMainクラスのインスタンスを作成し、ドキュメントの取得と保存のプロセスを開始します。

これでベクトルデータベース(もどき)の完成です。

続きは次の記事で。では。




0 件のコメント:

コメントを投稿