Files
maestro/docs/tools/webfetch.md
T
oss-sync 29ccaf1e92
CI / build-and-test (push) Has been cancelled
sync: update from private repo (dfadcd5f)
2026-06-23 06:38:48 +00:00

111 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WebFetch
URL を HTTP GET してレスポンス本文を取得するツール。静的ページ向け。
## 基本
```js
WebFetch({ url: "https://example.com/article", timeout: 30 })
```
- HTML は **readability 抽出**でクリーンな Markdown に変換されて返る(ナビ・広告・ヘッダー・フッターを除去し、見出し・リスト・テーブル・リンクは保持)
- JSON / XML / プレーンテキストもそのまま取得可能
- リダイレクトは自動で追従
返却テキストは context 節約のため約 10,000 文字で切り詰められる。**スペースタスクでは全文(未切り詰め)が `source/` に保存される**ので、切り詰めが起きると末尾に `... (truncated; full version saved to source/<file>)` という案内が付く。全文を読みたいときは保存された `source/` のファイルを `Read` で開けばよい。
## いつ使うか
| 状況 | 使うツール |
|------|-----------|
| 静的 HTML ページ | **WebFetch** |
| JS で動的レンダリングされる SPA | BrowseWeb |
| ボタン・フォーム操作が必要 | BrowseWeb |
| ファイルダウンロード | DownloadFile |
| 検索結果を一覧で取得 | WebSearch |
WebFetch は軽量で速い。BrowseWeb はブラウザ起動コストがかかるので、できる限り WebFetch を優先する。
## クリーン本文抽出(readability
取得した生 HTML は、記事本文だけを取り出す readability エンジンで処理してから返す。
内部パイプラインは `HTML → linkedom で DOM 化 → @mozilla/readability で記事抽出 → turndown(+gfm) で Markdown 化`
- **除去されるもの**: ナビゲーション、広告バナー、ヘッダー、フッター、サイドバー等のボイラープレート
- **保持されるもの**: 見出し(`#` 記法)、箇条書き、番号付きリスト、テーブル(GFM 記法)、リンク、コードブロック
- 相対リンクは取得 URL を基準に絶対 URL へ変換される
- `selector` を指定すると、その CSS セレクタにマッチする要素のサブツリーだけをクリーン抽出する(見つからなければページ全体の抽出にフォールバック)
抽出に失敗するページ(記事構造のない LP、JS で本文を生成する SPA、空ページ等)では、
従来の素朴なタグ除去にフォールバックするので WebFetch が失敗扱いになることはない。
本文がほぼ空のときは SPA の可能性が高いので `BrowseWeb` に切り替える。
### 全文は source へ、切り詰め版は agent へ
- agent のコンテキストに返るのは約 10,000 文字に切り詰めた版(context 膨張を防ぐため)
- **スペースタスクでは、切り詰める前の全文クリーン Markdown が `source/` に保存される**
- 切り詰めが起きた場合、返却テキスト末尾に `... (truncated; full version saved to source/<file>)` が付く
- 病的に巨大なページ対策として、`source/` 保存も 2MB で打ち切る(その旨ノートを付す)
## レスポンス履歴
各 WebFetch 呼び出しは `logs/webfetch-history.jsonl` に記録される。後から「どの URL を取得したか」を振り返れる。
## スクリーンショット添付(vlmEnabled 時のみ)
ワーカーが `vlm=true`(主 LLM が画像入力対応)の場合、WebFetch は成功時に Playwright でファーストビュー(1280×1600 viewport)のスクショを撮り、LLM の文脈に `image_url` として自動添付する。天気・ダッシュボード・地図など、HTML テキスト抽出では情報が欠落しやすいサイトの理解を補う目的。
- 保存先: `logs/webfetch-screenshots/{timestamp}-{url-hash}.png`
- `logs/webfetch-history.jsonl` の各レコードに `screenshotPath` が記録される
- Playwright 未インストール・CAPTCHA・タイムアウト等で失敗しても WebFetch 本体は成功扱い(テキストだけ返る)
- 無効化: `config.yaml``tools.webfetch_screenshot: false`
- タイムアウト: `tools.webfetch_screenshot_timeout_ms`(デフォルト 15,000
## SSRF 保護
ローカル/プライベート IP127.x.x.x, 10.x.x.x, 172.16-31.x.x, 192.168.x.x, ::1, fc00::/7 等)はデフォルトでブロックされる。社内ホストへアクセスする必要がある場合は Settings UI の「SSRF Allowed Hosts」に追加する。
## トラブルシューティング
- **本文がほぼ空**: SPA で JS レンダリングが必要 → BrowseWeb に切り替え
- **タイムアウト**: `timeout` パラメータを増やす(デフォルト 30 秒)
- **403/404**: User-Agent 制限・bot 検出の可能性 → BrowseWeb なら回避できる場合あり
- **SSRF blocked**: ローカル/プライベート IP に向いている → 設定追加またはターゲット見直し
## エラー時のフォールバック方針
WebFetch がエラーを返した場合、以下の原則で `BrowseWeb` にリトライする:
| エラー | BrowseWeb で再試行すべきか |
|---|---|
| HTTP 403 / 429 | **する** — bot 検出・レート制限。ブラウザ User-Agent で回避できる可能性 |
| HTTP 502 / 503 / 504 | **する** — CDN/upstream の一時的エラー。別の HTTP スタックで成功することがある |
| ネットワークエラー / タイムアウト | **する** — 動的ページが静的 fetch に応答しないケースが多い |
| HTTP 404 / 401 / 410 | しない — 永続的なエラー。URL を見直すべき |
| `invalid_url` | しない — URL の記述ミス |
| `ssrf_blocked` | しない — セキュリティ設定。Settings で allowed hosts を追加 |
| `pdf_blocked` | しない — `DownloadFile` + `ReadPdf` の組み合わせを使う |
| `binary_blocked` | しない — `DownloadFile` でバイナリ保存する |
| 本文が極端に短い(< 200 chars | **する** — SPA の空シェルを取得した可能性が高い |
| `Just a moment...` 等 Cloudflare challenge | **する** — ブラウザで JS challenge を通過できる |
リトライ時は同じ URL を `BrowseWeb({ url: "..." })` に渡すだけでよい。`BrowseWeb` はジョブ内で Cookie・セッションを保持するので、複数回呼んでもログイン状態は引き継がれる。
## バイナリの扱い
WebFetch は取得 body の先頭 8KB を sniff し(magic byte / NUL / 不正 UTF-8 / 制御文字比率)、
バイナリと判定したら**コンテキストに展開せずブロック**する。Content-Type が欠落・詐称
(例: `.xls``text/plain`)していても実バイトで検出する。バイナリを処理したい場合は
`DownloadFile``input/` に保存し、`ReadExcel` / `ReadPdf` 等を使う。テキスト body は
5MB で打ち切られる(末尾に `[truncated: body exceeded 5MB]`)。
## ソースライブラリへの蓄積(スペースタスク)
スペースのタスクで WebFetch がページ本文を取得すると、**クリーン抽出した全文 Markdown**agent への
返却で切り詰める前のもの)が `source/` に保存され、出典メタ(URL・タイトル・取得日時・サイズ)が
`source/index.jsonl` に追記される。
これにより「そのスペースのソース(資料)」が自動で溜まり、後から追加調査やグラウンディングに使える。
同一 URL は重複保存しない(既に index にあればスキップ)。スペース文脈でないタスク
ephemeral / gitea issue 等)では従来どおり蓄積しない。`logs/raw/` への生データ保存は従来どおり。
BrowseWeb(ブラウザ閲覧)や DownloadFile`section: "source"`)も同じ `source/index.jsonl` に合流する。