[控场AI]
· 15 分钟阅读· 7,541 字

用Accept头为AI Agent直接提供Markdown内容

用Accept头为AI Agent直接提供Markdown内容

网页正在为两类读者服务

互联网诞生以来,网页内容主要服务于人类读者——通过浏览器渲染的HTML、CSS和JavaScript,构建出图文并茂的视觉体验。然而随着AI Agent、大语言模型爬虫和自动化工具的爆发式增长,一个新的现实浮出水面:如今访问你网站的,可能有相当一部分是机器而非人类。

AI Agent(AI代理)是指能够自主感知环境、制定计划并执行行动以达成特定目标的人工智能系统。与传统的被动式AI应用(如聊天机器人只回答问题)不同,AI Agent具备主动性——它们可以自主决定浏览哪些网页、调用哪些API、如何组合多步操作来完成复杂任务。2024-2025年间,AI Agent从概念走向实际落地,代表性产品包括OpenAI的Operator(可自主操作浏览器完成购物、预订等任务)、Anthropic的Computer Use功能(Claude可以直接操控计算机桌面)、以及各类基于AutoGPT、CrewAI等框架构建的自主代理系统。这些Agent在执行任务时需要大量访问Web内容来获取信息,但它们的"阅读方式"与人类截然不同——不需要视觉渲染,只需要结构化的文本数据。这种新型"读者"的大规模涌现,正是本文讨论的技术方案得以成立的根本背景。

这些AI Agent并不关心你的CSS动画、导航栏布局或广告位。它们需要的是干净、结构化的文本内容。而传统的HTML页面对它们而言,充满了噪音——大量的标签、脚本和样式代码,需要额外的解析才能提取出真正有价值的信息。

最近在Hacker News上引发讨论的一个技术方案,提出了一个优雅的解决思路:利用HTTP的Accept头(Content Negotiation)机制,为AI Agent直接提供Markdown格式的内容。该帖子获得了81个点赞和44条评论,反映出开发者社区对这一话题的浓厚兴趣。

hackernews source: Serve Markdown to AI Agents with Accept Headers

核心思路:基于内容协商的双重服务

什么是Accept头

HTTP协议中的Accept请求头是一个由来已久的标准机制,它允许客户端告诉服务器自己期望接收什么格式的内容。例如,浏览器通常会发送Accept: text/html,表示希望获得HTML页面。这种机制被称为内容协商(Content Negotiation)。

内容协商的技术基础源自RFC 7231规范,是HTTP/1.1协议的核心组成部分。它支持多种协商方式:服务器驱动协商(Server-Driven Negotiation)由服务器根据请求头中的偏好信息自主决定返回格式;代理驱动协商(Agent-Driven Negotiation)则由客户端从服务器提供的多个可选表现中做出选择。除了Accept头之外,HTTP还定义了Accept-Language(语言偏好)、Accept-Encoding(压缩方式偏好)、Accept-Charset(字符集偏好)等一系列类似机制,形成了一套完整的内容适配体系。这一设计深刻体现了REST架构风格的核心理念——同一资源(Resource)可以有多种表现形式(Representation),客户端与服务器通过标准化的元数据交换来协调出最佳的内容表现。

REST(Representational State Transfer)由Roy Fielding在其2000年的博士论文中提出,其核心概念之一正是"资源"与"表现"的分离。一个资源(比如一篇博客文章)是一个抽象概念,它可以有多种具体的表现形式——HTML页面、JSON数据、PDF文档、Markdown文本——这些都是同一资源的不同"视图"。客户端通过URL定位资源,通过Accept头选择偏好的表现形式。从这个角度看,为AI Agent提供Markdown格式并不是什么创新发明,而是对HTTP协议原始设计意图的一次回归——只不过在过去的Web发展中,HTML几乎成了唯一的表现形式,内容协商机制在实践中被严重低估了。

这套方案的核心逻辑很简单:当请求头中包含Accept: text/markdown时,服务器返回内容的Markdown版本;当收到常规的Accept: text/html时,则返回完整的HTML页面。同一个URL,根据请求方的身份和需求,返回最合适的表现形式。

为什么选择Markdown作为AI Agent的内容格式

Markdown由John Gruber与Aaron Swartz于2004年共同设计,最初定位为一种轻量级标记语言,让人们能用纯文本格式编写文档,同时保持可读性。其设计哲学深受电子邮件纯文本排版惯例的影响——用#表示标题、用*表示强调、用-表示列表,这些符号选择都源自早期互联网社区的自发实践。Markdown最初只有Gruber定义的非正式规范,缺乏统一标准,导致不同实现(如GitHub Flavored Markdown、MultiMarkdown、PHP Markdown Extra)之间存在细微差异。2014年,John MacFarlane发起了CommonMark项目,试图为Markdown建立一套严格的、无歧义的语法规范。如今Markdown已成为技术文档、开源项目、知识管理系统的事实标准格式,GitHub、Stack Overflow、Notion、Obsidian等平台都以Markdown为核心内容格式。这种广泛的生态基础也意味着大语言模型的训练语料中包含了海量的Markdown文本,使得模型对Markdown的解析和生成能力格外强健。

Markdown之所以成为AI Agent的理想内容格式,原因在于以下几个方面:

  • 信噪比高:去除了HTML的冗余标签,纯粹保留内容与基本结构
  • 保留语义结构:标题、列表、链接、代码块等结构信息完整保留,便于模型理解文档层次
  • Token效率:对于按Token计费的大模型而言,Markdown比HTML节省大量Token,直接降低推理成本
  • 模型友好:主流大语言模型在训练中大量接触Markdown,对其格式有天然的理解能力

在Token经济学层面,这种格式选择的意义更加具体。大语言模型在推理时,输入文本首先被分词器(Tokenizer)切分为Token序列。以GPT-4的Tokenizer为例,一个普通英文单词平均占用1-2个Token,而一个HTML标签如<div class="container">可能消耗5-8个Token,却完全不携带语义信息。实际测试表明,同一篇文章的完整HTML版本通常比对应的Markdown版本多消耗40%-70%的Token。考虑到GPT-4等模型的API按Token计费(输入约$30-60/百万Token),在大规模内容抓取和分析场景下,格式优化带来的成本节省相当可观。这也解释了为什么Jina Reader、Firecrawl等专为AI设计的网页抓取工具,都内置了HTML-to-Markdown的转换能力——它们本质上是在客户端侧完成了服务端本可以直接提供的工作。

相比之下,让AI去解析原始HTML不仅浪费算力,还容易因为混杂的样式和脚本代码导致信息提取错误。

技术实现与生态背景

与llms.txt方案的对比

这一思路并非孤立出现,而是当前"为AI优化网站"浪潮中的一环。此前业界已经出现了llms.txt提案——类似于robots.txt,网站在根目录放置一个专门为大模型准备的Markdown文件,罗列关键内容和链接。

llms.txt由Jeremy Howard(fast.ai创始人、深度学习教育领域的知名人物)于2024年正式提出,其设计灵感直接来自robots.txt和sitemap.xml的哲学——通过一个约定俗成的文件路径,实现网站与自动化系统之间的标准化沟通。具体而言,网站在/.well-known/llms.txt路径放置一个Markdown格式文件,用结构化的方式描述网站的核心内容摘要、重要页面链接、API文档入口以及内容使用条款。与robots.txt侧重于控制爬虫的抓取行为("哪些不要爬")不同,llms.txt的目标是主动引导AI系统高效获取最有价值的信息("这些最值得看")。目前已有Cloudflare、Anthropic、Stripe等科技公司在其官网部署了llms.txt文件。该提案还衍生出llms-full.txt(网站完整内容的Markdown导出)等变体规范。

与llms.txt需要额外维护独立文件不同,基于Accept头的方案更加"就地取材":它不改变URL结构,而是让同一个资源地址根据请求方动态适配格式。这意味着AI Agent无需了解特殊的文件路径规则,只需在标准的HTTP请求中声明内容偏好即可。

服务端实现的关键步骤

在实际部署中,这套方案通常需要在服务端或CDN层做处理:

1. 检查请求头中的 Accept 字段
2. 若匹配 text/markdown,返回预生成或实时转换的 Markdown
3. 否则返回标准 HTML
4. 通过 Vary: Accept 头告知缓存系统按格式区分缓存

有意思的是Vary: Accept响应头的重要性——它确保CDN和浏览器缓存不会把Markdown版本错误地返回给期望HTML的人类用户,反之亦然。

Vary响应头是HTTP缓存体系中至关重要但常被开发者忽视的机制。它的作用是告知所有中间缓存节点(包括CDN边缘服务器、反向代理、浏览器本地缓存):对于同一个URL,响应内容会因为某些特定请求头的值不同而产生变化,因此需要为不同的请求头组合分别维护独立的缓存副本。具体到本方案,Vary: Accept意味着Accept: text/html和Accept: text/markdown两种请求对应的响应必须被独立缓存,互不干扰。如果服务端漏掉了Vary头,Cloudflare、Fastly等CDN可能会将首次缓存的Markdown响应错误地返回给后续的浏览器请求,导致用户看到一堆原始Markdown文本而非渲染好的页面。

在大规模部署时,CDN层面的缓存管理是最容易出问题的环节之一。主流CDN服务商对Vary头的处理策略差异显著:Cloudflare在其默认配置中会忽略Vary头中除Accept-Encoding以外的字段,这意味着即使服务端正确设置了Vary: Accept,Cloudflare的边缘缓存仍可能混淆HTML和Markdown响应,需要通过Cache Rules或Workers来自定义缓存逻辑;Fastly对Vary头的支持较为完善,但过多的Vary字段会导致缓存命中率急剧下降;AWS CloudFront则需要在Distribution配置中显式将Accept头加入缓存键(Cache Key),默认情况下不转发Accept头到源站。此外,如果Accept头包含了复杂的质量权重值(如Accept: text/html;q=0.9, text/markdown;q=1.0),理论上每种不同的权重组合都可能生成独立的缓存条目,进一步加剧缓存碎片化问题。这也是为什么在CDN层面实施内容协商需要格外谨慎的配置。

社区争议:理想与现实的差距

Hacker News的44条评论中,开发者们提出了不少值得深思的质疑,体现出这一方案在落地时面临的现实挑战。

AI爬虫是否会发送正确的Accept头

最核心的质疑在于:多数AI爬虫和Agent实际上并不会主动发送Accept: text/markdown。它们往往沿用通用的User-Agent和默认的Accept头,把自己伪装成普通浏览器,或者干脆抓取原始HTML后再自行清洗。除非有一个被广泛遵循的行业标准,否则服务端精心准备的Markdown可能无人问津。

当前AI爬虫的生态现状印证了这一担忧。主流AI公司的爬虫包括GPTBot(OpenAI)、ClaudeBot(Anthropic)、Google-Extended(Google DeepMind)、Bytespider(字节跳动)等,它们通常通过User-Agent字符串来自我标识身份。然而大量独立研究和监测数据表明,AI训练数据的抓取行为中有相当比例并不遵循robots.txt协议,也不使用标准化或可识别的请求头。DoubleVerify在2024年发布的报告显示,AI爬虫流量已占部分内容网站总流量的30%以上,但其中大量请求未正确标识来源身份。这意味着基于Accept头的方案面临一个典型的"鸡生蛋"问题:网站准备好了Markdown响应,但AI Agent不知道应该请求它;AI Agent没有动力发送特殊的Accept头,因为大多数网站并不支持这种协商。这种双向依赖需要某种行业协调或标准推动才能打破。

维护双份内容的同步成本

另一部分开发者担心内容一致性问题。如果Markdown和HTML是分别生成的,就存在两者不同步的风险。理想的做法是让两种格式从同一份内容源自动派生,但这对现有的许多CMS和静态站点生成器而言并非开箱即用。

从内容架构的角度来看,内容与呈现的分离是Web技术长期演进的方向,而现代Headless CMS的出现为解决这一问题提供了天然的基础设施。从早期CSS将视觉样式从HTML结构中剥离,到Headless CMS(如Strapi、Contentful、Sanity)将内容管理与前端展示完全解耦,再到如今为AI提供专用的纯文本格式,这条技术演进线索一脉相承。现代Headless CMS通常将内容存储为结构化数据(JSON对象或富文本的抽象语法树AST),前端应用通过API获取原始内容后自行渲染为HTML。这种架构天然支持多格式输出——同一份内容源可以同时生成HTML页面、Markdown文档、RSS订阅、AMP页面等多种格式,从根本上消除了手动维护双份内容的同步负担。对于仍在使用WordPress等传统CMS的站点,则可能需要借助HTML-to-Markdown转换库在请求时动态生成,这虽然增加了服务端计算开销,但避免了内容不一致的问题。

MIME类型与标准之争

还有讨论指出,究竟应该用text/markdown还是自定义的MIME类型、是否应与llms.txt等方案协同,目前尚无定论。在标准未统一之前,各家自行其是可能导致生态碎片化。

值得一提的是,text/markdown这一MIME类型实际上已在2016年通过RFC 7763被正式注册为IANA标准媒体类型,并非社区的非正式约定。该RFC还定义了charset和variant两个可选参数,其中variant参数允许指定具体的Markdown方言(如CommonMark、GFM等)。然而在实践中,这一MIME类型的采用率极低——绝大多数Web服务器和CDN的默认MIME类型配置中并不包含它,开发者需要手动添加。更复杂的问题在于,是否有必要进一步区分"面向人类阅读的Markdown"与"面向AI消费的Markdown",后者可能需要包含额外的元数据(如内容摘要、关键实体、更新时间戳等),这在现有的MIME类型体系中尚无对应的标准化方案。

更深层的思考:Web正在分叉

抛开具体的技术细节,这场讨论折射出一个更宏大的趋势:互联网内容的消费者正在从"以人为主"转向"人机并存"。

过去二十年,前端工程围绕人类的视觉体验不断加码——越来越复杂的单页应用、越来越重的JavaScript框架。现代单页应用(如基于React、Vue、Angular构建的站点)采用客户端渲染(Client-Side Rendering, CSR)模式:服务器返回的HTML文件几乎是空的(只有一个根节点如<div id="app">),所有实际内容都由JavaScript在浏览器中动态生成。这意味着传统的HTTP GET请求获得的HTML文档不包含任何实质内容。AI爬虫要获取真实内容,要么需要运行完整的JavaScript引擎(如Puppeteer、Playwright等无头浏览器),代价是显著增加抓取时间和计算资源消耗;要么依赖预渲染/服务端渲染(SSR)方案(如Next.js、Nuxt.js),但这需要网站主动配置。据Web Almanac的统计,2024年约有超过35%的网站高度依赖客户端JavaScript来呈现核心内容。而现在,我们不得不重新思考:当访问者是AI时,这些复杂性反而成了负担。在这种背景下,直接提供Markdown格式绕过了整个渲染链条,是一种从根本上降低AI内容获取成本的方案。

为AI提供Markdown,本质上是在为机器读者开辟一条"快车道"。这不仅仅是格式转换的技术问题,更是内容架构理念的转变——内容与呈现的彻底分离,让同一份知识能够以最适合不同消费者的形态被访问。

可以预见,随着AI Agent逐渐成为网站流量的重要组成部分,类似的内容协商机制、面向机器的内容格式规范,将成为Web开发中一个不可忽视的新维度。无论最终胜出的是Accept头方案、llms.txt还是其他标准,为机器读者优化内容这件事,都已势在必行。

结语

"用Accept头为AI Agent提供Markdown"是一个技术上简洁、理念上前瞻的方案。它复用了HTTP协议中成熟的内容协商机制,避免了引入全新的规范,同时切中了AI时代内容分发的真实痛点。

尽管在爬虫兼容性、内容同步和标准统一等方面仍存在现实障碍,但它所指向的方向——让Web同时优雅地服务人类与机器——无疑是未来几年值得持续关注的技术趋势。对于内容型网站的开发者而言,现在正是开始思考如何构建"AI友好"内容架构的时候。

核心要点

核心要点

#Accept头#AI Agent#Markdown#内容协商#Content Negotiation#llms.txt#AI爬虫优化#Web内容分发
分享:

相关推荐