21 ポイント 投稿者 GN⁺ 2025-10-21 | 1件のコメント | WhatsAppで共有
  • 8か月にわたり RAG(検索拡張生成) プロジェクトを進める中で、実際に効果のあった方法と時間の無駄だった方法を見極めた
  • 初期には Langchain と Llamaindex を使ってプロトタイプを素早く完成させたが、実際のユーザーフィードバックで性能の限界を経験した
  • 文書検索性能の改善に最も大きく寄与した要因は、クエリ生成、リランキング、チャンク化戦略、メタデータ活用、クエリルーティング であることが分かった
  • 実務では ベクターデータベース、埋め込み、リランキング、LLM などを柔軟に選択しながらカスタムパイプラインを構築する
  • あらゆる経験とノウハウを オープンソースプロジェクト(agentset-ai/agentset) に集約して公開した

8か月間の Production RAG 構築経験の概要

  • 合計900万ページ(Usul AI)、400万ページ(ある匿名の法務AI企業)などの大規模データセットで RAG システムを構築・運用 した経験を共有する
  • 初期には YouTube チュートリアルを追って Langchain から Llamaindex へ移り、数日でプロトタイプを完成させたが、実運用では ユーザーにしか気づけない低い性能 の問題が明らかになった
  • 数か月にわたりシステム構成要素を部分的に修正しながら、最適な性能に到達した

性能改善に実質的に寄与した要素(ROI順)

  1. クエリ生成(Query Generation)

    • ユーザーの最後のクエリだけではすべての文脈を含められないため、LLM で会話内容を見直し、意味的クエリとキーワードクエリを複数生成 する
    • これらのクエリを並列処理し、リランカーに渡すことで、検索範囲の拡大とハイブリッドサーチのバイアス補正 の効果を得る
  2. リランキング(Reranking)

    • 5行程度のコードで実装できるリランキングが性能に与える影響 は想像以上に大きい
    • 大量のチャンク入力(例: 50個)から上位の一部(例: 15個)のチャンクを再整列・選別する工程が、最も ROI が高い
    • リランキングだけでも、設計が不十分なパイプラインの不足分をかなり補える
  3. チャンク化戦略(Chunking Strategy)

    • 開発全体の 主要な時間を占める部分
    • データ構造とパターンを正確に理解し、論理単位でチャンク化し、文字や文が途中で切れないように直接確認する 必要がある
    • 各チャンクごとに独立した意味が保たれていなければならない
  4. LLM 入力におけるメタデータ活用

    • 単なるチャンクテキストだけを LLM に渡すのではなく、メタデータ(title, author など) を追加することで、文脈と回答品質を大きく改善した
  5. クエリルーティング(Query Routing)

    • RAG では回答不可能なタイプ(例: 記事要約、著者情報の要求など)に対しては、軽量ルーターを導入し、そのクエリを API+LLM 処理経路へ分岐 する

実運用スタック(Our stack)

  • ベクターデータベース: Azure → Pinecone → Turbopuffer(低コストで、デフォルトでキーワード検索をサポート)
  • 文書抽出: カスタム方式を適用
  • チャンク化ツール: 基本は Unstructured.io、企業向けパイプラインはカスタム(Chonkie も良い評価)
  • 埋め込みモデル: text-embedding-large-3 を使用(他モデルは未検証)
  • リランカー: None → Cohere 3.5 → Zerank(一般的ではないが実際には優秀)
  • LLM: GPT 4.1 → GPT 5 → GPT 4.1(主に Azure クレジットを使用)

オープンソース化と結論

  • すべての学習成果と実戦経験は オープンソースプロジェクトagentset-ai/agentset に結実した
  • MIT ライセンス で公開されており、自由に利用でき、問い合わせも可能(連絡先あり)

1件のコメント

 
GN⁺ 2025-10-21
Hacker Newsのコメント
  • 合成クエリ生成に言及していた部分は本当に重要だと感じる。実際のユーザーはクエリをかなり不正確に入力することが多いため、最初はLLMに合成クエリを作らせていた。しかし毎回生成される合成クエリ次第で結果のばらつきが大きかったので、1回のLLM呼び出しでクエリの3つのバージョンを多様に生成させ、それを並列に探索した後、reciprocal rank fusionで強力な結果リストを組み合わせている。検索には hybrid dense + sparse bm25 を使っており、denseだけでは専門用語に弱い。さらにrerankerまで加えると、検索関連の問題の大半は解決される
    • denseモデルが技術用語に弱い点を補うために hybrid方式(bm25 + dense search)を使うのは興味深い。SPLADEのように意味検索と語彙検索のバランスをうまく取るv3モデルも性能が良さそうだが、もっと単純なソリューションで置き換えられるのかは常に気になっている
    • こうした詳細なクエリ生成や最適化は、結局のところ Amazon、Microsoft、OpenAI のようなRAGソリューション提供企業が気を配るべき部分だと強調している
    • これらの方法が現時点のベストプラクティスであることは確かだが、性能をもう一段引き上げられる追加戦略(embeddingモデルの選択的分岐、さまざまな re-ranker の組み合わせなど)には、まだ何か足りないような物足りなさも感じる
    • 最後のヒントとして、LLMがユーザーの検索意図をどう解釈したかを結果と一緒にユーザーへ伝えれば、LLMの理解が正確かどうかをユーザー自身が確認できるという提案がある
  • self-hosted オプションについては混乱を覚える。関連ドキュメントを見ると最低でも6つ以上のサードパーティサービスのアカウントが必要だというが、これは本当の self-hosted の意味とはあまりに違うと指摘している
    • 該当コード自体は自分で self-host 可能だと説明している。“self-hosted" という用語に明確な公式基準はないという考えだ。たとえば self-hosted サービスにオフサイトバックアップ機能があっても、それは self-hosted であると同時に設計の良いサービスにすぎない
    • このような self-hosted マーケティングは自然なことかもしれないが、もともとの事業モデルがホスト版の販売にある以上、完全に独立した self-hosted 製品の提供を義務づける必要まではない
    • 制限されたネットワーク環境で働いてきた経験を共有している。過去20年間、完全に遮断された内部ネットワーク環境で働いてきたため、最新技術の波をかなり逃しているかもしれないという認識だ。YouTubeも自動車修理以外ではほとんど見ず、オンライン接続が必須の技術トレンドにはやや消極的だという
    • 自分はオープンソース版を非常に満足して使っている。ホスティング依存を望まないなら、全部 Rust で自分で書けばよいという実務的な意見だ
  • 大規模LLMベースの reranker(Qwen3-reranker など)は、以前から cross-encoder に期待していた性能を示しているので、ぜひ試してみるべきだと勧めている。ただし計算量はかなり大きい。また、メタデータやテーブル情報は人間にはあまりに自明な基礎情報だが、テキストチャンク内では繰り返されないことが多いため、これをLLM入力に注入するとずっと「賢く」見えるので良い。単純なRAGではうまく処理できない複雑なクエリ(例: 最新20件の文書の要約など)には注意が必要だ。そこで自分たちはUIを検索中心にし、チャットUXを減らした上で、モデルが実際に見ている情報だけをユーザーにも見せるようにしている
    • ユーザーの立場からLLMのコンテキスト処理の仕組みを正しく理解してもらうのは非常に難しいという意見には全面的に同意する。チャットUXから離れた公開事例は少なく、大企業が試してやめた理由が本当に「成果がなかったから」なのかには懐疑的でもある。実際、大規模な消費者向けアプリではコンテキスト/推論コストが主要コストであり、それを管理しなければならないため、context explicit UI は敬遠されたのだろう。一方で社内向けの自前RAGシステムはコスト負担が比較的小さく、結果品質や従業員の時間削減により強く集中できると経験的に感じる
    • 技術的最適化も重要だが、実際に顧客の業務効率がどれだけ改善されたのか、実例をもっと知りたい。そうでなければ、ただのまた別の技術トレンドにすぎない
  • 数百万ページ(特に技術資料)のRAG処理に関して、1年半前に書いたまとめ記事を共有している https://jakobs.dev/learnings-ingesting-millions-pages-rag-azure/
    • 技術検索のためのRAGシステムも前年に構築してみたが、今見返しても多くの部分がほとんど同じだと感じる
  • こうしたRAGシステムを構築または導入しようとする立場として、文書を Google Workspace フォルダにAPIでアップロードし、Google AI search API で文書検索を行うのが実用的な構成になり得るのか気になる。ユーザーごとに別フォルダへ分離して入れる形や、Azureでも同様のことが実現できるかを考えている
  • embedding のバージョン管理方法が気になる。データ更新や特定バージョンの露出、日付別フィルタリングをどうすべきかを質問しており、chunk の前に context バージョンを追加する案も考えている
    • ベクトルストアに元テキストとメタデータ(バージョン情報を含む)を一緒に保存すればよい。たとえば turbopuffer では attribute filtering が便利だとして、ドキュメントへのリンクを紹介している
    • この質問自体がかなり有用で重要な質問だと感じる
  • LLMバージョンの利用順が GPT 4.1 → GPT 5 → 再び GPT 4.1 に戻った理由と、スタック内の他コンポーネントのバージョン(例: text-embedding-large-3)との不一致が奇妙だと感じる
    • OPの回答: GPT-5 が出るとすぐに使ってみたが、多くのコンテキスト(最大10万トークン)を入力すると GPT-4.1 より性能が劣ったため、再び 4.1 に戻した。具体的には a) instruction follow が弱く system prompt にあまり従わない、b) 返答が長すぎてUXを大きく損なう、c) コンテキストウィンドウの12.5万トークン制限のため非常に大きな入力ではエラーになる、という点だ。こうした問題は「RAG」で多くのチャンクを渡すときに目立ち、一般的なタスクでは GPT-5 のほうが良い可能性もある
  • AWSの擁護者ではないが、S3 Vectors は現在この分野の state-of-the-art だと強調している。さらに Bedrock Knowledge Base と連携すれば Discovery/Rebalance も簡単になり、市場で最もシンプルなソリューションになるだろう。まもなく正式リリースされれば、大半の競合を圧倒するはずだと考えている
    • 「schlep」ではなく「shill」という単語が正しいと冗談めかして訂正している
    • S3 Vectors がなぜ SOTA(最先端)なのか気になる。結局はベクトルストアにすぎないのではないかと問い返している
  • Embedding ベースのRAGは、実際には最善の方法とまでは言えない。単一タスクやデモには良いが、現実の状況ではしばしば限界にぶつかると感じる
    • 必ずしもそうではないという経験もある。自分が手がけた Honeycomb 製品の Query Assistant ブログ も2023年からデータクエリに基づいており、この機能はシンプルな目的だけに絞って設計されていたため、むしろLLMベース製品の理想的な方向性だと感じる。non-LLM 処理と組み合わせるのが良い
    • rag は引き続きさまざまに再解釈され、用途も多い。自分たちは rag を1つのツールとして agentic search に統合しつつ、リアルタイムなソース検索や従来の chunk 方式も混在させている。まもなく登場する大規模 context window によって、1回のリクエストに文書全体を入れることも可能になりそうだ
    • どんな代替案を勧めるのか気になる。クエリ生成方式のことを言っているのかと質問している
    • ChatGPT の場合も RAG に基づいて最新情報を得るのに効果的であり、こうした現実的な有用性こそ、今すべての主要企業がこれを提供している理由だと強調している
    • 何と比較しているのかを明確に尋ねている
  • chunk 選定戦略に多くの時間と労力がかかると言っていたが、実際に使った具体的な戦略についてもっと詳しく聞きたい