返回博客

网站 GEO 优化实战:把一个内容站改造成「AI 搜索引擎友好」的全流程

2026-10-15
AI
9 分钟

前段时间我花了半天时间,给一个内容型网站做了一次完整的 GEO(Generative Engine Optimization,生成式引擎优化)改造。改完之后用 GEO 检测工具复查,大部分指标从红转绿。

这篇文章把整个流程整理出来:怎么发现问题、每个问题怎么修、以及一份可以直接套用的检查清单。案例站点是一个典型的 Next.js 内容站,但问题几乎都是通用的——你的站大概率也有同款。

AI 机器人用放大镜扫描网页:GEO 优化让内容被 AI 搜索引擎读取

一、先搞清楚:GEO 和 SEO 有什么区别

SEO 优化的对象是搜索引擎的爬虫和排序算法;GEO 优化的对象是 AI 搜索引擎(ChatGPT、Perplexity、豆包、Kimi 等)的抓取和引用逻辑。

两者最大的区别有一个非常具体的工程含义:

AI 爬虫基本不执行 JavaScript。

Google 至少还有二段渲染机制,会执行 JS 再索引;百度对 JS 渲染支持很差;而 GPTBot、ClaudeBot 这类 AI 爬虫,抓的就是原始 HTML。如果你的内容靠客户端 JS 渲染,对 AI 引擎来说,这个页面就是空壳。

第二个区别是内容偏好:AI 引擎引用内容时,偏爱结构清晰、结论明确、可直接摘录的段落——标题层级、列表、表格、结构化数据(JSON-LD)的权重,比传统 SEO 时代更高。

二、体检方法:用爬虫的视角看自己的站

改造之前先体检。方法很简单:伪装成 AI 爬虫,抓取自己的页面,看返回的 HTML 里到底有什么:

curl -s https://example.com/blog/some-article \
  -A "Mozilla/5.0 (compatible; GPTBot/1.2)" \
  -o page.html

然后检查两件事:

  1. 正文文字在不在 HTML 里(直接在 HTML 源码里搜索正文中的一句话)
  2. 有没有 <h2>、<table> 这类语义化标签

这一步的结果直接决定了后面所有工作的优先级。

三、发现的问题与修复(按严重程度排序)

1. 致命问题:正文全靠客户端渲染

案例站的文章正文组件是一个 Markdown 预览组件,为了减小首屏体积做了动态加载。这导致 SSR 输出的 HTML 里,正文位置只有一个「加载内容中...」的占位符,正文文本只存在于 JS 数据载荷里。

实测:用 GPTBot 的 UA 抓取文章页,HTML 中 <h2> 数量为 0——文章的所有小节标题都不在初始 HTML 里。

这意味着:百度基本读不到正文,AI 引擎完全读不到正文。几千字的文章,对这些爬虫来说等于不存在。

修复:把正文渲染从客户端挪回服务端。具体做法是用 react-markdown + remark-gfm + rehype-highlight 在 Server Component 里把 Markdown 同步渲染成语义化 HTML,客户端动态加载的预览组件直接删除。改完再测,同样的抓取方式下 <h2> 从 0 变成 8,表格、引用块、代码高亮全部直出。

这是我这次改造中收益最大的一步,没有之一。

2. 缺少 llms.txt —— AI 时代的 robots.txt

llms.txt 是一个正在形成的约定:在站点根目录放一个 Markdown 文件,告诉 AI 引擎这个站是干什么的、核心内容在哪。类似于给 AI 引擎准备的站点地图。

修复时我加了两个文件:

  • /llms.txt:站点简介 + 页面结构 + 全部文章的标题、链接、日期、摘要
  • /llms-full.txt:所有文章的 Markdown 全文,供 AI 引擎一次性摄取

两个文件都由服务端动态生成、每小时刷新,发新文章自动进入索引。然后在 robots.txt 里声明这两个入口。

3. 结构化数据(JSON-LD)的细节错误

案例站本来就有 BlogPosting 结构化数据,但仔细检查发现了好几个问题:

  • publisher 用了 Person 类型却带了 logo 属性——logo 是 Organization 的属性,校验器会报警
  • dateModified 一直等于发布日期,因为代码里映射的是创建时间而不是更新时间——文章更新后搜索引擎感知不到
  • 没有面包屑(BreadcrumbList)
  • 首页只有 Person 实体,没有 Organization——AI 引擎无法识别「这个站属于谁」

修复:publisher 改为 Organization,dateModified 改用真实的 updated_at 字段,文章页补上 BreadcrumbList(首页 › 博客 › 文章),首页补齐 WebSite + Person + Organization 三个实体声明。

4. RSS 只输出摘要

案例站的 RSS 每个条目只有百来字的摘要。RSS 是内容聚合器和部分 AI 引擎的重要抓取源,只给摘要等于自断一路。

修复:每个条目增加 <content:encoded> 输出全文 HTML,feed 体积从 15KB 涨到 195KB——这才是 RSS 该有的样子。顺手把频道描述改成与站点定位一致的文案。

5. sitemap 的 lastmod 被冻结在构建时刻

这是个很隐蔽的问题:sitemap 里的 lastmod 字段用的是 new Date(),听起来没问题对吧?但路由在构建时被静态化了,于是所有页面的 lastmod 全部定格在构建那一刻,之后再也不变。搜索引擎看 lastmod 半年不动,会降低抓取频率。

修复:sitemap 路由改成 ISR 每小时重新生成;文章的 lastmod 用真实更新时间;首页和列表页的 lastmod 跟随最新文章的更新时间。

6. 分享图和 favicon 全是 webp

案例站的 OG 分享图、favicon、apple-touch-icon 都是同一张 webp 图。webp 对现代浏览器没问题,但微信、iMessage 和不少平台的分享卡片对 webp 支持很差——链接分享出去没有缩略图,白白损失传播。

修复:生成一张 1200×630 的 PNG 品牌分享图 + PNG 版 favicon,全部自托管。另外还发现一个坑:Next.js 的页面级 openGraph 不会继承 layout 里的分享图,首页之前根本没有 og:image,五个页面的 openGraph 都得单独补上。

7. www 和裸域并存,重复内容

检测发现 www.example.com 和 example.com 都能访问且不跳转,而且 www 的 HTTPS 证书根本没配。两个域名同内容并存会分散权重。

修复:证书加上 www 域名(acme.sh 签发时记得给 nginx 的 80 端口配置 ACME 挑战文件的绿色通道,否则验证 404),nginx 层把裸域 301 到 www。关键收尾:代码里所有 canonical、sitemap、结构化数据里的域名要和 301 的目标域统一,否则每个对外 URL 都多跳一次,信号矛盾。

8. GEO 工具检测出的「软性问题」

改完上面这些硬问题后,我用 GEO 检测工具扫了一遍首页,工具又报了几条:

  • og:description 只有 31 字符(建议 120-200)
  • 首页正文只有 552 词(建议 600+)
  • 全文 0 个 <ul>、0 个 <table>,缺少可扫描的结构化内容
  • 没有 Organization schema(前面已修)

修复:首页描述扩写到 131 字符;加了一个「关于本专栏」区块(博主身份 + 内容主线 + 更新频率,顺便把词数补足);文章列表从 <div> 堆叠改成语义化的 <ul><li>。

工具还建议加 FAQPage 和 HowTo schema——这两条适合问答型和步骤型文章,属于内容写作层面的优化,不适合在站点层面硬套,留作后续写文章时用。

四、沉淀一份 GEO 检查清单

整个流程走完,我总结了一份可以复用的清单。给任何内容站做 GEO 体检,按这个顺序查:

可抓取性(生死项)

  1. 用 GPTBot UA 抓页面,正文在不在初始 HTML 里?
  2. 有没有 llms.txt?robots.txt 有没有误伤 AI 爬虫?

结构化数据(信任项)

  1. JSON-LD 的 publisher 类型对不对?dateModified 是真实更新时间吗?
  2. 首页有没有 Organization / Person 实体声明?
  3. 文章页有没有面包屑?

内容分发(传播项)

  1. RSS 有没有全文输出?
  2. sitemap 的 lastmod 是不是真实的?
  3. OG 图是不是 PNG/JPG?每个页面都有 og:image 吗?

域名与内容(信号项)

  1. www 和裸域统一了吗?canonical 指向的域名和 301 目标一致吗?
  2. 描述文字够长吗?页面有足够的实质内容和列表/表格结构吗?

总结

这次改造的核心认知就一句话:

把你的站点当成一个「不执行 JavaScript 的读者」来设计。

传统前端优化追求把 JS 拆小、延后加载,这没错;但正文这种核心内容必须服务端直出。SEO 时代这么做是「更快被收录」,GEO 时代这么做是「能不能被 AI 看见」的分水岭。

工具链层面,llms.txt、全文 RSS、准确的结构化数据,本质上都是同一件事:降低 AI 引擎理解你内容的成本。你让它越容易读,它就越愿意引用你。

留言