llms.txt 无人抓取?从协议原理到日志排查的完整实践指南 开头先还原一个真实场景你在自己站点根目录放了一个llms.txt严格按社区格式写了标题、Key Facts、Details也确认了 HTTP 200。过了两周查访问日志发现这个文件从发布到现在一次请求都没有。这不是个例。“Nobody Fetched My Llms.txt”这句话准确概括了现阶段很多站长的共同体验文件放了规范也遵守了但 LLM 爬虫并没有像想象中那样自动找上门。这篇文章围绕这个现象展开。先讲清楚llms.txt是什么、为什么出现再给出可复现的落地方法然后重点分析“没人来抓”的常见原因以及如何从日志、User-Agent、robots.txt 等维度定位问题最后给出当前阶段更务实的做法。适合已经接入了llms.txt但看不到收益的开发者也适合正准备接入、想先搞清预期的人阅读。1. llms.txt 是什么设计目标是什么1.1 一句话理解 llms.txtllms.txt是放在网站根目录下的一个纯文本文件作用是向大语言模型提供一份“关于这个网站的人类可读说明”。它不像网页那样有大量导航、广告和模板噪音而是直接用简洁文本告诉模型这个站点是什么、有什么内容、最重要的页面是哪些。从形式上看它很像站点的 AI 入口卡。模型抓取这个文件后不需要渲染页面、不需要解析复杂 DOM就能快速理解站点结构和内容重点。这个约定大约在 2024 年年中提出目的是弥补传统 SEO 体系在“给大模型看”这一场景下的空白。网站管理员可以在根目录提供https://example.com/llms.txt让有意愿读取它的模型或服务获取结构化指引。1.2 为什么会出现这样一套约定传统搜索引擎爬虫读取网页靠的是 HTML 语义、超链接、结构化数据和 sitemap。这个过程经过十几年发展已经非常成熟。但大语言模型抓取网页时行为完全不同它可能只抓取文本可能跳过 JavaScript 渲染后的内容也可能被网页里的广告、评论、推荐位干扰判断。更麻烦的是模型读完一个页面后很难判断这个站点的权威内容在哪、哪些页面是核心、哪些页面只是帮助中心或归档。如果不加指引模型可能把导航链接当成主要内容或者抓到一个 404 页面却不知道站点整体结构。llms.txt的设计动机就是“用一份短文件解决模型对站点的认知问题”。它让站长主动说明“请把以下内容当作本网站的核心信息”降低模型理解和提取信息的成本。这个思路和浏览器里人工写的 README 类似只不过阅读对象从人类开发者变成了大模型。1.3 与 robots.txt、sitemap.xml 的定位差异很多开发者容易把llms.txt和robots.txt、sitemap.xml混在一起。它们虽然都住在站点根目录但作用完全不同。文件主要读者作用是否限制爬取语义粒度robots.txt各类爬虫声明哪些路径允许或禁止抓取是粗粒度路径规则sitemap.xml搜索引擎和爬虫列出站点 URL 清单提升发现效率否URL 级清单llms.txt大语言模型及 AI 服务用文本说明站点定位和推荐入口否站点级语义说明robots.txt负责“什么不能爬”sitemap.xml负责“有哪些页面”llms.txt负责“这个站点到底在讲什么”。三者可以同时存在并不冲突。一个站点可以在 robots.txt 里放行 GPTBot同时用 sitemap 提供 URL 清单再用llms.txt告诉模型站点的核心结构和关键页面。理解这个差异后就不会把“没被爬”简单归因于文件本身。robots.txt一个Disallow就能挡住所有爬虫哪怕llms.txt写得再好也没有意义。2. llms.txt 的格式规范与最小示例2.1 文件位置和命名要求llms.txt的路径约定是站点根目录也就是和robots.txt、sitemap.xml同级。如果站点是https://example.com那么文件地址就是https://example.com/llms.txt文件名区分大小写。大多数 Web 服务器和静态托管平台默认区分Llms.txt、LLMS.txt都是不同的路径。如果站点做了强制 HTTPS 跳转要确保跳转不会破坏直接访问如果 CDN 有缓存要注意文件更新后缓存是否过期。文件建议使用 UTF-8 编码不要带 BOM。部分解析脚本对 BOM 处理不友好第一行会出现不可见字符导致 H1 标题解析失败。2.2 内容结构怎么组织从目前社区流传的格式约定来看llms.txt通常包含这几部分第一行是 H1 标题格式为# 站点名称。标题之后可以有一段简介说明站点定位和主要内容。可选的关键事实区块例如Key facts用短句列出站点的核心信息。可选的Details区块里面用 Markdown 链接列出重要页面。部分站点还会在末尾加入更多分类链接把帮助文档、API 文档、示例代码区分开。下面是一个示意结构# Example Tech Doc Example Tech Doc 是一个专注于编程实践、运维排错和工具链的中文技术博客。 Key facts - 写作语言中文 - 内容方向Java、Python、Linux、Docker - 更新频率每周更新 ## Details - [文章列表](https://example.com/articles)按时间排序的中文技术文章 - [Docker 专题](https://example.com/docker)Docker 安装、排错与最佳实践 - [关于本站](https://example.com/about)作者背景与联系方式这个示例用于说明结构不是强制的官方模板。实际站点应该根据自己的内容调整区块名和链接数量。关键是让模型在几秒钟内能回答出三个问题这个站点是什么、主要讲什么、最有价值的内容在哪。2.3 链接写法和描述信息Details区块里的链接建议使用 Markdown 格式并在链接后面用冒号补充一句描述。描述的作用是帮模型判断链接对应页面的用途避免模型把链接当成普通文本忽略。推荐写法- [Spring Boot 入门教程](https://example.com/spring-boot)从零开始搭建 Spring Boot 项目的完整系列不推荐写法- [点击这里](https://example.com/spring-boot)“点击这里”对模型没有语义价值。模型无法判断链接指向什么内容也就不会优先推荐给用户。2.4 解析时容易踩的坑第一个坑是第一行必须是 H1。如果站长在文件开头写了注释、空行或别的文本某些解析器会认为文件格式不合法直接跳过。第二个坑是链接数量失控。llms.txt的价值在于“精选”不是“全量”。把几百个 URL 塞进文件模型反而分不清主次。全量链接应该交给sitemap.xmlllms.txt只需要保留最有代表性的页面。第三个坑是内容过期。文件一旦发布很多人就不再更新。站点结构变了、页面路径变了llms.txt里还是旧链接模型拿到的信息就是错误的。要在发布流程里给llms.txt加一个更新提醒。3. 给站点加上 llms.txt最小可落地流程3.1 动手前先做环境检查在写文件之前先确认以下基础条件。对于一个学习或小流量站点这些条件通常已经满足。检查项要求确认方式域名和 HTTPS可以正常访问浏览器打开 https://example.com 返回 200根目录可写能放置静态文件使用 FTP、git 或控制台上传robots.txt 不冲突不能全局 Disallow 所有爬虫查看站点 /robots.txtCDN 缓存策略文件更新后能主动失效查看 CDN 控制台或缓存配置如果站点本身不对外公开或者 robots.txt 里写了Disallow: /那llms.txt放不放效果都不大因为外部爬虫根本进不来。3.2 编写 llms.txt 并部署编写上一步的示例内容将example.com替换成真实域名保存为llms.txt。如果站点由 Nginx 托管在 server 块里加一段精确匹配location /llms.txt { alias /var/www/example/llms.txt; default_type text/markdown; charset utf-8; }如果是纯静态站点直接把文件上传到根目录即可。此时还需要确认服务器返回的 Content-Type。有的服务器会返回application/octet-stream虽然浏览器仍然能打开但部分解析器可能因为类型不符而处理异常。3.3 用 curl 验证响应部署完成后先用命令行验证文件是否可访问。这一步能提前暴露路径错误、跳转问题和编码问题。curl -i https://example.com/llms.txt预期输出类似HTTP/2 200 server: nginx content-type: text/markdown; charsetutf-8 content-length: 1024curl -s https://example.com/llms.txt | head -n 20如果看到301或302说明站点强制跳转比如跳到了带www的域名。要确认最终地址和期望地址一致。如果看到404检查文件是否真的在根目录、文件名是否大小写一致。3.4 给发现入口robots.txt、sitemap 和首页文件放好只是第一步。要让爬虫有机会发现它至少要做三件事。第一在 robots.txt 里放行常见 LLM 爬虫。一个基础的放行片段User-agent: GPTBot Allow: / User-agent: ClaudeBot Allow: / User-agent: Google-Extended Allow: /第二检查sitemap.xml是否包含根路径或重要页面。虽然 sitemap 通常不会直接列出llms.txt但站点主要页面被正常索引爬虫才更有可能进入站点。第三在首页 HTML 的head中加一个链接让页面级入口指向该文件。对直接抓取首页文本的模型来说页面里的链接就是发现入口。link relalternate typetext/markdown href/llms.txt这三件事做完文件才真正进入“可被外部发现”的状态。4. 为什么没有人来抓取你的 llms.txt4.1 先分清“没被抓”和“抓了没效果”看到日志里没有llms.txt请求时先不要急着判断“所有人都不支持这个协议”。要区分两种情况完全没请求爬虫没有访问过这个文件。有请求但没被使用爬虫访问了文件但后续搜索效果没有变化。第二种情况更容易让人误判。如果只有零星几次请求搜索效果也不明显很可能说明爬虫探访了文件但产品层面并没有把它纳入可用的上下文或者模型只把它当参考而非权威来源。为了排查准确日志分析至少要保留 User-Agent 和状态码两列。4.2 LLM 爬虫的抓取链路还不包含 llms.txt这是最主要的原因。llms.txt是一个社区倡导的开放约定没有任何强制标准要求主流模型服务商必须读取根目录下的这个文件。很多 LLM 爬虫的抓取流程依然是“从 URL 清单出发 - 抓取 HTML - 提取正文”并不会主动探测https://example.com/llms.txt。具体到产品行为OpenAI、Anthropic、Google 的很多抓取程序直到目前仍然主要依赖普通网页内容。就算它们支持llms.txt也没有在自己产品的每一轮抓取中都执行“先取 llms.txt、再取页面”的逻辑。文件被忽略不是文件出了问题而是整个生态还没有形成稳定的读取习惯。对个人站点或新站点来说这个问题会被放大。知名资料站有外链、有历史抓取记录、有搜索流量爬虫本来就会频繁访问而普通个人博客如果没有外部入口爬虫可能压根没有进入你的站点自然不会碰到llms.txt。4.3 robots.txt 和 User-Agent 规则把爬虫挡在门外很多站长放了llms.txt却没检查 robots.txt。如果站点默认写了User-agent: * Disallow: /那么所有遵守 robots.txt 的爬虫都会止步。即使文件放在根目录爬虫也会先读 robots.txt发现禁止后直接放弃。还有一种情况是 WAF 或 CDN 设置了地域限制、人机验证、频率限制。某一个爬虫来源 IP 段被拦截后服务器访问日志里甚至不会出现请求记录因为它根本没到应用层。4.4 站点入口太少爬虫根本不知道你的域名爬虫发现新站点有三种常见途径从外部链接爬入、从提交的 URL 列表读取、从已有的数据种子库中扫描。个人博客如果没有外链、没有提交入口、也没有被任何公开目录收录那爬虫可能几个月都碰不到这个域名。llms.txt本质上是被动文件它只负责“被访问时提供高质量信息”不负责“让爬虫主动找到你”。没有发现入口文件再标准也没有用。4.5 内容不规范爬虫解析失败文件格式错误也会导致爬虫放弃。常见问题包括第一行不是 H1、链接使用了相对路径、文件是 HTML 而不是纯文本、标题和简介内容与页面实际内容严重不符。模型对这类文件的容忍度很低读取后如果发现信息与页面不符可能导致后续整个站点的内容权重下降。4.6 关键结论它不会带来即时可见的流量需要明确预期llms.txt不是 SEO 手段不会提升搜索排名也不会立刻给站点带来自然流量。它的价值是“当模型需要理解你的站点时给它一份高质量资料”。如果站点本身没有多少爬虫访问这个文件的价值就无法体现。因此不要用“有没有人来抓”作为成功与否的唯一指标而应把重点放在“站点整体是否已经被各类爬虫正常访问、页面内容是否清晰、链接是否可以被发现”。5. 如何验证 llms.txt 到底有没有被访问5.1 在 Nginx 访问日志中直接查找最直接的方法是查 Web 服务器访问日志。以 Nginx 为例默认日志路径通常是/var/log/nginx/access.loggrep llms.txt /var/log/nginx/access.log | tail -n 50如果没有任何输出说明文件中近期确实没有被访问过。如果输出很多说明已经有爬虫或人工请求了文件需要继续看 User-Agent。5.2 按 User-Agent 筛选 LLM 爬虫多数 LLM 爬虫会使用固定的 User-Agent。可以按关键字筛选grep llms.txt /var/log/nginx/access.log | grep -iE GPTBot|ClaudeBot|Google-Extended|Bytespider|PerplexityBot|CCBot | tail -n 50输出格式类似203.0.113.10 - - [28/Jun/2025:10:24:11 0800] GET /llms.txt HTTP/2.0 200 1024 - Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) GPTBot/1.2只要看到这类记录说明该爬虫已经请求了文件。接下来要关注状态码是否为 200。如果出现 403 或 429说明被 WAF 或频率限制拦截。5.3 按日期统计访问趋势如果想判断某一天是否有访问可以按日期分组统计grep llms.txt /var/log/nginx/access.log | awk {print $4} | cut -d: -f1 | sort | uniq -c输出类似3 28/Jun/2025 1 29/Jun/2025数量少是正常现象不必惊慌。重点看趋势文件发布后有没有任何请求以及请求是否来自真实爬虫。5.4 常见 LLM 爬虫 User-Agent 对照表不同服务商的爬虫标识会随时间调整下面是一份常见对照用于日志分析时参考。落地前建议通过官方文档确认最新名称。机构或产品常见 User-Agent 关键字主要用途OpenAIGPTBot、OAI-SearchBot、ChatGPT-User模型训练与搜索AnthropicClaudeBot模型训练与搜索GoogleGoogle-ExtendedAI 训练与生成式搜索控制ByteDanceBytespiderAI 数据抓取PerplexityPerplexityBot对话式搜索Common CrawlCCBot网页数据采集Metameta-externalagent外部内容抓取AppleApplebot-ExtendedAI 相关抓取控制注意不是所有带这些关键字的请求都会访问llms.txt但一旦它们访问站点日志中就会出现对应标识。如果你的日志里完全没有这些关键字说明这些爬虫还没进入你的站点。5.5 检查 CDN 和统计工具的缺口如果站点使用了 CDN源站访问日志可能无法反映真实请求因为 CDN 可能直接缓存并响应了文件。此时要查看 CDN 的日志或访问统计。也可以在 CDN 配置中临时关闭/llms.txt的缓存通过源站日志确认实际请求量。如果使用了百度统计、Google Analytics 这类前端统计工具它们通常无法统计爬虫请求因为爬虫不执行 JavaScript。因此这类工具不能用来判断llms.txt是否被访问。6. 抓不到 llms.txt 时的排查路径6.1 从下到上按五个层面排查如果确认“没人来抓”建议按以下顺序排查不要一开始就怀疑协议本身。第一文件是否存在且可访问。用 curl 直接请求确认状态码和响应体。第二服务器是否返回正确类型。确认content-type是text/markdown、text/plain或类似文本类型而不是application/octet-stream。第三robots.txt 是否放行。用 curl 查看/robots.txt确认User-agent: *没有全局Disallow: /并且常见 LLM 爬虫没有被单独禁止。第四是否有 WAF、CDN、频率限制拦截。查看服务器错误日志、WAF 拦截日志、CDN 统计。第五站点是否能被外部发现。检查 sitemap 是否有效、首页是否有外链、站点是否有提交记录。6.2 常见问题对照表现象常见原因检查方式处理建议curl 返回 404文件路径或文件名错误检查文件名大小写、目录层级把文件放到根目录并保持llms.txtcurl 返回 301/302站点跳转到 www 或 https检查完整跳转链统一域名避免跨域名跳转200 但 Content-Type 是八进制流静态服务器类型映射缺失使用curl -i查看响应头在 Nginx 或托管平台添加类型映射日志中无任何 llms.txt 请求爬虫未进入站点先看首页是否有爬虫请求完善 sitemap、外链、提交入口日志中有请求但状态码 403WAF 或 CDN 拦截爬虫 UA查看 WAF 日志对已知 LLM 爬虫放行或调整频率限制请求存在但搜索无变化模型侧未采用文件内容确认文件内容和页面一致持续更新文件同时优化页面本身6.3 一个典型排查案例假设站点日志里完全没有llms.txt请求。按顺序排查后curl 返回 200内容正确。服务器响应头正常。robots.txt 内容为User-agent: * Disallow: /此时原因非常明确全网爬虫入口被关闭了。修正方法是只屏蔽异常流量而不是全局关闭。User-agent: * Allow: /放宽后再等待几天重新查看日志。如果出现GPTBot或ClaudeBot的请求说明链路已经打通如果没有说明站点发现能力不足需要从外链、sitemap、提交入口继续优化。7. 当前阶段的务实建议和最佳实践7.1 不要只依赖 llms.txt先把站点本身做好对绝大多数内容型站点来说优先级应该是页面可访问、HTML 语义清晰、sitemap 有效、robots.txt 不过度限制。这四项打好基础后再谈llms.txt才有意义。大模型读取网页时仍然会把 HTML 作为主要信息来源。如果页面本身就是无意义的脚本渲染、正文藏在图片里、标题和内容不匹配即使llms.txt写得好模型的整体体验也会打折扣。7.2 把 llms.txt 纳入发布流程而不是一次性文件站点结构变化时llms.txt要同步更新。建议把它作为仓库中的一个文件管理与代码一起提交。可以在 CI 中加一条检查用脚本解析文件并验证所有链接是否返回 200。一个基础检查脚本思路#!/bin/bash # 提取 llms.txt 中的 URL 并检查状态码 grep -oE https?://[^)] llms.txt | while read url; do code$(curl -o /dev/null -s -w %{http_code} $url) echo $code $url done这个脚本只能检查可访问性不能检查内容维护度。实际项目还要定期人工确认文件里的信息没有过期。7.3 同时维护一份全量清单社区中有一种常见做法是同时提供llms.txt和llms-full.txt。前者提供精选入口供模型快速了解站点后者提供全量页面清单适合需要全面索引的场景。具体实现可以在构建时自动生成把全部文章的标题、URL、摘要写入llms-full.txt再手工维护一份精简版llms.txt。要注意这仅是站点层面的命名约定不保证所有模型都会读取。7.4 持续观察规范生态的更新llms.txt的生态还在变化。主流模型服务商是否开始读取该文件、是否在官方文档中给出明确策略、市场上有多少站点实际使用该文件这些信息每隔几个月就会更新。维护者要关注的是规范本身的变化而不是某个热搜词或一次抓取记录。在新版本出现之前一个可用的策略是保持llms.txt格式稳定不频繁调整标题和链接结构同时在页面层保持清晰的内容语义让即使不读llms.txt的模型也能天然获得正确信息。对新手来说最有价值的练习不是追求“让某家爬虫立刻来抓”而是坚持把站点内容、结构、链接做成一套清晰可读的体系。等到llms.txt被更多产品采纳时你的站点已经具备了最好的接收入口而不是临时补一个文件再等奇迹。