はじめに
Claude Code を使う開発者の多くは、外部サイトを参照したいとき WebFetch や WebSearch に手が伸びる。URL を渡せば内容を取得してくれる。便利だ。しかし使い込むうちに、コンテキストウィンドウが見るみる埋まっていく感覚を持ったことはないだろうか。
八雲では数ヶ月前に外部サイト調査を agent-browser に一本化するルールを設けた。この記事ではその判断の背景と、実運用で得た知見を書く。
課題: コンテキストウィンドウとトークン経済
WebFetch が返すのは HTML の全文だ。ナビゲーション・広告・スクリプトタグ・インラインスタイル、関心のないノイズがほぼそのままコンテキストに流れ込む。企業サイト 1 ページの HTML は軽くても 30〜80KB になる。競合調査で 10 社を比較するなら、それだけで数百 KB 分のコンテキストが飽和する。
問題はトークン消費だけではない。大量の無関係テキストが混入することで、Claude の推論の焦点が散る。「このサイトのカラートーンを教えて」と頼んでいるのに、フッターの免責事項や meta 属性の羅列を処理させることになる。信号対雑音比が悪化する。
WebSearch も同様だ。検索結果のスニペットは短いが、各 URL を取得し始めると状況は変わらない。リッチな調査をしようとするほど消費は加速する。
コンテキストウィンドウは有限の資源だ。長いセッションで複数の調査タスクを並走させるとき、その経済的合理性を無視するわけにはいかない。
アプローチ: agent-browser で別プロセスにブラウザを置く
agent-browser は Node.js ベースのヘッドレスブラウザ CLI ツールだ。Playwright を内部で使いつつ、Claude Code の外側でデーモンとして常駐する。
設計の核心は「ブラウザを親 Claude のコンテキストの外に置く」点にある。HTML の取得・レンダリング・DOM 操作はすべて子プロセスが担う。親 Claude は自分が必要とする情報の問いかけだけをして、抽出された答えだけを受け取る。
agent-browser open https://example.com
agent-browser snapshot # アクセシビリティツリー(軽量)
agent-browser eval "Array.from(document.querySelectorAll('h1,h2,h3')).slice(0,20).map(h => h.tagName + ':' + h.textContent.trim().slice(0,80)).join(' | ')"
agent-browser screenshot /tmp/ref.png
snapshot コマンドはアクセシビリティツリーを返す。HTML そのものではなくセマンティクスの骨格だ。見出し・ボタン・リンク・フォームが構造化されたテキストで得られる。これはページの本質的な情報構造を、HTML の 10 分の 1 以下のサイズで表現する。
eval で JavaScript を実行する方式は更に精密だ。欲しい要素だけをセレクタで取得し、必要なフィールドだけを join した文字列として返せる。コンテキストに乗るのは、その数十〜数百文字だけだ。
構造: 親 Claude が指示し、子プロセスが HTML を消化する
agent-browser を使う作業フローは次の形になる。
- 親 Claude が目的を定義する(「このサイトのナビゲーション構成を教えて」)
- agent-browser にページを開かせ、snapshot か eval で構造を抽出する
- 抽出結果のテキストだけをコンテキストに渡す
- 親 Claude が分析・判断を行う
HTML の消化は子プロセスの仕事だ。親 Claude はその結果だけを受け取り、推論に集中する。
研究系タスクでこのパターンをさらに延伸したのが並列サブエージェント方式だ。競合調査・デザインリファレンス収集・技術検証といった調査軸をそれぞれ独立したサブエージェント(general-purpose)に割り振り、並列で走らせる。各サブエージェントは agent-browser で調査を完遂し、結果を単一のファイルに保存して 3 行のサマリーだけを返す。
単一エージェントに全タスクを直列で処理させると、Plan の上限に達して成果が失われるリスクがある。並列化は速度だけでなく、そのリスクヘッジにもなる。
実例: スクレイピング・競合調査・ログイン継続セッション
agent-browser の使いどころは 3 つある。
スクレイピングでは、Lancers や CrowdWorks の案件一覧から必要なフィールドだけを eval で抽出している。HTML を保存するのではなく、タイトル・予算・URL の配列だけを JSON として取り出す。案件詳細も同様で、業務内容・必須スキル・報酬の箇所だけを狙い撃ちして文字列化する。
競合調査・コーポレートサイト設計では、サイトの構成とトンマナを調べる際に snapshot を活用する。ページのセクション構造、見出しの文言、CTA の配置が短いテキストで把握できる。スクリーンショットは視覚的なトンマナを確認するときだけ撮る(必要時のみ)。
ログイン継続セッションでは、永続プロファイル(~/.synapse/profiles/lancers 等)に Cookie が書き込まれた状態を保持する。一度ログインすれば以降はヘッドレスで認証済みセッションとして動く。Playwright の通常の使い方と同じだが、agent-browser のデーモンが常駐しているため起動コストがない。
運用してわかった効果と落とし穴
半年近く使った上での正直な評価を書く。
効果として実感しているのは、長時間セッションの安定性だ。以前は競合調査の途中でコンテキストが詰まって中断することがあったが、agent-browser を使うようになって大幅に減った。調査軸を並列サブエージェントに切り出す設計と組み合わせることで、大規模な調査タスクも最後まで完走するようになった。
コンテキストに乗る情報が精製されているため、推論の品質も上がったと感じる。HTML のノイズを排除した状態で「このサイトのサービス構成を整理して」と依頼すると、余計な情報に引っ張られずに本質的な構造の分析が返ってくる。
落とし穴として注意が必要なのは、eval の精度依存だ。セレクタの指定が甘いと意図しない要素が混入する。特に動的にクラス名が変わるサイトや、SPA でハイドレーション前に取得しようとするケースは注意が要る。wait コマンドでレンダリングを待ってから取得するか、snapshot に切り替えるかを状況で判断している。
もう一つは、視覚情報が必要なケースの見極めだ。カラートーンやレイアウトの雰囲気は snapshot や eval では完全には伝わらない。そういった場合は screenshot を使う。ただしその画像をコンテキストに乗せることになるので、必要最小限にとどめる判断は変わらない。
まとめ
WebFetch・WebSearch は使い勝手が良いが、コンテキストウィンドウを HTMLのノイズで埋めてしまうコストがある。agent-browser は「ブラウザを外に置いて抽出結果だけを返す」設計で、このトレードオフを解消する。
「何を返すか」を明示的に設計することがポイントだ。HTML をそのまま渡すのではなく、欲しい情報を eval や snapshot で精製してから受け取る。それだけで、コンテキストの使い方は大きく変わる。
Claude Code でウェブ調査タスクを扱うなら、agent-browser を最初から組み込む設計にすることを勧める。
関連記事
- Yakumo の AI 駆動開発のリアル — 八雲全体の AI 駆動開発の設計思想
- スキル vs エージェント — 八雲の判断基準 — 定型作業のスキル化と責任者エージェントの使い分け