AIクローラの制御方法として、robots.txtやHTMLのメタタグはよく知られています。 しかし、HTTPレスポンスヘッダーでクローラに指示を出す方法は、あまり注目されていません。

HTTPヘッダーによる制御は、HTMLファイル以外のリソース(PDF、画像、APIレスポンスなど)にも適用できます。 この記事では、X-Robots-TagとCache-Controlを中心に、AIクローラ向けのHTTPヘッダー設定を解説します。

X-Robots-Tagとは

X-Robots-Tagは、HTTPレスポンスヘッダーで検索エンジンのクローラに指示を出す仕組みです。 HTMLの<meta name="robots">と同じ指示をヘッダーレベルで伝えられます。

メタタグとの違い

観点<meta name="robots">X-Robots-Tag
適用対象HTMLファイルのみすべてのHTTPレスポンス
設定場所HTML内の<head>HTTPレスポンスヘッダー
PDF・画像への適用不可可能
設定の柔軟性ページ単位サーバー設定で一括適用可能

PDFや画像ファイルには<head>タグが存在しないため、メタタグでの制御ができません。 X-Robots-Tagを使えば、PDF資料やホワイトペーパーのインデックスも制御できます。

基本的なディレクティブ

ディレクティブ意味
indexインデックスを許可する
noindexインデックスを拒否する
followリンクをたどることを許可する
nofollowリンクをたどることを拒否する
nosnippetスニペット生成を拒否する
max-snippet:[n]スニペットの最大文字数を指定する

Nginxでの設定例

location /blog/ {
    add_header X-Robots-Tag "index, follow" always;
}

location /admin/ {
    add_header X-Robots-Tag "noindex, nofollow" always;
}

location ~* \.pdf$ {
    add_header X-Robots-Tag "index, follow, max-snippet:200" always;
}

クローラ別のX-Robots-Tag指定

X-Robots-Tagでは、特定のクローラにのみ指示を出せます。 User-Agent名をディレクティブの前に記述します。

X-Robots-Tag: GPTBot: index, follow
X-Robots-Tag: Google-Extended: noindex
X-Robots-Tag: ClaudeBot: index, follow

GEO対策で主要なAIクローラの推奨設定です。

クローラサービス推奨設定
GPTBotOpenAI(学習用)用途に応じて判断
ChatGPT-UserOpenAI(リアルタイム検索)index, follow
ClaudeBotAnthropic用途に応じて判断
PerplexityBotPerplexityindex, follow
Google-ExtendedGoogle Gemini(学習用)用途に応じて判断

「用途に応じて判断」は、学習データとして利用される可能性があるクローラです。 AI検索での引用を優先するならindex, follow、学習利用を拒否するならnoindexを設定します。

Nginxでのクローラ別設定

map $http_user_agent $ai_crawler_robots_tag {
    default                     "index, follow";
    "~*GPTBot"                  "GPTBot: index, follow";
    "~*ChatGPT-User"           "ChatGPT-User: index, follow";
    "~*ClaudeBot"              "ClaudeBot: index, follow";
    "~*PerplexityBot"          "PerplexityBot: index, follow";
    "~*Google-Extended"        "Google-Extended: noindex";
}

server {
    location /blog/ {
        add_header X-Robots-Tag $ai_crawler_robots_tag always;
    }
}

Next.jsでの設定

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

const CRAWLER_POLICIES: Record<string, string> = {
  'GPTBot':         'index, follow',
  'ChatGPT-User':  'index, follow',
  'ClaudeBot':     'index, follow',
  'PerplexityBot': 'index, follow',
  'Google-Extended': 'noindex, nofollow',
}

export function middleware(request: NextRequest) {
  const userAgent = request.headers.get('user-agent') || ''
  const response = NextResponse.next()

  for (const [crawler, policy] of Object.entries(CRAWLER_POLICIES)) {
    if (userAgent.includes(crawler)) {
      response.headers.set('X-Robots-Tag', `${crawler}: ${policy}`)
      break
    }
  }
  return response
}

Cache-ControlヘッダーとAIクローラ

Cache-Controlは直接的にクローラを制御するものではありませんが、間接的に影響します。

ディレクティブAIクローラへの影響
max-age=3600コンテンツ有効期限のヒントになる
no-cache毎回最新のコンテンツ取得を示唆
no-storeキャッシュ禁止(クローラが従うとは限らない)
stale-while-revalidate期限後もキャッシュを利用する期間

ブログ記事の推奨設定です。

Cache-Control: public, max-age=3600, s-maxage=86400, stale-while-revalidate=604800

その他のAIクローラ関連ヘッダー

Last-Modified と ETag

AIクローラは、前回のクロール時のETagやLast-Modifiedの値を保持し、If-None-MatchIf-Modified-Sinceで送信することがあります。 コンテンツ未変更なら304 Not Modifiedが返り、帯域を節約できます。

HTML内の<link rel="canonical">と同等の指示をHTTPヘッダーで行えます。 PDFやAPIレスポンスの正規URL指定に有用です。

Link: <https://example.com/blog/original-article>; rel="canonical"

Content-Type

AIクローラがコンテンツの種類を判定するために参照します。 llms.txtなど特殊なファイルではtext/plain; charset=utf-8を明示します。

包括的な設定例(Nginx)

map $http_user_agent $is_ai_crawler {
    default         0;
    "~*GPTBot"      1;
    "~*ChatGPT"     1;
    "~*ClaudeBot"   1;
    "~*PerplexityBot" 1;
}

server {
    # ブログ記事
    location /blog/ {
        add_header X-Robots-Tag "index, follow" always;
        add_header Cache-Control "public, max-age=3600, s-maxage=86400, stale-while-revalidate=604800" always;
        etag on;
    }

    # PDFファイル
    location ~* \.pdf$ {
        add_header X-Robots-Tag "index, follow, max-snippet:200" always;
        add_header Cache-Control "public, max-age=86400" always;
    }

    # APIエンドポイント
    location /api/ {
        add_header X-Robots-Tag "noindex, nofollow" always;
        add_header Cache-Control "no-store" always;
    }
}

ヘッダー設定の検証方法

# AIクローラのUser-AgentでX-Robots-Tagを確認
curl -sI -A "GPTBot/1.0" https://example.com/blog/test | grep -i "x-robots-tag"

# Cache-Controlを確認
curl -sI https://example.com/blog/test | grep -i "cache-control"

# ETagとLast-Modifiedを確認
curl -sI https://example.com/blog/test | grep -iE "(etag|last-modified)"

よくある問題

ヘッダーの二重設定。 CDNとオリジンの両方でX-Robots-Tagを設定すると、ヘッダーが二重になります。 どちらか一方でのみ設定してください。

CDNキャッシュとクローラ別ヘッダーの競合。 クローラ別にX-Robots-Tagを変えている場合、CDNのキャッシュに最初のリクエスト時のヘッダーが残ります。 多くの場合はクローラ共通のX-Robots-Tagを設定し、個別制御はrobots.txtで行う方が実用的です。

まとめ

HTTPヘッダーによるAIクローラの制御は、HTMLメタタグを補完する手段です。 X-Robots-Tagを使えば、PDF・画像・APIレスポンスなどHTMLファイル以外のリソースもクローラの動作を制御できます。

設定の優先度は以下のとおりです。

  1. robots.txt — サイト全体のクロール許可・拒否
  2. X-Robots-Tag — ファイル種別やディレクトリ単位のインデックス制御
  3. HTMLメタタグ — 個別ページのインデックス制御
  4. Cache-Control — コンテンツの鮮度管理

これらを組み合わせて、AIクローラに「何を読んでよいか」「何を引用してよいか」を正確に伝えてください。