0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

なぜRAGにベクトルストアが要るのか ― S3 Vectors で学ぶ「意味で検索する」仕組み

0
Posted at

はじめに

ChatGPT や Claude に何か聞くと、たいてい賢く答えてくれる。だが、こう聞くとどうだろう。「うちの会社の就業規則で、有給の繰り越しは何日まで?」。LLM(大規模言語モデル)は途端に黙るか、それらしい嘘を返す。あなたの会社の規則など、学習していないのだから当然だ。

ならば、規則の全文をプロンプトに貼り付ければいい。そう思った人は鋭い。だが、文書が 1 通ならまだしも、社内に 3 万通あったらどうする。全部は貼れない。「関係しそうな数通だけ」を選んで貼る必要がある。この「関係しそうなものを選ぶ」工程こそが、RAG(検索拡張生成、Retrieval-Augmented Generation)の心臓部だ。それを担う部品が ベクトルストア である。

「RAG」「ベクトル検索」という言葉は、聞いたことはあっても中身は曖昧、という人は多い。この記事はそのモヤモヤを一段で解く。貫くテーマは次の二つである。

  • RAG の仕組み:LLM が「知らないこと」を答えるには、外部知識を 意味で 検索して渡す必要がある。その検索基盤がベクトルストアだ。
  • S3 Vectors の実装イメージ:常時課金なしでベクトル検索を持てる新しい選択肢。筆者が開発する Aboardix(X 投稿生成の SaaS=Software as a Service)の実例で、チャンク→埋め込み→検索→注入の流れを具体化する。

概念から実装まで、一本の線でつなぐ。読み終えたとき、手元の文書 20 件で小さく RAG を試せる状態になっているはずだ。


1. そもそも LLM は何を「知らない」のか

最初に、LLM の知識の輪郭をはっきりさせたい。

LLM は、学習に使われた大量のテキストから言葉のパターンを覚えている。だから一般常識やプログラミングの定石はよく知っている。だが、その知識には二つの境界がある。

一つは 時間の境界。学習データには「いつまで」のカットオフがあり、それ以降の出来事は知らない。もう一つは 公開の境界。学習されたのは世に出回ったテキストであって、あなたの会社の Slack や Google Drive の中身は含まれない。

問題は、LLM が「知りません」とは言わず、知っているフリで それらしい嘘 を返すことだ。これをハルシネーション(幻覚)と呼ぶ。社内文書を扱う業務アプリで、嘘は致命傷になる。

では、知らないなら教えればいい。質問と一緒に、答えの根拠になる文書をプロンプトに同梱して渡す。これは正しい発想だ。実際 RAG はこれをやっている。だが素朴に「全部貼る」とすぐ壁にぶつかる。

  • コンテキスト長の壁:一度に入力できるトークン(テキストの最小単位)には上限がある。3 万通の文書は入らない。
  • コストの壁:入力トークンには課金される。毎回大量に貼れば、質問 1 回あたりの単価が跳ね上がる。
  • 精度の壁:長文を詰め込むほど、モデルは中盤の情報を取りこぼす。「lost in the middle(中盤の見落とし)」と呼ばれる現象だ。

試験にたとえると分かりやすい。教科書を全ページ持ち込んでも、制限時間内に全部は読めない。むしろ答えに関係するページだけ付箋を貼っておくほうが速く正確に解ける。LLM も同じだ。渡すべきは全文ではなく、質問に関係する一部 である。

その「関係する一部」をどう選ぶか。ここで「意味で検索する」技術が要る。次章でその土台を作る。


2. ベクトルと埋め込み ― 「意味」を座標にする

「関係する文書を選ぶ」と聞くと、まず全文検索(キーワード一致)を思い浮かべる。だがキーワード検索には弱点がある。言葉が違えば引っかからないのだ。

たとえばユーザーが「サブスクをやめたい」と書いたとする。社内 FAQ の見出しは「解約手続きについて」。人間には同じ話だと分かるが、「やめたい」で全文検索しても「解約」の項目はヒットしない。表記が一致しないからだ。

ここで主役になるのが 埋め込み(embedding) である。埋め込みとは、テキストを「意味を表す数値の並び」に変換する処理だ。この数値の並びを ベクトル と呼ぶ。

ポイントは、意味が近いテキストほどベクトルが近くなる ように学習されていることだ。「退会したい」と「解約の方法」は座標上で隣り合い、「今日の天気」は遠くに置かれる。表記ではなく意味で近さが決まる。だからキーワードが一致しなくても、意味でつながる。

ベクトルが「近い」かどうかは距離で測る。よく使うのが コサイン距離(二つのベクトルが向いている方向の差)だ。長さではなく向きの近さを見るので、文章の長短に左右されにくい。

このベクトルが何次元あるかはモデルによる。Aboardix では AWS の Amazon Bedrock(マネージドな生成 AI サービス)上の埋め込みモデル「Titan Text Embeddings v2」を使っている。1 つのテキストが 1024 次元 のベクトルになる。1024 個の数値で、その文の意味を一点として表す、というイメージだ。

地図にたとえると、埋め込みは「すべての文章を、意味という広大な地図の上の一点に置く」作業だ。似た話題は同じ街に集まり、無関係な話題は別の大陸に飛ぶ。あとは「質問の点」を地図に落とし、その近所にある文書を拾えばいい。

ただし、この「地図上で近所を探す」処理が曲者だ。文書が数万、数百万とあると、毎回すべての点との距離を測るのは重い。ここで専用の道具が要る。それがベクトルストアである。


3. ベクトルストアとは何か

ベクトルストアとは、ひとことで言えば 大量のベクトルを保存し、「あるクエリに最も近い K 件」を高速に返すことに特化したデータベース だ。ベクトルデータベースとも呼ぶ。

なぜ専用品が要るのか。普通のリレーショナル DB(RDB)でもベクトルを保存することはできる。だが「最も近い K 件」を取るには、原理的には保存した全ベクトルとの距離を一件ずつ計算して並べ替える必要がある。100 万件あれば 100 万回の距離計算だ。これを毎クエリ走らせるのは現実的でない。WHERE 句は完全一致や大小比較は速いが、「意味的に近い順」は守備範囲外なのだ。

そこでベクトルストアは 近似最近傍探索(ANN:Approximate Nearest Neighbor) という技術を使う。全件を総当たりせず、事前に作った索引をたどって「ほぼ最も近い K 件」を一気に絞り込む。多少の近似と引き換えに、桁違いの速さを得る。図書館で全棚を歩き回る代わりに、分類番号で目的の棚へ直行するようなものだ。

ベクトルストアの仕事は、大きく二系統に分かれる。

  • 書き込み(upsert):文書を埋め込んでベクトル化し、ストアに入れる。あとから増減・更新できる。
  • 検索(query):クエリも同じモデルで埋め込み、近い K 件を取り出す。

さらに実務で効くのが メタデータフィルタ だ。各ベクトルに「誰の文書か(userId)」「いつのものか」などのタグを添えて保存し、検索時に「この userId のものだけ」で絞れる。これがないと、マルチテナント(複数顧客が同居する SaaS)で他人の文書がヒットしてしまう。Aboardix も各レコードに userId を持たせ、検索時に必ずフィルタしてユーザーを分離している。

ここまでで部品が揃った。LLM の知識の穴(1 章)、意味を座標にする埋め込み(2 章)、近い文書を高速に引くベクトルストア(3 章)。これらを一本の流れに組み上げたものが RAG だ。


4. RAG の全体像 ― 検索を生成につなぐ

RAG(検索拡張生成)は、その名のとおり「検索(Retrieval)」で「生成(Generation)」を拡張する仕組みだ。LLM に答えさせる直前に、関係する文書を検索して渡す。LLM は渡された文書を根拠に答える。

比喩でいえば、閉じた本だけで暗記勝負をするのが素の LLM、関係するページを開いて横に置いてから答えるのが RAG だ。手元に根拠があるぶん、嘘が減り、最新情報や社内文書にも答えられる。

RAG は二つのフェーズからなる。前章の「書き込み」と「検索」が、それぞれ取り込みフェーズと応答フェーズに対応する。

取り込みフェーズはバッチでよい。文書が増えたタイミングで、チャンク(文書を扱いやすい大きさに切った断片)に分け、埋め込んでストアに入れておく。Aboardix では Drive 文書を 500 トークン単位のチャンクにしている。大きすぎると 1 件に話題が混ざって検索精度が落ち、小さすぎると文脈が切れる。この粒度の設計が地味に効く。

応答フェーズが本番だ。質問を埋め込み、近い K 件を取り、それを質問と一緒に LLM へ渡す。ここで分かるのは、回答の質の上限を決めているのは検索の質 だということだ。見当違いの K 件を渡せば、どれだけ賢い LLM でも見当違いに答える。逆に的確な根拠を渡せば、安いモデルでも十分実用になる。

だからこそ、検索を担うベクトルストアは RAG の「要(かなめ)」だ。扇の骨をまとめる留め具が外れれば扇は開かない。RAG も、検索が外れれば成立しない。

仕組みが分かれば、次の問いは現実的になる。「で、そのベクトルストアを AWS でどう持つのか」。ここで S3 Vectors が登場する。


5. S3 Vectors という選択肢

ベクトルストアを本番で持とうとすると、多くの人が同じ壁にぶつかる。お金だ。

従来の代表格は OpenSearch、Pinecone、専用ベクトル DB だ。その多くは、検索を速くするためにベクトルの索引をメモリ上に常駐させる。つまりサーバやクラスタが常時起動している。これは「使っていない時間にも課金が続く」ことを意味する。検索が 1 日 10 回しかない小さなサービスでも、24 時間ぶんの基本料が乗る。客が来なくても一晩中エアコンを点けっぱなしにする店のようなものだ。RAG を試したい個人や、立ち上げ期のスタートアップには、この固定費が重い。

ここに Amazon S3 Vectors(S3 にベクトル検索を組み込んだ機能。2025 年 7 月にプレビュー公開、同年 12 月に GA=一般提供となった)が新しい答えを出す。発想はシンプルで、ベクトルをオブジェクトストレージである S3 にネイティブに保存し、そこへ検索 API を生やす。料金体系も S3 流、つまり「置いた分のストレージ+叩いた分のリクエスト」に寄る。常駐クラスタがないので、アイドル時のコストがほぼゼロ になる。AWS は専用ベクトル DB と比べて最大 90% のコスト削減をうたう。

もちろん万能ではない。トレードオフは レイテンシ(応答の速さ) だ。メモリ常駐型がミリ秒級で返すのに対し、S3 Vectors は数百ミリ秒のオーダーになる。ユーザーが 1 文字打つたびに候補を出すような、リアルタイムの検索 UI には向かない。一方で、バッチ生成や非同期処理、「数百ミリ秒なら許せる」用途には十分だ。

スケールも十分だ。GA 時点で 1 インデックスあたり 20 億ベクトル、バケット全体では 20 兆ベクトルまで載る。東京リージョンでも使えるので、データ量や所在地で先に詰むことは当面ない。

判断の軸を整理すると、こうなる。

観点 S3 Vectors が向く 常駐型(OpenSearch 等)が向く
トラフィック 低〜中・むらがある 高く安定して多い
レイテンシ要件 数百 ms で OK(バッチ/非同期) 数十 ms 必須(リアルタイム UI)
コスト感 アイドルを削りたい 稼働率が高く固定費を割り切れる
運用 クラスタ管理を持ちたくない チューニングを握りたい

「まず RAG を載せたい」「使われ方が読めない」「常時課金が怖い」――この三拍子なら、S3 Vectors は有力な第一候補だ。実際にそう判断した例として、筆者の Aboardix を見てみる。


6. 実例:Aboardix での使い方

Aboardix は、X(旧 Twitter)の投稿案を AI が生成する SaaS だ。ユーザーの Google Drive にある資料や、過去にバズった投稿を素材に、「その人らしい」投稿案を毎日まとめて作る。生成の中心がバッチ処理なので、レイテンシは数百ミリ秒で困らない。S3 Vectors の特性とかみ合う。

ベクトルの構成はこうだ。埋め込みは Bedrock の Titan Text Embeddings v2(1024 次元)、距離はコサイン。インデックスを用途別に 2 本に分けている。

インデックス 中身 使われ方
drive-chunks Drive 文書を 500 トークンで刻んだチャンク 投稿生成時に top-K を引いて根拠にする
library-posts 過去の高反応(バズった)投稿だけ 「あなたの過去ヒットの空気感」を文脈に注入

データの流れを追うとこうなる。

ここに、これまでの章の部品がすべて顔を出す。Drive 文書を チャンクに割り(4 章)、Titan v2 で 埋め込み(2 章)、userId 付きで ベクトルストアに upsert(3 章)。生成時はテーマを埋め込んで 近傍検索し、引いてきた根拠を Claude に渡して 生成する。まさに RAG だ。

library-posts の使い方が面白い。過去の自分のヒット投稿を近傍検索することで、「以前ウケたあの感じ」を新しい投稿案に効かせる。検索の対象は外部知識だけでなく、そのユーザー自身の成功パターン でもよい、という好例だ。

マルチテナントの肝も外していない。全ベクトルに userId を付け、検索時に必ずフィルタする。他人の Drive 文書が混ざる事故を、メタデータフィルタで構造的に防いでいる。

埋め込みは生成以外にも効く。Aboardix には「過去 90 日の投稿と似すぎた案はブロックする」重複検知があり、ここでも文面の埋め込み類似度を使う(しきい値を超えたら止める)。一度作った「意味の座標」は、検索にも重複判定にも使い回せる。

なぜ S3 Vectors を選んだか。理由は本記事の流れそのままだ。生成はバッチ中心でレイテンシに余裕がある。ユーザーが増えても「使った分」課金なので、常駐クラスタのように固定費が先行しない。立ち上げ期のサービスにとって、この「使わなければ寝ていてくれる」性質はありがたい。将来リアルタイム検索が要るなら OpenSearch へ寄せる、という逃げ道も用意できる。


7. 使いどころの判断

最後に、自分のケースで「ベクトルストアを採るべきか」「採るなら何を選ぶか」を判断できるよう、線を引いておく。

まず ベクトルストアが要るシーン はこのあたりだ。

  • 社内文書・マニュアル・FAQ への自然文での質問応答(RAG 全般)
  • 過去事例・問い合わせ・チケットの「似た案件」検索
  • レコメンド(似た商品・似た記事)
  • 重複・類似コンテンツの検知
  • 表記ゆれを越えて意味でつなぎたい検索

逆に 要らない、あるいは過剰なシーン もある。

  • ID やステータスでの完全一致・絞り込み(普通の DB の WHERE で十分)
  • 対象が数百件しかない(メモリ上で総当たりしても一瞬。専用ストアは過剰)
  • キーワード一致で困っていない(全文検索で足りる)

「意味で曖昧に探したい」かつ「件数が多い」。この二つが揃って初めてベクトルストアの出番だ。

製品選定はこの順で考えると迷いにくい。

ざっくりした早見表も置いておく。

選択肢 強み 向く場面
pgvector(PostgreSQL 拡張) 既存 DB に同居、運用が一つ 件数が中規模まで、DB をすでに持っている
S3 Vectors アイドルコストほぼ 0、巨大スケール バッチ/非同期、低〜中トラフィック、コスト重視
OpenSearch / Pinecone ミリ秒級レイテンシ、機能が厚い リアルタイム検索 UI、高トラフィック

正解は一つではない。「今のトラフィックとレイテンシ要件とお金」で選ぶ。立ち上げ期は S3 Vectors で軽く始め、リアルタイム性が要求されたら常駐型へ移す、という段階移行も現実的だ。


おわりに

ベクトルストアとは何か。改めて一言でいえば、LLM に「外部の記憶」を持たせ、その記憶を意味で引き出すための装置 だ。

  • RAG の仕組み:LLM は自社文書も最新情報も知らない。だから関係する知識を 意味で 検索して渡す。埋め込みで意味を座標に変え、ベクトルストアで近い K 件を引く。この検索こそが回答の質を決める要だ。
  • S3 Vectors の実装イメージ:ベクトル検索を常時課金なしで持てる選択肢。Aboardix では Drive 文書と過去ヒット投稿を埋め込み、userId で分離しながら投稿生成の根拠に引いている。バッチ中心・コスト重視のサービスによく刺さる。

理屈は分かっても、手を動かすと一段腑に落ちる。次の一歩はこうだ。手元の文書を 20 件だけ用意し、チャンクに割って埋め込み、ベクトルストアに入れて、自然文で 1 問引いてみる。 「やめたい」で「解約」が引けた瞬間、この記事の 意味で検索する という感覚が、頭ではなく手で分かる。そこから先は、件数とレイテンシとお金を見ながら本物に育てていけばいい。


参考リンク

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?