web-search-plus について
複数の検索プロバイダーを利用し、URLから内容を抽出するコマンドラインスキルです。クエリの意図に応じた検索や並行リサーチに対応し、モデル生成の回答ではなくリンクとページ本文を返します。
主な機能
- 0111種類の検索プロバイダーに接続
- 02クエリの意図に応じた検索ルーティング
- 03複数プロバイダーによるURL内容の抽出
- 04並行リサーチ検索と重複排除
- 05キャッシュ、品質フィルター、再ランキング
活用シーン
- 01最新のウェブ情報と検索結果の取得
- 02リサーチ用に複数プロバイダーから情報源を収集
- 03後続の分析に向けたウェブページ本文の抽出
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ robbyczgw-cla/ web-search-plus --skill web-search-plusインストール後、Claude Code で/web-search-plusを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSE.gitignoreTROUBLESHOOTING.mdCHANGELOG.mdconfig.example.json.env.exampleREADME.mdFAQ.mdpackage.jsontest-auto-routing.shscripts/docker_detect.pyprovider_registry.pyprovider_stats.pyextract.pyhttp_client.pyurl_security.pysearch_locale.pyresearch.pyquality.pysetup.pysearch.pytests/test_http_keepalive.pytest_research_and_quality.pytest_routing_and_extract.pytest_v431_sync.pytest_v33_plugin_sync.pytest_source_only.pytest_security.py詳細
Web Search Plus
検索プロバイダー選びは不要です。スキルに任せましょう。
このスキルは現在、11 の検索プロバイダーに接続し、URL からコンテンツを取得するための補完的な抽出フローを追加しています。幅広いウェブ検索なら? → Brave または Serper。調査に関する質問なら? → Tavily または Exa。引用と根拠が必要なら? → Linkup。スクレイピング対応コンテンツが必要なら? → Firecrawl。プライバシーを優先するなら? → SearXNG。プリペイドクレジットで低コストの Google SERP が必要なら? → SerpBase(明示的に指定した場合、またはフォールバック専用)。最後の手段として独立したインデックスを使いたいなら(キーなしでも可)? → Keenable。
このスキルはソース専用です。返すのはランキング済みリンクと抽出したページテキストであり、モデルが生成した回答ではありません。Perplexity/Kilo による回答の合成は 4.0.0 で削除されました。ネイティブの OpenClaw プラグインは web-search-plus-plugin-v2 です。
🔐 データの取り扱いとプライバシー
機密性の高いクエリで検索する前にお読みください。
- 検索クエリと抽出 URL はサードパーティのプロバイダーに送信されます。 検索のたびに、設定されたプロバイダー(Serper、Brave、Tavily、Linkup、Querit、Exa、Firecrawl、SerpBase、Keenable、You.com、または SearXNG インスタンス)にクエリテキストが送信されます。抽出のたびに、選択した抽出プロバイダー(Tavily、Exa、Linkup、Firecrawl、You.com、Keenable、Serper)に対象 URL が送信され、プロバイダーのインフラストラクチャがページを取得します。各プロバイダー独自のプライバシーポリシーとデータ保持ルールが適用されます。
- 機密性の高い作業では、自動ルーティングに任せず、プロバイダーを明示的に選択してください(
--provider <name>)。これにより、クエリを受け取るサードパーティを正確に制御できます。セルフホストの SearXNG を使えば、クエリを管理下のインフラストラクチャ内にとどめられます。 - 内部 URL や非公開 URL を抽出に使用しないでください。 抽出する URL は外部サービスに転送されます。このスキルは、デフォルトでプライベート/ループバック/リンクローカルの対象とクラウドメタデータエンドポイントもブロックします(下記の「セキュリティ」を参照)。
- ローカルキャッシュはデフォルトで有効です。 クエリ、結果、プロバイダーの障害履歴、プロバイダーのパフォーマンスサンプル(適応型ルーティング用のレイテンシ/結果数/エラー)は、キャッシュディレクトリ(デフォルトは
.cache、移動する場合はWSP_CACHE_DIR)に保存されます。これには、プロバイダーのエラーメッセージを含むprovider_health.jsonとprovider_stats.jsonも含まれます。キャッシュファイルは所有者のみがアクセスできる権限で書き込まれます(ディレクトリは0700、ファイルは0600)。- 1 回の呼び出しで無効にする:
--no-cache - 全体で無効にする:
WSP_DISABLE_CACHE=1 - 消去する:
python3 scripts/search.py --clear-cache(--cache-statsで内容を確認できます)
- 1 回の呼び出しで無効にする:
- API キーがログに記録されたり、スキルによって保存されたりすることはありません。 エラーは、キャッシュや stderr に出力される前にサニタイズされます。
🎯 トリガー
日常的なリクエストで自動的に有効にならないよう、マニフェストには対象を限定したトリガーフレーズのみが登録されています。
web search pluswsp searchsearch the web formulti-provider web searchextract url contentextract content from url
「search」「find」「look up」「research」などの一般的な単語では、このスキルが有効にならないよう意図的に設定されています。
✨ このスキルの特長
- 検索するだけ — どのプロバイダーを使うか考える必要はありません
- スマートルーティング — クエリを分析し、最適なプロバイダーを自動的に選択します
- 11 プロバイダーを 1 つのインターフェースで — 一般的なウェブ検索、調査、セマンティック検索、プライバシー優先、プリペイドクレジット対応、抽出対応の各プロバイダーをまとめて利用できます
- URL 抽出に対応 — 7 つのプロバイダーを順次利用するフォールバック機能で、Markdown/HTML コンテンツを取得できます(Tavily を優先)
- 調査モード — 複数プロバイダーでの並行検索、重複排除、上位ソースからのコンテンツ抽出を 1 回の呼び出しで実行します
- 正規ソースによる再ランキング — リリース/ドキュメント/ポリシー/金融/セキュリティに関するクエリでは、ミラーサイトより公式/一次ソースを優先します
- 認証情報は 1 つだけでも利用可能 — 任意のプロバイダー 1 つから始めて、後から追加できます
- 無料/セルフホストの選択肢あり — SearXNG は API コスト 0 ドルで運用できます
🚀 クイックスタート
# Interactive setup (recommended for first run)
python3 scripts/setup.py
# Or manually
cp .env.example .env
python3 scripts/search.py -q "latest OpenClaw release"
python3 scripts/extract.py --url https://example.com
ウィザードで各プロバイダーの説明を確認し、キーを登録して、デフォルトを設定できます。
🔑 プロバイダー
検索プロバイダー
- Serper — ショッピング、価格、ローカル検索、Google 形式の一般的な検索結果。幅広い検索の高速なフォールバック
- Brave — 独立したウェブインデックスと一般的な最新ウェブ検索。Google 以外を補完するのに適しています
- Tavily — 調査、解説、統合。調査向けのルーティングに適しています
- Querit — 多言語・国際的な最新情報。言語をまたいだ最新情報の検索に適しています
- Linkup — 情報源に基づく、引用重視の検索。証拠を優先するクエリに適しています
- Exa — 意味に基づく検索と、情報源 URL を含む類似サイト検索
- Firecrawl — スクレイピング対応のメタデータを含む検索。情報抽出プロバイダーとしても優れています
- You.com — 最新ウェブ検索や RAG に適したスニペット。情報抽出にも対応しています
- SearXNG — プライベート/セルフホスト可能な検索。API キーは不要で、インスタンス URL のみを指定します
- SerpBase — プリペイドクレジットを利用する低コストの Google SERP。明示的な指定またはフォールバック専用です(
--provider serpbaseでオプトインするか、config.jsonのprovider_priorityに追加します) - Keenable — 独立したウェブインデックス。
KEENABLE_API_KEYでキーを指定するか、キー不要の オプトイン共有パブリックティアを利用できます(WSP_KEENABLE_ALLOW_PUBLIC=1、約 1000 リクエスト/時間、SLA なし、結果メタデータに警告あり)。自動ルーティングの優先度は最も低く、設定済みのキー付きプロバイダーに取って代わることはありません
情報抽出プロバイダー
scripts/extract.py は、信頼性を重視して Tavily を最初に、以下の順で自動的にフォールバックします。
- Tavily
- Exa
- Linkup
- Firecrawl
- You.com
- Keenable
- Serper(
scrape.serper.dev経由のウェブページスクレイパー。Markdown を優先)
🧠 ルーティングの概要
デフォルトの優先順位(設計上 SerpBase は除外されており、オプトインのみです):
tavily → linkup → querit → exa → firecrawl → brave → serper → you → searxng → keenable
ルーティングでは、プロバイダーのパフォーマンスに関する適応型メモリも適用されます。各プロバイダーの呼び出しで、レイテンシ、結果数、エラーがローリングウィンドウ(50 サンプル、鮮度 7 日、provider_stats.json に保存)に記録されます。新しいサンプルが 5 件たまると、これを基にルーティングスコアが上限付き(±1.0)で調整されます。これは同点を解消し、僅差の選択を後押しするには十分ですが、クエリクラスの明確な最適候補を覆すほどではありません(routing.adaptive_adjustments)。
例:
python3 scripts/search.py -q "weather in Vienna today"
# generic current-web intent → Brave or Serper
python3 scripts/search.py -q "find credible sources for AI tutoring outcomes"
# citation/evidence intent → Linkup
python3 scripts/search.py -q "latest AI policy updates in Germany"
# multilingual + recency → Querit or Tavily
python3 scripts/search.py -p exa --exa-depth deep -q "LLM scaling laws research"
python3 scripts/search.py -p firecrawl -q "YC startups web scraping"
python3 scripts/search.py -p serpbase -q "best laptop 2026" # explicit SerpBase
ルーティングのデバッグ:
python3 scripts/search.py --explain-routing -q "your query"
ダッシュで始まるクエリには、--query=-foo または -q -- "-foo" を使用できます。-n を省略すると、件数には defaults.max_results が使われます(フォールバックは 5 件)。件数は 1~20 件に制限されます。
--time-range は --freshness より優先されます。Tavily は日/週/月/年をネイティブの time_range として送信します。Exa はリクエストで送信された公開期間の範囲を報告します。
--cache-ttl SECONDS は検索キャッシュの有効期間を設定します。ライブ/時間単位のクエリでは最大 60 秒、最新情報/日単位では最大 300 秒、週単位のフィルターでは最大 1800 秒です。キャッシュされた結果には cache_age_seconds が含まれます。--no-cache は検索結果のキャッシュを無効にします。接続の再利用を無効にするには WSP_HTTP_KEEPALIVE=0 を設定します。プロキシ経由のリクエストでは標準のトランスポートが使われます。
鮮度、ニュースの分野、ロケール
python3 scripts/search.py -q "AI regulation" --freshness week
# providers with native date filters receive the mapped value; others run the
# normal search and report freshness.applied=false in metadata
python3 scripts/search.py -p serper --type news -q "quantum computing"
# Serper serves the Google news vertical natively (date/source/thumbnail);
# other providers report search_type.applied=false
python3 scripts/search.py -q "beste Kaffeehäuser Wien"
# explicit location hints (curated city/country table) set the country (at);
# set locale.language="auto" (or WSP_LOCALE_LANGUAGE=auto) to also infer the
# query language conservatively. Resolved values + sources appear in
# metadata.locale. Without configuration behavior stays exactly us/en.
結果品質フィルター
既知の Stack Overflow/GitHub/ドキュメントミラーのドメインからの結果は除外されます(完全一致のドメイン/真のサブドメインのみを対象とし、類似ドメインによる誤検出はありません)。config.json の quality.blocked_domains で対象を追加するか、quality.allowed_domains で除外対象から外せます。ドメイン多様性の再ランキングでは、先頭枠に同一ドメインの結果が 2 件までとなるよう制限します(超過分は削除せず順位を下げます)。明示的なドメイン指定(site: クエリ、--include-domains)がある場合、どちらの制限も適用されません。除外と順位の引き下げは metadata.result_filter に報告されます。
📖 情報抽出の例
python3 scripts/extract.py --url https://example.com
python3 scripts/extract.py --url https://docs.linkup.so --provider linkup
python3 scripts/extract.py --url https://example.com --url https://example.org --include-images
python3 scripts/extract.py --url https://example.com --format html --include-raw-html
python3 scripts/extract.py --url https://example.com --provider serper # Serper webpage scraper
python3 scripts/extract.py --url https://example.com --extract-char-limit 30000
大きすぎるページでは、先頭と末尾の範囲、および説明用フッターが返されます(デフォルトのインライン予算は 15,000 文字です。WSP_EXTRACT_CHAR_LIMIT または --extract-char-limit で変更できます)。インラインの base64 画像データは、コンテンツのサイズを測定する前に [IMAGE: alt] のプレースホルダーに置き換えられます。これにより、通常の http(s) 画像リンクを保持したまま、データ URI によるトークンの大量消費を防ぎます。
🔬 リサーチモードと品質レポート
リサーチモードでは、最大3つのプロバイダーに同時にクエリを送信します(実際の所要時間は合計ではなく、最も遅いプロバイダーにかかる時間にほぼ等しくなります)。プロバイダー間で重複を排除し、決定的な順序で並べ替えた後、根拠として使用する上位ソースを抽出します。
python3 scripts/search.py --mode research -q "EU AI Act obligations for foundation models"
python3 scripts/search.py --mode research -q "..." --research-providers tavily linkup exa
python3 scripts/search.py --mode research -q "..." --research-extract-count 2 --research-time-budget 30
時間予算によって起動するプロバイダーと抽出を実行するかどうかが決まります。完了できなかったステップは呼び出しを失敗させるのではなく、routing.provider_errors / routing.extraction_error に報告されます。
品質レポートでは、透明性の高いルーティング/結果の診断情報が追加されます。これには、正規ソースへのルーティングクラスの権威性シグナル(canonical_domain_hits、demoted_domain_hits、canonical_top_result)が含まれます。
python3 scripts/search.py -q "official anthropic claude release notes" --quality-report
これらの正規ソースクラス(ベンダー公式リリース、公式ドキュメント、ポリシー PDF、財務/IR、セキュリティ勧告)では、結果が意図に応じて再ランク付けされます。一次ソースの順位を上げ、ミラー/アグリゲーターのドメインの順位を下げます(変更内容は metadata.intent_rerank に表示されます)。
⚙️ 設定に関する注意事項
.env.exampleには、サポート対象の環境変数が記載されていますconfig.example.jsonには、プロバイダーの優先順位とプロバイダー固有のデフォルト値が含まれていますconfig.jsonはローカルの実行時設定です- SearXNG では、明示的な URL 設定と Docker を考慮した自動検出が引き続きサポートされています
- SerpBase はデフォルトでは明示指定/フォールバック専用です。自動ルーティングに含めるには、
config.jsonのauto_routing.provider_priorityに"serpbase"を追加します - Keenable は自動ルーティングおよび抽出のフォールバックで最後に使用されます。キーなしでの使用を有効にするには、
WSP_KEENABLE_ALLOW_PUBLIC=1または"keenable": {"allow_public": true}を明示的に設定します - ロケールのデフォルト値は、
config.jsonの"locale": {"country": "...", "language": "..."}で設定します(またはWSP_LOCALE_COUNTRY/WSP_LOCALE_LANGUAGEを使用します)。--country/--languageCLI フラグが常に優先されます - レート制限:429 レスポンスでは
Retry-Afterを解析し、再試行は最大1回です(30秒以下の待機時間はそのまま適用されます)。プロバイダーが要求した待機時間はクールダウン段階にも反映されます。30分より古い失敗履歴は減衰するため、クールダウンがいつまでもエスカレートすることはありません。キー未設定による設定エラーでは、クールダウンは発生しません
🔒 セキュリティ
URL SSRF 保護(抽出、--similar-url):
http/httpsの URL のみを受け付けます- ホスト名を解決し、プライベート/ループバック/リンクローカル/予約済みの範囲(
10/8、127/8、169.254/16、172.16/12、192.168/16、CGNAT の100.64/10、::1、fc00::/7、fe80::/10、IPv4-mapped IPv6、0.0.0.0)を参照している場合はブロックします - クラウドメタデータエンドポイント(
169.254.169.254、metadata.google.internal)は常にブロックされます - 信頼できるプライベートネットワークで保護を無効にするには、
--allow-private-urlsまたはWSP_ALLOW_PRIVATE_URLS=1を使用します(デフォルトでは無効です。メタデータエンドポイントは引き続きブロックされます)
SearXNG SSRF 保護:
http/httpsのみを許可します- 一般的なクラウドメタデータエンドポイントをブロックします
SEARXNG_ALLOW_PRIVATE=1が設定されていない場合、プライベート/内部 IP への解決をブロックします- インスタンス URL には、オペレーターが管理する設定/環境変数のみを使用します
ローカルデータ:
- キャッシュディレクトリは
0700で作成されます。キャッシュ、プロバイダーのヘルス情報、プロバイダーの統計情報の各ファイルは、アトミックな一時ファイル置換によって0600で書き込まれます - API キーがキャッシュやログに書き込まれることはありません
宣言された権限(package.json → clawhub.permissions を参照):
- 外部ネットワークアクセスは、一覧に記載されたプロバイダー API ホスト(およびユーザーが設定した SearXNG インスタンス)に制限されます
- 環境変数の読み取りは、プロバイダーの
*_API_KEY変数、SEARXNG_*、WSP_*設定に制限されます - ファイルシステムへの書き込みは、キャッシュディレクトリに制限されます
✅ 検証
python3 -m unittest discover -s tests -p 'test_*.py'
python3 scripts/search.py --explain-routing -q "find credible sources for climate change impacts"
python3 scripts/extract.py --url https://example.com --provider auto --compact