Ruby on RailsでAIクローラーをブロックする実装方法
RailsでのAIボットブロックアプローチ
Ruby on RailsアプリケーションでAIクローラーをブロックするには、主に3つのアプローチがあります:
- Rack Middleware(全リクエストに適用、最も効率的)
- ApplicationController の before_action(Railsレイヤーでの制御)
- 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スタック処理を省けます。