OpenAI APIとVertex AIのベクトル検索でお手軽RAG実装

はじめに

GMO NIKKOのY-Kです。
GCPのVertex AIのベクトル検索を利用してRAGを作ったので軽くまとめてみようと思います。

RAGの応答精度向上のための手法は枚挙に暇がないので、今回は精度を度外視して一番シンプルなRAGモデルの骨格を作成していきます。

GCPのVertex AIのベクトル検索のクイックスタートを参考にしていきます。
https://cloud.google.com/vertex-ai/docs/vector-search/quickstart?hl=ja

データ準備

まずはRAGが参照するデータを準備します。
GMOの企業理念や経営ノウハウなどを集約した、GMO スピリットベンチャー宣言を元データにしようと思います。
https://www.gmo.jp/brand/sv/

以下のような構造のGCSバケットを作成して、上記URL先の内容をtxtにしたものをoriginへアップロードします。

batch_rootに関してはクイックスタートの名前に合わせているだけなので、わかりやすい名前に変更しても問題ないです。

データ整形

colab上で作業していきます。

まずは認証

必要ライブラリのインストール

importと作業用ディレクトリの作成

GCSからoriginのファイルをcolabのローカルにダウンロードします

読み込ませる元データをチャンクに分割します。

チャンクに分割できているのか軽く見てみます。

いい感じにできていそうです。

GCSに一旦あげます。

ベクトル化

chunkにあげたファイルをベクトル化して、vertexAIのインデックスにアップロードできる形式に加工します。
ベクトル化にはOpenAIのAPIを利用します。

今回は{ID, ベクトル}のjson(jsonl)形式で作成しましたが、定義できるファイル形式やフィールドは他にもあります。
詳細が気になる方はVertex AIのドキュメントの以下のページをご確認ください。
https://cloud.google.com/vertex-ai/docs/vector-search/setup/format-structure?hl=ja

GCSにアップロードします。

GCPのVertex AIのベクトル検索を利用する

作成したベクトルデータをアップロードしてベクトルDBを作成します。
GCPのGUIベースで解説していきます。

Vertex AIのベクトル検索のページを開き、右上の新しいインデックスを作成を選択します

表示名はrag_test_indexとし、ベクトルデータを保存したGCSのフォルダを指定します。
次元数はベクトルの次元数と合わせましょう(今回は1024)
近似近傍数は20にし、あとはデフォルトで問題ないです。

アップロードには1時間ほどかかります・・・・

アップロードの時間潰しに今何をやっているかを軽く説明します。

GCP上でベクトル検索を行うモデルを作成するには以下の工程が必要になります。

1:検索対象となるデータの準備
  IDとembeddingの要素を持った特定の形式でアップロード
  {ID: 0, “embedding”: [1,2,3,4,…]}{}

2:インデックスの作成 (今ここ)
  ベクトルデータをVertex AI上で扱えるようにしたデータ形式に加工

3:インデックスエンドポイントの作成
  予測データを投げて結果を受け取るためのエンドポイントの作成

4:インデックスをインデックスエンドポイントにデプロイ
  予測データを投げた時にインデックスでベクトル的に近いものを検索して返す

おそらく、ここまで読んでもまだインデックスの作成は完了していないと思います。
待っている間に、インデックスエンドポイントの作成も行います。

こちらは数分で完了すると思います。

インデックスの作成が完了したら次はインデックスエンドポイントへデプロイします。
終わっていない場合は次の「RAGの実装」を先にやるのが良いと思います。

作成したインデックスのデプロイをクリックし、エンドポイントへデプロイします。

デプロイにも1時間ほどかかるので、ベクトル検索について資料を読むか、次の「RAGの実装」を進めるでも良いと思います。

デプロイが完了すると、インデックスの詳細からデプロイされたインデックスをクリックすることができるようになります。

それをクリックすると、デプロイしたインデックスに対してリクエストを送るコードが表示されます。
<FEATURE_VECTOR>を検索したいベクトルにする必要があるのでコードを整形します。
ついでに neighbor_count=3 にして3件だけ返すようにします。

入力文に近い順にデータが返されます。
ベクトルデータのIDをチャンクのファイル名にしているので、返却されたIDを利用してGCSのファイルを読みにいきます。

これで、入力文と類似する内容をベクトル検索することができるようになりました。

RAGの実装

参照するデータの準備もできたので、いよいよRAGの実装に入ります。

まずはChatGPTを利用できるようにします。

返答が返ってきていればOKです。

プロンプトを作成します。

動くかテストしてみます。
今回は入力文を与えてベクトル検索をした結果が返ってきたと仮定してテストします。

正しく動いてそうです。

エンドポイントへインデックスのデプロイが完了しているのであれば、先ほど仮定していた部分を補完しつつ実装していきます。

応答を確認してみます。

割と良い精度で出ました。よかったです。

まとめ

今回はOpenAIのAPIとGCPのVertex AIのベクトル検索を利用してRAGを作成しました。
精度は度外視でシンプルなものを作成したので、これを元に肉付けをしていくとより良いものができると思います。(特にチャンクの分割やベクトル化の部分)

より良いものができるとは思いますが、、、

・ベクトル検索を使う必要があるのか(tf-idfなどの古典的アルゴリズムで検索するのはダメなのか?)
・参照する情報をプロンプトに全部含めて回答するだけでも良い回答が得られる

などなど、そもそもRAGである必要がない場合もあるので、実際の要望と今回の実装&今後の改修の手間を比較して決めていくのが重要かと思います。

ここまで読んでいただきありがとうございました。