すべての記事

再クロールの課題: RAGパイプラインを新鮮に保つ

RAGナレッジベースはリリースしたその週に古くなります。エンジニアリング予算を圧迫せずに数百の垂直ソースを再クロールする方法を解説します。

The Challenge

垂直型AIスタートアップは、2ヶ月目あたりで皆同じ壁にぶつかります。サポートコパイロット、法務リサーチアシスタント、あるいはコンプライアンスボットをリリースします。最初のデモで顧客を獲得します。その後データが古くなり、回答が現実から乖離し始めます。

私たちは、チームがAI側をきれいに構築し、データ側を後回しにするのを見てきました。取り込みパイプラインは、誰かのラップトップで実行される1つのPythonスクリプトです。200のソースURLを一度スクレイピングし、きれいなMarkdownをベクターストアにダンプして、皆で喜びます。6週間後、回答の半分が、削除されたページ、非推奨のAPI、あるいは3月にリリースされて5月に再リリースされた製品機能を引用するようになります。

修正は簡単そうに聞こえます。毎週すべてのソースを再クロールすることです。現実はもっと醜いです。2026年までに、信頼できるサイトの約60%がAIクローラーをブロックする(2023年後半の23%から増加)ようになり、その保護はもはや単純な User-Agent チェックではありません。セッションの動作、リクエストのリズム、ハンドシェイクレベルのシグナルを監視します。1月に機能していた単純なスクリプトは、3月には静かに空のページを返すようになります。

さらに悪いことに、一部のサイトでは、埋め込みを汚染するまでタールピットコンテンツ(本物の散文のように読めるマルコフ生成のちんぷんかんぷんな文章)を提供するようになりました。そのため、エンジニアは製品を出荷する代わりに、週の半分をスクレイパーへのパッチ当てに費やすことになります。検索の質が低下し、顧客はそれに気づき、AIを構築するために雇ったチームはスクレイパーのメンテナンスショップになります。

The Approach

再クロールの問題は、すべてのリクエストで発生しなければならない3つの具体的な決定に分かれます。

  1. レンダリングするかしないか? ほとんどのドキュメントポータルはきれいなHTMLを提供します。増加するシェア(Next.jsで構築されたもの、クライアントサイドレンダリングを備えたもの)は、有用なコンテンツを返すために完全なブラウザレンダリングを必要とします。
  2. どの proxy を使用するか? 住宅、データセンター、モバイル、地理的固定、ISP固有。適切な選択はターゲットによって変わります。
  3. それは実際に機能したか? 空の本文を持つ200、または CAPTCHA HTMLページは、HTTPリクエストとしては成功していますが、クロールとしては失敗です。

FourAのようなプラットフォームは、これらのそれぞれを最重要事項として処理します。

レンダリングの決定には、安価で高速なケースには Single を、JSを多用するターゲットには Browser を呼び出します。呼び出しの本文は同じ形であるため、取り込みコードは、何百ものサイト固有の癖を持ち運ぶ代わりに、ソースごとのフラグで一度分岐するだけです。

proxy の選択については、Proxy Finder がすべての Single、Browser、および Auto 呼び出しの一部として実行されます。プラットフォームはリクエストごとに機能する出口を選択し、その不透明なIDを response (r.proxy のトップレベルの Single/Browser、または r.session.proxy の Auto) で返し、同じ出口に固執する必要がある場合はフォローアップの呼び出しでそのIDを再利用します。クローラーは独自の proxy ランキングアルゴリズムを持ちません。(プールサイズが差別化要因ではなくなった理由については、Why Proxy Pool Size Stopped Mattering in 2026 で書いています)。

そして、「それは実際に機能したか」という質問に対して、すべての request は validate ブロックをサポートしています。何が成功とみなされるかを宣言します。許可されたステータスコード、必要な header 値、表示される必要がある、または表示されてはならない本文の文字列です。FourAは7つの結果のいずれかを返し、success のみが請求対象です。コンテンツルールに失敗した200は application_fail とスタンプされ、データセットに入ることはありません。

JSレンダリングを必要とするドキュメントポータルの再クロール呼び出しの例を次に示します。Auto にオーケストレーションさせます。適切な製品(Single、Proxy、またはBrowser)を選択し、ボット防御を処理し、次の再クロールが同じ出口に固執できるようにセッショントリプルを返します。

import requests

r = requests.post(
    "https://api.foura.ai/api/auto",
    headers={"Authorization": "Bearer pk_live_..."},
    json={
        "url": "https://docs.example.com/changelog",
        "validate": {
            "status": {"accept": [200]},
            "data":   {"accept": ["<article"], "fail": ["captcha", "Just a moment"]},
        },
    },
).json()

# r["data"] or r["body"]   — rendered content (Auto runs the right sub-product per host;
#                            Single populates "data", Browser populates "body")
# r["session"]              — { "proxy": "<base36 id>", "cookies": [...], "userAgent": "..." }
# On the next recrawl, pass r["session"]["proxy"] back as `ignoreProxies: [<id>]` to avoid
# the same exit, or via /api/single with `proxy: <id>` to stick to it.

ターゲットがCloudflareのインタースティシャルをスローした場合、validate.data.fail ルールがそれをキャッチします。使用量に対してスタンプされる結果は application_fail です。料金は発生せず、取り込みコードは、「しばらくお待ちください...」というページを埋め込みにフィードするのではなく、別の proxy で再試行することを認識します。

より広いコーパスについては、既存のジョブキューで同じパターンをラップします。私たちが話しをしたチームは、前回のクロールに対して夜間にdiffを実行し、実際に変更されたドキュメントのみを再埋め込み、数時間のウォールクロックタイムで500ソースのコーパスを更新します。ジョブキューはあなたのものです。proxy の変更、レンダリングの決定、成功の判定は私たちのものです。

Results

インフラストラクチャがボトルネックではなくなった後の鮮度ループの様子(垂直AIチーム全体で見られるパターンに基づく説明的なシナリオ):

  • 500のソースURLを毎週再クロール。リリース時の200URLのワンショットではありません
  • スクレイパーのエンジニアリング時間: 週2時間未満。1〜2日から短縮
  • 検索の陳腐化ウィンドウ: 5〜7日。無制限ではありません
  • ベクターストアのガベージ率はほぼゼロ。Cloudflareのインタースティシャルとタールピットページは、埋め込みモデルに到達する前に validate レイヤーで拒否されるためです
  • ソースごとのコストは予測可能。失敗したクロールは請求に表示されないためです

重要なのは、これらが魔法ではないということです。重要なのは、それらが退屈だということです。そして退屈こそが、本番AIが必要としているものです。(ホストされたLLM抽出で計算が機能しなくなる場所の詳細については、When LLM Extraction Stops Paying for Itself を参照してください)。

Key Takeaway

垂直AIを構築しているほとんどのチームは、モートがプロンプト、モデルの選択、または検索アルゴリズムであると考えています。そうではありません。モートは鮮度ループ、つまりナレッジベースを毎週正直に保つ魅力のないインフラストラクチャです。

2026年まで垂直AIで勝つチームは、最も賢いプロンプトを持つチームではありません。ユーザーがデータが最新であることに決して気づかないチームになるでしょう。常にそうだからです。