robots.txt 管得住与管不住:它是许可声明不是访问控制|洹拓科技

一、先承认它的性质:声明不是闸门
抓取声明与访问控制的差别,落在一个具体问题上:谁在什么时机会看到这条规则。访问控制在请求到达服务端时判定,判定发生在对方取到内容之前,不通过就没有内容;抓取声明是一份公开文件,靠对方在抓取前先读一次并自愿按它行动。前者的执行者是我们,后者的执行者是对方。
这个差别直接决定了它无法约束已持有权限的客户端。一个客户端能不能取到某个资源,取决于服务端是否认它拿到的凭据、该路径是否在公开可达范围内,而与它是否读过那份声明无关。把声明当闸门用,会出现一种很典型的事故形态:某类内容被认为“已经在声明里禁掉了”,于是省掉了鉴权,实际暴露面由对方是否自觉来决定。
我们的立场是:声明只负责表达许可范围,可达性与鉴权负责实际边界。两层各自成立,任何一层不能替另一层说话。这条判断决定了下面所有做法的顺序——先定分档,再写声明,最后核验。
二、三条管不住,各对应一条真实暴露路径
它管不住的三类情形,每一类都有具体的暴露路径,应对动作也各不相同。共同点是:应对都不是“再补一条规则”。
| 管不住的情形 | 真实暴露路径 | 应对层次 |
|---|---|---|
| 不遵守协议的抓取方 | 直接按路径请求,不读取声明 | 可达性与授权层设计 |
| 已流出并被第三方留存的内容 | 副本、摘要、存档在各处独立存在 | 撤回请求路径与留痕 |
| 不经过爬虫的获取方式 | 授权接口、第三方平台分发、缓存与聚合服务、人工复制 | 对外接口字段最小化与授权范围 |
第一类靠可达性设计。判断标准很简单:假设对方完全不读声明,这个路径还能不能拿到内容。拿到就属于暴露面问题,改声明无用;要改的是资源的可达方式与鉴权归属。非常规路径的隐蔽性不是授权手段,靠“猜不到路径”保护的公开文件,本质上和没保护一样。
第二类靠一条走得通的撤回请求路径。已经流出的内容,站方能做的是发起与留痕,不是单方面消除。工程上要有这么一个入口:外部主体可以对我们持有的内容副本提出请求,我们能记录对方是谁、涉及哪些内容、答复了什么、是否二次提出。这一层只讨论“管不住已流出内容,所以要留一条可发起、可记录的通道”;至于内容通过哪些条款被授权流转、外部副本台账怎么建,是另一个层面的议题,不在这篇里重复。
第三类靠字段与范围。接口返回的每一个字段都是暴露面的一部分,凡是下游用不到的字段都要能说明为什么带上。授权范围要按用途写而不是按渠道写:同一个渠道承接两种用途时,按渠道写的范围会失效。分发与聚合渠道带来的内容出现,通常不经爬虫,因此也不受声明约束。
三、三种声明的作用对象不能混
站方手上其实有三份不同层面的表达,把它们混为一谈,客户问“我们屏蔽了 AI 吗”就答不上来,因为这句话至少要分成“对哪一类访问方、在哪一层、由谁执行”。
| 声明形式 | 作用对象 | 约束内容 | 由谁执行 | 常见失效方式 |
|---|---|---|---|---|
| 面向搜索引擎的抓取声明 | 会读取该文件的自动化访问方 | 哪些路径可被抓取 | 访问方自行 | 对方不读取 |
| 面向大模型的内容说明文件 | 按该文件约定取数与引用的模型侧访问方 | 内容用途与引用意愿的说明 | 对方策略 | 对方不识别该文件,或不纳入自身策略 |
| 页面级元标签 | 解析该标记的特定访问方与呈现环节 | 单页在索引、摘要、转发上的意愿 | 解析方 | 标记缺失,或与站点级表达不一致时被忽略 |
本站同时维护前两类文件,二者作用对象与约束力不同:抓取声明解决“可以抓哪些路径”,内容说明文件解决“抓到之后希望怎么用”。后者连“抓到之后”这件事都要靠对方自愿,约束力比前者更弱一层。所以对外表述时不能把两者合并成一句“我们做了抓取限制”,也不能把元标签当作前两者的补充细则。
三者的关系可以这样记:抓取声明管路径,内容说明管用途,元标签管单页例外。三者出现冲突时,以哪一份为准要写在自己的运维约定里,否则同名内容在不同访问方那里会得到不同结论。
四、粒度陷阱与默认策略
声明的写法有三种粒度:文件级、目录级、路径级。粒度粗细不是风格选择,它决定了误伤和漏禁同时增加还是减少。目录级一条规则覆盖整棵子树,最容易出的问题是子树里混进一个需要被引用的页面;路径级精确但条目多,条目一多就没人复核实际效果。
更要紧的是默认策略。只写“这些不给抓”而不写“其余是否允许”,默认值就由对方解释,而不是由我们解释。不同访问方对默认值的处理并不一致,这类不一致不会报错,只会静默地改变暴露面。所以默认策略要显式写出来,让声明自身成为一个完整表达,而不是一串例外。这里也要诚实一句:把默认写成拒绝,对不读声明的一方没有强制力,它只让愿意遵守的一方有明确依据。
还有一个维护问题。多访问方分组时,更具体的分组与通用分组之间存在覆盖关系,改一条容易抵消另一条。我们的做法是维护一张三列对照:这条规则想达成什么意图、实际写在声明里的片段是什么、复核看到的是哪一处。没有这张对照,声明会变成只增不减的历史堆栈,等到需要说明“某段内容为什么可抓”时,没有人能从一堆条目里复原出当时的意图。
五、被引用是业务目标时,分档而不是一刀切
洹拓的业务里包含让内容被大模型引用与检索到,所以“全部屏蔽”不是答案,它会把获客侧的收益一起切掉。可行的做法是按页面类型分档,而不是一页一议。
| 档位 | 适用页面类型 | 配套技术动作 | 无法验证的部分 |
|---|---|---|---|
| 可引用 | 面向公众的解释性文章、公开产品说明 | 保持可抓,稳定标识与可摘引结构 | 对方是否真的引用、引用是否准确 |
| 可摘要不可长期留存 | 时效性内容、活动页、阶段结论 | 在两份声明文件里表达留存意愿,控制索引面 | 留存多久由对方系统决定,站方看不到 |
| 不可用 | 内部文档、客户交付物、含个人信息的页面 | 不放在公开可达路径,靠鉴权与接口范围,而不是靠声明 | 是否已被复制走,只能靠核验发现 |
分档要落到可维护的归属关系上:每类页面有唯一档位,档位变更要有记录,一次规则改动要能说明它影响了哪些页面类型。做不到这三点,分档就只是文档里的一张表,改内容时没人记得查它。
第三档最容易被误解。不可用档的技术动作里,声明只是附属项,主力是可达性与鉴权:内容压根不放在公开可取的路径上,也不出现在任何对外接口的返回字段里。把不可用档做成“在声明里禁掉”,等于把最敏感的内容交给对方自觉去保护。反过来,第一档也不能只做“不禁止”,还需要页面结构本身便于被准确摘引,这属于内容工程而不是声明工程。
六、三条核验路径与对外答复口径
既然规则的实际效果取决于对方是否自愿,核验就不能只看我们写了什么。三条路径各自有判定方式与触发口径。
- 服务端是否真的对未授权获取返回受限。判定方式:由站方自身以未授权身份直接请求不可用档资源,不依赖那份声明被读取,期望得到的是受限响应而不是内容正文。只看声明文件的文本不算核验,那只能证明我们写了什么。触发口径:鉴权逻辑、路由规则与目录结构发生相关变更时各做一次,另设固定的复查节奏。
- 外部是否出现我方内容的副本与摘要。判定方式:用可复核的手段检查站外是否存在我方正文的整段复制或未授权摘要,并核对来源标注。这一条查的是“存在与否”,不讨论对方侧的更新滞后。触发口径:接入新的分发或聚合渠道时必做,存量渠道按抽样轮次回看。
- 引用来源里是否仍带着不该出现的内容。判定方式:在能看到的引用与来源清单里核对档位归属,看不可用档的标题、片段或标识是否出现在引用面。触发口径:每次内容下线或改档后各做一次,并把结果回写进第四节的对照表。
对外沟通的口径要把三条管不住分开说,一句都不能合并。可以复用的答复结构是这四段。
- 结论三句:我们能约束愿意遵守协议的访问方抓哪些路径;我们拦不住不遵守协议的抓取方;我们也拦不住已经流出的内容,以及不经过爬虫的获取方式。
- 我们做了哪三层:按页面类型分档;不可用档靠可达性与授权层;对外接口做字段最小化。
- 核验怎么做:上面三条路径各自的判定与触发口径,能出记录。
- 边界在哪:不承诺对方模型是否删除已用于训练的内容,不承诺外部副本的清除结果,也不承诺引用行为一定发生或一定不发生。
这份口径的价值在于它不给客户错误期待。能承诺的是我们这一侧的行为与证据:声明的现状与粒度、受限响应的实际表现、字段范围、撤回请求通道与留痕。不能承诺的是对方系统内部发生的事情。把两类话混在一起说,短期能把单子签下来,长期一定会在争议时反噬;而这三条核验路径,恰好是我们唯一能够拿证据说话的部分。