The Kashitaka Blog

Cover Image for RAGで初っ端からベクトルDBは使いませんでした

RAGで初っ端からベクトルDBは使いませんでした

kashitaka
kashitakaエンジニア / 米ジョージア工科大学のCS修士

サイトのドメインが.devなのにテック系の記事がないのもどうかと思い、今回はテックな記事です。

というのも、自分は最近AIエージェント開発案件を受け、harness や tools も含めた調査、設計、構築を行い、本番運用までやる機会を頂けたので、そこでの気付きを、記憶がフレッシュなうちに共有していこうかなと思ったのでした。

RAGといったらベクトルDBになりがち

AIエージェントを自作するなら、ほぼ間違いなく求められるのはRAG(Retrieval Augmented Generation)だと思います。
平たくいうと、LLMが特定の業務を遂行するために、

  • 必要な情報を取らせて(Retrieve)
  • 知識を拡張させ(Augment)
  • 回答を生成させる(Generate)

というものです。

なので広義にはWeb検索なんかもRAGということになるのですが、自分の経験上、 RAGというとすぐにベクトルDB作りの話になる人が多い 気がしてます。

で、自分的にはベクトルDB作りって最終手段というか、ベクトルDBじゃないとワークしないようなユースケースのみで使うべきで、なるべく使わない方がいいと思っとります。というのが今回のお話。

ベクトルDBの運用はそれなりにシンドイと思う

まず、ベクトルDBの構築自体はそこまで大変じゃないとは思ってます。PostgreSQLなんかもベクトル検索に対応してますし、テキストをAPIやライブラリに投げれば割と気軽にベクトル化できます。

で、しんどいのは構築後の運用だと思います。

まず、当然何かしら参照したい知識となるデータソースの更新に合わせて、リアルタイムなのかバッチ処理なのかはともかく、ベクトルDBを更新する必要があります。

てことは

  • 少なくとも簡単なデータパイプラインの構築と月々のインフラ代が必要だし
  • 期待通りの同期がなされているかの監視と、失敗時のリカバリが必要だし
  • データソースの仕様が変わる際の人間的な情報共有の運用整理も必要

と思うわけです。この運用コストに見合うだけのメリットがあるのかは精査したいのです。

あとは検索精度の問題もあって、LLMが生成に必要な情報をベクトルDBから的確に取り出すことができるようにするのは、当然開発者の責務になるわけです。

  • じゃあどれくらいの粒度でデータソースをチャンクしてレコードにしていくのが適切なのか?
  • LLMがベクトルDB検索をかける検索ワードは期待通りなのか?

みたいなチューニングが必要で、その検索精度が回答精度に影響します。曖昧検索エンジンを作っているようなものだと思います。

で、検索精度が悪ければ回答精度も悪くなり、回答精度がイマイチなエージェントは使われなくなります。

まずはプロンプトにMarkdownでベタ書きがいいと思う

で、AIエージェントを作り始めるなら、自分は「知識はプロンプトにMarkdownでベタ書きしちゃえ」と思ってます。

「それRAGなの?」と言われると、まあ定義上はリアルタイムな取り出しをしないのでRAGじゃないです。

「プロンプトにそんな知識載せられるの?」と言われると、実はかなり載ります。

AnthropicのAPIであれば、執筆時点では1回のリクエストで1 million tokensまで載せられます。 これは日本語だとA4にびっしり100ページ程度の知識になるそうです。

なので例えば、Webページ数十個くらいの知識量であれば、要約してMarkdown化すればせいぜい100k tokens程度。
例えば、100ページあるパワポを要約してMarkdown化しても、多くても100k tokensはいかないと思います。

この知識量で足りるくらいのAIエージェント要件であれば、まずはプロンプトにMarkdownでベタ書きするのがいいです。いや、足りないとしてもPoCであればまずここから始めるべきです。

「でも毎回そんな大量のtoken送ったら無駄じゃん」と思うかもしれません。
確かにそうなんですが、promptはキャッシュが効きます。で、キャッシュが効いている部分のtoken使用料は1/10程度のコストになります。
キャッシュのTTLはAnthropicの場合は1時間に設定ができます。

てことで、少なくとも最初はこの方法でビジネス課題が解決できるかの検証をする方がいいと思います。 この方法であれば、プロンプトに情報自体は渡っているので、少なくともベクトル検索のように情報そのものの取りこぼしは問題になりません。

その次の案として知識テーブル

「そんなこと言っても参照したい知識が1 million tokensに届きそうだよ!」となったらベクトルDBが必要なのでしょうか?

いえ、まだまだ。そんな時はDBに知識テーブルを作って持たせるのがいいと思います。
知識テーブルのカラムとしては「見出し」と「詳細」カラムを作り、膨大な知識をある程度のカテゴリーに区切ってMarkdownとして「詳細」カラムに載せます。
そして「詳細」を要約したものを「見出し」カラムに載せるわけです。

エージェントにはToolsとして、「見出し一覧を取得するTool」と「行を指定して詳細を取得するTool」の2つを提供します。
仮に見出し1つが500文字程度あって、レコード数が100件程度だと、見出し一覧取得の結果でも100k tokens程度でまだまだ余裕があります。
欠点としてはpromptが動的になるので、キャッシュが効かないか、効かせる工夫が必要です。

ベクトルDBが必要なケースも確かにある

で、これでも無理な要件ならベクトルDBの出番です。上の2方式でツラくなってくるのは

  • 知識量が膨大すぎる:プロンプトに載りきらない・載せるとtoken量をドカ食いしてコスパが悪い
  • 更新がリアルタイム〜日次:プロンプトのメンテ、知識テーブルのメンテに工数がかかってツラくなってくる

あたりだと思います。「token消費コストや知識のメンテコスト」が、「ベクトルDB+データパイプラインの運用コスト」より高くなりそうなら、ベクトルDBを検討すべきだと思います。
それくらいガンガン使われるエージェントなら、それなりにビジネス的な価値も出ていると思うので、運用面でもデータパイプラインのメンテやベクトルDBのチューニングの人員も張れる気がします。

(雑談)Google DriveのMCPとか使えないかな

これは妄想レベルですが、ベクトルDBも使わず知識をほぼ無限に拡張する方法として、「Google DriveのMCPとか使えないんかなー」とか思ったりします。

エージェントに参照させたい知識は、どこかDriveのフォルダにテキストファイルとして大量に突っ込んで、エージェント専用のサービスアカウントにフォルダの参照権限をつけておきます。

んで、エージェントにToolsとして、「Google Driveの検索」と「指定ファイルの読み取り」を渡せば、フルマネージドの検索エンジンとして使えると思うんですよね。

しかもエンジニア以外でも知識を気軽に追加・編集できるし。新たに別のフォルダも知識としてエージェントに授けたくなったら、エージェントのサービスアカウントに参照権限を渡せばいいし。

なかなかいいアイデアじゃないですか?誰かやってないのかな。まあなんかうっかり権限設定ミスって、意図しない情報を参照しちゃったりする事故のリスクはありそうですけど。

なんかこういう感じで、知識をCMSでメンテできてMCPとしてエージェントに提供できるSaaSとかあったらニーズありそうだけどな〜。どうでしょ?

おわりに

てことで、実際に自分が最近関わった案件では、エージェントの要件や必要とされる知識量を調査した上で、上記のような検討を経て、知識の大半はmarkdownでpromptにベタ書きしつつ、個別の会話コンテクストに合わせてDBも取得するような設計を採用してます。

まずはこれでビジネス価値を検証。そのあとで「更新頻度がもっと多ければ」あるいは、「知識がもっとあれば」もっとエージェントの価値が上がるみたいなのが見えてきたら、ベクトルDBも検討かなぁという感じ。

これからAIエージェント作り始める人の参考になれば幸いです。おしまい。


More posts about

kashitaka
kashitaka

ソフトウェアエンジニア。アメリカのGeorgia TechでCSの修士課程に在学。 ブログでアメリカの生活のあれこれを書いていきたい。 経歴:埼玉育ち→東工大→新聞社→リクルート→ベンチャーCTO→(株)サイカ→CSを学びに渡米