世界を動かす技術を、日本語で。

プロダクションRAG:500万以上の文書処理から得た教訓

概要

  • RAGシステム開発 の8か月間の実体験をもとに、効果的だった施策と無駄だった作業を共有
  • Usul AI (900万ページ)と法律系AI企業(400万ページ)向けに構築した事例
  • LangchainLlamaindex を利用し、プロトタイプから本番運用までの課題と改善策
  • ROIが高かった施策 をランキング形式で紹介
  • 学びをオープンソース プロジェクトとして公開

RAG開発の現場から:実際に効果があったこと・無駄だったこと

  • YouTubeチュートリアル で学習開始、最初は LangchainLlamaindex を利用
  • 2日でプロトタイプ完成、100ドキュメントでのテストでは高評価
  • 本番データ (数百万ページ)で動かすと、ユーザーからの評価は低調
  • 数か月かけてシステムを 部分的に再設計・改善 し、パフォーマンス向上
  • ROI(投資対効果)順 に改善策をまとめ

効果が大きかった施策

  • クエリ生成

    • ユーザーの直近クエリだけでは 文脈を網羅できない 課題
    • LLM でスレッド全体をレビューし、 セマンティック+キーワードクエリ を複数生成
    • すべてのクエリを 並列処理 し、 リランカー に渡すことで検索範囲拡大
    • ハイブリッド検索 のスコア依存から脱却
  • リランキング

    • 最もROIが高い 5行のコード改善
    • チャンクの順位が大きく変動し、 十分な数のチャンク を渡せばセットアップの弱点を補完可能
    • 理想的な設定 は「50チャンク入力→15チャンク出力」
  • チャンク戦略

    • 最も工数がかかる 部分
    • 各企業ごとに カスタムフロー を構築
    • チャンクが 単語や文の途中で分断されない ことを確認
    • それぞれのチャンクが 独立した情報単位 として成立しているかを重視
  • メタデータ付与

    • 最初はチャンクテキストのみを LLM へ入力
    • タイトル・著者などのメタデータ も同時に投入することで、 文脈と回答精度が大幅向上
  • クエリルーティング

    • RAGでは対応できない質問(例:記事要約、著者名)も多発
    • APIコール+LLM で直接回答する 小型ルーター を作成し、 RAGの無駄な呼び出しを回避

技術スタックとツール選定

  • ベクターデータベース
    • AzurePineconeTurbopuffer (低コスト、キーワード検索ネイティブ対応)
  • ドキュメント抽出
    • Chunking :デフォルトは Unstructured.io、企業向けにはカスタム対応( Chonkie も評価高い)
  • Embeddingモデル
    • text-embedding-large-3 を採用、他は未検証
  • リランカー
    • Cohere 3.5Zerank (知名度は低いが高品質)
  • LLM
    • GPT 4.1GPT 5GPT 4.1 (Azureクレジットでカバー)

オープンソースへの展開

  • 学びを集約 したオープンソースプロジェクト
    • agentset-ai/agentset (MITライセンス)
    • 質問や相談は歓迎、GitHubで連絡可能

Hackerたちの意見

チャンカーが一番大事って言われてるけど、あれは素朴に見えるね。ライブラリなしでも簡単に書けそうなものしかないし。

ここはOPです。agentset.aiにフルタイムで2ヶ月取り組んできました。今は、すぐに使えるものができてるよ。RAGの経験がない人でも、かなり良いものが得られると思う。短期的には、インジェストとエージェント検索に注力してる。

このリポジトリにチャンカーがあるかはよくわからないな。リンクしたファイルは、チャンクを処理するわけじゃなくて、チャンクのデータモデルを定義してるだけみたい。実際にチャンクを操作してる場所はRedisから取得してるけど、リポジトリ内にはRedisに書き込むものは見当たらないから、チャンカーは別のところにあると思う。

1.5年前にRAG用に数百万の(技術的な)ページを処理するために書いた似たような記事があるよ。結構同じことが続いてるみたい。

俺も約1年前に技術検索のためにRAGシステムを作ったけど、全部同じに見えるな!

同意するよ:大規模なLLMベースの再ランク付け(例えばQwen3-reranker)は、クロスエンコーダーに求めていたものそのものだし、試してみることを強く勧める。残念ながら、計算コストはかなり高いけどね。メタデータや表形式のデータには、人間が当たり前だと思う基本的な事実が含まれてるけど、それがすべてのテキストチャンクに繰り返されるわけじゃないから、注入することで最終モデルが無知に見えにくくなるよ。シンプルなRAGでうまくいかないクエリ(例えば「最近の20件の文書を要約して」)についての指摘は、非常に重要だと思う。私たちはUIを検索重視にして、チャットをあまり強調しないようにした。ユーザーに、検索が裏で行われていることを伝えたかったから。モデルは、あなたが見るものしか見えないんだ。

記事に実際の顧客の使用についてもっと情報があればいいのに。特にプロセスの効率が改善されたかどうか。システム最適化の技術的な側面に焦点を当てるのは素晴らしいけど、それが具体的なビジネス価値に繋がらないと、結局はただの宣伝に過ぎないからね。

君の意見には完全に同意するよ。特に、コンテキストで何が起こっているのかをユーザーのメンタルモデルを発展させるのが難しいって点と、チャットUXから離れる必要性についてね。コンテキスト管理を明示的にする非チャットUIの公開例がまだ少ないのが興味深い。大手がこれを試して、価値がないと判断した可能性もあるけど、ここでのコメントを見る限り、プロダクションのRAGシステムを構築した人たちは逆の結論に達しているみたいだね。本当の理由は別のところにあると思う。消費者向けアプリではコンテキストを管理すること(特に無料ユーザー向け)や、推論時間がスケールでのコスト管理の主なレバーの一つだから。プライベートRAGは、結果の質を最大化し、特定の問題に費やす時間を最小限に抑えることにもっと関心があるみたいで、クエリごとのコストはあまり気にしない --- これは俺の経験だけどね。

埋め込みベースのRAGは、せいぜいまあまあって感じだね。チェーンの小さな部分や技術デモには役立つけど、実際の使用ではいつも失敗するよ。

何を勧める?クエリ生成?

何と比べて?

ほとんどのChatGPTのクエリはRAGを使ってるよ(クエリに基づいてChatGPTがウェブを検索する必要があるかどうか決める)。実際の生活では効果的で、だから大手プロバイダーがみんなサポートしてるんだよね。

ragは何度も違う発音になるよ。使い道はあるけどね。私たちはエージェント検索に移行して、ragをツールとして使ってる。他の情報取得戦略は、リアルタイム検索をソースで使ってることが多い。取り込んだりチャンク化したソースをスキップすることもあるよ。次のウィンドウでは、大きな変更があって、ほぼ全体のドキュメントを1つのリクエストに入れられるようになるよ。

必ずしもそうじゃない?2023年から私が関わった製品では、人々がデータをクエリする主要な方法の一つの基盤になってるよ:https://www.honeycomb.io/blog/introducing-query-assistant この機能はあまり多くのことをするようには設計されていないのが違いで、ほとんどのLLMベースの製品を作るにはそれが一番いい方法なんだよね。

合成クエリ生成についての指摘はいいね。ユーザーのクエリがすごくひどかったから、最初はLLMに合成クエリを生成させてたんだ。でも、生成された合成クエリによって結果が大きく変わることがわかったから、3つのバリエーションを作らせることにしたんだ(1回のLLM呼び出しでいろんなバリエーションを生成させるためにね)。それから並列検索を行って、相互ランク融合を使ってリストを広く強いパフォーマーのセットにまとめたんだ。検索にはハイブリッドの密なbm25とスパースbm25を使ってる。密な方は技術用語にはあまり合わないからね。これに続く再ランク付けを組み合わせることで、検索の問題はほぼ解消されたよ。

最後のアドバイスは、ユーザーの検索の解釈を相手側のユーザーにも伝えて、LLMの理解が正しかったか確認できるようにすることだね。

検索にはハイブリッドの密なBM25とスパースBM25を使ってるよ。密なやつは技術用語にはあまり合わないからね。いつも気になるのは、これをもっとシンプルにして、SPLADEを使って良い結果が得られるかってこと。v3モデルはすごく良さそうで、意味的な検索と語彙的な検索のバランスが取れてるみたいだね。

それはエンドユーザー(開発者)の心配じゃなくて、AmazonやMicrosoft、OpenAIなどでRAGソリューションをサービスとして実装している人たちの心配だね。

再ランク付け:追加する価値のある5行のコード。チャンクのランク付けはかなり変わったよ。予想以上にね。再ランク付けは、十分なチャンクを渡せば、悪いセットアップを補うことができることが多い。理想的な再ランク付けのセットアップは、50チャンク入力 -> 15出力だね。RAGの文脈での再ランク付けって何?たった5行ならコードを見せればいいじゃん?

OP。再ランク付けは、ユーザーのクエリと候補結果のリストを受け取って、どれがクエリに関連しているかに基づいて順序を再設定する専門的なLLMだよ。サンプルコードはこれだよ: https://docs.cohere.com/reference/rerank

AWSの宣伝をするつもりはないけど、S3 Vectorsはここでは間違いなく最先端だよ。それにBedrock Knowledge Baseを組み合わせてDiscovery/Rebalanceタスクを処理すれば、市場で最もシンプルな実装になるね。S3 Vectorsに支えられたBedrock KBがベータ版からリリースされたら、みんなのランチを奪うことになるよ。

シルじゃなくてシュレップだよ。細かいことを言うつもりじゃなくて、正しい用語が面白いから訂正してるんだ。

こんなに多くのサービスやツールが調査されたのに、埋め込みモデルが除外されてるのが面白いね。それが一番大きなレバーの一つだと思ってたんだけど。

彼らは最初からより良いもの(3-large)を選んだだけだよ。3-smallの6倍のコストだけど、それでも小さいね。

何か見落としてる気がするんだけど、これってセルフホスティングできるって書いてあるよね。でも、セルフホスティングのドキュメントの最初のページには、6個以上の他のサードパーティのホスティングサービスのアカウントが必要って書いてある。セルフホスティングの意味について、考え方が全然違うみたい。

これは良いオープンソースだと思うし、彼らのOSSを使ってて満足してる。ホスティング依存を避けたいなら、全部Rustで書けばいいじゃん。

そんな環境で働いたことないから、インターネットに自由にアクセスできるっていうのが全くなかった。これのおかげで、プログラミング技術の大きな波を見逃してるかもしれないし、過去20年間、安定した給料を得るためにどうにかやってきた。自分はあまりいい例じゃないと思うけど、YouTubeの動画を7時間も見たことないし、それも車の修理のためだけだった。オンラインや接続が必要な技術は避けてる。

すごくしっかりしたまとめだね。おもちゃみたいな例を超えて、RAGのスケーリングの本当のトレードオフを解説してるのは珍しい。再ランキングやチャンク化が、派手なLLMのトリックよりも実際に効果があるっていう部分、すごく共感できる。