Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dr Turu アーキテクチャ完全解説​

Dr Turu アーキテクチャ完全解説​

4/22 Engineers GUILD Vol.8 | 世界トップの学会コンペの優勝者が解説する、最先端のDeep Researchシステムのアーキテクチャ
のスライド資料です。
https://finolab.tokyo/jp/events/20260422_engineer/

Avatar for Hisanori Ozaki

Hisanori Ozaki

May 24, 2026

Other Decks in Technology

Transcript

  1. 本イベントの背景と講演の内容 背景 電通総研の事業開発室が、NeurIPS 2025 の MMU-RAG コンペティションで優勝 上記のコンペでの取り組みを対外的に発表する機会が増えた その中での気づき: データサイエンティスト向けの勉強会は多いが、エンジニア向けの勉強会は少ない

    → エンジニアが「Deep Research システムをどう作るか」を議論する会を開催しよう! 本日の内容 Deep Research の理論の解説には踏み込まず、 Deep Research システムのアーキテクチャにフォーカスした情報をお届けします。
  2. Deep Research "システム" とは 1つのLLMモデルではなく、LLMモデルを内包した「システム」 LLM に加えて、検索エンジン、Webクローラー、キャッシュ、API連携、ツール制御層、エラー処理など 複数のコンポーネントを組み合わせて構築される AIが自律的に検索・読解し、根拠付きの長文レポートを作成する仕組み全体を指す 長文レポート形式で

    Deep Research を行う商用システム ChatGPT Deep Research OpenAIが提供。月額200ドルProプランで利用可能 Gemini Deep Research Googleが提供。Google One AI Premiumで利用可能 Perplexity Pro Search 検索特化AI。無料プランあり。論文検索にも対応 → オープンソース技術で構築された長文レポート形式の Deep Research システムは存在しなかった
  3. オープンソース技術で構築された Deep Research システム 各研究機関がオープンな Deep Research システムの実現に取り組んでいる Search-R1 UIUC

    veRL ベース(Volcano Engine 強化学習ライブラリ) PPO/GRPO で検索ツール呼び出しを学習している。短文形式での出力向け R1-Searcher Renmin University veRL ベース(Volcano Engine 強化学習ライブラリ) Search-R1 と同系統。2段階の強化学習で検索能力を強化 DeepResearcher ByteDance OpenRLHF ベース エンドツーエンドの強化学習訓練。Web検索中心 DR Tulu ★本日の解説対象 Allen Institute for AI (Ai2) open-instruct ベース(Ai2 独自の post-training コードベース) 長文レポート形式の生成に特化。Evolving Rubrics で報酬設計
  4. DR Tulu とは 基本情報 ・Allen Institute for AI (Ai2)が開発 ・下記の3つの組織が共同研究

    ・University of Washington (ワシントン大学) ・Carnegie Mellon University (カーネギーメロン大学) ・Massachusetts Institute of Technology (MIT) なぜ注目しているのか ・商用 Deep Research と同等の性能を達成 ・Qwen3-8B (80億パラメータ)ベース ・GPU 1-2枚で動作する手頃なサイズ ・コード・モデル・学習データが完全公開 ・ライセンスは Apache 2.0 (商用利用可) ・エージェント設計パターンが実践的 ライセンス上の注意点 DR Tulu 本体は Apache 2.0 だが、学習時に OpenAI GPT-4.1-mini を LLM as a Judge として使用している。 OpenAI は、利用規約において「出力を用いた競合モデルの訓練」を制限しているため、 DR Tulu が公開しているモデルの重みを商用で利用する際は、取り扱いについて別途検討が必要。
  5. DR Tulu の学術的な貢献 1 オープンウェイトモデルの実力を証明 ・8B パラメータという小さいモデルで商用 Deep Research と同等のベンチマーク性能を達成。

    ・HealthBench、Deep Research Bench 等の各種ベンチマークで検証済み。 ・コード・モデル重み・学習データを完全公開 ・本番推論に外部 API が不要で、自社 GPU 環境で自律動作が可能。 2 Evolving Rubrics(共進化) ・長文レポートでは「正解データとの一致」で報酬を計算できない課題がある。 ・Dr Tuluでは、ルーブリック(採点基準)を採用して、この課題の解決に挑戦している ・ただし、良いルーブリックを作成するには質問に対する深い知識が必要&大量に作るコストが高い ・LLMを活用して、良いルーブリックを大量に作成することも検討されている ・ルーブリック作成のために、LLMが正確な専門知識をインターネット上から検索する必要がある ・つまり、Deep Research的な挙動が必要となり、鶏と卵問題のような様式になる ・この問題をモデルとルーブリックの共進化で解決する。
  6. 参考:なぜ長文レポート形式は報酬の計算ができないのか RLVR(Reinforcement Learning with Verifiable Rewards:検証可能な報酬を用いた強化学習)の系譜 2024.9 OpenAI o1 -

    「推論モデル」の流行 Chain-of-Thought (思考連鎖) を内部で長く走らせる推論特化モデル。"考えてから答える" パラダイム ↓ 〜2024 萌芽的研究 CoT prompting / Self-Consistency / Process Reward Models等、推論の外挿や報酬設計の研究が蓄積 ↓ 2025.1 DeepSeek R1 - RLVRによる推論学習の登場 RLVRが登場し、「数学の問題を解かせて、その答えの一致」「コードを実装させて、テストの通過」といった、 評価が非常に単純なタスクで報酬を計算。高度な CoT 推論が強化学習だけで獲得できることを実証 ↓ 2025.3 Search-R1 -検索行動も RLVR で学習 RLVR を LLM + 検索ツールに拡張。QA の短い答えが正解と一致するかを報酬として検索戦略を学習 ↓ 今ここ 現在: 長文レポート形式 はどうする? → Rubrics レポート形式の回答は「正解との一致」で測れない。Rubricsを LLM as a Judge で採点して報酬にしている
  7. DR Tulu のシステム構成 概要 主要なフォルダ app/: チャットUI(フロントエンド)で、技術スタックは Next.js + React

    + TypeScript agent/: DRエージェント実行基盤(バックエンド)で、技術スタックは FastAPI + MCPサーバ rl/: 学習用コード sft/: 学習用コード リポジトリ https://github.com/rlresearch/dr-tulu Agent Library (dr-agent-lib) Next.js Port: 3000 Fast API Port: 8080 BaseAgent, BaseWorkflow Search Tools S2 / PubMed / Google Google Scholar / Serper Content Fetchers Jina Reader / Crawl4AI WebThinker / Serper Ranking VLLM Reranker Relevance Scoring Dense Retrieval Massive-serve Local Index PC Browser Chrome, Safari etc.. MCP Server Port: 8000 Search Agent Port: 30001 Browse Agent Port: 30002 vLLM DR-Tulu-8B Outbounds
  8. 参考:学習の流れ 概要 ・train_dr_tulu.sh というシェルスクリプトで学習を実行 ・一方、「2ノード × 各8GPU(合計16GPU)」という ハードウェア要件があるため、インフラ側のセットアップが 別途必要です。 ・また、分散制御に

    Ray を使用しているので、事前に Rayクラスターの構築と、Headノード、Workerノードを 起動しておく必要があります。 ・train_dr_tulu_mini_base.sh というテストスクリプトも存在 ・Qwen3-0.6Bを1GPUで学習するので、ローカルPCでの 動作確認が可能です。 ライセンス上の注意点 DR Tulu に限らず、Deep Researchを内製化する際の、 大きな課題は、クローズドなLLMの利用規約になります。 学習や推論など、どの部分でクローズドなLLMが使われ ているのかを正確に把握する必要があります。
  9. 推論部の工夫 10選 以降のスライドで各工夫を1ページずつ解説します 1 システムプロンプト 約80行で全行動を定義 2 MCPによるツール分離 LLMと検索ツールを独立HTTPサーバーに分離 3

    検索ツールに関する共通処理パイプライン 全検索ツール共通の処理フロー 4 スニペットの展開 検索結果のスニペットをWebページ全文の文脈に拡張 5 2つのGPUで並列化 HTML取得とテキスト整形を別GPUで並列処理 6 エラーハンドリングの3つの戦略 stop_on_error / keep_progress / continue 7 トークンの予算管理 トークンの予算を設定することで自然な収束メカニズム 8 3層の並行制御 (Semaphore) LLM / MCP / タスクで独立してセマフォを設定可能に 9 10 tenacity による自動リトライ 指数バックオフ + 3つのエラーモード YAML 1つで全切替 モデル・ツール・パラメータを一括管理
  10. 工夫1: システムプロンプト(約80行で全行動を定義) unified_tool_calling_v20250907.yaml プロンプトの構造 DR Tulu の全行動は 約80行のシステムプロンプト で定義さ れている。

    コードではなく プロンプトがエージェントの振る舞いを決定 する。 ▪ 4つのXMLタグのみを定義: <think> 思考過程を記録 <call_tool name="..."> ツール呼び出し <answer> 最終回答 <cite id="ID"> 出典の紐付け ▪ エージェントが使うツールも3つのみ: google_search 一般Web検索 browse_webpage URL読み取り snippet_search 論文スニペット 3つの回答モード と 幻覚防止原則 ▪ 幻覚防止の原則: ・返されたスニペットIDのみ使用(IDを捏造しない) ・「お飾りの文は引用しない。事実の主張だけ引用する」 (「〜と言われている」のような曖昧な文ではなく、 具体的な数字や事実だけに引用を紐付ける) ▪ exact_answer ¥boxed{答え} 形式。短文での回答向け。 ▪ short_form 1段落 + 出典。簡潔なまとめとして出力。 ▪ long_form 複数段落レポート + マークダウン。 プロンプトは ファイル名に「v20250907」 のようにバージョンを記載することで、破壊的な変更を避ける工夫もあり SFT 段階でこのプロンプトに従う能力を学習済み
  11. 工夫2: MCPによるツール分離 LLMと検索ツールを独立したHTTPサーバーとして分離する設計 MCPとは Anthropic社が提唱したプロトコルで、LLMが 外部ツールを呼び出すための標準規格 DR Tulu は FastMCP

    で実装し、 HTTPサーバー (port 8000) として動作させている @mcp.tool(tags={...}) デコレータ1つで ツール定義が完了する。 ▪ 対応する2つのトランスポート: ・StreamableHttpTransport (既定) ・FastMCPTransport (stdio) タグベースでツールを切替 検索系7種 (Google, S2, PubMed 等) + 閲覧系3種 (Jina, Crawl4AI 等) + リランカー = 計11のツールを実装している。 各ツールに複数のタグを設定できる: @mcp.tool(tags={"search","necessary"}) ▪ 環境変数で有効ツールを制御: MCP_INCLUDE_TAGS="search,browse" (既定: search,browse,rerank) ▪ 代表的なタグ: search 検索系 browse Web 閲覧系 rerank リランカー local ローカル検索 (既定は無効) necessary 必須ツール (内部マーカー)
  12. 工夫3: 検索ツールに関する共通処理パイプライン MCPSearchTool.__call__() -- 全検索ツール共通の処理フロー(+ Step 0: 遅延スキーマロード) 0 schema

    cache 初回呼び出し時に MCP サーバーからスキーマを取得してキャッシュする (2回目以降は省略) 1 preprocess_input パーサーで LLM 出力からクエリと追加パラメータ (year, limit 等) を抽出 2 get_mcp_params クエリとパラメータを MCP サーバーが受け付ける辞書形式に変換 3 _execute_mcp_call MCP サーバーに HTTP 送信。失敗時は指数バックオフで最大3回リトライ 4 error check レスポンスに error フィールドがあればエラー出力を即返却 5 extract_documents 生レスポンスから Document 型 (title, url, snippet, score) のリストに変換 6 stringify 各 Document を <snippet id=xxx> 形式のテキストに変換 7 return DocumentToolOutput として LLM のコンテキストに追加 (call_id / runtime 記録) サブクラスが実装すべきは get_mcp_tool_name / get_mcp_params / extract_documents の3メソッドのみ
  13. 工夫4: スニペットの展開 F1スコアで検索スニペットをWebページの実際の文脈に展開する 課題 検索APIには、「スニペット」と呼ばれる各Webページ の内容を表す断片的な文章が含まれる。 Google 検索のスニペットは短い文章で情報が少なく、 またWebページ全体のどの位置にある断片か不明であ る。

    さらに、スニペットのテキストとWeb ページのテキス トは完全一致しない(表示用に加工されている) そのため、前後の文脈がないと LLM が正確に理解でき ない。 解決策: F1 スコアマッチング ① Webページの全文を文単位に分割 ※ 全文は 100,000 文字に上限 ② 各文と検索スニペットの 単語重複率 を計算: F1 = 2×(精度×再現率)/(精度+再現率) ③ best_f1を0.2で初期化し、それを超える文のみを候補に ④ 候補文の 前後 3000 文字を切り出して返却する。 (候補がない場合は、ページの先頭 6000 文字を返却) → これにより、LLM は断片で判断することがなくなり、 前後の文脈を見た上で判断できるようになる 前処理: 小文字化 + 句読点除去 (単語集合化) → 表記ゆれに強い / nltk 未インストール時は正規表現でフォールバック
  14. 工夫5: 2つのGPUで並列化 Web 閲覧処理を「HTML取得」と「テキスト整形」に分離することで並列化 パイプラインの構成 Step1: Crawl4AIBrowseTool → URL から

    HTML を取得 Step2: WebPageReaderAgentV2 (Qwen3-8B BrowseAgent) → 広告・ナビ等の不要な情報を除去 → 32000×4(1トークン当たり4文字)÷文書数 で配分 → <think>...</think> 除去 → 「Cleaned webpage text:」 以降を抽出 ▪ 3つの出力モード: 'last’ 最後のツール出力のみ 'combine’ 全出力を結合 'callable' カスタム関数で集約 2GPU 並列化 + bm25_query 動的設定 内部で NullToolCallParser に差替え → XML タグの二重解析を防止 GPU 0: DR-Tulu-8B (SearchAgent) 思考・検索・回答を担当 port 30001 GPU 1: Qwen3-8B (BrowseAgent) Web ページの整形を担当 port 30002 ▪ bm25_query の動的設定: 実行時に 「browse_tool.bm25_query = 問題文」を 設定し、BM25 でページ内の関連箇所を優先抽出。 → SearchAgent の思考中に BrowseAgent が 別ページを整形する並列処理が可能。
  15. 工夫6: エラーハンドリングの3つの戦略 ChainedTool でのツール実行失敗時の振る舞いを選択できる(既定は stop_on_error) stop_on_error(既定・最安全) エラー時に即停止して返す。’raw_output’ に ‘failed_at’ と

    ‘outputs’ を保持するため、後からデバッグ可能。 用途: 本番での推論ではこちらの設定。あるツールの処理失敗が後続処理に影響を及ぼす場合 keep_progress 失敗まで実行した結果を保持して停止。「Chain partially completed - {失敗ツール名} failed at step N」の注釈を付与。 用途: 「HTML 取得後の整形」をするツールは処理を失敗しても後続処理に影響が少ないため、この設定が有効 continue エラーを無視して残りのツールを実行。失敗箇所の番号と名前を全て記録し最後にまとめて返す。 用途: 複数の独立処理を一括実行し、全エラーを収集したい場合
  16. 工夫7: トークンの予算管理 ツール結果が増えるほど生成余地が減る自然な収束メカニズム 仕組み(vLLM 自前モデル用) 「上限: 32,000 トークン」のように設定 各ステップで残りのトークンを動的に計算: remaining

    = 32,000 - 使用済み max_tokens = max(100, remaining) 初期: 大量に生成可能 → 積極的に検索などを実施 中盤: 残りのトークン予算が減る → 検索を絞る 終盤: ほぼ枯渇 → 回答して終了 最低 100 トークン は常に確保する ※ 商用 API は動的計算をスキップ 固定 max_tokens を毎回指定 トークン数カウントの3段フォールバック 1. 商用 API モデル: litellm.token_counter(model, text) 2. 自前モデル (tokenizer あり): self.tokenizer.encode(text) 3. 最終フォールバック: len(text) // 4 (英語で 1 トークン ≒ 4 文字の経験則) ▪ なぜ3段フォールバック? ・tokenizer の未ロード ・litellm がモデルを未対応 ・ネットワーク障害 どれでも停止せず動き続ける 「何回検索するか」を明示的に決めず、トークン予算が自然に収束を促す設計
  17. 工夫8: 3層の並行制御(Semaphore) LLM / MCP / タスクのそれぞれのレイヤーで、独立して同時実行数を制御 3つのレイヤー Layer 1:

    LLMToolClient クラス変数として定義され、全インスタンス共有で保持 既定 20 件(LLM_MAX_CONCURRENT_CALLS) vLLM サーバーの過負荷を防止 Layer 2: MCPMixin クラス変数として定義され、全インスタンス共有で保持 既定 20 件(MCP_MAX_CONCURRENT_CALLS) 外部 API のレート制限対策 Layer 3: BaseAgent.map map 呼び出しごとに新規で作成 既定 5 件(max_concurrent_tasks) 複数のタスクを同時処理 階層構造の巧妙さ ▪ 上位2層はクラス変数: 全インスタンスでセマフォを共有。 アプリ全体で1つの上限を守る。 ▪ 最下層は呼び出しごと: 毎回新しいセマフォを作ることで、各ユースケースに対応 ▪ 3層のカスケード効果: LLM 20 × map 5 = 最大 100 同時 でもレート制限は別で守られる。 ▪ 環境変数で切替可: 訓練時は MCP_MAX_CONCURRENT_CALLS=512 推論時の 25 倍に引き上げている 各層のボトルネックが GPU / APIのレート制限 / メモリ使用量 と異なるため、制御も独立して実装している
  18. 工夫9: MCP リトライと3つのエラー処理モード tenacity というライブラリによる自動リトライ + 3層のタイムアウト検出 自動リトライ (tenacity) @retry(

    retry = retry_if_exception_type(...) stop = stop_after_attempt(3) wait = wait_exponential(multiplier=1, min=4, max=10) ) 指数バックオフ 実際の待ち時間: 1回目失敗 → 4 秒 待機 (2^1=2 だが min=4 でクランプ) 2回目失敗 → 4 秒 待機 (2^2=4) 3回目失敗 → 8 秒 待機 (2^3=8) その後、例外を投げる 3つのエラー処理モード + 多層タイムアウ ト検出 RETURN_ERROR: 訓練時 常にエラー辞書を返す。例外なし。 RAISE_EXCEPT_TIMEOUT (既定): 推論時 タイムアウト以外は例外。 RAISE_ALL: デバッグ時 全エラーで例外 ▪ 3層のタイムアウト検出: 1. asyncio.TimeoutError 型 2. McpError +「Timed out...」文字列 3. 汎用 Exception + "timeout" 検索 外部ライブラリは様々な型でタイムアウトを返してくるため 全て型で区別するのは困難。最後は文字列検索で拾う 環境変数 MCP_ERROR_HANDLING_MODE で切替可。リトライ対象: Connection/Timeout/Mcp/FastMCP/BrokenResource
  19. 工夫10: YAML 1つで全切替 「auto_search_sft.yaml」 vs 「auto_search_sft-oai.yaml」 の設計思想の対比 本番 (vLLM) vs

    デバッグ (OpenAI) vLLM版(auto_search_sft.yaml): model: rl-research/DR-Tulu-8B base_url: localhost:30001/v1 search_agent_temperature: 1.0 browse_agent_temperature: 0.3 max_tool_calls: 10 timeout: 180 OpenAI版(auto_search_sft-oai.yaml): model: gpt-4.1-2025-04-14 api_key: ${oc.env:OPENAI_API_KEY} search_agent_temperature: 1 browse_agent_temperature: 1 max_tool_calls: 5 timeout: 60 対比に込められた設計思想 ▪ temperature の違い: vLLM: search=1.0 (多様な思考を促す) browse=0.3 (整形を決定論的に行うため) OpenAI: GPT-5 は temperature を指定できない browse も 1 にせざるを得ない ▪ max_tool_calls の違い: vLLM: 10 (深いリサーチを許容する) OpenAI: 5 (APIのコストを制御するため少なめ) ▪ timeout の違い: vLLM: 180秒 (ローカル計算は安定) OpenAI: 60秒 (API レート制限)
  20. 検索エンジンとスクレイピングの重要性 Google Custom Search API $5/1000 クエリ ◦ 検索精度は高い。関連記事がない場合は、指定数よりも少ない件数で返却してくれる。 ×

    スニペットが短く途中で切れる。呼び出し上限あり。2025年から新規受付停止。規約により検索結果を保存できない Serper.dev (Google 非公式) ~$0.001/クエリ(大容量だと $0.0003) ◦ Google の結果を安価で高速 (1-2秒) × スニペットが短く途中で切れる Bing Web Search API ★2025/8/11 廃止 Grounding with Bing ($15/1000件) ◦ $3/1000件 で安価 × 提供終了。後継サービスのGrounding with Bing は生データ返却なし、コスト 40〜483% 増。規約により検索結果を保存できない Tavily Search API $30/4000 credits または $0.008/credit ◦ AI エージェント特化のAPI設計。 SOC 2 認証あり × クレジットは月末失効。 大量利用でコスト増。 かならず指定件数を返却するためフィルタリングが必須 Jina Reader(スクレイピング) / DeepSearch(検索) Reader は無料 (有料 API key で高レート) ◦ スクレイピングは他検索APIに比べて高精度 × 検索自体の精度は低め / 新価格 2025/5/6〜 Brave Search API $3/1000 Data for Search ◦ 30B+ ページの独自インデックス。Google 非依存。 低レイテンシ × Google ほどの網羅性はない Deep Research システム構築にあたり、精度面やコスト、プロダクト提供の可否など非常に大きな意思決定となる部分である
  21. その他に必要なコンポーネント ① 埋め込み (ベクトル検索) Qwen3-Embedding (0.6B/4B/8B) 多言語 MTEB 1位 (70.58)、Apache

    2.0 であるため、候補の筆頭になりやすい BGE-M3 dense/sparse/multi-vector のハイブリッド。長文 8192 token 対応で次点の選択肢 intfloat/multilingual-e5-large 多言語対応で、特に日本語性能が強い ② リランカー Cohere Rerank v3.0 / v4.0 高精度、マネージドサービス、多言語対応。本番の品質を重視するなら BAAI/bge-reranker-v2-m3 OSSでセルフホスト可能、多言語、日本語対応、無料 Jina Reranker v3 200ms 以下、BEIR で 61.94 nDCG を達成している。 ③ 要約・Web 整形 GPT-4o-mini / Claude Haiku 低コスト、低遅延で大量処理向け Qwen3-8B / Llama-3.1-8B セルフホスト可能であり、DR Tulu の BrowseAgent もこちらを採用している 日本語 fine-tune 版 Qwen / Llama 日本語に強いため、要約文に日本語らしさが見られ、差が出る いずれも MTEB / MMTEB 等のベンチマークが公開されているので、自分のユースケースに合うか事前に評価を推奨
  22. まとめ ① 概要 Deep Research は 1つの LLM ではなく LLM

    を内包したシステムである 商用のDeep Research ・ChatGPT Deep Research ・Gemini Deep Research ・Perplexity Pro Search OSSのDeep Research ・Search-R1 ・R1-Searcher ・Deep Researcher ・DR Tulu ・長文レポート形式のオープンソース システムはこれが初めて ② 学んだ設計パターン 推論部の11の工夫: ・システムプロンプトで行動定義 ・MCP によるツール分離 ・検索ツールの共通パイプライン ・スニペットの展開 ・2つのGPUで並列化 ・3つのエラーハンドリング ・トークン予算管理 ・3層の並行制御 ・tenacity による自動リトライ ・YAML 1つで全切替 ③ プロダクトへの示唆 オープンソースシステム& オープンウェイトモデルであるが、 学習時に利用規約を踏んでいる 検索エンジンの選定が重要 内製化の判断基準: ・機密データが社外に出せない ・コスト(毎クエリ課金)が厳しい ・業界固有の判断軸が必要 ・商用が特定領域で品質不足 自作の優先順位: 1. プロンプト調整 (SFT不要) 2. RAG (検索追加) 3. SFT (行動学習) 4. RL (DR Tulu 方式) 本番推論では GPT API 不要。GPU 1-2枚で自律動作。学習時のみ LLM as a Judge として GPT を使用