AIエージェント Markdown 配信ガイド:Accept: text/markdown・Content-Signal・Link ヘッダーの解説
結論: AIエージェント Markdown 対応とは、クライアントがリクエストヘッダー
Accept: text/markdownで求めたときに、サーバーが同じアドレスで HTML の代わりにプレーンな Markdown を返すことです。ブラウザーには引き続き HTML を返します。数行のサーバーコードか、CDN の機能を有効にするだけで済み、エージェントはメニューやスクリプトのないきれいなテキストを受け取れます。順位や AI による引用への効果は確認されていません。読みやすい HTML、適切な robots.txt、サイトマップの上に載せる安価な追加策と考え、これらの代わりにはしないでください。
なぜ AI エージェントは Markdown を好むのか
Web ページはブラウザー向けに作られています。本文の周りには、ナビゲーション、Cookie バナー、スクリプト、フッターが並びます。人間の目はそれを読み飛ばせますが、ページを言語モデルに渡すプログラムはそうはいきません。コンテキストウィンドウには限りがあり、余計な要素はそのぶん場所を取るからです。
Markdown は、読むために大事なもの(見出し、段落、リスト、表、リンク)だけを残します。llms.txt の提案が Markdown で書かれているのも同じ理由です。このファイルは llms.txt とは?書き方と効果の整理 で解説しました。
Cloudflare の Markdown for Agents の発表では、サンプルの応答に推定トークン数を示す x-markdown-tokens ヘッダー(例では725)が付いており、クライアントはページがどれだけのコンテキストを使うかを見積もれます。
ただし、大手の AI 検索システムが Markdown を要求するかどうかは、これでは分かりません。発表には OAI-SearchBot への Markdown 応答を示す Radar のデータがありますが、応答が存在することを示すだけで、クローラーが要求している証拠ではなく、OpenAI も文書化していません。当サイトは断定しません。文書で確認できるのは、一部のエージェントがすでに要求していることです。
コンテントネゴシエーションの仕組み:Accept・Vary・Content-Type
コンテントネゴシエーションは HTTP の古くからある仕組みです。1つのアドレスに複数の表現があり、クライアントが好みを伝えます。全体を支えるのは3つのヘッダーです。
| ヘッダー | 送る側 | 意味 |
|---|---|---|
Accept | クライアント(リクエスト) | 欲しいコンテンツタイプ。重み(q=0.8)を付けることもある |
Content-Type | サーバー(レスポンス) | サーバーが実際に送ったもの。ここでは text/markdown; charset=utf-8 |
Vary: Accept | サーバー(レスポンス) | 応答が Accept に依存するので、キャッシュは版を混ぜてはいけない |
ブラウザーはまず text/html を挙げ、予備としてワイルドカードの */* を加えます。Markdown が欲しいエージェントは、Accept: text/markdown や Accept: text/markdown, text/html;q=0.8 のように明示します。Cloudflare は、Claude Code や OpenCode といった一般的なコーディングエージェントが、すでにこの種の Accept ヘッダーを送っていると書いています。
全員を守るルールは単純です。text/markdown が明示され、かつ text/html より低く評価されていないときだけ、Markdown で応答します。ワイルドカードの */* は決して数えません。そうしないと、何でも受け付けるブラウザー、リンクチェッカー、SNS のプレビュー用ボットまでが Markdown を受け取ってしまいます。
Cloudflare で AIエージェント Markdown 配信を有効にする
2026年2月12日、Cloudflare が Markdown for Agents を発表しました。ゾーンで有効にすると(ベータ版で、Pro・Business・Enterprise プランでは追加費用なしです)、Accept: text/markdown 付きのリクエストには、HTML がその場で Markdown に変換されて返ります。オリジンサーバーは変更不要です。発表のサンプル応答は、期待できるヘッダーを示しています。
content-type: text/markdown; charset=utf-8
vary: accept
x-markdown-tokens: 725
content-signal: ai-train=yes, search=yes, ai-input=yes
すでにこれらのプランで Cloudflare の背後にあり、変換結果も問題なければ、これが最短です。頼る前に、curl で結果を確認してください(後述)。Markdown 版の内容を自分で完全に管理したい場合や、別の環境で動かしている場合は、自分で実装します。
自分で実装する:Node の短いコード例
次のスケッチには、上のルールが入っています。明示的に求められたときだけ Markdown を返すこと、両方の版に Vary: Accept を付けること、ネゴシエーションしないクライアント向けの固定アドレス /index.md、そして Markdown 応答のヘッダーに canonical リンクを付けることです。最小限の例であり、本番用のコードではありません。
import http from 'node:http';
import { readFileSync } from 'node:fs';
function wantsMarkdown(accept = '') {
const weight = new Map();
for (const part of accept.toLowerCase().split(',')) {
const [range, ...params] = part.trim().split(';');
const q = params.find((p) => p.trim().startsWith('q='));
weight.set(range.trim(), q ? Number(q.trim().slice(2)) : 1);
}
const md = weight.get('text/markdown') ?? 0;
const html = weight.get('text/html') ?? weight.get('text/*') ?? weight.get('*/*') ?? 0;
return md > 0 && md >= html; // ワイルドカードだけでは Markdown を選ばない
}
http.createServer((req, res) => {
if (req.url === '/index.md' || (req.url === '/' && wantsMarkdown(req.headers.accept))) {
res.writeHead(200, {
'Content-Type': 'text/markdown; charset=utf-8',
'Vary': 'Accept',
'Link': '<https://example.com/>; rel="canonical"',
});
return res.end(readFileSync('index.md'));
}
if (req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', 'Vary': 'Accept' });
return res.end(readFileSync('index.html'));
}
res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' }); // それ以外のアドレスはすべて 404 を返す
res.end('Not found');
}).listen(3000);
注目したい点が3つあります。
- 両方の版に Vary を付ける。 HTML の応答にも
Vary: Acceptが必要です。ないと、共有キャッシュが HTML を保存して、Markdown を求めたエージェントに渡したり、その逆が起きたりします。 - 固定アドレス。
/index.mdは、クライアントが何を送っても必ず Markdown を返します。エージェントも人もリンクでき、ヘッダーを設定できない場面でも使えます。当サイトの seogrinder.com/index.md がこの方式で、トップページではネゴシエーションと固定アドレスの両方を提供しています。ネゴシエーションなら両方の読み手に1つのアドレスで足り、固定アドレスならリンクもテストも簡単です。 - canonical ヘッダー。 Markdown 版は、同じページのもう1つの表現です。Google は、HTML ではないファイルに対して
rel="canonical"を HTTP ヘッダーで送れると文書化しています。Markdown 版がそのページに属することを示す強いシグナルになりますが、保証ではありません(Google)。
Markdown ファイルは手で書くか、HTML と同じ元データから生成します。どちらの場合も、枠組みを除いてページと同じ内容にしてください。
Link ヘッダーと Content-Signal の行
Link レスポンスヘッダーは RFC 8288 で定義されています。関連するアドレスと関係の種類を示すもので、たとえば Link: </llms.txt>; rel="describedby" と書きます。describedby は登録済みの関係で、リンク先のリソースがこのリソースを説明しているという意味です。レスポンスヘッダーを読むクライアントは、本文を解析する前に、サイトの説明がどこにあるかを知ることができます。seogrinder.com はトップページでこのヘッダーを送り、自分の llms.txt を指しています。Markdown 応答では、同じ Link ヘッダーに上で示した canonical の関係もカンマ区切りで入ります。現時点でこのリンクをたどるエージェントがいるかどうかは確認されていません。コストはサーバー設定の1行です。
2025年9月に Cloudflare は、取得したコンテンツでクローラーが何をしてよいかを示す行を、robots.txt 向けに導入しました。
Content-Signal: search=yes, ai-input=yes, ai-train=no
search はインデックスとスニペット、ai-input は AI の回答でのコンテンツの直接利用、ai-train はモデルの学習やファインチューニングを意味します。形式は Cloudflare の発表と contentsignals.org に書かれています。これは宣言であって防壁ではなく、守る義務は誰にもありません。Cloudflare は、Content Signals は好みを表すもので技術的な対抗措置ではなく、無視する企業もありうると述べています。Cloudflare の Markdown のサンプルにも、content-signal レスポンスヘッダーが入っていました。
この行は、AI ボットに関する他のルールと同じく robots.txt に書きます。ボットごとにグループを分けるときの典型的な間違いなどは、AIクローラー robots.txt の設定 にまとめました。seogrinder.com の robots.txt は、すべてのクローラーに共通する1つのグループと9つの AI 識別子を使い、Content-Signal: search=yes, ai-input=yes, ai-train=yes を設定しています。
curl で確認する方法
エージェントが使うのと同じ道具で確認します。-I オプションはヘッダーだけを表示します。
curl -sI -H "Accept: text/markdown" https://example.com/
応答では4点を見ます。ステータス 200、content-type: text/markdown、Accept を含む vary、canonical のアドレスを持つ link ヘッダーです。seogrinder.com での結果を、関係する行だけに短くして示します。
HTTP/2 200
content-type: text/markdown; charset=utf-8
vary: Accept
link: </llms.txt>; rel="describedby"; type="text/plain", <https://seogrinder.com/>; rel="canonical"
次に逆の確認をします。以下はどれも text/html を返さなければなりません。
curl -sI -H "Accept: text/html" https://example.com/
curl -sI -H "Accept: */*" https://example.com/
curl -sI https://example.com/
最後に -H "Accept: text/markdown, text/html;q=0.8" を送ります。Markdown のほうが高く評価されているので、Markdown が選ばれるはずです。
SEOgrinder でのチェック方法
スキャンのあとで SEOgrinder の AI 対応 タブを開きます。「AI エージェント向けのチェック」には7つの行があり、この記事に関わるのは3つです。いずれも「追加」グループにあります。
- HTML ではなくテキストを返す(Markdown Negotiation):
Accept: text/markdown付きのリクエストに Markdown が返れば満たされます。 - エージェントをデータへ導く(Link Headers): レスポンスヘッダーに役立つ関係があるかを調べます。
- コンテンツの用途を宣言する(Content Signals):
ai-train・search・ai-inputをすべて含む、完全なContent-Signalの行を探します。
エージェント用プロンプトをコピー のボタンは、未達の項目では行にそのまま表示され、満たされた項目では行を開くと、見つかった内容とともに表示されます。未達の項目では、プロンプトに作成する内容、curl で見る現状、結果を確認するコマンドが書かれています。満たされた項目では、既存の内容を確認し、必要な部分だけを変え、理解できないルールを削除する前には質問するよう、アシスタントに求めます。AI クローラーの許可や拒否といった判断は、あなたの側に残ります。未達の項目のプロンプトには例として値を提案するものもあるので、先に方針を決め、Claude Code、Cursor、GitHub Copilot、ChatGPT に貼る前に読んでください。そのあと 再チェック を押します。レポートは最大24時間キャッシュされ、このボタンは新しい実行を強制します(1時間に数回まで)。
SEOgrinder は「追加」グループについて率直です。一部のベンダーによる提案であり、Google への効果は確認されていません。また、ChatGPT・Gemini・Perplexity が実際にブランドを挙げるかどうかは測りません。確認するのは技術的な土台、つまり機械がページに到達して読めるかどうかです。
手間をかける価値はあるか
サイトが何を提供しているかによります。ドキュメント、リファレンス、長いガイド、ナレッジベースは、エージェントが具体的な質問に答えるために取得するタイプのコンテンツで、きれいな Markdown 版が役に立ちます。5ページの小さなショップや地域の店舗なら、時間は基本に使うほうが有効です。JavaScript なしで HTML に入っているテキスト、検索用ボットを通す robots.txt、サイトマップです。
Google は、AI による概要や AI モードに表示されるための追加要件も、特別な最適化も必要ないと述べています(Google のドキュメント)。そこでは Markdown 版は要件ではありません。他のアシスタントは違う動きをするかもしれませんが、AI アシスタントがあなたのページを挙げると約束できる人はいません。
よくある間違い
- Vary ヘッダーがない。
Vary: Acceptがないと、キャッシュや CDN が次の訪問者に違う版を返すことがあります。 - ヘッダーを無視するキャッシュが手前にある。 オリジンサーバーだけでなく、公開アドレスを通してテストしてください。
- ブラウザーに Markdown を返す。 チェックがワイルドカード
*/*を Markdown の要求として扱うと、訪問者に生のテキストが見えてしまいます。通常のブラウザーでテストしてください。 - canonical リンクがない。 Markdown 版が別のページとして扱われることがあります。当サイトが
noindexではなく canonical ヘッダーを選んだのは、ネゴシエーションで返す版がページと同じアドレスにあるからです。 - HTML と違うことを書いた Markdown 版。 両者の違いを検索エンジンがどう扱うかを示す出典はないので、枠組みを除いて同じ内容にしておきます。
- 古いままのファイル。 去年の提供内容を並べた手書きの
index.mdは、エージェントを迷わせます。ページの元データから生成してください。 - 空の HTML ページ。 JavaScript が動くまで HTML にテキストがないなら、Markdown では SNS のプレビューなど他のクライアントの問題は解決しません。SEOgrinder は、ブラウザーの中で初めて組み立てられるページを指摘します。
よくある質問
AIエージェント向けの Markdown はランキング要因ですか?
そうだという証拠はありません。機械向けの配信形式であって、順位を上げる手段ではないと考えてください。
ChatGPT、Claude、Perplexity は Markdown を要求しますか?
Cloudflare は、Claude Code や OpenCode などのコーディングエージェントが Accept: text/markdown をすでに送っていると書いています。大手の検索クローラーが要求しているという文書はありません。Radar のデータは OAI-SearchBot への Markdown 応答を示していますが、リクエストヘッダーの証拠にはならず、確認されていません。
Cloudflare は必須ですか?
いいえ。Cloudflare は変換を機能として提供しています(ベータ版、Pro・Business・Enterprise プラン)。上の Node のスケッチのとおり、数行のサーバーコードで足り、同じルールはどのサーバーやフレームワークにも組み込めます。
次の一歩
SEOgrinder で無料スキャンを実行し、AI 対応 タブを開いてください。Markdown、Link Headers、Content Signals の3つの「追加」の行を見て、自分のサイトがエージェントに読まれるタイプかどうかを判断します。読まれるなら、エージェント用プロンプトをコピーし、アシスタントに変更を任せ、curl で結果を確認して、再スキャンしましょう。