跳到主要内容

llms.txt — 文件规范

本章讲约定本身:一个 llms.txt 文件长什么样、每一部分什么意思、还有哪两条配套约定。依据是规范原文 nbs/index.qmd("Format" 与 "Existing standards" 两节)。

1. 为什么用 markdown 而不用 XML/JSON

先回答一个自然的疑问:既然是给程序解析的,为什么不用 XML 或 JSON?

因为这个文件要被两类读者同时消费:人要能顺手写和读,语言模型要能直接理解。markdown 恰好两边都行——模型对 markdown 的理解目前最好,人写起来也没负担(nbs/index.qmd 的 "Format" 节)。

代价是:markdown 不像 XML 那样天然结构化。规范的解法是约束——只要文件遵守一套固定的顺序和写法,就能用"经典"手段(正则、解析器)可靠地读出来。所以 llms.txt 是"看着自由、其实很规矩"的 markdown。

2. 文件的固定结构

一个合规的 llms.txt 按固定顺序包含这几段(nbs/index.qmd "Format" 节逐条列出):

顺序成分必填?markdown 写法
0字节序标记 BOM可选(文件开头的隐藏字节)
1项目/站点名必填,唯一必填# 名字(H1)
2一句话摘要可选> 摘要…(引用块)
3详细说明可选任意 markdown 段落/列表,但不能有标题
4若干"文件清单"分区可选,可多个## 分区名 下跟一个 markdown 列表

第 4 段里,每一条链接的写法是固定的:

- [名字](URL): 可选的说明

必须有一个 markdown 超链接 [名字](URL),后面可选跟一个冒号加备注。

2.1 一张图看清各段边界

怎么读:从上到下就是文件从头到尾;## 之前的都算"开头段",## 开始进入"分区"。

# Title ← ① H1,唯一必填

> Optional description ← ② 摘要(引用块)
├ 这三段合称"开头",归到 title/summary/info
Optional details go here ← ③ 说明段(不能含标题)

## Section name ← ④ 一个分区开始
- [Link title](url): details ← 分区里的链接清单(可多条)

## Optional ← ④ 又一个分区,名字"Optional"有特殊含义
- [Link title](url)

这张"开头 / 分区"的切分,正是参考解析器切文件的依据(见 02-parser.md):它先用 ## 把文件劈成"开头"和"各分区",再分别处理。

3. "Optional" 分区的特殊含义

分区名大多随意,但有一个保留名:Optional

它的约定含义是:当上下文预算紧张时,这一分区的链接可以整段跳过——放"次要、常可省"的资料(nbs/index.qmd "Format" 节末尾)。

这不是纯文字约定,而是被工具落实的:

  • CLI 默认展开 Optional;加 --optional True 才带上。
  • 代码里 mk_ctxskip = '' if optional else 'Optional' 决定跳不跳(llms_txt/core.py:101-105)。

所以"官方 FastHTML 文档"才会给出两份产物:llms-ctx.txt(不含 Optional)和 llms-ctx-full.txt(含 Optional)——同一个源文件、要不要 Optional 两种展开(nbs/index.qmd "Proposal" 节)。

4. 配套约定:给页面加 .md 镜像

规范其实提了两条约定。上面讲的是第一条(根路径放 llms.txt);第二条是关于每个页面的:

对那些对 LLM 有用的网页,在同一个 URL 后面加 .md 提供一份干净的 markdown 版本。没有文件名的 URL(如目录),则加 index.html.md。 —— nbs/index.qmd "Proposal" 节

举例(规范原文给的):

版本URL
普通 HTML 页https://www.fastht.ml/docs/tutorials/by_example.html
对应 markdown 镜像https://www.fastht.ml/docs/tutorials/by_example.html.md

这条约定解释了为什么 llms.txt 里的链接常以 .html.md.md 结尾:清单里指向的通常是页面的 markdown 镜像,而不是原始 HTML。作者的 nbdev 工具链现在默认给所有页面生成 .md 版本,所以 Answer.AI / fast.ai 的项目文档天然满足这条(nbs/index.qmd "Proposal" 节)。

5. 和 robots.txt / sitemap.xml 的分工

"放在固定根路径"这一招是跟 /robots.txt/sitemap.xml 学的。但三者目的不同,别混:

文件给谁目的关键差异
robots.txt爬虫声明"哪些能爬"是"访问许可",不给内容
sitemap.xml搜索引擎列出全部可索引页面求全;常无 markdown 版、无外链、总量超上下文
llms.txtLLM / agent给出精选的 LLM 友好资料索引求精;人工策展,可含外链

规范特别强调 llms.txt 与 sitemap 不是一回事(nbs/index.qmd "Existing standards" 节):sitemap 常常含页面的 LLM 可读版本、含有用的外部站点链接、而且总量太大塞不进上下文。llms.txt 的价值恰在"少而精 + 可跨站"。

还有一层时机上的差异:robots.txt 面向"索引期"的爬虫,llms.txt 主要面向推理期(inference)——用户当场问问题、需要把某库文档拉进上下文时按需取用,而非用于训练(nbs/index.qmd "Existing standards" 节)。

6. 边界:规范"不管"什么

诚实地说清约定的边界:

  • 不规定怎么处理。 规范明说"不对如何处理 llms.txt 给任何特定建议,因为这取决于应用"(nbs/index.qmd "Proposal" 节)。本仓库的 llms_txt2ctx 只是一种处理方式,不是规范的一部分。
  • 不是强标准。 它是一份"informal overview"(非正式提案),开放社区讨论(nbs/index.qmd "Next steps" 节),没有强制校验、没有版本号协商机制。
  • 分区名无枚举。 除了 Optional 有特殊含义,其余 H2 分区名(DocsExamples…)完全自由,规范不限定集合。

7. 代码地图

主题文件符号 / 位置
规范原文(格式 / 标准共存)nbs/index.qmd"Format" / "Existing standards" 节
Optional 跳过的落地llms_txt/core.py:101mk_ctx(skip = '' if optional else 'Optional')
示例 llms.txtnbs/llms-sample.txtnbs/llms.txt整文件
展开产物示例nbs/llms-ctx.txtnbs/llms-ctx-full.txt整文件