1. llms.txt 是什么
llms.txt 是一个约定:在网站根目录放一个 Markdown 文件,用自然语言告诉大模型和 AI Agent——这个网站是什么、哪些内容值得读、每一篇讲了什么。
它由 Jeremy Howard(Answer.AI)在 2024 年 9 月提出,规范全文只有一个页面。
简单说,robots.txt 管的是「你能不能抓」,llms.txt 管的是「抓完怎么理解」——前者是许可,后者是导读。
-
规范地址:https://llmstxt.org/ -
参考实现:https://github.com/AnswerDotAI/llms-txt
一个最小可用的 llms.txt 长这样:
# xxx的网站
> 关于 AI、云原生与基础设施工程的个人技术博客,700+ 篇实践笔记。
站点以中文为主,包含 Kubernetes、Ceph、RDMA、GPU 运维、
AI Agent 等方向的实操记录,每篇都有可复现的命令与结论。
## 核心内容
- [Ceph 架构与运维](https://www.chenshaowen.com/blog/container-deploy-ceph-architecture-operations-and-testing.html):集群架构、日常巡检、监控与升级
- [RDMA 运维](https://www.chenshaowen.com/blog/rdma-ops.html):RoCE、Soft RoCE、InfiniBand 的配置与测试
## Optional
- [关于我](https://www.chenshaowen.com/about.html):联系方式与咨询方式
注意整份文件就是给人看也给模型读的普通 Markdown:没有 XML、没有 JSON Schema、没有配置文件。这个约定的全部复杂度,就是「把话说清楚」。
2. 为什么需要它
2.1 HTML 页面本身对模型不友好
把一个页面喂给模型,真正有用的正文只占其中一小部分,其余是导航栏、侧边栏、广告位、cookie 提示、内联脚本和样式。模型要先做一轮「抽取正文」,这个过程既消耗 token,也容易抽错。
更麻烦的是入口问题。站点有几百篇文章时,模型没有什么好办法知道「哪几篇是核心、哪几篇已经过时」。它只能靠 sitemap 遍历、靠搜索命中、靠猜 URL 规律。
llms.txt 的思路是:与其让模型自己猜,不如主动告诉它。
2.2 有/无 llms.txt 对比
假设用户问 AI:「Ceph 出问题怎么排查?」
没有 llms.txt:
抓首页 → 只列出最新 5 篇,要翻 140+ 页才能看全
→ 改抓 sitemap.xml → 上千条 URL,多半是标签页和分页,无从下手
→ 按关键词命中 3 篇 → 逐页抓 HTML、抽正文、去模板噪声
→ 其中 1 篇是几年前的旧文,命令已失效
→ 给出答案(token 大量花在模板和旧文上)
有 llms.txt:
请求 /llms.txt → 一次拿到站点定位 + 核心文章清单 + 每篇一句话摘要
→ 直接选中「Ceph 架构与运维」
→ 抓正文 → 给出答案
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2.3 它和 SEO 不是一回事
值得先说清楚:llms.txt 不提升搜索排名,Google 明确表示不用它做排名信号。
它服务的是另一条链路——AI 搜索、AI 浏览器、编程 Agent 在回答问题时如何取用你的内容。这个环节通常叫 GEO(Generative Engine Optimization)。做 SEO 是把页面喂给爬虫,做 GEO 是把理解喂给模型。
2.4 顺带一提:站点自述
llms.txt 还有一层容易被忽略的价值:它是一份写给机器看的站点自述,却也适合人读。新访客、搜索引擎之外的分发渠道、以及你自己在做内容盘点时,都能拿它当导览页——这也决定了它该怎么写,见第 4 节。
3. 文件格式
规范给的结构非常克制:按固定顺序排列的几个部分,其中只有一个是必需的。
# 站点名
> 一句话摘要,说明这个站点是什么
补充说明段落,可以写定位、语言、内容范围、更新频率等
## 分组标题
- [链接标题](https://example.com/page):这条链接讲了什么
## Optional
- [次要链接](https://example.com/other):模型可自行决定是否读取
各部分的作用和约束:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
必需 |
|
> |
|
|
|
|
|
|
|
|
|
- [名称](URL):说明 |
## Optional |
|
|
几条硬性要求:
-
放在站点根目录或任意子路径,路径就是 /llms.txt或/docs/llms.txt。文件只覆盖它所在路径下的 URL,同时存在多份时,客户端取最具体的那一份 -
必须是 Markdown,纯文本输出,Content-Type 用 text/plain或text/markdown -
列表项没有链接就不是链接,规范要求用标准 Markdown 超链接语法,不要写裸 URL -
除 H1 外所有部分都是可选的,但只有 H1 的 llms.txt 基本没有价值
3.1 Markdown 版本:.md后缀
规范在索引文件之外,还提了一件事:给页面本身配一份干净的 Markdown 源文,让模型少做一轮 HTML 抽取正文。
下面的示例都用本博客举例,但本站尚未实现这一能力,示例是假设实现之后的样子。
原提案对 URL 给了两种写法,都算合规:
-
追加: page.html→page.html.md -
替换扩展名: page.html→page.md
没有文件名的路径则用 index.html.md或 index.md。原提案自己用的是追加写法——by_example.html配 by_example.html.md——实战里也更推荐它:静态托管上 page.md有可能和真实路由撞车,追加后缀则不会。
curl -s https://www.chenshaowen.com/blog/rdma-ops.html # 默认:HTML
curl -s https://www.chenshaowen.com/blog/rdma-ops.html.md # 追加 .md:Markdown
后者返回的就是文章原文,没有模板噪声:
---
title: RDMA 运维
tags:
- RDMA
- RoCE
- InfiniBand
- 网络
- 运维
- 高性能计算
enableToc: true
layout: post
url: blog/rdma-ops.html
updated: 2026-08-22 00:00:00
date: 2026-08-22 00:00:00
---
## 1. RoCE
### 1.1 连接要求
RDMA 要求端到端同一类网络,比如同一个 B 段网。
...
对比一下同一段内容在 HTML 里的样子——模型得先自己判断哪一块才是正文:
<body>
<nav class="navbar">...</nav>
<aside class="sidebar">...</aside>
<main>
<article>
<h2>1. RoCE</h2>
<h3>1.1 连接要求</h3>
<p>RDMA 要求端到端同一类网络……</p>
</article>
</main>
<div class="adsense">...</div>
<script>
...
</script>
</body>
3.2 怎么让模型找到这份 Markdown
多出一份文件,模型怎么知道它存在?规范的答案是用标准的 link 关系声明,两种写法等价:
<link rel="alternate" type="text/markdown" href="/blog/rdma-ops.html.md" />
<link rel="describedby" href="/llms.txt" />
或者放在 HTTP 响应头里,效果一样:
Link: </blog/rdma-ops.html.md>; rel="alternate"; type="text/markdown",
</llms.txt>; rel="describedby"
rel="alternate" type="text/markdown"指向这一页的 Markdown 版本,rel="describedby"指向覆盖它的 llms.txt。规范推荐请求头形式,理由是它同样适用于非 HTML 资源,而且能在 Web 服务器或 CDN 配置里统一加,不用改任何一个页面。
3.3 另一种做法:请求头内容协商
还有一种不改 URL 的做法,靠 Accept请求头区分返回格式,在 HTTP 里叫内容协商(content negotiation)。规范没有提这种方式,是工程实践里常见的另一种选择。
# 默认:拿 HTML
curl -s https://www.chenshaowen.com/blog/rdma-ops.html | head -2
# <!DOCTYPE html>
# 声明偏好:同一个 URL,拿 Markdown
curl -s -H 'Accept: text/markdown' \
https://www.chenshaowen.com/blog/rdma-ops.html | head -2
# ---
按 HTTP 语义,Accept表达的是偏好而非命令,所以更常见的写法是带权重:
Accept: text/markdown, text/html;q=0.9
意思是「优先 Markdown,HTML 也能接受」。服务端无法满足时应当回退到 HTML,而不是返回 406——否则普通浏览器也会拿不到页面。
服务端的判断逻辑大致是这样:
map $http_accept $prefer_markdown {
default 0;
"~*text/markdown" 1;
}
location /blog/ {
if ($prefer_markdown) {
rewrite ^(/blog/.+)\.html$ $1.md last;
}
}
这段配置只做了字符串匹配,没有解析 q权重,实际实现要更细致一些。
3.4 社区惯例:llms-full.txt
实践中还流行一个伴生文件 /llms-full.txt,把清单里所有页面的正文全文内联进去。需要说明的是:它不在规范里,是社区约定,由各文档平台和工具自行支持。
分工是这样:
-
llms.txt是索引,小而精,用来选页面 -
llms-full.txt是全集,大而全,一次请求拿到全部内容
对文档站、API 文档这类内容总量可控的站点,llms-full.txt的价值更大——模型一次请求就拿全,省掉多轮抓取。对内容持续增长的博客,它的体积会失控,索引模式更合适。
3.5 方案比较
|
|
|
|
|---|---|---|
llms.txt |
|
|
.md
|
|
|
Link
|
|
|
|
|
|
Accept、权重与回退,缓存策略更复杂 |
llms-full.txt |
|
|
llms.txt是入场券:成本最低,但只解决「选哪篇」。中间两行是同一件事的两种做法——.md版本负责「读得干净」,Link响应头负责让模型发现它,两者通常一起上,成本也一起算。内容协商解决同样的问题,不必多产出一份文件,代价是把复杂度搬到了服务端和缓存上。
内容协商最容易踩坑的是缓存:如果响应还存在 CDN,第一个请求缓存了 HTML,后续带 Accept: text/markdown的请求也会拿到 HTML,而发起方往往察觉不到。缓存 key 必须带上 Accept才安全。
正因如此,不少 CDN 厂商开始把这层转换做成边缘能力,站点的改造成本从「改服务端」降到「开一个开关」。这类能力还在演进,具体支持情况以各厂商文档为准。
4. 内容怎么写
格式五分钟就能学会,难点在内容。写 llms.txt 时最容易犯的错,是把它写成 sitemap 的 Markdown 版。
4.1 策展,不要罗列
如果站点有 700 篇文章,全部列进去等于没列——模型仍然要读完 700 行才能决策,而且分不清主次。
好的 llms.txt 是一次编辑行为:挑出 10~30 个真正值得作为入口的页面,按主题分组。
## 存储
- [Ceph 架构与运维](https://www.chenshaowen.com/blog/container-deploy-ceph-architecture-operations-and-testing.html):集群架构、日常巡检、池与 OSD 管理、监控与升级
- [MinIO 多节点多盘部署与运维](https://www.chenshaowen.com/blog/minio-multi-node-multi-disk-deployment-and-maintenance.html):部署、桶与用户管理、备份,以及节点重启、单盘更换、节点重建
- [JuiceFS 性能测试](https://www.chenshaowen.com/blog/performance-testing-and-comparison-of-juicefs-ce-ee-and-dragonfly.html):本地盘、社区版、企业版与 Dragonfly 集成的 dd / benchmark / fio 实测对比
## AI 基础设施
- [常用 GPU 运维及故障处理](https://www.chenshaowen.com/blog/common-gpu-operation-and-fault-handling.html):XID 错误码、掉卡、ECC、显存泄漏等故障的处理笔记,持续更新
- [RDMA 运维](https://www.chenshaowen.com/blog/rdma-ops.html):RoCE、Soft RoCE、InfiniBand 三种模式的连接要求、装机和点对点测试
4.2 每个描述都要回答「读了能得到什么」
描述不是标题的复述,而是筛选依据。对比一下:
|
|
|
|
|---|---|---|
|
|
[RDMA 运维](https://www.chenshaowen.com/blog/rdma-ops.html):RDMA 运维 |
|
|
|
[RDMA 运维](https://www.chenshaowen.com/blog/rdma-ops.html):RoCE、Soft RoCE、InfiniBand 的配置与测试 |
|
4.3 摘要要写清「是什么」,不是「很好」
摘要那一段最容易被写成宣传语。「专注于分享高质量技术内容」这种句子对模型没有信息量。
有用的摘要包含三个要素:领域、内容形态、规模或边界。
> 关于 AI、云原生与基础设施工程的个人技术博客,700+ 篇实践笔记,
> 以中文为主,每篇都有可复现的命令与结论。
4.4 Optional 只放次要内容
## Optional是规范里唯一带约定含义的分组,用来放锦上添花的内容——关于页、更新日志、友链、法律声明。早期版本的提案给过它机械语义(上下文紧张时整段跳过),新版已经去掉了这层规定,但把次要内容单独归置仍然是有用的惯例。
反过来说,把核心内容放进 Optional,等于告诉模型「这些可以先不看」。
5. 现状与争议
写到这里必须说清楚一件事:llms.txt 目前没有强制力,也没有被主流厂商承诺支持。
几点观察:
-
没有厂商背书。OpenAI、Google、Anthropic 等都没有承诺「会读取 llms.txt」。它不是 robots.txt 那种被广泛遵守的约定——robots.txt 从 1994 年沿用至今,有合规压力和明确的爬虫行为规范,llms.txt 一样都没有。 -
公开的爬虫日志分析普遍显示,AI 爬虫对 /llms.txt的请求量很低,主要流量仍然集中在页面和小部分 feed 上。 -
但它并非无用。成本是一个静态文件和半小时的整理,副作用接近于零。这是它最实际的用途——给人看的站点导览和内容盘点。
所以合理的定位是:一个便宜的赌注,不是 SEO 银弹。
如果你的目标只是「让 AI 更容易取用我的内容」,按投入产出比排序,真正该先做的其实是这几件:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
<article>
<h1>比一堆 <div>有用 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
换句话说:llms.txt 是锦上添花的那一层。如果正文本身抓不到,写再好的 llms.txt 也没用。
6. 小结
llms.txt 要做的事很简单:在站点根目录放一份 Markdown,用自然语言写清这个站点是什么、哪些内容值得读。
具体来说:
-
格式:H1 标题唯一必需,加引用块摘要、正文说明、按主题分组的 Markdown 链接列表, ## Optional放次要内容。除了根目录,也可以放在任意子路径,只覆盖该路径下的页面。 -
配套:给页面配一份 .mdMarkdown 版本,再用Link响应头里的rel="alternate"声明出来,是比 llms.txt 更本质的一步。 -
怎么写:策展而非罗列,10~30 个精选入口,每条描述写清价值而不是复述标题。 -
怎么落地:静态站把文件放进站点根目录即可,无需任何服务端改动;需要覆盖更多页面时,可用构建工具生成初稿再人工删减。 -
如何看待:没有厂商背书、爬虫请求量低,但成本极低、副作用小。先保证正文能被抓取,再顺手加这一个文件。
花半小时写一份,至少能换来一个清晰的站点自述——这件事本身就有价值。
7. 参考链接
-
https://llmstxt.org/ -
Ahttps://github.com/AnswerDotAI/llms-txt
微信赞赏
支付宝扫码领红包





