rag-pipeline について
rag-pipelineは、ウェブ検索を活用するLLMアプリや検索エンジンの開発者向けに、Bright Data Discoverを使ったRAG構成を解説するスキルです。ライブ検索、ベクトルストアへの取り込み、ハイブリッド構成に加え、引用元とコンテンツの検証方法を扱います。
主な機能
- 01ライブ検索と取り込み構成の設計
- 02Discoverによるウェブ情報の取得と順位付け
- 03チャンク化・埋め込み・ベクトル検索の構築
- 04引用元リンクの保持と検証
- 05JavaScriptとPythonのサンプル
活用シーン
- 01ウェブ検索に基づく最新のQ&A
- 02ウェブページのベクトルナレッジベースへの取り込み
- 03既存インデックスとライブ検索の併用
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ brightdata/ skills --skill rag-pipelineインストール後、Claude Code で/rag-pipelineを入力して読み込まれたか確認します。
同梱ファイルreferences/code.md
詳細
Bright Data — RAG/検索エンジンパイプライン
Discover を LLM アプリやカスタム検索エンジンの検索レイヤーとして使用します。
Discover はすでに 意図に基づいて順位付けされ、関連性スコアが付与された 結果を、解析済みのページ content とともに返すため、RAG の「検索+取得+クリーンアップ」段階を担います。これは discover-api スキルを基盤とする コード/アーキテクチャ スキルです。API の仕組み(トリガー/ポーリング、モード、パラメーター、制限)についてはそちらをお読みください。
用途に合った関連スキルを選んでください。文章によるブリーフなら live-research、すでに把握している特定 URL の Markdown 化なら scrape、プラットフォームの構造化レコードなら data-feeds です。
2 つのアーキテクチャ — まず選択する
Does the corpus change every query, or is it a stable knowledge base?
├── Per-query, always-fresh ("ground each answer in live web data")
│ → LIVE RETRIEVAL: Discover(include_content) at query time → top-k → LLM
│ Pros: always current, no storage. Cons: per-query latency + cost.
│
└── Reused across many queries ("build a knowledge base / search engine")
→ INGESTION: Discover(include_content) → chunk → embed → vector store
then at query time: embed query → vector search → (rerank) → LLM
Pros: fast queries, cacheable. Cons: can go stale (re-ingest on a schedule).
多くのシステムでは両方を使用します。幅広い情報を得るために取り込んだベースと、鮮度を保つためのライブ Discover 呼び出しを、LLM に渡す前に統合します。
ライブ検索(ウェブに基づいた回答)
パターン:ユーザーから質問があるたびに、明確な intent を指定して Discover を実行し、relevance_score 上位 k 件を選んで、その content をコンテキストとして LLM に渡します。LLM は link を引用します。
import { bdclient } from '@brightdata/sdk';
const client = new bdclient(); // BRIGHTDATA_API_TOKEN
async function retrieve(question, k = 6) {
const res = await client.discover(question, {
intent: `authoritative sources that directly answer: ${question}`,
includeContent: true,
numResults: Math.min(k * 2, 20), // over-fetch, then trim
});
// NOTE: the JS SDK returns a WRAPPER object, not a bare array:
// { success, data: [ {link,title,description,relevance_score,content?} ], totalResults, cost, taskId, ... }
// The result rows are in `.data` (CLI/REST use `.results` instead — see discover-api).
if (!res.success) throw new Error(`discover failed: ${res.error ?? 'unknown'}`);
return (res.data ?? [])
.filter(r => r.content && !/just a moment|captcha|access denied|not found/i.test(r.content) && r.content.length > 200)
.sort((a, b) => b.relevance_score - a.relevance_score)
.slice(0, k);
}
// → build a prompt from sources[].content, ask the LLM to answer WITH [n] citations to sources[].link
プロンプトの組み立てと引用のパターン全体については、references/code.md を参照してください。
取り込み(ベクトルナレッジベース/検索エンジンの構築)
パターン:幅広く検索し(大量取得には REST 経由の zeroRanking が最適です)、各ページの content をチャンクに分割してチャンクを埋め込み、ソース URL をメタデータとしてベクトルストアにアップサートします。クエリ時は、クエリを埋め込んでベクトル検索し、必要に応じて再ランキングしてから LLM に渡します。
段階は、検索 → 重複排除 → チャンク分割 → 埋め込み → アップサート(取り込み)、続いて クエリの埋め込み → 検索 → 再ランキング → 生成(提供)です。チャンク分割やメタデータを含む、両段階のプロバイダーに依存しないコードは references/code.md にあります。
コーパスを一括で構築する場合は、discover-api スキルの REST の生データ "mode":"zeroRanking" フロー(生の結果を最大限取得し、ランキングなし)を推奨します。ただし、このモードでは num_results が無視され、include_content はサポートされないため、別途コンテンツを取得する必要があります(コンテンツありの Discover standard/deep、または scrape スキルを使用)。
設計ルール
- 出典情報を保存します。 各チャンクにソースの
link(できればタイトルとrelevance_scoreも)を保持します。引用のない RAG は検証できません。 - ページではなくモデルに合わせてチャンク分割します。 重複部分を設けて約 500~1500 トークンとし、文の途中ではなく見出しや段落で分割します。
- 埋め込み前に
contentを検証します。 ブロックページや本文が空のページは除外します(サイズの大きい PDF はcontentが null になることがあります)。不適切なデータを埋め込むと検索結果の品質が損なわれます。 - 多めに取得してから
relevance_scoreで絞り込みます。 Discover のスコアは、再ランキングの前、または再ランキングの代わりに top-k を選ぶ際の強力な事前指標です。 - 鮮度が重要な場合は、定期的に再取り込みします。 ウェブコンテンツは変化します。取り込んだベースは古くなりますが、ライブ検索は古くなりません。
- 件数を制限し、重複を排除します。 1 回の呼び出しにつき
num_resultsは 20 以下です。3 つのアグリゲーター経由で同じ記事が重複して重み付けされないよう、呼び出しをまたいで正規化 URL を基準に重複を排除します。 - 埋め込みモデル/ベクトルストアを差し替え可能にします。 Discover は検索元です。埋め込みモデルとベクトル DB は自由に選択できるため、特定のものに固定しないでください。
検証ゲート
- 既知のテストクエリに対して、検索結果にトピックに合った空ではないチャンクが返されます(top-k のリンクを目視で確認します)。
- ブロックページや空の
contentがインデックスに含まれていません(保存されたチャンクを抜き取り確認します)。 - 引用が有効です。LLM が出力するすべての
[n]が、検索結果セット内の実在するソースlinkに対応しています。 - 鮮度が保たれています。アプリが最新データを約束する場合は、古いインデックスではなく、ライブ検索(または最近の再取り込み)を使用していることを確認します。
- 根拠の確認 — 回答がモデルの既存知識ではなく検索したコンテンツに裏付けられていることを確認します。回答が検索結果のページにしか載っていない質問を使ってテストしてください。
注意すべき点
- ユーザーが最新の回答を必要としているのにインジェストパイプラインを構築する(ライブ検索を使用してください)、またはキャッシュ済みのインデックスで十分なのに Discover を何度もライブ実行する。
- ブロックページや null を除外せずに
contentを埋め込む。 - ソース URL を保存しない。保存していないものは引用も更新もできません。
num_resultsに上限がないかのように扱う(上限は 20 件です)、またはzeroRankingでinclude_contentを利用できると期待する。- LLM が学習データから回答するのを許す。「提供されたソースのみから回答し、該当する情報がない場合はその旨を伝える」よう徹底してください。
- 1 ページにつき巨大なチャンクを 1 つだけ作成する(検索精度が低下します)、または文の途中で分割する。
参考資料
references/code.md— 2 つのアーキテクチャ(プロンプトと引用を組み立てるライブ検索、および完全なインジェストパイプライン(検出 → 重複排除 → チャンク化 → 埋め込み → アップサート → クエリ))に対応した、実行可能な JS と Python のコードです。プロバイダーに依存しない埋め込みモデル/ベクトルストアのインターフェースも含まれています。
関連スキル
discover-api— 検索 API(トリガー/ポーリング、モード、include_content、上限)。最初にお読みください。live-research— 常設システムの代わりに、単発の統合レポートを作成します。scrape— すでに把握している特定の URL から Markdown を取得します。js-sdk-best-practices/python-sdk-best-practices—client.discover()のオプションの詳細とバッチ処理のパターンです。