·8分で読める

Ruby on RailsでAIクローラーをブロックする実装方法

Ruby on RailsアプリケーションでGPTBot・ClaudeBot等のAIクローラーをブロックする方法を、before_action・Rack Middleware・robots.txtの観点から解説します。

Ruby on RailsRubyAIクローラーMiddlewareブロック

Ruby on RailsでAIクローラーをブロックする実装方法

RailsでのAIボットブロックアプローチ

Ruby on RailsアプリケーションでAIクローラーをブロックするには、主に3つのアプローチがあります:

  1. Rack Middleware(全リクエストに適用、最も効率的)
  2. ApplicationController の before_action(Railsレイヤーでの制御)
  3. robots.txtのルーティング(ファイルベース設定)

方法① Rack Middlewareでブロック(推奨)

Rack MiddlewareはRailsより手前で動くため、パフォーマンスが最も良い方法です。

lib/middleware/ai_bot_blocker.rb を作成

module Middleware
  class AiBotBlocker
    AI_BOT_PATTERN = /GPTBot|OAI-SearchBot|ClaudeBot|anthropic-ai|
                      PerplexityBot|Google-Extended|Amazonbot|
                      Bytespider|CCBot|cohere-ai|MistralBot|Diffbot/xi

    def initialize(app)
      @app = app
    end

    def call(env)
      user_agent = env["HTTP_USER_AGENT"] || ""

      if AI_BOT_PATTERN.match?(user_agent)
        [403, { "Content-Type" => "text/plain" }, ["Forbidden: AI crawlers are not permitted"]]
      else
        @app.call(env)
      end
    end
  end
end

config/application.rb または config/environments/production.rb に追加

config.middleware.use Middleware::AiBotBlocker

方法② ApplicationController の before_action

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  AI_BOT_PATTERN = /GPTBot|OAI-SearchBot|ClaudeBot|anthropic-ai|
                    PerplexityBot|Google-Extended|Amazonbot|
                    Bytespider|CCBot|cohere-ai/xi

  before_action :block_ai_bots

  private

  def block_ai_bots
    ua = request.user_agent || ""
    if AI_BOT_PATTERN.match?(ua)
      render plain: "Forbidden", status: :forbidden
    end
  end
end

特定のコントローラーのみに適用する場合:

# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  before_action :block_ai_bots, only: [:show, :index]

  def show
    @article = Article.find(params[:id])
  end
end

方法③ robots.txtのルーティング設定

静的ファイルとして設置

最もシンプルな方法は public/robots.txt を編集することです:

User-agent: GPTBot
Disallow: /

User-agent: ClaudeBot
Disallow: /

User-agent: PerplexityBot
Disallow: /

User-agent: Google-Extended
Disallow: /

User-agent: Amazonbot
Disallow: /

User-agent: Bytespider
Disallow: /

User-agent: *
Allow: /

動的生成(Railsルーティング)

# config/routes.rb
Rails.application.routes.draw do
  get "robots.txt", to: "robots#index", format: false
  # ...
end

# app/controllers/robots_controller.rb
class RobotsController < ApplicationController
  skip_before_action :block_ai_bots  # robots.txtはブロックしない

  def index
    @ai_bots = %w[GPTBot OAI-SearchBot ClaudeBot anthropic-ai
                   PerplexityBot Google-Extended Amazonbot Bytespider CCBot]
    render plain: generate_robots_txt, content_type: "text/plain"
  end

  private

  def generate_robots_txt
    lines = @ai_bots.map { |bot| "User-agent: #{bot}
Disallow: /
" }
    lines << "
User-agent: *
Allow: /
"
    lines << "Sitemap: #{request.base_url}/sitemap.xml"
    lines.join("
")
  end
end

Sinatraでの実装

require "sinatra"

AI_BOT_PATTERN = /GPTBot|ClaudeBot|PerplexityBot|Google-Extended|Amazonbot/i

before do
  user_agent = request.user_agent || ""
  if AI_BOT_PATTERN.match?(user_agent)
    halt 403, "Forbidden"
  end
end

get "/" do
  "Hello World"
end

動作確認とテスト

# RSpecでのテスト例
# spec/middleware/ai_bot_blocker_spec.rb
require "rails_helper"

RSpec.describe Middleware::AiBotBlocker do
  let(:app) { ->(env) { [200, {}, ["OK"]] } }
  let(:middleware) { described_class.new(app) }

  context "AIボットのUser-Agentの場合" do
    it "403を返す" do
      env = { "HTTP_USER_AGENT" => "GPTBot/1.0" }
      status, _, _ = middleware.call(env)
      expect(status).to eq(403)
    end
  end

  context "通常ブラウザのUser-Agentの場合" do
    it "200を通す" do
      env = { "HTTP_USER_AGENT" => "Mozilla/5.0 Chrome/124" }
      status, _, _ = middleware.call(env)
      expect(status).to eq(200)
    end
  end
end

Heroku・Renderへのデプロイ時の注意

HerokuやRenderでデプロイする場合、ミドルウェアスタックは本番環境でも同様に動作します。追加設定は不要です。

さらにAIアクセスを可視化したい場合は、AI Access MonitorのトラッキングコードをRailsのapplication.html.erbに追加してください:

<!-- app/views/layouts/application.html.erb -->
<%= javascript_include_tag "https://monitor-api.microforge.works/agent.js",
    "data-site-id": ENV["MONITOR_SITE_ID"], async: true %>

まとめ

RailsでのAIボットブロックはRack Middlewareを使うのが最も効率的です。before_actionよりも手前でリクエストを処理できるため、不要なRailsスタック処理を省けます。

AI Access Monitor

まず計測から始めよう

1行のコード追加で、AIクローラーの計測を今日から開始。無料・設定不要。

無料で始める →