概要
AI エージェントはもはや実験段階ではなく、日々何十億もの HTTP リクエストを送り、ウェブを巡回し、API を呼び出し、複雑なワークフローをオーケストレーションする本番インフラです。しかし、エージェントがエラーに遭遇したとき、今までブラウザ向けに作った HTML エラーページ(数百行のマークアップ、CSS、メッセージ)を受け取っていました。これらはエージェントにとって「手がかり」にはなるものの、実行指示ではなく、トークンと時間の無駄遣いです。
Cloudflare は本日より、AI エージェント向けに RFC 9457 準拠の構造化された Markdown と JSON のエラーペイロードを返し、重い HTML ページを機械可読な指示に置き換えます。Accept: text/markdown、Accept: application/json、Accept: application/problem+json のいずれかを送信したクライアントが Cloudflare のエラーに遭遇した場合、HTML の代わりに一つの意味論的契約(structured format)を返し、実行可能なガイダンスを含みます。
このアプローチにより、単に「ブロックされました」と伝えるのではなく、例えば「レート制限されています — 30 秒待ち、指数バックオフでリトライしてください」のように、エージェントにとって実行可能な指示が与えられます。構造化エラー応答は、HTML と比べてペイロードサイズとトークン使用量を 98% 以上削減します(ライブの 1015('rate-limit')エラー応答で計測)。ワークフロー中に複数回エラーが発生する場合、この節約は急速に累積します。
これらはネットワーク全体で自動的に有効です。サイトオーナーの設定は不要で、ブラウザは従来どおり HTML を受け取り続けます。これは単なるエラーページではなく、エージェント化されたウェブのための実行指示です。
現状(エージェントが見ているもの)
Cloudflare が生成するエラーは、多くの場合 Cloudflare 自体の障害ではなく、リクエストをそのまま提供できない(無効なホストや DNS ルーティング、顧客定義のアクセス制御(WAF、ジオ、ASN、ボットルール)、エッジで強制される制限など)ために発生します。現在、これらの応答は人間向けにレンダリングされた HTML です。例:
<!DOCTYPE html>
<html>
<head>
<title>Access denied | example.com used Cloudflare to restrict access</title>
<style></style>
</head>
<body>
<div class="cf-wrapper">
<h1 data-translate="block_headline">Sorry, you have been blocked</h1>
</div>
</body>
</html>
エージェントにとってこれはほぼノイズで、どのエラーが起きたのか、なぜブロックされたのか、リトライが有効かどうかを判断できません。HTML をパースできたとしても、次に何をすべきか(人間にも機械にも)は明示されていません。
エージェント開発者が Cloudflare エラーに優雅に対応するには選択肢が限られていました。Structured responses は、サイトごとの設定に依存するパスには存在しましたが、エージェント向けの一貫したデフォルトにはなっていませんでした。Custom Error Rules で多くの 1xxx エラーをカスタマイズできますが、サイトごとの設定に依存するため、ウェブ全体の共通契約にはなりえません。
Cloudflare はリクエスト経路の前段に位置するため、デフォルトの機械応答を定義できます: retry するか停止するか、待ってバックオフするか、エスカレーションまたはルーティングを変更するか。エラーページが装飾ではなく実行指示になります。
Cloudflare の対応(何をしたか)
Cloudflare はすべての 1xxx クラスのエラー経路(DNS 解決問題、アクセス拒否、レート制限などのエッジ側失敗を表すプラットフォームエラー)に対して RFC 9457 準拠の構造化応答を返します。形式は両方サポートされています:
Accept: text/markdown は Markdown を返す
Accept: application/json は JSON を返す
Accept: application/problem+json は application/problem+json の Content-Type で JSON を返す
これは現時点で全ての 1xxx クラスエラーをカバーしています。将来的には Cloudflare が生成する 4xx/5xx エラーにも同じ契約を拡張します。
Markdown 応答は二部構成です:
- YAML frontmatter(機械可読フィールド)
- 明示的なガイダンスのための本文("What happened" と "What you should do")
JSON 応答は同じフィールドをフラットなオブジェクトとして持ちます。YAML frontmatter は自動化にとって重要な層で、エージェントは HTML をスクレイピングしたりコピーから意図を推測したりせずに安定したキーを抽出できます。
フィールド例: error_code, error_name, error_category, retryable, retry_after, owner_action_required, ray_id, timestamp, zone, cloudflare_error など。これらにより、エージェントは失敗を分類し、バックオフロジックを決定し、エスカレーションが必要かどうかを判断できます。スキーマは意図的に安定化されているため、プレゼンテーションの変更を追いかける必要がありません。
この安定性自体は Cloudflare の独自発明ではありません。RFC 9457 — Problem Details for HTTP APIs は HTTP 上でエラーを報告するための標準 JSON 形状を定義しており、クライアントは事前に特定の API を知らなくてもエラー応答をパースできます。Cloudflare の JSON 応答はこの形状に従い、以下の基本メンバーは問題詳細を理解するためにそのまま使えます:
- type: Cloudflare の特定エラーコードに関するドキュメントへの URI
- status: 実際のレスポンスステータスと一致する HTTP ステータスコード
- title: 問題の短い人間向け概要
- detail: この発生に特有の人間向け説明
- instance: この特定の発生を識別する一意の値(Ray ID と一致することが多い)
運用フィールド(error_code, error_category, retryable, retry_after, owner_action_required など)は RFC 9457 の拡張メンバーです。これらを知らないクライアントは単に無視できます。
この変更はネットワーク全体で追加的(additive)であり、サイトオーナー側の設定は不要です。ブラウザは明示的に Markdown または JSON を要求しない限り従来の HTML を受け取り続けます。
応答の例(1015 rate-limit)
JSON 例:
{
"type": "https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/error-1015/",
"title": "Error 1015: You are being rate limited",
"status": 429,
"detail": "You are being rate-limited by the website owner's configuration.",
"instance": "9d99a4434fz2d168",
"error_code": 1015,
"error_name": "rate_limited",
"error_category": "rate_limit",
"ray_id": "9d99a4434fz2d168",
"timestamp": "2026-03-09T11:11:55Z",
"zone": "<YOUR_DOMAIN>",
"cloudflare_error": true,
"retryable": true,
"retry_after": 30,
"owner_action_required": false,
"what_you_should_do": "**Wait and retry.** This block is transient. Wait at least 30 seconds, then retry with exponential backoff.\n\nRecommended approach:\n1. Wait 30 seconds before your next request\n2. If rate-limited again, double the wait time (60s, 120s, etc.)\n3. If rate-limiting persists after 5 retries, stop and reassess your request pattern",
"footer": "This error was generated by Cloudflare on behalf of the website owner."
}
同じエラーをモデルファーストワークフロー向けに最適化した Markdown 例(YAML frontmatter を含む):
---
error_code: 1015
error_name: rate_limited
error_category: rate_limit
status: 429
ray_id: 9d99a39dc992d168
timestamp: 2026-03-09T11:11:28Z
zone: <YOUR_DOMAIN>
cloudflare_error: true
retryable: true
retry_after: 30
owner_action_required: false
---
You are being rate-limited by the website owner's configuration.
**Wait and retry.** This block is transient. Wait at least 30 seconds, then retry with exponential backoff.
Recommended approach:
1. Wait 30 seconds before your next request
2. If rate-limited again, double the wait time (60s, 120s, etc.)
3. If rate-limiting persists after 5 retries, stop and reassess your request pattern
---
This error was generated by Cloudflare on behalf of the website owner.
両フォーマットは、エージェントが失敗を分類し、リトライ動作を選び、エスカレーションが必要かどうかを判断するのに十分な情報を与えます。これはサイトごとの設定ではなく、ネットワーク全体のデフォルトの機械契約です。
1つの契約、2 つのフォーマット
価値はフォーマットの選択肢ではなく意味論的安定性にあります。エージェントは次の運用上の疑問に対して決定論的な答えを必要とします: リトライすべきか、どれくらい待つべきか、エスカレーションすべきか。
Cloudflare は 2 つのワイヤ形式で 1 つのポリシー契約を公開します。Markdown でも JSON でも、運用上の意味は同一です。 Accept: application/problem+json を送信したクライアントには application/problem+json; charset=utf-8 が返り、HTTP クライアントライブラリがメディアタイプで分岐するのに便利です。Accept: application/json を送ると application/json; charset=utf-8 が返ります。
サイズ削減とトークン効率
この契約は置き換えるものよりも圧倒的に小さくなります。HTML はブラウザ向けで重く、構造化応答はコンパクトです。1015 の比較(計測):
| ペイロード | Bytes | Tokens (cl100k_base) | サイズ比(HTML) | トークン比(HTML) |
|---|
| HTML response | 46,645 | 14,252 | — | — |
| Markdown response | 798 | 221 | 58.5x less | 64.5x less |
| JSON response | 970 | 256 | 48.1x less | 55.7x less |
両方の構造化フォーマットは HTML と比べて約 98% の削減を実現します。エージェントにとってサイズはそのままトークンコストに直結するため、ワークフロー内で複数回エラーが発生すると、こうした節約はモデルへの支出削減と高速なリカバリループにつながります。
10 カテゴリと明確な行動
すべての 1xxx エラーは error_category にマップされ、エラー処理はページごとの壊れやすいパースではなくルーティングロジックになります。
| Category | 意味 | エージェントが行うべきこと |
|---|
| access_denied | 意図的なブロック(IP, ASN, 国別制限, firewall rule 等) | リトライしない。予期せず発生した場合はサイトオーナーに連絡。 |
| rate_limit | リクエストレート超過 | バックオフ。retry_after 秒待ってリトライ。 |
| dns | オリジンでの DNS 解決失敗 | リトライしない。サイトオーナーに報告。 |
| config | 設定エラー(CNAME, トンネル, ホストルーティング等) | 通常はリトライしない。サイトオーナーに報告。 |
| tls | TLS バージョンまたは暗号の不整合 | TLS クライアント設定を修正。現状のままリトライしない。 |
| legal | DMCA や法的な制限 | リトライしない。法的制限。 |
| worker | Cloudflare Workers のランタイムエラー | リトライしない。サイトオーナーがスクリプトを修正する必要あり。 |
| rewrite | 無効な URL rewrite 出力 | リトライしない。サイトオーナーがルールを修正する必要あり。 |
| snippet | Cloudflare Snippets のエラー | リトライしない。サイトオーナーが Snippets 設定を修正する必要あり。 |
| unsupported | サポートされないメソッドや非推奨機能 | リクエストを変更する。現状のままリトライしない。 |
この一覧を実用的にする 2 つのフィールド:
retryable はリトライが成功する可能性があるかを示す
owner_action_required は問題がエスカレーション(サイトオーナーの介入)を必要とするかを示す
これにより「if status == 429 then maybe retry」のような壊れやすいヒューリスティックを、フロントマターを一度パースして明確な制御フローに置き換えられます。フロントマターを一度解析し、error_category や retryable、retry_after、owner_action_required に基づいて分岐処理を行えば、安定したエラー処理が可能です。
まとめ
Cloudflare の RFC 9457 準拠の構造化エラー応答は、エージェントに対して明確で機械可読、かつ小さい応答を提供します。これによりトークンコストが大幅に削減され、エージェントは決定論的な制御フローでエラーに対処できるようになります。ネットワーク全体で自動的に有効化され、サイトオーナーの追加設定は不要です。