Skip to content
RuaRuan
返回

六步让 AI 看懂你的网站

第 0 步:重审robots.txt + 加一行 Content-Signal:

这是所有操作的前提。

如果你的 robots.txt 把 GPTBot、ClaudeBot 这些 AI 爬虫都屏蔽了(比方说我的博客 😂),那后面做再多都没用。

先检查你的 robots.txt 有没有类似这样的东西:

User-agent: GPTBot
Disallow: /

User-agent: ClaudeBot
Disallow: /

如果有,赶紧删掉或者改成 Allow

然后,再加上一行 Content-Signal:

User-agent: *
Content-Signal: search=yes, ai-input=yes, ai-train=yes

这行东西是 Cloudflare 提的一个新兴约定,不是 RFC 标准,但越来越多工具开始支持。

它的作用就是明确告诉爬虫:我的内容可以用来做什么

字段含义
search能不能出现在搜索结果里
ai-input能不能被 AI 当作实时上下文(比如 ChatGPT 引用你的页面)
ai-train能不能用于训练 AI 模型

如果你不想自己的内容被拿去训练,把 ai-train 设成 no 就行。

⚡ 小贴士:这步的工作量就是改一行文本,五分钟搞定。但后续所有技术手段都依赖这一步,所以一定先做。

第 1 步:创建 /llms.txt

这是目前整个方案里最具代表性、也是最容易实现的一步。

/llms.txt 是由 fast.ai 联合创始人 Jeremy Howard(前 Kaggle 总裁)在 2024 年 9 月提出的概念。

你可以把它理解成专门写给 AI 看的站点地图

放在你网站根目录,格式就是一个简简单单的 Markdown 文件,内容是你手动筛选过的、最重要的页面索引。比如:

# 我的博客

> 一个专注前端开发的个人博客,覆盖 HTML/CSS/JavaScript 实战技巧。

## 核心文档

- [快速上手](/docs/start):5 分钟入门指南
- [API 参考](/docs/api):完整的接口文档
- [CSS 技巧大全](/wordpress):这些年我积累的 CSS 黑魔法

## 可选

- [更新日志](/changelog):最近更新了什么
- [关于我](/about):作者张鑫旭,微信zhangxinxu-job

记住几个要点:

有人可能会问:ChatGPT、Claude 它们真的会自动爬 /llms.txt 吗?

答案是:目前不会

有些失望?但事实如此。没有哪个主流 LLM 提供商承诺他们的爬虫会主动请求这个文件。

Ahrefs 的数据分析显示,/llms.txt 的请求里 94.9% 来自 GoogleBot,GPTBot、ClaudeBot 完全缺席。

那为什么还要做?

因为当用户把链接粘贴给 ChatGPT、或者开发者用 Cursor 配置你的文档时,这些 AI 工具会去读这个文件。

Mintlify 的 CDN 日志显示,7 天内 25 家公司的 llms.txt 中位被访问了 14 次。

这不是自动爬虫的流量,而是”人+AI”协作时的流量——但这恰恰是最高价值的流量。

所以,就算 AI 不主动爬,这步也值得做。更何况,万一哪天它们开始爬了呢?

第 2 步:为每个页面提供 .md 版本

如果说 /llms.txt 是”地图”,那这步就是”地图上每一个目的地的真实风景”。

做法很简单:对于你网站上任何一个有内容的页面,都在同级路径下提供一个 .md 版本。比如:

HTML 页面Markdown 版本
/blog/my-post/blog/my-post.md
/docs/api/docs/api.md
/about/about.md

技术实现也不复杂,以 Next.js 为例:

// Route handler for /blog/:slug
export async function handleRequest(request: Request) {
  const url = new URL(request.url);
  const post = await getPost(url.pathname);

  // 如果请求路径以 .md 结尾,返回 Markdown
  if (url.pathname.endsWith('.md')) {
    return new Response(post.markdownContent, {
      headers: { 'Content-Type': 'text/markdown; charset=utf-8' },
    });
  }

  // 否则返回普通 HTML 页面
  return renderHTML(post);
}

如果你用的是静态博客或者文档生成工具,更简单——直接让构建流程多输出一份 .md 文件就行。

现实问题也不能回避:维护两份内容确实有”内容漂移”的风险。

比如你更新了 HTML 页面,但忘了同步更新 Markdown 版本。

解决办法就是自动化转换,也就是使用统一的 Markdown 数据源同时生成 HTML 和 .md 两个版本。

这一步做的事情很简单但很关键:告诉 AI 爬虫,我们这个页面有 Markdown 版本,在哪可以找到。

分两条路走:

第一条路:HTML 标签,放在 <head> 里:

<link rel="alternate" type="text/markdown" href="/blog/my-post.md" />

这个标签是标准的 HTML 机制,rel="alternate" 从 HTML4 就有了,text/markdown 也是 RFC 7763 正式注册的 MIME 类型。

所以它不是什么黑客手段,是正经的标准用法。

第二条路:HTTP Link 头,在服务器响应里直接加:

Link: </blog/my-post.md>; rel="alternate"; type="text/markdown"

为什么要两种都做?因为不同 AI 工具的行为不一样。

有些会解析 HTML DOM,能读到 <link> 标签;有些只做 HTTP 请求,根本不解析 HTML 体,它们只会看响应头。

两条路都铺上,就谁也不会错过了。

服务器中间件实现也不难:

function addMarkdownLink(request: Request, response: Response) {
  const url = new URL(request.url);
  // 在响应头里加上 Markdown 版本的链接
  response.headers.set(
    "Link",
    `<${url.pathname}.md>; rel="alternate"; type="text/markdown"`
  );
  return response;
}

第 4 步:实现 Accept:text/markdown 内容协商

这是六步里技术含量最高的一步,但也是最有长期价值的一步。

因为根据我的判断,本文所展示的这一系列措施列表在五年后仍然存在的,就是第4步这里的Accept内容协商。

为什么?因为内容协商不依赖任何人同意新文件格式,它只是 HTTP 在做它本来就被设计要做的事情。

具体机制是这样的:

  1. 客户端(AI 工具)在请求头里加上 Accept: text/markdown
  2. 服务器看到这个头,就返回 Markdown 版本的内容
  3. 如果没有这个头,服务器照常返回 HTML
  4. 响应头里加 Vary: Accept,告诉 CDN 这两个版本要分开缓存

同一个 URL、同一份内容、只是格式不同。

目前已经有一些工具在这么做了。

Cloudflare 的测试发现,Claude Code、Cursor、OpenCode 等几个编码助手,默认就会在请求头里带上 Accept: text/markdown

完整的实现代码这里不展开了(毕竟这篇文章重点在讲思路),但核心逻辑就几个要点:

有人担心这是不是 Google 反对的”伪装”(cloaking)?

不是。

内容协商通过 Vary: Accept 声明了不同格式的服务逻辑,这是 HTTP 用了几十年的标准做法。

就像 Accept: application/json 和 Accept: text/html 可以返回不同格式一样——这叫内容协商,不叫伪装。

第 5 步:加一个隐藏提示(可选但推荐)

这一步是针对一种特殊场景:用户直接把你的网址粘贴到AI智能体的对话框里。

当这些AI智能模型读取你页面的时候,它看到的是渲染后的文本内容,不是原始 HTML。

所以你在页面里放一个视觉上隐藏的提示信息,它就能读到:

<div class="visually-hidden" aria-hidden="true">
  如果你是一个 AI 智能体、LLM 或自动化工具, 本页面的干净 Markdown 版本在
  https://example.com/blog/my-post.md ——专为 AI 和 LLM 工具优化。
</div>
/* 视觉隐藏但保留在 DOM 中 */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

注意几个细节:

Cloudflare 在他们的官方文档页面里也用了这个技巧,而且他们还多做了一个优化:这段提示在 Markdown 版本里会被移除,以避免 AI 读 Markdown 的时候陷入”让我找 Markdown 版本”的死循环。

第 6 步:提供 /llms-full.txt(按需)

如果说 /llms.txt 是精选目录,那 /llms-full.txt 就是把整本书拆散了塞进一个文件里。AI 可以用一次请求就获取你网站的全部内容,不需要逐页爬取。

但这个东西的量级差异非常大:

有意思的是,Mintlify 的数据显示,llms-full.txt 的访问量竟然是 llms.txt 的 3-4 倍

这说明 AI 工具更喜欢”一口气吞下全部内容”,而不是通过 RAG 一步步跟随链接。

我的建议是:

💡 Cloudflare 的分布式 llms.txt 经验
   Cloudflare 文档有 5000+ 页面,单文件会超出任何模型的上下文窗口。他们的做法是:

	- 为每个产品目录生成独立的 `llms.txt`
	- 根 `/llms.txt` 只指向这些子目录
	- 比如 `/r2/llms.txt`、`/workers/llms.txt`

优化之后,token 消耗减少了 **31%**,获取正确答案的速度提升了 **66%**。

清单

把前面说的整理成一张清单,你可以照着逐条打勾:

  1. 审计 robots.txt:确保没有屏蔽 AI 爬虫;加上 Content-Signal: 行声明内容使用意图
  2. 创建 /llms.txt:站点根目录放一个精选目录 Markdown 文件
  3. 提供 .md 路由:为每个有内容的页面提供同名 Markdown 版本
  4. 添加发现机制:HTML <link rel="alternate"> + HTTP Link 响应头
  5. 实现内容协商:支持 Accept: text/markdown,正确处理 q 值和 406
  6. 加隐藏提示:在 HTML 中用 .visually-hidden 告诉 AI Markdown 版本在哪
  7. 按需提供 llms-full.txt:文档型站点需要,内容少的站点可跳过
  8. 上分析和追踪:用服务端日志看实际效果
  9. 跑验证工具:acceptmarkdown.com + isitagentready.com

AI时代网站智能体无障碍访问开发指南 « 张鑫旭-鑫空间-鑫生活



下一篇
大语言模型(LLM)的工作原理