你的博客读者已经不是人:llms.txt 和 .md 才是它的入口
AI 成了博客的第一个读者:.md、llms.txt、Accept 协商、显式 robots 与 IndexNow,全是文件。
Deallocated Objects 的作者 Jake Marsh 有一次意识到,读他博客的"人"里有相当一部分不是人:Claude、ChatGPT、Perplexity 这一批,替某个正在提问的人来取一个页面。于是他花了一个晚上,让这个博客对它们好读一点——顺手也把搜索引擎那边该补的补上。
他的站是 nginx 托着的静态站,所以整篇的每条改法都落成两种东西:构建时生成的文件,或者几行 nginx 配置。 没有框架,没有插件,也没有"等 CMS 出功能"。
2026 年 10 月 24 日他把过程写了出来。下面是完整编译。
一、每篇文章都有一份 markdown
HTML 对 agent 来说噪音太多:导航、脚本、样式、埋点、模板壳子,真正的内容被埋在一堆标签里。所以他给每篇文章加了一份纯 markdown 版本——在任何文章 URL 后面加 .md:
https://deallocatedobjects.com/posts/the-art-of-the-reveal.md
每个文件开头有一小块 YAML frontmatter(标题、canonical URL、作者、日期、一句简短描述),然后是正文。老文章当年本来就是用 markdown 写的,所以构建过程只需要把那些文件清理一遍,并把它们的图片指向自托管的副本。
这一步的价值不在"多一种格式",而在同一份内容只维护一次。正文是 markdown,HTML 和 .md 都是它的产物,不存在两份内容各自漂移的问题。
二、更讨巧的是内容协商:不用加 .md
如果客户端在 Accept 头里要 markdown,他就从普通 URL 直接返回 markdown——访问者不需要知道 .md 存在。
在 nginx 里,这是一个 map 加上每个 location 一行判断:
# http context
map $http_accept $deallocated_md {
default "";
"~*text/markdown" ".md";
}
# server block
location ~ ^/posts/[^/.]+$ {
if ($deallocated_md) { rewrite ^ $uri.md last; }
try_files $uri.html =404;
}
验证一下:
curl -H "Accept: text/markdown" https://deallocatedobjects.com/posts/the-art-of-the-reveal
这里有两个细节比配置本身更重要。
第一,每个响应都带 Vary: Accept。 否则中间任何一层缓存都可能把手里的 HTML 交给 agent,或者反过来把 markdown 交给浏览器——而这个 bug 只在特定的缓存命中路径上出现,本地怎么测都是好的。
第二,.md 响应同时发两个头。 一个是 Link,指向对应的 HTML 页面并声明 canonical:
Link: <https://deallocatedobjects.com/posts/the-art-of-the-reveal>; rel="canonical"
另一个是 X-Robots-Tag: noindex。两个头配合,是为了让 Google 不把这些 .md 当成每篇文章的重复副本:内容给 agent 用,权重归 HTML 页。 只做密钥协商不声明 canonical,等于给自己制造一批重复内容。
三、llms.txt:告诉 agent 它在看什么
/llms.txt 是站点根目录下的一个纯 markdown 文件,作用是让 agent 知道"这是哪儿、怎么用"。他的那份包含:博客的一行简介、怎么拿到 markdown、feed 在哪里、希望文章被怎么引用,以及全部文章的清单——每篇一个 markdown 链接加一行摘要。
另外还有两个文件:
/llms-full.txt:所有文章的全文塞进一个文件,约 225 KB;/index.md:首页的 markdown 版本。
这三个文件加上一行响应头就完整了:每个响应都带一个指向 llms.txt 的 Link 头,agent 不用猜路径就能找到它。
注意 llms.txt 目前在格式上还只是社区提案(起源于 2024 年 9 月),Google 没有表示会读它。但他这里的判断很朴素:它是一份文件,写一次,成本近乎为零,而它明确表达了"我希望被怎么引用"。
四、robots.txt:沉默等于允许,但他选择写明
robots.txt 里什么都不写,技术上等于"允许所有"。他更愿意显式表达:先放行所有人,然后把大的几家点名列出——GPTBot、ClaudeBot、PerplexityBot、Google-Extended,再加十来个同类 UA,最后加一行 Content-Signal:
User-agent: *
Allow: /
Content-Signal: search=yes, ai-input=yes, ai-train=yes
这条 Content-Signal 不是 robots.txt 的标准指令,而是一类"内容用途声明"的做法(由 CDN 厂商推动):分别表示允许进搜索索引、允许作为 AI 的输入、允许用于训练。
他的取舍写得也很直白:对一个博客来说这是对的选择,因为他想被引用;一个产品站可能会做不同的选择。 这句话是整篇文章里最该被抄走的一句——robots 的取值不是"技术正确/错误",而是"你要什么"。
五、Feed:Atom 保留,另加 JSON Feed
老的 Atom feed 还在 /feed,但每条 entry 现在都带摘要,以及一个 text/markdown 的 alternate 链接。他还加了一份 JSON Feed,每条 item 里带一个 _markdown_url——JSON Feed 允许以下划线开头的自定义键,所以这不算破坏规范。
Feed 这一层经常被当成"老古董",但对 agent 来说它是最省事的结构化入口:一次请求拿到最近 N 篇的标题、时间、摘要和正文链接,不用逐页爬列表。
六、Meta 标签:从"几乎没有"到一整套
老站几乎没有这些标签,所以这次给每个页面补齐:
- 真实的 meta description、canonical URL、robots 标签,以及
lang="en"; - Open Graph 与 Twitter card 标签,包括
article:published_time和modified_time; - JSON-LD 结构化数据:每篇文章有
BlogPosting和面包屑,索引页有WebSite、Blog,以及代表他本人的Person。
描述这一项比他预想的脏。旧数据库里存着每篇文章的"现成描述",但它是把段落直接拼起来的(…your app.The RevealWhat do I mean…),还有几条里带着裸露的 HTML 标签。现在改成从渲染后的正文里生成摘要。
另外修了 2014 年留下的两处老 markup:
- viewport 标签里带着
maximum-scale=1,它会让手机用户没法双指放大——删掉; - 完全没有
og:image,于是分享文章时 X 和 Threads 会抓页面上的第一张图,而那恰好是顶部那张 Little Bites of Cocoa 的横幅。现在每篇都有 1200×630 的预览卡。
七、IndexNow:发布就通知,30 行脚本
最后是一个 IndexNow key,加一个脚本:每次发文就 ping 一下 Bing 和它的合作方。Google 不参加这个协议,但 Bing 的索引是很多 AI 搜索工具的数据来源,所以这 30 行脚本值得写。
他对整件事的总结很克制:没花多少时间,而且大部分只是文件。 如果你也有一个博客,起点就是两样东西——llms.txt,以及每篇文章的 .md 版本。文章末尾他自己留了一条验证命令:
curl -H "Accept: text/markdown" https://deallocatedobjects.com/posts/making-my-blog-readable-by-ai-agents
八、我们的整理:三种读者、一份自查、五条边界
原文是"我做了什么",下面是我们按它整理出来的"你的站该怎么判断"。
三种读者要的东西不一样
| 人(浏览器) | 搜索爬虫 | AI agent | |
|---|---|---|---|
| 主要读什么 | 渲染后的页面、排版、交互 | HTML、canonical、结构化数据 | 正文纯文本,越长越好一次拿全 |
| 最怕什么 | 弹窗、跳转、慢、字太小 | 重复内容、缺 canonical、JS 才渲染的内容 | 模板噪音、分页、取不到正文 |
| 一次看多少 | 一篇 | 一批 URL | 通常一两页,但要能直接引用 |
| 给你的回报 | 停留、转化 | 排名、收录 | 被复述、被引用、被当成来源 |
这张表解释了一个常见错配:很多"优化"是给人做的(加载速度、视觉),对 agent 完全不起作用;而对 agent 有用的东西(.md、llms.txt、干净的 meta、清楚的 canonical)几乎不会伤到人。所以两边不冲突,只是没人做。
30 分钟自查:五条命令
在你的站上依次跑,能定位到"哪一层缺了":
# 1) 有没有 markdown 端点
curl -sI https://your.site/posts/some-post.md | head -1
# 2) 支不支持 Accept 协商(关键:看 Content-Type)
curl -s -o /dev/null -D - -H "Accept: text/markdown" https://your.site/posts/some-post | grep -i -E "content-type|vary|link|x-robots"
# 3) 有没有 llms.txt
curl -s https://your.site/llms.txt | head -20
# 4) robots.txt 里 agent 有没有被点名(以及有没有被拦)
curl -s https://your.site/robots.txt | grep -i -E "GPTBot|ClaudeBot|PerplexityBot|Google-Extended|Content-Signal"
# 5) 结构化数据在不在
curl -s https://your.site/posts/some-post | grep -o '"@type":"[A-Za-z]*"' | sort -u
判据很硬:第 2 条如果只回 text/html,说明协商没生效;Vary 缺失就不用往下做了,先修缓存那一层。
三个判断,比配置更容易做错
- canonical 与
noindex必须成对出现。 只发.md不声明 canonical,搜索引擎会把它当重复内容;只noindex不给 canonical 链接,agent 拿到了正文却不知道原始页面是哪个,引用就指不回来。两个头是一件事的两半。 Content-Signal是表态,不是协议。 它不会强制任何人遵守,写ai-train=no也不等于模型方就会照做。它的真实作用是把"你的意图"写进可被机器读到的位置,将来出纠纷时有据可依。llms.txt现在不保证被谁读,但成本极低。 它没有标准地位,主流模型厂商也没承诺采纳。判断方法不是"有没有用",而是"维护它要多少成本"——如果它和你的文章清单是同一份构建产物,成本接近零,那就是划算的。
能不能抄到你的站:按平台能力粗分
| 你的站 | .md 版本 |
Accept 协商 | llms.txt |
IndexNow |
|---|---|---|---|---|
| 静态站 + 自建 nginx | 可做 | 可做 | 可做 | 可做 |
| 自托管 Ghost / WordPress(能改主题与反代) | 需写路由或插件 | 需反代层拦截 | 可做 | 可做 |
| 托管型博客平台(不能碰服务器) | 多半不行 | 不行 | 看平台是否允许根目录静态文件 | 看平台 |
| 纯 SaaS 内容站 | 不行 | 不行 | 不行 | 不行 |
最后一行不是嘲讽:平台不给这些能力的时候,能做的只有把内容写清楚、把标题和摘要写对——而这恰恰是权重最大的一项。
站内几条同一条线
- AI 爬虫流量:11 个问答分清爬取、引荐与转化——先分清"AI 在读你"和"有人从 AI 那里点进来"。
- AI 爬虫冒充读者:近 5 倍流量暴涨的取证与 AWS WAF 拦截——反过来的一面:不是所有自称 AI 的流量都值得放进来。
- AI 读到的不是你看的那页:WhatsApp 隐藏指令事件——同一套"给机器读的文本",被用在不想让人看见的地方时是什么样。
五条边界,别把它读成"照做就能被引用"
- 这是个人博客的经验,样本是 1。 原文没有给出任何流量或引用数据,也没有"改完之后被引用次数上升"的证据。它证明的是"这些事可以做,且不难做",不是"做了就有效"。
llms.txt与Content-Signal都还没有标准地位。 引用它们时要说明性质:一个是社区提案,一个是内容用途声明,都不是被广泛实现的协议。- Accept 协商依赖你能改服务器。 托管型博客做不到,这不是技术难度问题,是权限问题。硬要绕(用 CDN 的 edge function)也能做,但维护成本会转移。
.md端点相当于多开一个入口。 凡是多开的入口都会被扫、被抓、被拿去训练;原文的做法(canonical + noindex + 明确的 robots 声明)是"开得可控",不是"开得安全"。- 别指望它替代基础 SEO。 标题、摘要、内链、可抓取性这些老东西仍然是主干;这篇讲的是在主干已经通的情况下,多铺一条给 agent 的车道。
来源:Jake Marsh,《Making My Blog Readable By AI Agents》, Deallocated Objects, 2026-10-24。原文链接:https://deallocatedobjects.com/posts/making-my-blog-readable-by-ai-agents。原文代码块中的 map/rewrite 配置与 curl 命令按原样保留;表 1(三类读者)、自查命令、平台能力表与"三个判断"为我们整理,非原文内容。
本文由汇智网编译整理,转载请注明出处。
这是「AI 基建 / 评测 / 安全」专题的一部分。完整地图见:AI 基建 / 评测 / 安全完全指南