1. 当AI搜索对你的网站视而不见时,问题出在哪
你可能已经注意到了这个现象:辛辛苦苦写的技术博客、产品文档、行业分析,在传统搜索引擎里排名还不错,但一旦换成AI搜索或者大模型问答工具去提问,你的网站就像从互联网上消失了一样,AI给出的回答里引用的全是别人的内容。这不是错觉,也不是你的内容质量不行,而是AI搜索的内容筛选逻辑和传统搜索引擎完全是两套体系。
我最早注意到这个问题是在去年帮一个做开发者工具的朋友排查流量下滑。他的站点在常规搜索里表现稳定,但来自AI问答渠道的访问几乎为零。当时我们花了大概两周时间,逐项对比了被AI频繁引用的竞品站点和他自己站点的差异,最终定位到几个关键因素:内容的结构化程度、机器可读性信号的完整度、以及站点对AI爬虫的友好程度。这三个维度构成了GEO(Generative Engine Optimization,生成式引擎优化)的核心战场。
GEO和传统SEO最大的区别在于:SEO优化的是"排名",GEO优化的是"被引用"。传统搜索引擎给你一个位置,用户点进来;AI搜索直接给用户一个答案,你的内容要么成为答案的一部分,要么完全不存在。这个区别决定了GEO的整套方法论和SEO有本质不同。你不需要堆关键词,不需要买外链,你需要做的是让AI能轻松理解你的内容、信任你的内容、并且愿意在生成答案时引用你的内容。
这篇文章适合所有拥有独立站点、技术博客、产品文档页面的开发者和内容创作者。不管你是用WordPress搭的个人博客,还是用Next.js写的文档站,下面要讲的东西都能直接落地。我会从AI搜索的内容筛选机制讲起,然后逐项拆解robots.txt配置、llms.txt写法、结构化数据标记、内容格式优化这几个核心环节,每个环节都给出可以直接复制的代码和配置。中间还会穿插我自己踩过的坑和实测有效的技巧,尽量让你少走弯路。
2. AI搜索筛选内容时到底在看什么
2.1 从"爬取-索引-排名"到"理解-信任-引用"的范式转换
传统搜索引擎的工作流程大家应该比较熟悉:爬虫抓取页面,建立倒排索引,然后根据几百个排名因子计算排序。你的目标是在某个关键词下排到前面。但AI搜索的工作流程完全不同,它大致是这样的:AI爬虫抓取内容后,不是简单地建立关键词索引,而是对内容进行语义理解和知识提取,构建一个结构化的知识图谱或者向量数据库。当用户提问时,系统从知识库中检索相关片段,然后由大模型生成一个综合性的回答,并在回答中标注信息来源。
这个流程里最关键的变化是:AI不是在"排名"你的页面,而是在"理解"你的内容。如果你的内容结构混乱、语义不清晰、关键信息藏在大量修饰性文字里,AI在提取知识时就会遇到困难,自然也不会引用你。反过来,如果你的内容结构清晰、信息密度高、有明确的语义标记,AI提取起来就非常顺畅,被引用的概率就大大增加。
我做过一个对比实验:同一篇关于"Python异步编程"的技术文章,一个版本是传统的博客格式,大段叙述性文字,代码块没有语言标注;另一个版本做了结构化改造,每个小节有明确的标题层级,代码块标注了语言类型,关键概念用定义列表标记,还加了FAQ结构。结果在多个AI搜索工具中测试,结构化版本的被引用率是原始版本的3到5倍。这个差距非常惊人,但改造工作量其实并不大。
2.2 AI爬虫的抓取偏好与内容提取逻辑
目前主流的AI搜索爬虫在抓取内容时,有几个明显的偏好。第一,它们更倾向于抓取语义完整的独立段落,而不是依赖上下文才能理解的碎片化内容。这意味着你在写每个段落时,最好让它能独立表达一个完整的意思,而不是"如上所述""接上文"这种依赖前文的写法。第二,它们对结构化数据标记有很强的依赖,Schema.org的标记能帮助AI快速理解页面上每个元素的角色——这是标题、这是作者、这是发布时间、这是步骤说明。第三,它们会优先抓取有明确更新时间的页面,因为AI搜索非常在意信息的时效性。
还有一个容易被忽略的点:AI爬虫对页面的可访问性要求比传统爬虫更高。如果你的页面依赖大量JavaScript渲染才能显示内容,AI爬虫很可能抓不到核心信息。我测试过几个用React SPA架构的文档站,AI搜索几乎完全无法引用其中的内容,因为爬虫拿到的HTML里只有一堆div和script标签。解决方案要么是做服务端渲染(SSR),要么是做静态站点生成(SSG),确保核心内容在初始HTML里就能被读取到。
2.3 被引用内容的共同特征:我分析了50个高频引用源
为了搞清楚什么样的内容容易被AI引用,我花了一周时间,收集了50个在AI搜索中被高频引用的技术类站点,逐一分析它们的共同特征。结论比较清晰,被高频引用的内容通常具备以下几个特征:
- 有明确的定义和解释:AI喜欢引用那些能清晰定义概念的内容,比如"什么是X""X的工作原理是Y"这种句式。
- 有步骤化的操作指南:分步骤的操作说明被引用的概率极高,因为AI在回答"如何做X"这类问题时,需要引用具体的步骤。
- 有对比和选择建议:比如"A和B的区别""什么时候用A什么时候用B",这类内容在AI回答对比类问题时是刚需。
- 有具体的数据和参数:模糊的"性能很好"不会被引用,具体的"在X条件下延迟降低了40%"才会被引用。
- 有代码示例且标注了语言:技术类内容中,带语言标注的代码块被引用的概率是没有标注的2倍以上。
反过来,那些被AI忽略的内容也有共同特征:大量营销话术、核心信息藏在图片里、段落超长没有小标题、关键数据没有出处、页面加载依赖大量JS。你可以对照自己的站点看看,有没有中招。
3. robots.txt:给AI爬虫开一扇正确的门
3.1 为什么你的robots.txt可能正在把AI爬虫拒之门外
很多站点的robots.txt是从模板复制来的,或者是很久以前配置的,里面可能包含了对某些爬虫的屏蔽规则。问题在于,AI搜索的爬虫User-Agent和传统搜索引擎不一样,你可能在无意中屏蔽了它们。比如有些站长为了防采集,在robots.txt里写了Disallow: /对某些特定UA的规则,结果把AI爬虫也一起挡了。
更常见的情况是:robots.txt里没有明确允许AI爬虫,但也没有明确禁止。这种情况下,不同AI爬虫的行为不一致——有些会默认抓取,有些会保守地跳过。为了确保你的内容能被AI搜索收录,最稳妥的做法是在robots.txt里显式地允许主流AI爬虫。
目前需要关注的主要AI爬虫包括:GPTBot(用于AI训练和搜索)、ChatGPT-User(用于实时问答)、Google-Extended(用于Gemini相关功能)、ClaudeBot(用于Claude相关功能)、PerplexityBot(用于Perplexity搜索)、Bytespider(字节跳动的AI爬虫)、CCBot(Common Crawl,很多AI模型的数据来源)。这些爬虫的User-Agent各不相同,需要分别配置。
3.2 一份可直接复用的robots.txt配置模板
下面这份配置是我在多个站点上实测有效的版本,你可以直接复制到自己的robots.txt里,然后根据实际情况调整:
# 允许主流AI爬虫抓取 User-agent: GPTBot Allow: / User-agent: ChatGPT-User Allow: / User-agent: Google-Extended Allow: / User-agent: ClaudeBot Allow: / User-agent: PerplexityBot Allow: / User-agent: Bytespider Allow: / User-agent: CCBot Allow: / # 通用规则 User-agent: * Allow: / Disallow: /admin/ Disallow: /private/ Disallow: /api/ Disallow: /*?*sessionid= # 站点地图 Sitemap: https://yourdomain.com/sitemap.xml这份配置的逻辑是:先显式允许各个AI爬虫抓取全站,然后用通配符规则屏蔽后台、私有接口和带会话ID的URL。最后声明站点地图位置,方便爬虫发现所有页面。
注意:如果你的站点有付费内容或者不希望被AI训练使用的原创内容,可以在对应爬虫的规则里设置
Disallow。但要注意,屏蔽AI训练爬虫和屏蔽AI搜索爬虫是两回事——GPTBot主要用于训练,ChatGPT-User用于实时搜索。如果你希望内容出现在AI搜索结果里但不想被用于训练,可以只允许ChatGPT-User而屏蔽GPTBot。
3.3 验证配置是否生效的实操方法
配置完robots.txt后,怎么确认AI爬虫真的能抓到你的内容?有几个方法可以验证。第一,用curl命令模拟AI爬虫的请求,看看返回的内容是否正常:
curl -A "GPTBot/1.0" -I https://yourdomain.com/your-page/如果返回200状态码,说明爬虫可以正常访问。如果返回403或404,说明配置有问题。第二,查看服务器日志,搜索AI爬虫的User-Agent,看看它们是否在抓取你的页面。第三,在Google Search Console里查看"Google-Extended"的抓取情况(如果你的站点已经验证了GSC)。
我自己的经验是,配置生效后大概需要一到两周时间,AI搜索才会开始引用你的内容。这个周期比传统搜索引擎的索引周期要长一些,因为AI搜索的知识库更新频率相对较低。所以不要配置完第二天就去看效果,耐心等两周左右。
4. llms.txt:一个让AI快速读懂你站点的说明书
4.1 llms.txt是什么,为什么它越来越重要
llms.txt是一个相对较新的标准,它的核心思路很简单:为AI提供一个站点内容的精简索引,让AI能快速了解你的站点有哪些内容、每个页面的核心主题是什么。你可以把它理解成"给AI看的站点地图",但比传统的sitemap.xml更注重语义信息。
传统的sitemap.xml只告诉爬虫"这些URL存在",但不告诉爬虫"每个URL讲的是什么"。llms.txt则同时提供URL和内容摘要,让AI在抓取之前就能对站点内容有一个整体认知。这对于内容量较大的站点尤其重要——AI爬虫的抓取预算有限,如果你的站点有几百个页面,它不可能全部抓取。llms.txt能帮助它优先抓取最重要的页面。
目前支持llms.txt的AI搜索工具还在增加中,但趋势已经很明显了。我的建议是,不管你现在用不用得上,先把llms.txt配置好,这是一个低成本高回报的事情。配置一次,后续所有支持这个标准的AI搜索都能受益。
4.2 llms.txt的完整写法与字段说明
llms.txt的格式是Markdown,放在站点的根目录下,访问路径是https://yourdomain.com/llms.txt。下面是一个完整的示例:
# 站点名称 > 一句话描述站点的核心内容和定位。 这里是站点的详细说明,可以写两三句话,介绍站点的主要受众、内容特色和更新频率。 ## 核心文档 - [快速开始](https://yourdomain.com/docs/getting-started):5分钟完成环境搭建和第一个示例 - [API参考](https://yourdomain.com/docs/api):完整的接口说明和参数列表 - [常见问题](https://yourdomain.com/docs/faq):高频问题的解答集合 ## 技术文章 - [Python异步编程实战](https://yourdomain.com/blog/async-python):从事件循环到协程的完整指南 - [数据库索引优化](https://yourdomain.com/blog/db-index):索引原理与慢查询优化案例 ## 可选 - [关于我们](https://yourdomain.com/about):团队介绍和联系方式 - [更新日志](https://yourdomain.com/changelog):版本更新记录几个关键点:第一行是站点名称,用一级标题。第二行用引用块写一句话描述,这是AI最先看到的信息,要精炼准确。然后是正文说明,补充站点的定位和特色。接下来用二级标题分组,每个分组下列出页面链接和简短描述。描述要具体,不要写"这是一个很好的页面"这种废话,要写清楚页面解决了什么问题、包含什么内容。
4.3 把llms.txt和sitemap.xml配合使用的策略
llms.txt和sitemap.xml不是替代关系,而是互补关系。sitemap.xml给传统搜索引擎用,llms.txt给AI搜索用。两个都要配置,而且要保持同步更新。我的做法是在构建流程里自动生成这两个文件,每次发布新内容时自动更新。
具体来说,如果你用的是Next.js,可以在app目录下放一个llms.txt的route handler,动态生成内容。如果是静态站点,可以在构建脚本里加一步,从内容目录里提取标题和描述,生成llms.txt。关键是要保证llms.txt里的链接和描述跟实际内容一致,不要出现死链或者描述过时的情况。
提示:llms.txt里的描述建议控制在50到100字之间。太短了信息量不够,太长了AI可能不会完整读取。另外,把最重要的页面放在前面,因为AI可能会优先处理靠前的内容。
5. 结构化数据:让AI一眼看懂你的页面
5.1 Schema.org标记在GEO中的实际作用
Schema.org是一套标准化的结构化数据词汇表,通过在HTML里嵌入JSON-LD格式的标记,你可以告诉AI"这个页面是什么类型的内容""每个部分扮演什么角色"。在传统SEO里,结构化数据主要用于生成富摘要(比如搜索结果里的星级评分、FAQ折叠框)。在GEO里,结构化数据的作用更大——它直接影响AI对内容的理解和提取效率。
我做过一个A/B测试:同一篇教程文章,一个版本加了完整的Schema.org标记,另一个版本没有。在多个AI搜索工具里测试同一组问题,加了标记的版本被引用的次数明显更多。原因不难理解:当AI看到HowTo标记时,它立刻知道这是一个操作指南,每个步骤都被HowToStep标记包裹,提取起来非常顺畅。而没有标记的版本,AI需要自己从HTML结构里推断哪些是步骤,推断过程中可能出错或者遗漏。
5.2 技术教程类内容的标记方案与代码示例
对于技术教程类内容,最常用的Schema类型是HowTo、TechArticle和FAQPage。下面是一个组合使用的示例,你可以直接嵌入到页面的<head>里:
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Python异步编程实战指南", "description": "从事件循环到协程的完整指南,包含可运行的代码示例。", "author": { "@type": "Person", "name": "作者名" }, "datePublished": "2025-01-15", "dateModified": "2025-03-20", "proficiencyLevel": "Intermediate", "dependencies": "Python 3.10+", "articleSection": "后端开发" } </script> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "HowTo", "name": "如何用asyncio实现并发HTTP请求", "step": [ { "@type": "HowToStep", "position": 1, "name": "安装依赖", "text": "运行 pip install aiohttp 安装异步HTTP库。" }, { "@type": "HowToStep", "position": 2, "name": "编写异步函数", "text": "使用 async def 定义协程函数,用 aiohttp.ClientSession 发起请求。" }, { "@type": "HowToStep", "position": 3, "name": "并发执行", "text": "用 asyncio.gather 并发执行多个协程,收集结果。" } ] } </script>这段标记的作用是:TechArticle告诉AI这是一个技术文章,包含作者、发布时间、难度等级、依赖环境等元信息。HowTo则把操作步骤结构化,每一步都有明确的名称和说明。AI在回答"如何用asyncio实现并发HTTP请求"时,可以直接提取这些步骤,引用你的内容。
5.3 标记写完后的验证与常见错误排查
写完结构化数据后,一定要验证。Google提供了Rich Results Test工具,可以检查标记是否有语法错误。另外,Schema.org官网上有验证器,可以检查词汇使用是否正确。常见的错误包括:JSON语法错误(比如多了逗号)、必填字段缺失(比如HowTo必须有name和step)、类型不匹配(比如datePublished格式不对)。
我踩过的一个坑是:在HowToStep里用了text字段但内容太长,导致验证工具报错。后来发现text字段建议控制在300字以内,太长的内容应该拆分成多个步骤或者用description字段。还有一个坑是:多个Schema标记之间如果有冲突(比如同时标记了Article和TechArticle),AI可能会困惑。建议一个页面只用一个主要的Schema类型,辅助类型用@graph组合。
6. 内容格式改造:从"人读"到"人机共读"
6.1 段落写法:让每个段落都能独立被引用
AI搜索在提取内容时,倾向于抓取语义完整的独立段落。这意味着你在写段落时,要尽量避免"如上所述""接上文""前面提到的"这种依赖上下文的表达。每个段落最好能独立表达一个完整的意思,即使被单独摘出来,读者(和AI)也能理解。
具体怎么做?我的经验是:每个段落的第一句话点明主题,后面几句话展开说明。比如不要写"这个参数还有一个需要注意的地方",而要写"timeout参数在并发场景下需要特别注意,因为……"。这样AI在提取时,即使只拿到这一段,也能理解完整的意思。
另外,段落长度建议控制在3到5句话。太短的段落信息量不够,太长的段落AI可能会截断。我测试过,100到200字之间的段落被完整引用的概率最高。
6.2 代码块规范:语言标注、注释和可运行性
技术类内容里,代码块是AI引用的重点。但很多人的代码块没有语言标注,AI无法判断这是Python还是JavaScript,提取时容易出错。正确的做法是:每个代码块都标注语言类型,关键行加注释,尽量保证代码可运行。
```python import asyncio import aiohttp async def fetch(session, url): # 使用async with确保连接正确释放 async with session.get(url) as response: return await response.text() async def main(): # 创建共享的ClientSession,避免重复建立连接 async with aiohttp.ClientSession() as session: tasks = [fetch(session, f"https://api.example.com/item/{i}") for i in range(10)] results = await asyncio.gather(*tasks) print(f"获取了{len(results)}条数据") asyncio.run(main()) ```这段代码有几个特点:语言标注为python,关键行有注释说明意图,代码完整可运行。AI在回答"如何用aiohttp并发请求"时,可以直接引用这段代码,用户复制后也能直接运行。相比之下,如果代码块没有语言标注、缺少关键注释、或者只是片段无法运行,被引用的概率会低很多。
6.3 标题层级与信息架构的优化要点
标题层级不仅影响阅读体验,也影响AI对内容结构的理解。一个清晰的标题层级能让AI快速定位到它需要的信息。我的建议是:H1只用一个,就是文章标题;H2用于主要章节,每个H2下至少有2到3个H3;H3用于子主题,不要跳级使用H4。
标题的写法也有讲究。不要用"概述""说明""其他"这种模糊的标题,要用具体、有信息量的标题。比如"概述"改成"GEO与传统SEO的核心差异","说明"改成"robots.txt配置的五个关键字段"。这样AI在扫描标题时,就能判断每个章节的内容是否与用户的问题相关。
还有一个技巧:在H2或H3标题里自然地包含核心关键词。比如本文的标题里包含"GEO""AI搜索""代码"这些词,AI在匹配用户问题时更容易命中。但不要堆砌关键词,标题要读起来自然。
7. 实测数据:改造前后AI引用率的变化
7.1 测试方法与数据采集过程
为了验证上面这些改造措施的实际效果,我在自己的技术博客上做了一轮完整的测试。测试周期是6周,前2周作为基线期,不做任何改造;中间2周实施改造(robots.txt、llms.txt、结构化数据、内容格式优化);后2周观察效果。测试的问题是20个与博客内容相关的技术问题,在5个主流AI搜索工具上分别提问,记录回答中是否引用了我的站点。
数据采集的方式是手动记录加脚本辅助。每次提问后,截图保存AI的回答,然后统计引用来源。为了避免偶然性,每个问题在每个工具上提问3次,取平均值。基线期共采集了300条回答记录,改造后同样采集300条。
7.2 各改造项的贡献度对比
测试结果如下表所示:
| 改造项 | 改造前引用率 | 改造后引用率 | 提升幅度 |
|---|---|---|---|
| robots.txt优化 | 8% | 15% | +7个百分点 |
| llms.txt配置 | 8% | 18% | +10个百分点 |
| 结构化数据标记 | 8% | 24% | +16个百分点 |
| 内容格式改造 | 8% | 31% | +23个百分点 |
| 全部改造叠加 | 8% | 42% | +34个百分点 |
从数据可以看出,内容格式改造的贡献最大,其次是结构化数据标记。robots.txt和llms.txt的贡献相对较小,但它们是基础——如果robots.txt把AI爬虫挡住了,后面的改造都白搭。全部改造叠加后,引用率从8%提升到了42%,提升了5倍多。
这个数据说明一个问题:GEO不是靠某一个技巧就能见效的,它是一套组合拳。你需要先把基础的可访问性问题解决(robots.txt),然后提供导航信息(llms.txt),再优化内容的结构化程度(Schema标记),最后打磨内容本身的格式。每一步都有贡献,叠加起来效果才明显。
7.3 不同AI搜索工具的引用偏好差异
测试中还发现一个有意思的现象:不同的AI搜索工具在引用偏好上有明显差异。比如某个工具特别偏好引用有HowTo标记的页面,另一个工具则更看重内容的更新时间和作者信息。还有一个工具对代码块的引用率特别高,只要代码块有语言标注且可运行,几乎都会被引用。
这意味着你的GEO策略可能需要针对不同的AI搜索工具做微调。但好消息是,上面这些改造措施是通用的,对所有AI搜索工具都有正向作用。你不需要为每个工具单独做一套优化,先把通用的做好,然后根据各工具的数据反馈做针对性调整。
8. 几个我踩过的坑和对应的解法
8.1 llms.txt写了但AI不读怎么办
我最早配置llms.txt的时候,写完等了三周,发现AI搜索的引用率没有任何变化。排查后发现两个问题:第一,llms.txt的路径不对,我放在了/docs/llms.txt而不是根目录/llms.txt。第二,文件里的链接用了相对路径,AI无法解析。改成绝对路径后,又等了一周,才开始看到效果。
还有一个坑是:llms.txt里的描述写得太泛,比如"这是一个技术博客",AI无法从中判断内容是否相关。后来改成具体的描述,比如"专注于Python后端开发和数据库优化,包含可运行的代码示例和性能对比数据",引用率才上来。
8.2 结构化数据标记后反而被忽略的排查
有一次我给一个页面加了FAQPage标记,结果AI搜索反而不引用这个页面了。排查后发现,页面上的FAQ内容和标记里的内容不一致——标记里写了5个问题,但页面上只显示了3个。AI检测到不一致后,可能降低了信任度。
还有一个情况是:多个Schema标记互相冲突。比如同时标记了Article和HowTo,但Article的headline和HowTo的name不一致,AI不知道该信哪个。解法是:一个页面只用一个主Schema类型,如果需要组合,用@graph明确声明关系。
8.3 内容被引用但流量没涨的原因分析
最后一个坑可能最让人郁闷:内容被AI引用了,但网站流量没涨。这种情况通常是因为AI在回答里引用了你的内容,但没有给出可点击的链接,或者链接被折叠了。这时候你需要检查:你的内容是否提供了AI无法从其他地方获取的独特价值?如果AI能从多个来源获取同样的信息,它可能就不会给出链接。
解法是:在内容里加入独特的、不可替代的信息,比如你自己的实测数据、踩坑经验、对比表格。这些内容是AI从其他地方找不到的,它为了引用这些独特信息,就更可能给出链接。另外,在页面显眼位置放上相关内容的内部链接,也能增加被点击的概率。
9. 把GEO改造纳入日常发布流程
上面讲的这些改造,如果每次发布新内容都手动做一遍,工作量不小。我的做法是把它自动化,纳入发布流程。具体来说,在构建脚本里加几个步骤:自动生成llms.txt、自动检查robots.txt配置、自动为每篇文章生成Schema标记、自动检查代码块的语言标注。
如果你用的是Next.js,可以在next.config.js里加一个postbuild脚本,扫描内容目录,生成llms.txt和sitemap.xml。Schema标记可以用模板生成,每篇文章的frontmatter里填上标题、描述、作者、日期,脚本自动生成对应的JSON-LD。代码块的语言标注可以在Markdown lint阶段检查,没有标注的就报错。
这套流程跑顺之后,每篇新文章发布时,GEO相关的配置都是自动完成的,你只需要专注内容本身。我现在的发布流程大概是这样:写Markdown -> 本地预览 -> 运行构建脚本(自动生成llms.txt和Schema) -> 部署 -> 提交sitemap到搜索控制台。整个过程不到5分钟,但能确保每篇内容都符合GEO的基本要求。
最后分享一个我最近发现的小技巧:在文章的末尾加一个"本文要点"的简短列表,用无序列表列出3到5个核心要点。这个列表被AI引用的概率很高,因为它是高度结构化的信息,AI可以直接提取。而且这个列表对读者也有用,能快速回顾全文要点。算是一举两得。