「RAGシステム作ってみたい」「Pinecone?pgvector?何が違うの?」
そんな疑問を抱えながら、私たちはPDF検索AIの開発に着手しました。OpenAI APIを叩くだけなら1時間でできる。でも本番運用を見据えたシステムとなると...気づけば2週間が溶けていました(睡眠時間も溶けた)。
本記事では、playparkが実際に構築したPDF-RAGシステムのアーキテクチャを公開します。試行錯誤の末にたどり着いた、GCPマネージドサービスで月額1万円以下の構成。失敗談も含めて、赤裸々にお伝えします。
システム概要:PDF → ベクトル → 質問応答
PDF-RAGは、PDFファイルをアップロードすると自然言語で中身を検索できるシステムです。「〇〇について教えて」と聞くだけで、関連する箇所を見つけて回答を生成します。
...と書くと簡単そうですが、実際にやってみると「あれ、OCRの精度悪くない?」「チャンクサイズこれで合ってる?」と疑問が次々と湧いてきます。
処理フロー
見た目はシンプル。でも各ステップに罠が潜んでいます。
アーキテクチャ全体像
技術スタック
| コンポーネント | 技術選定 | 選定理由 |
|---|---|---|
| API Server | Fastify + Cloud Run | 高速・サーバーレス・自動スケーリング |
| Vector DB | Cloud SQL + pgvector | マネージド・PostgreSQL互換・コスト効率 |
| Embedding | Vertex AI text-embedding-004 | 高精度・日本語対応・GCP統合 |
| OCR | Cloud Vision API | 高精度・非同期バッチ処理対応 |
| LLM | Gemini 1.5 Flash | 高速・コスト効率・長文対応 |
| Storage | Cloud Storage | 耐久性・低コスト |
| Cache | Memorystore (Redis) | 低レイテンシ・マネージド |
設計判断と、そこに至るまでの迷走
1. pgvectorを選んだ理由(Pineconeへの未練を断ち切るまで)
最初は「ベクトルDBといえばPinecone」と思っていました。ドキュメントも充実してるし、専用サービスだし。
...でも月額料金を見て目が覚めました。
比較検討した選択肢:
| サービス | メリット | デメリット |
|---|---|---|
| pgvector | PostgreSQL互換、RDBと同居可能、マネージド | 大規模時のパフォーマンス |
| Pinecone | 高パフォーマンス、専用サービス | 月額$70〜(スタートアップには痛い) |
| Weaviate | オープンソース、多機能 | 運用コスト、学習コスト |
| Vertex AI Vector Search | GCP統合、大規模対応 | 小規模だとオーバースペック |
pgvectorの決め手:
- RDBと同居できる:ユーザー情報・ドキュメントメタデータと同じDBに格納できる
- SQLで操作:Prismaがそのまま使える。新しいこと覚えなくていい(これ大事)
- コスト:Cloud SQLの料金のみ、追加課金なし
正直、「専用サービス使わなくて大丈夫?」という不安はありました。でも数万件のドキュメントなら全然問題なし。Pineconeが必要になるのは、もっと大規模になってから考えればいい。YAGNIの精神です。
2. OCR処理の非同期化(同期処理で痛い目を見た話)
最初のバージョン、OCRを同期処理で実装したんです。「PDFアップロードしたら、その場で処理してレスポンス返せばいいじゃん」と。
50MBのPDFをアップロードしたら、タイムアウトしました。当然ですね(なぜ気づかなかった)。
改善後の設計:
- ユーザーがPDFをアップロード → Cloud Storageに保存
- DBにドキュメントレコード作成(status: 'processing')
- Cloud TasksにOCRジョブを投入
- ユーザーにはすぐレスポンス返却(UX大事)
- Worker側でOCR処理 → 完了後にステータス更新
- フロントでポーリングして完了を検知
Cloud Tasksの設定で「最大リトライ回数」を設定し忘れて、無限リトライで課金が...という事故もありました(小声)。設定項目は全部見ろ、という教訓。
3. チャンキング戦略(最初の設定が全然ダメだった)
PDFから抽出したテキストをどう分割するか。これ、検索精度に直結します。
最初に試した設定:
- チャンクサイズ: 1000トークン(大きすぎた)
- オーバーラップ: なし(繋がりが切れる)
結果:「〇〇について教えて」と聞いても、関係ない段落が大量にヒット。使い物にならない。
改善後の設定:
| 項目 | 設定値 | 理由 |
|---|---|---|
| チャンクサイズ | 512トークン | 小さすぎず大きすぎない黄金比 |
| オーバーラップ | 64トークン(12%) | 文脈の繋がりを維持 |
| 区切り優先 | 段落 > 文 > 単語 | 意味のまとまりを壊さない |
チャンクサイズの最適値は、ドキュメントの性質によって変わります。マニュアル系なら小さめ、論文系なら大きめ、くらいの感覚。正解はないので実際に試して調整するしかない。
4. ハイブリッド検索(ベクトルだけじゃ足りなかった)
「山田さんの報告書」で検索したら、全然違う人の報告書がヒット。
ベクトル検索は意味的な類似度を見るので、固有名詞に弱いんです。「山田」も「田中」も「人名」として似たベクトルになってしまう。
解決策:ベクトル検索 + キーワード検索のハイブリッド
PostgreSQLの全文検索(ts_rank)とpgvectorのベクトル検索を組み合わせて、両方のスコアを重み付けして最終スコアを算出。
- ベクトル検索: 70%
- キーワード検索: 30%
この比率は何度か調整しました。固有名詞が多いドキュメントならキーワード検索の比率を上げる、みたいなチューニングが必要。
コスト最適化:月額1万円以下を実現するまで
最初の見積もり、月額3万円でした。「まあこんなもんか」と思っていたら、「もっと削れない?」と言われて(誰に)、頑張りました。
コスト内訳(最適化後)
| サービス | 月額目安 | 備考 |
|---|---|---|
| Cloud Run | ~¥2,000 | 最小インスタンス1、リクエスト課金 |
| Cloud SQL | ~¥4,000 | db-f1-micro、SSD 10GB |
| Cloud Storage | ~¥500 | Standard、100GB想定 |
| Vision API | ~¥1,000 | 月1,000ページ想定 |
| Vertex AI | ~¥1,500 | Embedding + Gemini Flash |
| 合計 | ~¥9,000 | (コーヒー30杯分) |
最適化でやったこと
1. Cloud Runの最小インスタンス制御
常時1台は起動(コールドスタート回避)、でも上限は3台まで(請求書が怖い)。
2. Embedding結果のキャッシュ
同じクエリはRedisからキャッシュ返却。「〇〇とは」みたいな質問、意外と重複するんです。
3. バッチ処理の活用
- Vision API: 1ページずつ → 10ページずつバッチOCR
- Vertex AI: 1チャンクずつ → 5チャンクずつバッチEmbedding
API呼び出し回数を減らすだけで、結構変わります。
4. Gemini Flash の選択
Gemini Proより10倍安い。RAGの回答生成には十分な精度でした。「Proじゃないと品質が...」という先入観、捨てて正解。
本番運用で気づいたこと
エラーハンドリングは最初から真面目にやるべき
「とりあえず動くもの作って、エラー処理は後で」と思ってました。後悔しました。
Vertex AIが一時的に503返すこと、あるんです。リトライなしだと、ユーザーに「処理失敗しました」が連発。
教訓:
- 外部API呼び出しには指数バックオフ付きリトライ必須
- jitter(ランダム遅延)を入れて、リトライの集中を避ける
- 最大リトライ回数は必ず設定(無限ループ防止)
モニタリングは最初から
「後で設定しよう」は「永遠に設定しない」の同義語。
Cloud Monitoring + Cloud Loggingで以下を可視化:
- APIレイテンシ(P50, P95, P99)
- エラー率(API別、エンドポイント別)
- コスト推移(日次アラート設定)← これ大事
月末に「え、こんなに使ってたの?」を防げます。
セキュリティは妥協しない
- IAM最小権限: サービスアカウントは必要なAPIのみ許可
- VPCサービスコントロール: Cloud SQLへの直接アクセス禁止
- ユーザー分離: ドキュメントは所有者以外アクセス不可(当然だけど確認必須)
まとめ
GCPのマネージドサービスを組み合わせることで、運用負荷を抑えながら本番品質のRAGシステムを構築できました。
設計判断のポイント:
| 判断 | 結果 |
|---|---|
| Pinecone → pgvector | コスト1/10以下、PostgreSQLの知識が活きた |
| 同期処理 → Cloud Tasks非同期 | タイムアウト地獄から解放 |
| ベクトル検索のみ → ハイブリッド | 固有名詞の検索精度が大幅改善 |
| Gemini Pro → Flash | 品質維持でコスト1/10 |
...ところで、NotebookLMって知ってますか?
ここまで読んで「なるほど、でも大変そう...」と思った方へ。
実は、Google NotebookLM を使えば、この記事で紹介したシステムの8割の機能が無料で手に入ります。
NotebookLMでできること
| 機能 | 自作RAG | NotebookLM(無料版) |
|---|---|---|
| PDF読み込み | Cloud Vision API | ✅ 最大200MB/ファイル |
| ベクトル検索 | pgvector構築必要 | ✅ Gemini内蔵 |
| 自然言語Q&A | Gemini API連携 | ✅ そのまま使える |
| 引用表示 | 要実装 | ✅ クリックで原文ジャンプ |
| 月額コスト | ~¥9,000 | ¥0 |
| 開発工数 | 2週間〜(睡眠削って) | 即日利用可能 |
PDFをアップロードして「〇〇について教えて」と聞くだけ。それだけで、この記事で解説したRAGの基本体験ができてしまいます。
それでも自作RAGが必要なケース
では、なぜ我々は自作したのか?NotebookLMには以下の制限があります。
無料版の制限:
- ノート数:100冊まで
- ソース:50件/ノート(各最大50万語)
- ファイルサイズ:200MB/件
- チャット:50件/日
自作RAGが必要になる場面:
- 大規模データ: 数百〜数千のPDFを横断検索したい
- API連携: 社内システムやSlack/Teamsと統合したい
- セキュリティ要件: データを外部クラウドに出せない
- カスタマイズ: 独自のチャンキング・検索ロジックが必要
- SLA要件: 可用性・レスポンス時間の保証が必要
2026年の正しい選択
まずNotebookLMで試す → 限界を感じたら自作RAG
これが、今の時代の賢い進め方です。
NotebookLMで「RAGってこういうことか」を体感してから、本当に自作が必要かを判断する。無料で試せるツールがあるのに、いきなり開発に入るのはもったいない。
この記事の本当の価値は、NotebookLMでは対応できないケースに直面したとき、「じゃあどう作ればいいのか」の設計指針を提供することにあります。
「自社でもRAGシステムを構築したい」「GCPでのAI活用を検討している」という方は、ぜひご相談ください。
あわせて読みたい
- 【RAG導入事例】社内ナレッジ検索をAIで90%高速化した方法 — RAGの全体像と導入の進め方
- 【PDF RAG】社内文書AI検索で検索時間90%削減 - RAG導入の実践事例 — PDF検索に特化したRAGシステムの導入事例



