
NVIDIA RAG Blueprint × DGX Spark でチーム共通 RAG を組んで MCP でつないでみた
はじめに
こんにちは、クラスメソッド製造ビジネステクノロジー部の森茂です。
チームの検証メモや公開記事を 1 か所に集めて、Claude Code や opencode からそのまま引ける共通ナレッジ基盤があったらいいな……と考えたことはないでしょうか。NVIDIA が公開している RAG Blueprint は、ドキュメント取り込みから検索・生成・Web UI・MCP サーバまでを docker compose 一式で提供するリファレンス実装で、まさにこの用途に刺さりそうな構成です。
私の所属するチームでは opencode + NeMo Switchyard + オープンウェイトモデルの開発環境の運用を検証しており、その共通ナレッジ置き場の候補として、この RAG Blueprint を手元の DGX Spark に載せてチーム運用に向けた検証を進めています。方針はローカル完結です。回答を作る生成 LLM は DGX Spark 上の DeepSeek V4 Flash が担い、検索を支える embedding や rerank も NIM コンテナとして手元で動かして、ドキュメントと推論を外部 API に出さない構成にしています。
先に結論を書いておくと、DGX Spark 3 台(サービス 1 台 + 推論 2 台)の 2 層構成で、ドキュメント取り込みから Claude Code / opencode の MCP 接続、日本語 query まで一通り実用レベルで動いています。RAG サービスと検索系 NIM を合わせた常駐は実測約 22GiB に収まり、日本語の表入り PDF もセル値まで正しく引けています。現在はチーム開放前の検証段階ですが、10 名規模の同時アクセスにも問題なく耐えています。
なお、ルーティングに使っている NeMo Switchyard は以前 first-touch 記事を書いています(2026-07-03 公開の記事です)。
この記事では、細かい構築手順やトラブルシュートには踏み込まず、全体の構成と仕組み、そして実際の使い方を紹介します。チーム向けのナレッジ基盤をローカル寄りで組みたい人の設計図として使ってもらえるといいなと思っています。
チーム共通 RAG の全体構成
まず全体像です。DGX Spark 3 台を、役割の違う 2 つの層に分ける構成で検証を進めています。
サービス層は RAG Blueprint 一式(API サーバ・取り込みパイプライン・ベクタ DB・Web UI)に、検索を支える embedding / rerank の NIM、取り込み時に使う抽出 NIM 群、MCP サーバ、ルーターの Switchyard まで集約したノードです。一方の推論層は vLLM だけを動かす 2 台で、生成 LLM の DeepSeek V4 Flash を並列で配信します。外部に出るのは生成の fallback 先(Fireworks AI)だけで、ドキュメントの取り込みと検索は DGX Spark の中で完結します。
層を分けている理由は 2 つあります。1 つは障害分離で、vLLM のモデル入れ替えや再起動が RAG サービスや Web UI を巻き込まないこと。もう 1 つはメモリです。128GB の統合メモリでも、100B 級モデルの vLLM と RAG スタックを同居させると空きがほぼ消えます。生成を専用ノードに逃がすことで、サービス層は CPU と I/O だけで回る軽いノードになりました。
チームメンバーからのアクセスは、Tailscale や Cloudflare Tunnel + WARP のようなプライベートネットワークの内側に閉じる設計です。インバウンドの公開ポートを一切設けず、Web UI も MCP も同じ境界の内側に置く形なので、認証基盤を自前で作り込まなくても比較的セキュアに運用できます。個人や小規模の検証なら Tailscale が手軽で、チーム展開なら社内アカウント認証と組み合わせられる Cloudflare Zero Trust(サービス層の cloudflared がアウトバウンドに Tunnel を張り、メンバーは WARP クライアントから到達)が収まりが良いですね。どちらを選んでも RAG 側の構成は変わりません。
NVIDIA RAG Blueprint とは何者か
NVIDIA RAG Blueprint は、エンタープライズ向け RAG パイプラインのリファレンス実装です。今回使ったのは v2.6.0(執筆時点の latest tag)で、主なコンポーネントは次のとおりです。
- rag-server: 検索と生成をまとめた API サーバ(LLM は OpenAI 互換で差し替え可能)
- ingestor-server + nv-ingest: ドキュメント取り込みパイプライン(PDF のレイアウト解析・表抽出など)
- Milvus・Redis・SeaweedFS・etcd: ベクタ DB とその足回り
- rag-frontend: 同梱の Web UI
- examples/nvidia_rag_mcp: RAG API を MCP tools として公開する薄いアダプタ
このスタックの良いところは、抽出・embedding・rerank・生成といった推論系コンポーネントをすべて環境変数で差し替えられることです。ローカルの NIM コンテナで動かすことも、NVIDIA hosted API(build.nvidia.com のエンドポイント)へ逃がすことも、任意の OpenAI 互換サーバへ向けることもできます。この差し替え口の広さが、DGX Spark 向けに構成を組み替える土台になりました。
v2.6.0 の目玉として Agentic RAG も同梱されています。リクエストに "agentic": true を足すだけで、質問をタスクに分解して計画を立て、タスクごとに検索と回答を繰り返してから統合する plan-and-execute 型のパイプラインに切り替わります。手元でも「2 つのツールの違いと組み合わせ方」のような複合質問に対して、それぞれの文書から正しく引いた統合回答が返ることを確認できました。そのぶん LLM 呼び出しが増えるため、応答は standard の数秒に対して 1 分前後かかります。今回の構成でこれをどう位置づけたかは、MCP の章で触れます。
DGX Spark 固有の事情にも触れておきます。コアのコンテナイメージは公式配布が amd64 のみで、arm64 の DGX Spark ではそのまま動きませんが、コア 4 イメージともソースからのビルドがパッチなしで通りました(依存パッケージにも arm64 非対応のものはゼロ)。embedding / rerank や表構造系の NIM コンテナは arm64 版が公式提供されており、そのまま動きます。唯一の例外は OCR の NIM で、現行の arm64 イメージには x86_64 ビルドのバイナリが同梱されており起動できません。ここは OCR エンジン本体(nemotron-ocr)が arm64 向けの wheel ごと PyPI で公開されているため、NIM 互換の薄い API サーバで包んで代替しています。
どこで何を動かすかの割り切り
DGX Spark は 128GB の統合メモリを持つとはいえ、Blueprint が想定するデータセンター GPU 構成をそのまま持ち込むのは無理があります。そこで機能ごとに「どこで・いつ動かすか」を割り切りました。
| 機能 | 動かす場所 | 動かし方 |
|---|---|---|
| RAG コア(rag-server・ingestor・nv-ingest) | サービス層(CPU) | 常駐。arm64 ソースビルドで稼働 |
| ベクタ DB(Milvus CPU 版)と足回り | サービス層(CPU) | 常駐。CPU 検索で十分な規模 |
| embedding / rerank(1B 級 NIM) | サービス層(GPU) | 常駐(計約 9.4GiB) |
| 文書抽出(レイアウト解析・表構造の NIM 群) | サービス層(GPU) | 取り込みのときだけ起動 |
| 生成 LLM | 推論層(vLLM × DeepSeek V4 Flash) | 常駐。2 台で並列配信 |
考え方はシンプルで、いちばん重い生成だけを推論層の 2 台に分離し、それ以外はサービス層 1 台にまとめる形です。embedding と rerank は 1B 級と小さく、1 クエリあたりの GPU 実働も 100ms 前後の間欠バーストなので、常駐させてもメモリ以外の負荷はほぼありません。一方の文書抽出 NIM 群はイメージが大きくメモリも食うため、取り込みのときだけ compose profile で起動する運用にしています。取り込みは頻度の低いイベントなので、これで困りません。
検索系の性能は実測で裏を取ってあります。embedding は単発 p50 88ms、rerank は p50 31ms。外部 API と違ってレート制限がないため、取り込みも検索もハードウェアの許す速度で回せます。
メモリはこうなりました。RAG サービス一式が約 12.7GiB、embedding + rerank の NIM が約 9.4GiB で、常駐の合計は約 22GiB。128GB 機の 2 割弱に収まり、負荷をかけてもこの数字はほぼ動きません。10 名チームの同時利用を想定して MCP 経由の同時アクセスを 4 本 → 8 本 → 16 本と段階的にかけた試験でも、全件成功・エラーゼロで、ホストのメモリはほとんど変化しませんでした。サービス層のハードウェアが先に音を上げる心配はなさそうです。
生成はローカルの DeepSeek V4 Flash が担う
生成 LLM の配線がこの構成の要です。RAG Blueprint の LLM は生成だけでなく、クエリ書き換え・フィルタ式生成・要約と 4 つのロールがあり、それぞれ環境変数で接続先を差し替えられます。ここを個別のサーバへ直結せず、間にルーターの NeMo Switchyard を 1 段挟みました。
# 公式の env 上書きパターン(後勝ち source)で、LLM 4 ロールだけをルーターへ
source deploy/compose/.env
source switchyard.env # SERVERURL をすべて Switchyard :4200 へ
Switchyard 側の route は 2 本です。生成用の rag-main と、書き換え系の軽ロール用 rag-light に分けてあり、それぞれの向き先を独立にチューニングできます。既定の向き先は推論層の vLLM(local 優先)で、推論層のメンテナンス時は Fireworks AI の同じ V4 Flash へ fallback します。オープンウェイトモデルの良いところで、ローカルもクラウドも同じモデルが動くため、fallback してもモデルの挙動が変わりません。
この配線にした狙いは可搬性です。RAG 側から見える接続先は常に Switchyard の route 名だけなので、向こう側を vLLM から Fireworks へ、あるいは別のモデルへ差し替えても、RAG 側の設定は 1 文字も変わりません。実際、route の defaults に思考トークンの抑制設定を入れて全ロールへ一律適用する、といった調整もルーター側だけで完結しています。
推論層の V4 Flash は、DGX Spark 2 台の vLLM 並列で動かした実績があります(2026-06-30 公開の記事です)。同時 16 リクエストの合計で約 290 tok/s が出る構成で、RAG の生成ロールには十分な性能です。
ドキュメントを取り込む
使い方の話に入ります。取り込みは Web UI からのアップロードと API の 2 経路があり、どちらも ingestor-server 経由で nv-ingest のパイプラインに入ります。PDF はテキスト抽出(pdfium)に、レイアウト解析・表構造の NIM 群を組み合わせて処理されます。
取り込みの品質で特筆したいのは表の扱いです。表入り PDF がレイアウトごと table 要素として構造化され、「表の具体的な値を挙げよ」という query を投げると、両テーブルの実セル値を正しく列挙できました。年別データの表も、パッケージ依存バージョンの表も正答です。速度も表入り PDF 2 本で 25 秒と実用域で、社内 wiki 1 セクション分くらいの規模なら数分で入る感覚です。より高精度な VLM ベースの抽出が必要になったら、Nemotron Parse を差し込む口も用意されています。
日本語も問題ありませんでした。日本語の技術記事 4 本と、日本語の表を 2 つ入れた自作 PDF を取り込んだところ、日本語表も 2 つとも table 要素として抽出されています。スキャン系の PDF も、前述の自作 OCR サービング経由で取り込めます。テキストレイヤーのない画像だけの PDF で試したところ、日本語の表はセル値の質問に正答し、装飾の多い A4 チラシからも注意喚起の手口や相談窓口の電話番号まで正しく引けました。1 点だけ、チラシのように表を含まない文書は infographic 抽出の有効化(APP_NVINGEST_EXTRACTINFOGRAPHICS=True)が必要です。既定では表・チャート領域しか OCR されないため、抽出要素ゼロで取り込みに失敗します。
Claude Code と opencode から MCP でつなぐ
ここからが本題です。Blueprint には RAG API を MCP tools として公開する薄いアダプタが同梱されており、streamable_http transport で立てておけば、各メンバーの端末からリモート接続できます。Tailscale や Cloudflare WARP のプライベートネットワーク経由でサービス層のアドレスへそのまま到達できるため、MCP クライアント側に認証ヘッダの設定は不要です。Claude Code からの登録は 1 コマンドで済みます。
claude mcp add --transport http nvidia-rag http://<サービス層の IP>:8091/mcp
opencode からも、設定ファイルに MCP サーバを 1 エントリ足すだけでつながります。
// opencode.jsonc
{
"mcp": {
"nvidia-rag": {
"type": "remote",
"url": "http://<サービス層の IP>:8091/mcp",
},
},
}
これでエージェントが search(ベクタ検索 + rerank)と generate(検索 + 回答生成)をツールとして呼べるようになります。使い分けは search が基本です。search は 1 回 3〜4 秒で引用チャンクが返り、エージェント側が自分の文脈で咀嚼できます。チーム全員が重ねて撃つ同時 16 本の試験でも全件成功でした。回答文まで RAG 側で作ってほしいときだけ generate を呼ぶ使い分けを想定しています。
先ほど紹介した Agentic RAG は、この MCP 経由では既定で使わない判断にしました。Claude Code や opencode はエージェント自身が質問を分解し、search を何度も呼び直すループを外側で回せるため、RAG 側でも計画と分解を重ねると役割が二重になり、待ち時間だけが増えるからです。Agentic RAG が活きるのは、Web UI や Slack のような 1 問 1 答の入口だと考えています。
そのまま公開せず、チーム向けには MCP サーバを 2 面に分けました。仕組みとしてはここが今回の工夫どころです。
| 面 | bind | tools | 用途 |
|---|---|---|---|
| public | 0.0.0.0 | 読み取り 5 本のみ | チームのエージェント用 |
| admin | 127.0.0.1 | 全 12 本 | 管理者のローカル操作用 |
同梱アダプタは既定でコレクション削除などの破壊系を含む 12 tools を公開するため、public 面は読み取り 5 本(search・generate・要約・コレクション一覧・ドキュメント一覧)だけに絞っています。もう 1 つ、既定の embedding が画像対応の VL モデルのため、表チャンクの引用にはページ画像の base64 が載り、search 1 回の応答が 507KB まで膨らむケースがありました。エージェントのコンテキストを直撃するので、public 面には画像をプレースホルダへ置換するフィルタを入れています。これで 応答は約 24KB(95% 削減) に収まりました。Web UI では画像引用が活きるため、サーバ側ではなく MCP アダプタ層で削るのが正しい切り所だと考えています。
チームへの配布は、既存の Switchyard バンドルに opencode.jsonc の設定例と、search / generate の使い分けをまとめた Agent Skill を同梱する形を予定しています。エージェントがこの skill を読めば、コレクションの選び方から引用の扱いまで迷わない、という寸法です。
Web UI から使う
エンジニア以外の入口として、同梱の rag-frontend がそのまま使えます。ブラウザからコレクションの作成・ドキュメントのアップロード・チャットまで一通り完結するので、「まず触ってもらう」にはこちらが手軽です。
日本語でも実用品質だった
チームで使うなら日本語が本丸です。取り込んだ日本語コーパス(技術記事 4 本 + 表入り自作 PDF)に対して、日本語 query を 3 問投げました。
| 問い | 判定 | 根拠 |
|---|---|---|
| ツールの概念説明 | 正答 | ルーティング方式・ライセンス等、元記事の記載と一致 |
| 記事固有の実測ディテール | 正答 | 属性名や「117 個のツール定義」まで正確に引用 |
| PDF 表のセル値の比較 | 正答 | 2 サービスの単価を正しく対比し、比率計算まで正確 |
3 問目は自作 PDF の表からモデル API 2 サービスの単価($0.09/$0.18 と $0.14/$0.28)を引き比べる問いでしたが、セル値の引用だけでなく約 1.56 倍という比率計算まで返ってきました。事前の embedding プローブでも日英の同義文ペアが cosine 類似度 0.910 と強い言語横断アラインメントを示しており、日本語 query で英語文書も引ける水準です。
retrieval・抽出・生成のすべてが日本語で機能しており、日本語ドキュメント中心のチーム利用は実測ベースで成立と言えそうです。生成がオープンウェイトの DeepSeek V4 Flash であることも、日本語の回答品質に効いていそうですね。
まとめ
NVIDIA RAG Blueprint を DGX Spark の 2 層構成(サービス 1 台 + 推論 2 台)に載せて、検索から生成までローカルに閉じたチーム共通 RAG がどこまで実用になるかを検証しました。要点を振り返ると、生成は推論層の DeepSeek V4 Flash が、embedding と rerank はサービス層の NIM が担い、常駐は合計約 22GiB。生成の配線は Switchyard を 1 段挟んで可搬性を確保しました。境界は Tailscale や Cloudflare Tunnel + WARP のプライベート網で公開ポートなし。入口は MCP(Claude Code / opencode)と Web UI の 2 系統で、日本語も実測で実用品質でした。
次はこの RAG を Slack から自然文で使えるようにする、チームアシスタント化を試したいと考えています。










