Claude API Web Search & Web Fetch実践ガイド — Dynamic Filteringでコンテキスト消費を最小化するRAGレスなリアルタイム検索エージェント構築
RAGパイプラインの構築・運用に疲弊していませんか? ベクトルDB、Embeddingモデル、チャンク戦略、インデックス更新。2026年2月にGA化されたClaude APIのWeb Search/Web Fetchツール最新版(20260209)は、Dynamic Filtering機能によって検索結果をコンテキストに載せる前にノイズを自動除去します。本記事では、RAGパイプラインを一切組まずに、APIコール1回でリアルタイムWeb情報を取得・フィルタ・回答する軽量エージェントの構築パターンを、動くコード付きで解説します。
Web Search / Web Fetchツールの全体像と2つのバージョン
基本版とDynamic Filtering版の違い
Claude APIが提供するWebアクセスツールには、それぞれ2つのバージョンが存在します。
| ツール | 基本版 | Dynamic Filtering版 |
|---|---|---|
| Web Search | web_search_20250305 | web_search_20260209 |
| Web Fetch | web_fetch_20250910 | web_fetch_20260209 |
基本版はそのまま残っているため、段階的な移行が可能です。既存コードのツール名を差し替えるだけでDynamic Filteringを有効化できます。
対応モデルと前提条件
Dynamic Filteringは Claude Opus 4.6 と Claude Sonnet 4.6 のみ対応です。Haikuでは利用できません。また、Claude API直接呼び出しとMicrosoft Azureで利用可能ですが、Google Vertex AIではDynamic Filteringは使えません(基本版のみ)。
最小構成のTypeScript実装は以下のとおりです。
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
// 基本版: "web_search_20250305"
// DF版: "web_search_20260209" に差し替えるだけ
const response = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 4096,
messages: [{ role: "user", content: "最新のNext.js 16の変更点を教えて" }],
tools: [{ type: "web_search_20260209", name: "web_search" }],
});
DF版を指定すると、Code Executionが自動的に有効化されます。追加のツール指定やベータヘッダは不要です。
Dynamic Filteringの仕組み — なぜトークン24%削減・精度11%向上なのか
従来のWeb Searchの課題
基本版のWeb Searchでは、検索結果のHTML全文がそのままコンテキストウィンドウに投入されます。ページ1つで数万トークンを消費することも珍しくなく、大半がナビゲーションやフッター等のノイズです。
Dynamic Filteringの内部動作
DF版では、Claudeが検索結果を受け取った後、サンドボックス内でフィルタリングコードを自動生成・実行し、関連性の高い部分だけを抽出してからコンテキストに載せます。
データフロー比較:
- 基本版: 検索実行 → 全結果をコンテキストに投入 → 回答生成
- DF版: 検索実行 → Claude がフィルタコードを生成・実行 → 関連部分のみコンテキストに投入 → 回答生成
BrowseCompベンチマークでの結果は明確です。
| モデル | 基本版 | DF版 |
|---|---|---|
| Opus 4.6 | 45.3% | 61.6% |
| Sonnet 4.6 | 33.3% | 46.6% |
BrowseCompとDeepsearchQAの2ベンチマーク平均で精度11%向上、入力トークン24%削減。トークン削減はそのままコスト削減に直結します。しかもCode Execution料金はWeb Search/Fetch併用時は無料です。正直、これを使わない理由がありません。
実装: Dynamic Filtering付きWeb Searchエージェント
基本実装: 検索→フィルタ→回答の1ショットパターン
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
async function searchAndAnswer(question: string) {
const response = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 4096,
messages: [{ role: "user", content: question }],
tools: [
{
type: "web_search_20260209",
name: "web_search",
max_uses: 5,
allowed_domains: ["developer.mozilla.org", "docs.anthropic.com"],
},
],
});
// テキストブロックとcitationsを抽出
const textBlocks = response.content.filter((b) => b.type === "text");
const answer = textBlocks.map((b) => b.text).join("");
const citations = extractCitations(textBlocks);
return { answer, citations, usage: response.usage };
}
// citations抽出ユーティリティ
function extractCitations(textBlocks: Array<{ type: string; text: string; citations?: any[] }>) {
const sources: Array<{ url: string; title: string; citedText: string }> = [];
for (const block of textBlocks) {
if (!block.citations) continue;
for (const cite of block.citations) {
if (cite.type === "web_search_result_location") {
sources.push({
url: cite.url,
title: cite.title,
citedText: cite.cited_text,
});
}
}
}
// URL重複を除去
return [...new Map(sources.map((s) => [s.url, s])).values()];
}
citationsの抽出と活用
Web Searchのcitationsは常時有効で無効化できません。レスポンス内の各テキストブロックに citations 配列が付与され、cited_text(引用元テキスト最大150文字)と url が含まれます。上記の extractCitations 関数で一覧抽出できます。
max_uses でリクエストあたりの検索回数上限を設定し、allowed_domains / blocked_domains でドメインを絞ることでコスト管理が可能です。
Web Search + Web Fetch併用戦略 — 検索で見つけて、Fetchで深掘り
併用パターン: いつFetchを追加すべきか
Web Searchは「広く浅く」スニペットを取得し、Web Fetchは「狭く深く」特定ページの全文を取得します。技術ドキュメントの詳細確認、ニュース記事の全文取得、API仕様のパラメータ一覧取得など、スニペットだけでは不十分なケースでFetchを併用します。
Web Fetchのcitationsはオプションです(citations: { enabled: true } で明示的に有効化)。
セキュリティ制約: 動的URL構築の禁止
重要な制約があります。Claudeはツール結果から動的にURLを構築してFetchすることが禁止されています。Fetchできるのは、ユーザーメッセージ内のURL、または過去のWeb Search/Fetch結果に含まれるURLのみです。Web Search結果のURLをそのまま渡す形が正しいパターンです。
async function searchThenFetch(question: string) {
const response = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 8192,
messages: [
{
role: "user",
content: `${question}\n\nまず検索で関連ページを見つけ、最も関連性の高いページの全文を取得して詳細に分析してください。`,
},
],
tools: [
{
type: "web_search_20260209",
name: "web_search",
max_uses: 3,
},
{
type: "web_fetch_20260209",
name: "web_fetch",
max_uses: 2,
citations: { enabled: true },
},
],
});
return response;
}
Claudeは自律的にWeb Searchで候補を見つけ、有望なURLをWeb Fetchで深掘りするフローを実行します。Web Fetch料金は追加課金なし(消費トークン分のみ)なので、地味にコスト効率が良い組み合わせです。
RAG vs Web Search+DF: コスト・精度・運用の比較
コスト試算: 月1万クエリ想定
| 項目 | Web Search + DF | RAG構成 |
|---|---|---|
| 検索/クエリ | $100($10/1,000検索) | Embedding API: ~$5-20 |
| インフラ | なし | ベクトルDB月額: $70-300+ |
| トークン | 入出力トークン代(DF版は24%削減) | 入出力トークン代 |
| 運用工数 | ほぼゼロ | インデックス更新、チャンク最適化、監視 |
| Code Execution | 無料 | - |
どちらを選ぶべきか
RAGが適するケース:
- 社内文書・プロプライエタリデータを検索したい
- 低レイテンシ(100ms以下)が必須
- オフライン環境で動作させる必要がある
Web Search + DFが適するケース:
- リアルタイム性が求められる(ニュース、株価、技術ドキュメント最新版)
- データ更新頻度が高く、インデックス更新コストが無視できない
- インフラ管理を最小化したい
ハイブリッド構成も有力です。社内データはRAGで検索し、外部の最新情報はWeb Search + DFで取得する。両方の強みを活かせます。
よくあるハマりポイントと対処法
DF版を指定したのにフィルタリングが動かない — 対応モデル(Opus 4.6 / Sonnet 4.6)を使っているか確認してください。Haikuでは動作しません。
Vertex AI環境でDF版が使えない — 現時点でGoogle Vertex AIはDynamic Filtering非対応です。Claude API直接呼び出しまたはMicrosoft Azureに切り替えてください。
Web Fetchで特定サイトが取得できない — Claudeはrobots.txtを尊重します。ブロックされているサイトは取得できません。
検索結果が英語に偏る — user_location パラメータで地域を指定します。
tools: [
{
type: "web_search_20260209",
name: "web_search",
max_uses: 5,
allowed_domains: ["zenn.dev", "qiita.com"],
user_location: {
type: "approximate",
country: "JP",
timezone: "Asia/Tokyo",
},
},
];
コスト爆発 — max_uses で検索回数を制限し、allowed_domains で範囲を絞るのが基本対策です。Web Fetchでは max_content_tokens パラメータで取得コンテンツ量も制限できます。
Dynamic Filtering付きWeb Search/Web Fetchは、RAGパイプラインの構築・運用コストを丸ごとスキップできる強力な選択肢です。特にリアルタイム性が求められるユースケースでは、ベクトルDB + Embeddingの構成を組むよりもシンプルかつ低コストで実現できます。まずは既存のRAGパイプラインの一部をWeb Search + DFに置き換える小さな実験から始めてみてください。精度11%向上・トークン24%削減という数値は、本番環境でのコスト最適化にも直結します。
