全部文章

一个 AI 代理刚刚访问了你的网站,你怎么确认它是真的?

写着 GPTBot 的 User-Agent 什么也证明不了。本文说明如何真正验证 AI 代理:官方公布的 IP 段、反向 DNS 与 ASN 核对,以及如何为验证不通过的流量分类。

2026年8月12日阅读约 11 分钟

一个 AI 代理刚刚请求了一个页面,日志里写着 GPTBot/1.2。这串文字并不是证据。User-Agent 由客户端 自行写入,任何人都能发送,因此验证 AI 代理唯一可靠的途径,是核对它发起连接所用的地址。真正起作用的 检查只有三种:把来源 IP 与运营方公布的 IP 段文件比对、执行正向确认的反向 DNS 查询,或确认该 IP 由运 营方自己的 ASN 通告。

究竟适用哪一种,完全取决于运营方,而这正是麻烦所在。OpenAI 按 bot 分别公布 JSON 格式的 IP 段文件; Anthropic 只公布一个前缀文件,同时覆盖 ClaudeBot、Claude-User 与 Claude-SearchBot;Apple 既支持反向 DNS,也提供 IP 段文件;Meta 两者都不提供,默认由你自行核对 AS32934。还有相当一部分爬虫什么都不公布, 此时请求头里的名字只是装饰,你只能依据来源与行为做判断。

声称不花钱,核验才花钱

不妨想想「User-Agent 含有 GPTBot 就跳过机器人规则」这样一条放行规则究竟意味着什么。它等于宣布:任何 愿意敲下九个字符的客户端,都能获得你原本只留给可信爬虫的待遇。爬虫会读你的 robots.txt,看清楚你欢迎 哪些代理,然后照着打扮。这种冒充谈不上高明,只是成本极低,而且对任何从不看请求头以外信息的站点都有效。

核验的代价则要高得多。你需要运营方当前的 IP 段、一个 DNS 解析器或路由数据,逐家维护,并在对方变更时 同步更新。已经有研究者报告过自称 PerplexityBot、却来自 Perplexity 公布范围之外地址的流量。这正是典型 的失效场景:名字是借来的,网络不是。

查询某个代理请求实际来自哪个网络

每一家运营方的文档都不一样

这件事没有统一标准,验证只能逐家查。以下是AI 爬虫目录中的一部分,该目录收录了 150 个代理:

代理运营方公布内容验证方式
GPTBotOpenAIopenai.com/gptbot.json比对 IP 段,无反向 DNS 约定
ClaudeBotAnthropicclaude.com/crawling/bots.json比对 IP 前缀,一个文件覆盖 Anthropic 全部 bot
PerplexityBotPerplexityperplexitybot.json比对 IP 段,已出现冒充案例
ApplebotAppleIP 段文件与 rDNS反向 DNS 解析至 applebot.apple.com,并正向确认
AmazonbotAmazon反向 DNS 约定正向确认的反向 DNS,无 IP 段文件
Meta-ExternalAgentMeta未按 bot 公布确认该 IP 由 AS32934 通告
BytespiderByteDance无法验证,且无视 robots.txt
CCBotCommon Crawl无可用信息无法验证,运行在租用的云资源上
Google-ExtendedGoogle仅 robots 令牌无从验证,它从不作为 User-Agent 出现

Google-Extended 值得多看一眼,因为它打破了常见的认知模型。它是一条用于退出 Gemini 训练的 robots.txt 指令,而不是爬虫。如果收到自称 Google-Extended 的请求,那按定义就是伪造的,因为根本不存在真实版本。

目录收录的 150 个代理中,有 33 个提供了可用的核验方式,即公布的 IP 段、反向 DNS 或 ASN;有 9 个被明 确记录为无视 robots.txt。其余则处于中间地带:只有一个名字,没有任何东西为它背书。

冒充在日志里长什么样

两条请求,请求头完全相同,相隔几分钟:

198.51.100.7  "Mozilla/5.0 ...; compatible; GPTBot/1.2; +https://openai.com/gptbot"
203.0.113.44  "Mozilla/5.0 ...; compatible; GPTBot/1.2; +https://openai.com/gptbot"

单看日志行毫无差别。把地址解析出来,差别立刻显现:一个落在 OpenAI 公布的出口 IP 段内,另一个由一家按 小时出租服务器的主机商通告。后者还在九十秒内请求了 400 个商品页,且从未加载任何样式表,而遵守自身公布 抓取配额的爬虫不会这样做。

同样的模式在各家运营方身上反复出现:来自 VPS 网段的假 ClaudeBot;PTR 记录指向主机商域名、甚至根本没有 PTR 记录的假 Applebot;PTR 看起来合理、但正向解析却返回另一个地址的假 Amazonbot,而正向确认这一步存在 的意义正在于此。每一次,请求头都完全吻合,网络却对不上。

已验证、无法验证与恶意,是三种不同的答案

一旦不再把请求头当作证据,流量就会分成几类需要区别对待的群体,而一个二元的机器人标记无法表达这种差异。

已验证的 AI 爬虫属于策略选择:放行、计费,或按名称拦截,因为你不希望内容进入那份语料。声称某个身份却 未通过 IP 核验的请求则不是策略问题,而是伪造,绝不应继承真实代理所享有的访问权限。完全没有公布任何信息 的爬虫无法验证,需要的是限速而不是判定。至于来自数据中心网段、 根本不声称任何 bot 名称的无头浏览器,恰恰是你的放行名单从未关注过的那一类。

正因如此,Agentscan 返回的是类别而非布尔值。每个请求都会得到 humanknown_botai_agentmalicious_automation 之一,并附带置信度以及形成该判定的各项信号。

伪造 User-Agent 也骗不过的信号

IP 来源能回答大部分问题,但不是全部。代理可以运行在住宅地址上,爬虫也可以租一个没有历史记录的干净 IP。 当请求头说谎时,还有三类信号站得住脚:

JA4 TLS 指纹。 客户端在发送第一个请求头之前,就已经暴露了自己如何进行 TLS 交握:加密套件顺序、扩展、 ALPN、版本。一个自称 Chrome 124 的 Python 脚本,产生的握手特征是任何 Chrome 版本都不会产生的。请求头是 声称,握手是行为。

无头浏览器痕迹。 webdriver 标记、缺失的浏览器接口,以及 Playwright、Puppeteer 或原生 HeadlessChrome 留下的自动化标记。单独看每一项都很弱,但与数据中心来源叠加,画面就不再含糊。

请求头一致性。 真实浏览器会成组发送 Accept、Accept-Language 与 Accept-Encoding,顺序稳定,并与所声称 的版本相符。手工构造的请求对象往往只发送其中一部分,而这些缺口足够规律,可以作为信号使用。

任何一项信号都不足以单独定案,这正是关键所在。只有把它们融合起来,才能把已验证的爬虫与技术娴熟的冒充者 区分开,并把两者与普通访客区分开。同样的叠加逻辑也适用于更早的爬虫,详见 如何验证 Googlebot

一套经得起真实流量考验的策略

验证只有在之后产生动作时才有意义。一个可行的默认方案:

  1. 在任何放行规则生效之前,先按该运营方的方法核验身份。 IP 段文件、反向 DNS 还是 ASN,取决于对方公布 了什么。
  2. 核验失败不是模糊信号。 自称 ClaudeBot 却来自 Anthropic 前缀之外的请求就是冒充。按未知爬虫处理, 而不是当作有待商榷的情况。
  3. 按用途拆分放行决策。 训练爬虫、AI 搜索爬虫与助手取页请求应各有规则。拦截搜索爬虫会让你从该引擎 引用的答案中消失,这是流量决策,不是安全决策。
  4. 对无法验证的流量限速。 对 Bytespider、CCBot 以及其他未公布核验方式的代理,名字说明不了任何问题, 但请求频率、路径模式与来源能说明很多。
  5. 记录类别,而不只是拦截数。 知道 AI 代理流量上个月增长了两倍,比一个拦截计数器有价值得多,尤其是 在你还要决定把哪部分变现的时候。

Agentscan 通过一次 POST /v1/agentscan/check 完成上述工作:经反向 DNS 验证的放行名单、公布 IP 段比对、 IP 来源、无头标记与 JA4 全部在一次调用中处理,并带缓存,重复查询在 50 毫秒内返回。这个速度足以放进中间件, 而不必留给夜间的日志复盘。

总结

你无法凭一个代理的自称来验证它。把来源 IP 与运营方真正公布的信息比对,把核验失败视为伪造,再用 JA4、 无头痕迹与 IP 来源去判断放行名单无法担保的其余流量。问题从来不是「这是不是机器人」,而是刚刚到达的属于 四类流量中的哪一类,以及你打算如何对待每一类。

常见问题

常见问题解答

核对来源 IP,绝不要相信 User-Agent。具体做法取决于运营方:将 IP 与官方公布的 IP 段文件比对(OpenAI 公布 gptbot.json,Anthropic 用一个前缀文件覆盖旗下全部 bot)、执行正向确认的反向 DNS 查询(Applebot、Amazonbot),或确认该地址由运营方的 ASN 通告(Meta 使用 AS32934)。如果运营方三者都未公布,那么这个身份声明根本无法验证。

相关文章