
# 如何在 robots.txt 里放行或拦截 AI 机器人

大多数网站只决定过一次，而且决定得很糟，此后再没回头看过。要么是怕被拿去训练，一慌之下全部拦掉，顺手连带来客户的流量一起掐死；要么干脆什么都不配，任由每个爬虫按自己方便的方式去猜。

合理的立场有三种。下面是每一种对应的文件，以及那些会让它们前功尽弃的错误。

## 先说决定一切的那个区别

AI 公司跑的代理有两类，两者不能互相替换。

**爬虫**按自己的节奏批量收页面，通常是为了训练或建索引：`GPTBot`、`ClaudeBot`、`PerplexityBot`、`CCBot`、`Bytespider`、`Google-Extended`、`Applebot-Extended`。

**按需抓取器**只取一个页面，因为刚刚有人就这个页面提了问：`ChatGPT-User`、`Claude-User`、`Perplexity-User`。这次请求没人在训练任何东西，是有个人在等一句关于你的答案。

拦住前一类，是关于你内容的生意决定。拦住后一类，更接近于把一个手动输入你网址的访客挡在门外。你会读到的那些「把 AI 全拦了」的建议，基本不区分这两者。

## 情况一 —— 放它们进来

凡是希望被找到的东西，这就是正确的默认值：文档、想要被署名引用的媒体、想被推荐的商家。

```
User-agent: *
Allow: /
Disallow: /admin/
Disallow: /cart/
Disallow: /*?session=

Content-Signal: search=yes, ai-input=yes, ai-train=no

Sitemap: https://example.cn/sitemap.xml
```

看清楚它说了什么：进来吧，收录我，拿我去回答问题，但别拿我训练。这个立场光靠 robots.txt 表达不出来，所以才有后面的 Content-Signal 那一节。

## 情况二 —— 回答可以，训练不行

多数企业真正想要的就是这一种，而几乎没人把它配对。

```
User-agent: GPTBot
Disallow: /

User-agent: ClaudeBot
Disallow: /

User-agent: CCBot
Disallow: /

User-agent: Bytespider
Disallow: /

User-agent: Google-Extended
Disallow: /

User-agent: Applebot-Extended
Disallow: /

User-agent: OAI-SearchBot
Allow: /

User-agent: Claude-SearchBot
Allow: /

User-agent: PerplexityBot
Allow: /

User-agent: ChatGPT-User
Allow: /

User-agent: Claude-User
Allow: /

User-agent: Perplexity-User
Allow: /

User-agent: *
Allow: /

Content-Signal: search=yes, ai-input=yes, ai-train=no

Sitemap: https://example.cn/sitemap.xml
```

关于这份文件有两点值得知道。`Google-Extended` 管的是 Gemini 的训练，**不是** Google 搜索，拦掉它不影响你的搜索排名。`Applebot-Extended` 是同样的道理，它对应 Apple Intelligence，和支撑 Siri 与 Spotlight 的 `Applebot` 是两回事。

## 情况三 —— 彻底拦住 AI

对付费墙后的档案、有授权的素材，以及任何你卖的是访问权的内容，这么做站得住脚。

```
User-agent: GPTBot
User-agent: OAI-SearchBot
User-agent: ChatGPT-User
User-agent: ClaudeBot
User-agent: Claude-SearchBot
User-agent: Claude-User
User-agent: PerplexityBot
User-agent: Perplexity-User
User-agent: CCBot
User-agent: Bytespider
User-agent: Google-Extended
User-agent: Applebot-Extended
User-agent: Amazonbot
User-agent: meta-externalagent
Disallow: /

User-agent: *
Allow: /

Content-Signal: search=no, ai-input=no, ai-train=no

Sitemap: https://example.cn/sitemap.xml
```

连着写的 `User-agent` 行共享它们下面的规则。这是合法写法，也比十四个各写各的段落好维护得多。

选之前先想清楚代价：你会从 AI 的回答里消失。有人向助手打听你这个行业时，被点名的是你的竞争对手，不是你。

## 那些错误

**只有最具体的那一组会生效。** 爬虫一旦匹配到自己的名字，就会完全无视 `User-agent: *`。所以下面这段并不像看上去那样管用：

```
User-agent: *
Disallow: /private/

User-agent: GPTBot
Disallow: /
```

`GPTBot` 确实被全站拦下了，但其他机器人只读 `*` 那一组；而且哪天你在 `GPTBot` 下面加一条 `Allow`，`/private/` 对它就不再有任何保护，因为那一组从头到尾没提过 `/private/`。

**空行是分组的分隔符。** 一组中间的空行会把这组就此结束，后面的行在下一个 `User-agent` 出现之前不属于任何人。

**`Disallow:` 后面什么都不写，意思是全部允许。** `Disallow: /` 才是全部拦住。开着的门和关上的门，差一个字符。

**robots.txt 不是访问控制。** 它是一个请求，守规矩的爬虫会照办。不守规矩的抓取器过去无视它，以后也照样无视。真正不能被读到的东西需要的是身份验证，不是一条指令。

**`Crawl-delay` 基本被 AI 爬虫忽略。** 如果问题出在负载，就在边缘做限流。

## Content-Signal：说清用途，而不只是能不能

robots.txt 只回答一个问题：这个你能不能抓。它没有办法表达「可以收录我，但别拿我训练」，而这恰恰是大多数网站真正的立场。

`Content-Signal` 用三个互相独立的信号补上这一层：

```
Content-Signal: search=yes, ai-input=yes, ai-train=no
```

- `search` —— 这些内容能否出现在搜索索引里
- `ai-input` —— 能否作为生成答案的材料，并注明出处
- `ai-train` —— 能否用来训练模型

它像上面那样写进 robots.txt，也可以作为 HTTP 响应头随每个响应一起发出，我们就是这么做的。这是个年轻的约定，不是谁有义务遵守的标准，但它只占一行、机器能读，而且表达了 `Disallow` 表达不了的意图。

## 确认你的那份真的送到了

写好文件和把它发出去，是两码事：

```bash
curl -s https://example.cn/robots.txt
curl -sI https://example.cn/robots.txt | grep -i "server\|cf-cache-status"
```

第二条命令比看上去重要。如果你在 CDN 后面，而自己没有一份 robots.txt，CDN 可能会替你回答一份你从没写过的文件：一个看着很像样的 `200`，里面没有你的任何一条规则，也没有你的 sitemap。我们的就这样持续了好几个月，而源站那边一直返回 `404`。

[生成你的 robots.txt](/zh/tools/robots-txt-generator) · [检查你实际发出的那份](/zh/tools/robots-txt-checker) · [机器人被允许了吗](/zh/tools/ai-crawlers-checker)
