网站正在面对一种新的访问者:它们不是传统用户,也不完全是搜索引擎。AI 搜索需要抓取页面生成答案,智能体会替用户完成任务,训练爬虫则把内容带进模型语料。新的 AI 流量选项把这些访问拆成 Search、Agent、Training 三类,并允许站点对广告变现页面做额外保护。重点不是“全放”或“全挡”,而是让站点所有者按页面价值和业务目标定规则。
三类 AI 流量,应该用三套策略
传统 robots.txt 只能表达比较粗的允许或拒绝。现在更实用的做法是按访问意图分层:
- Search bots:服务搜索发现和答案索引。很多站点愿意开放公开内容,因为它可能带来品牌曝光和回流。
- Agent bots:代表用户执行动作,例如读取文档、比较商品、整理资料。它们可能有真实用户意图,但访问频率和路径更像自动化程序。
- Training bots:用于模型训练或数据集构建。它们对站点即时流量贡献有限,却可能复制内容价值。
这三类流量的风险不同。搜索流量要关注可见性,智能体流量要关注速率和权限边界,训练流量则要关注版权、许可和商业价值流失。
广告变现页面为什么需要单独保护
广告页面的商业模型依赖真实曝光、点击和用户会话。如果 AI 机器人大量抓取这类页面,可能带来三个问题:
- 广告库存被非人类访问消耗,影响报表质量。
- 页面内容被摘要后,用户不再访问原站,广告收入减少。
- 自动化访问改变缓存、限流和分析系统的判断。
因此,把“是否广告变现”作为规则条件很合理。新闻、评测、教程、论坛帖等页面可以按路径或标签区分:公开摘要可以让搜索机器人访问,但训练流量和高频智能体访问需要更严格的门槛。
可以这样实践:在边缘或应用层先建一张策略表
下面是一个可运行的最小 Flask 示例。它假设你的 CDN、WAF、反向代理或边缘函数已经把机器人分类写入 X-Bot-Class 请求头,取值为 search、agent、training 或空值。实际接入时,可以把这个头替换成平台提供的 bot 分类字段。
先安装依赖:
python -m venv .venv
source .venv/bin/activate
pip install flask
创建 app.py:
from flask import Flask, request, abort, jsonify
app = Flask(__name__)
POLICY = {
"search": {
"allow_prefixes": ["/", "/blog", "/docs"],
"block_prefixes": ["/account", "/checkout"],
},
"agent": {
"allow_prefixes": ["/docs", "/help"],
"block_prefixes": ["/account", "/checkout", "/ads"],
},
"training": {
"allow_prefixes": ["/open-data"],
"block_prefixes": ["/", "/blog", "/docs", "/ads"],
},
}
AD_MONETIZED_PREFIXES = ["/news", "/reviews", "/ads"]
def starts_with_any(path, prefixes):
return any(path == prefix or path.startswith(prefix + "/") for prefix in prefixes)
@app.before_request
def enforce_ai_traffic_policy():
bot_class = request.headers.get("X-Bot-Class", "").lower()
path = request.path
if not bot_class:
return
if bot_class not in POLICY:
abort(403, description="Unknown automated traffic class")
rule = POLICY[bot_class]
if starts_with_any(path, rule["block_prefixes"]):
abort(403, description=f"{bot_class} bots are not allowed here")
if starts_with_any(path, AD_MONETIZED_PREFIXES) and bot_class in {"agent", "training"}:
abort(403, description="Ad-monetized pages are protected")
if not starts_with_any(path, rule["allow_prefixes"]):
abort(403, description=f"{bot_class} bots are outside allowed areas")
@app.get("/")
def home():
return jsonify(page="home", status="ok")
@app.get("/docs/<path:name>")
def docs(name):
return jsonify(page="docs", name=name)
@app.get("/news/<path:name>")
def news(name):
return jsonify(page="news", name=name, monetized=True)
@app.get("/open-data/<path:name>")
def open_data(name):
return jsonify(page="open-data", name=name)
if __name__ == "__main__":
app.run(port=8080, debug=True)
运行并测试:
python app.py
curl -i -H 'X-Bot-Class: search' http://127.0.0.1:8080/docs/start
curl -i -H 'X-Bot-Class: agent' http://127.0.0.1:8080/news/today
curl -i -H 'X-Bot-Class: training' http://127.0.0.1:8080/open-data/sample
预期结果是:搜索机器人可以访问文档;智能体访问广告变现新闻页会被拒绝;训练机器人只能访问明确开放的数据区。这个例子不是某个平台的专有 API,而是一种容易迁移到 CDN 规则、WAF、自建网关或应用中间件的策略模型。
把规则写清楚,比“屏蔽 AI”更重要
落地时建议从一张表开始,而不是直接全站封禁:
- 列出页面类型:公开内容、登录内容、交易流程、广告变现页、开放数据。
- 为每类 AI 流量定义默认动作:允许、拒绝、限速、挑战或只允许部分路径。
- 对高价值内容加独立规则,不要只依赖全局配置。
- 监控命中率、403 比例、缓存变化和广告报表异常。
- 定期复审,因为 AI 爬虫的用途和身份声明会持续变化。
这次变化的价值在于把控制权还给站点:搜索可以继续发现内容,智能体可以在安全边界内帮用户工作,训练抓取则必须接受更明确的许可边界。对内容站来说,这不是一次单纯的安全配置更新,而是一次内容分发策略的重新定价。