Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】How We Built Perceive: Web Content Extraction for RAG Pipelines

2026年09月05日に「Dev.to」が公開したITニュース「How We Built Perceive: Web Content Extraction for RAG Pipelines」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

AIがWebページの情報を効率良く使うには、不要な広告やナビゲーションを除き、主要なコンテンツだけを渡す必要がある。PerceiveはURLから記事の本体を正確に抽出し、構造を保ったMarkdown形式で提供する。これにより、AIは無駄なく情報を処理でき、検索や応答の精度を高められる。

ITニュース解説

私たちは日々、インターネット上のウェブページから情報を得ているが、大規模言語モデル(LLM)のようなAIも同じようにウェブページから学習し、質問に答えたりする。しかし、人間とLLMでは、ウェブページの見え方が大きく異なるという問題がある。人間はウェブページを見たとき、ナビゲーション、広告、ボタンなどの視覚的な要素は無視して、記事の本文や求めている情報に集中できる。ところが、LLMにウェブページの内容を伝える際、ただ生のHTMLデータを渡すと、その「余計な情報」まで全て与えてしまうことになる。

この「Perceive」というシステムは、このような課題を解決するために作られた。特に、LLMが外部情報を参照してより正確な回答を生成するRAG(Retrieval Augmented Generation)パイプラインにおいて、ウェブページから効率的かつ高品質な情報を抽出することを目指している。

生のHTMLデータをRAGパイプラインにそのまま入力することは、いくつかの深刻な問題を引き起こす。まず、「トークンの無駄」が発生する。ウェブページのHTMLコードには、記事の本文だけでなく、ナビゲーションメニュー、スクリプト、スタイル情報、広告など、本来のコンテンツとは関係のない「クローム」と呼ばれる部分が大量に含まれている。例えば、800ワードの記事の本文が900〜1,200トークンで表現できるのに対し、生のHTMLでは6,000〜12,000トークンにも膨れ上がることがある。LLMには一度に処理できるトークンの量(コンテキストウィンドウ)に限りがあるため、このような無駄な情報が多すぎると、本来のコンテンツに割けるスペースが減り、処理コストも増大する。

次に、「埋め込みの汚染」という問題がある。LLMはテキストを数値のベクトル(埋め込み)に変換し、その類似度に基づいて関連情報を検索する。しかし、生のHTMLには<div class="sidebar-widget__title">関連記事</div>のようなマークアップ(構造を示すタグ)が多く含まれており、これらの情報も一緒に埋め込みの対象となってしまう。埋め込みモデルは自然言語で訓練されているため、マークアップが混ざると、コンテンツ本来の意味合いを表すベクトルが曖昧になり、サイトのデザイン構造に関する情報が混入してしまう。結果として、本当に意味的に関連する情報よりも、偶然同じマークアップパターンを持つ情報が上位に表示されるなど、検索の精度が大きく低下してしまう。

さらに、「チャンク化の破綻」も大きな課題だ。RAGでは、長い文章を意味のある小さな単位(チャンク)に分割してから埋め込みを行うが、標準的な分割ツールは通常、自然な文章や構造化されたMarkdownを前提としている。HTMLのタグは必ずしも意味的な段落の区切りではないため、生のHTMLを単純に文字数で分割しても、意味的に連続しているべき内容が分断されたり、無関係な内容が同じチャンクにまとめられたりしてしまい、適切な情報検索ができなくなる。

Perceiveはこれらの問題を解決するために、URLを受け取ってクリーンなMarkdown形式のコンテンツを返す。この変換プロセスは以下の4つの段階を経て行われる。

最初の段階は「Fetch(取得)」だ。ここでは、指定されたURLからウェブページのデータがHTTPリクエストによって取得される。リダイレクトの処理、タイムアウト管理、応答の検証、さらにはサイトごとのアクセス制限(レートリミット)やrobots.txtのルール遵守もこの段階で対応される。

次に「Render(レンダリング)」が行われる。現代のウェブページにはJavaScriptを使って動的にコンテンツを生成するもの(シングルページアプリケーション、SPAなど)が多い。このようなページでは、Fetchで取得した生のHTMLだけでは完全な内容を得られないため、Perceiveは実際のブラウザ(ヘッドレスChromeなど)を起動し、ページを完全にレンダリングする。この際、アンチボット対策を回避するための高度な技術も使われ、クッキーバナーの非表示化、遅延読み込みコンテンツの表示のためのスクロール、画像の読み込み待機なども行う。特に重要なのは、DOM(Document Object Model)が準備完了しただけでなく、「ネットワークアイドル」状態まで待つことだ。これにより、初期表示後にAPIを呼び出してコンテンツを読み込むようなページでも、その内容を確実に取得できるようになる。

三番目の段階は「Extract(抽出)」で、これが最も複雑な処理だ。レンダリングされたページの中から、記事の本文やメインとなるコンテンツ(コンテンツ)と、ナビゲーション、サイドバー、フッター、広告などの「クローム」を識別し、本文だけを抽出する。ウェブサイトによってコンテンツの構造は様々であり、<nav>タグや<div class="nav-wrapper">など、多様な方法でナビゲーションが実装されているため、明確なルールで区別するのは難しい。そのためPerceiveは、DOM内での要素の位置、テキストとリンクの比率、ページ全体に対するテキストの密度、一般的な構造パターンなど、様々な経験則(ヒューリスティック)を組み合わせてコンテンツの境界を推測する。

最後の段階は「Structure(構造化)」だ。抽出されたコンテンツは、Markdown形式に変換される。HTMLの見出し構造はMarkdownの見出しレベル(###など)に、リストはネストされたリストに、テーブルはMarkdownのテーブル形式にそれぞれマッピングされる。コードブロックは元の言語ヒントを保持し、インラインリンクや画像も適切な形式で変換される。

Perceiveには「only_main_content: true」というオプションも用意されている。このオプションを有効にすると、抽出されたコンテンツからさらに厳選されたメインコンテンツのみを返す。これは「もし人間がこのURLを読みに来たとすれば、本当に気にする情報は何だろうか?」という問いに答えることを目的としている。ナビゲーション要素、サイトのヘッダー・フッター、クッキー同意バナー、サイドバーの内容、関連記事ブロック、ソーシャル共有ウィジェットなどが除去され、ページのタイトル、本文、その中の見出し構造、リスト、テーブル、コードブロック、インラインリンクなどが残される。ただし、コンテンツとクロームの境界が曖昧な場合もあり、完全に除去しすぎると本来必要な情報まで失われる可能性があるため、このオプションは注意が必要であり、その結果の信頼性も評価される。

なぜMarkdown形式が選ばれるのかというと、プレーンテキストでは見出しやリスト、テーブルといった重要な構造情報が失われてしまうからだ。構造が失われると、RAGにおけるチャンク化の際に、意味的なまとまりを保ったまま分割することが非常に難しくなる。一方でJSON形式は、事前に複雑なスキーマ定義が必要であり、データをLLMに渡す前に解析する手間がかかる。Markdownは、見出しの階層、リストのネスト、テーブルの構造、コードブロックの言語識別子を保持しつつ、特別なパーサーなしでも人間が読みやすく、またLLMの埋め込みモデルにとっても自然言語に近い形式として処理しやすいという利点がある。さらに、Perceiveは常に一貫したMarkdownのスタイル(例えば、ハッシュ記号の後のスペースや、言語識別子付きのコードブロックなど)を出力するため、ダウンストリームの処理(チャンク化など)が安定して機能する。

もちろん、Perceiveにも限界がある。JavaScriptが非常に複雑で、特定のユーザー操作なしにはコンテンツが表示されないSPAや、URLが変わってもページ全体が再読み込みされないようなクライアントサイドルーティングを使用しているサイトでは、完全にコンテンツを抽出できない場合がある。また、ペイウォール(有料購読)で保護されたコンテンツは、公開されている部分しか取得できず、ログインを回避する機能は提供されていない。スクロールやクリックによって初めて表示される遅延読み込みコンテンツ(無限スクロールのフィードや、折りたたまれたアコーディオン内のコンテンツなど)も、常に取得できるとは限らない。そして、最も課題となるのは、ウェブサイトの構造が非常に一貫性がなく、メインコンテンツとサイドバーなどが構造的に区別しにくい場合だ。このようなサイトでは、Perceiveのヒューリスティックが誤った判断をしてしまい、本来のコンテンツを十分に抽出できなかったり、逆に不要なクロームを含んでしまったりすることがある。

PerceiveのAPIは、curlコマンドやPythonのスクリプトから簡単に利用できる。URLを指定し、必要に応じてonly_main_contentオプションなどを設定してリクエストを送信すると、Markdown形式のコンテンツが返される。この際、結果にはrender_qualityというスコアも含まれており、0.40未満の場合はレンダリングが失敗した可能性や信頼性が低いことを示唆しているため、このスコアを確認することで、抽出されたコンテンツの品質を判断できる。取得したMarkdownデータは、LangChainのようなRAGフレームワークに組み込み、意味のある単位でチャンク化してLLMの学習や情報検索に活用することが可能だ。

Perceiveは、RAGパイプラインがウェブ上の膨大な情報を効率的かつ高品質に利用するための重要なツールであり、LLMの能力を最大限に引き出す上で欠かせない役割を担っている。ウェブコンテンツの複雑さからくる問題を解決し、より精度の高い情報検索と回答生成に貢献するシステムだ。

関連コンテンツ

関連IT用語

関連ITニュース