越来越多的人在用 AI 辅助开发,把脑子里那些一直想做但没时间做的想法真正跑起来了。
一个能自动生成图片的 Skill、一个帮你整理笔记的小工具、一个开源的 Agent 框架,做出来了,想让更多人用到,希望 GitHub 仓库能被更多人发现,希望有人问 AI「有没有好用的 XX 工具」时,它能提到你。
但很多人会发现,工具做出来之后,AI 给出的推荐名单里根本没有自己。
不是工具不够好,很可能是 AI 根本没有读到你写的介绍。这背后有一个容易被忽略的技术问题,而且有明确的解法,接下来从技术层面把这件事讲清楚。
先划重点
这篇聊三件事:AI 到底怎么找内容、为什么 SPA 项目对爬虫不友好、以及开发者可以做哪些具体的事让产品出现在 AI 的推荐里。
读完你能判断自己的项目该用哪种渲染方式,知道 SSG / SSR / ISR / CSR 各自适合什么场景,以及掌握 JSON-LD、FAQ 结构这几个提升 GEO 效果的具体手段。
AI 是怎么找到你的内容的
先把底层逻辑搞清楚,后面的选型才有意义。
有人问 AI「有没有好用的 AI 自动生图工具」,AI 不是从训练数据里背答案。开启联网功能之后,它的实际流程是:把这个问题转成搜索词,去搜索引擎搜索,拿到排名靠前的几个页面,读完,综合写出回答。
SEO 是 GEO 的前提。 SEO 做的事,简单说就是让你的页面出现在搜索引擎的结果里、排名靠前。你没有出现在搜索引擎的结果里,AI 根本找不到你,更谈不上引用。
找到你之后,AI 还要做第二个判断:要不要引用你。
这里有两个概念需要区分清楚。
SEO(搜索引擎优化)解决的是「出现在搜索结果列表里」,用户自己决定要不要点进来看。
GEO(Generative Engine Optimization,生成式引擎优化)解决的是「被 AI 挑中引用」,AI 替用户读完你的页面,把内容消化之后写进回答,用户看到的是 AI 的总结,不是你的页面。
AI 凭什么选择引用你?
把这个过程想象成自己在写一篇报告,手边有十篇参考文章。你会优先引用说清楚了的、有数据支撑的、这个角度别处没有的。
一大段混在一起讲了好几件事的,找不到干净的句子可以摘出来用,会被跳过。AI 的选择逻辑和你完全一样。
为什么 SPA 项目,AI 找不到
爬虫读页面,不是浏览器。它发一个 HTTP 请求,拿到服务器返回的原始 HTML 字符串,解析里面的文字,完事。这个过程完全没有 JavaScript 参与。
SPA(Single Page Application,单页面应用)是目前比较主流的前端架构,React 和 Vue 默认做出来的项目都是 SPA。它的工作方式是:服务器返回一个几乎空白的 HTML,所有内容由浏览器下载 JS、执行之后动态渲染出来。
用 React 或 Vue 搭起来的 SPA 项目,服务器返回的 HTML 是这样的:
<!DOCTYPE html>
<html>
<body>
<!-- 空的,没有任何内容 -->
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>
内容在 bundle.js 里,需要浏览器把 JS 下载下来、执行、再把内容塞进 <div id="root"> 里,用户才能看到东西。
爬虫拿到这个 HTML,解析完,什么都没有。
不同爬虫对 JS 的处理方式不同,但对 SPA 都不友好。
以 Google 的搜索爬虫为例。它的搜索爬虫叫 Googlebot,负责发现和索引网页。它有一定的 JS 渲染能力,但采用两阶段机制:先抓原始 HTML 存快照,再把需要渲染的页面排进队列等待处理。这个队列等待时间不可控,新页面可能延迟几小时到几天才能被完整索引。
AI 爬虫就更直接了。GPTBot、ClaudeBot、PerplexityBot 这些 AI 爬虫的目标是大规模抓取内容,不可能为每个页面排队等 JS 渲染。
这不只是推测,Vercel 和 MERJ 联合分析了超过 5 亿次 GPTBot 的真实抓取请求,在所有记录里,没有找到任何一次 JavaScript 执行的证据。
Googlebot 是「晚到但最终会来」,AI 爬虫是「根本不会等」。
你的 SPA 介绍页,在 AI 检索系统眼里,内容几乎不存在。
四种渲染方式,对 SEO 和 GEO 的影响完全不同
问题出在「服务器返回的 HTML 没有内容」,解法是让服务器直接返回有内容的 HTML。要做到这一点,需要理解四种渲染方式的本质区别。
CSR:客户端渲染
CSR(Client Side Rendering)就是 SPA 的默认方式。服务器返回空 HTML,内容由浏览器执行 JS 后生成。
Figma 的工作区是最典型的案例。打开 Figma 登录后的页面,右键查看页面源代码,会看到:
<div id="react-page"></div>
整个 div 是空的,没有任何文字内容。
但这对 Figma 完全合理,工作区是私人内容,不需要被任何搜索引擎或 AI 索引。
CSR 对 SEO 弱,对 GEO 无效。
SSG:静态站点生成
SSG(Static Site Generation)在构建时提前生成所有页面的 HTML 文件,部署后服务器直接返回静态文件,不需要任何实时计算。
Next.js 的官方文档就是 SSG。打开 nextjs.org/docs 任意一页,查看页面源代码,第一行就是完整的文章内容,标题、正文、代码块全在 HTML 里,爬虫不需要等任何 JS 执行。
SSG 对 SEO 最友好,对 GEO 效果最佳。
SSR:服务端渲染
SSR(Server Side Rendering)在每次请求时,服务器实时拉取数据、拼装 HTML、返回。
内容是动态的,但爬虫拿到的仍然是完整 HTML。
以 nextjs 的 GitHub Star 数为例:
打开 github.com/vercel/next.js 查看页面源代码,你会找到这样一行:
<span
id="repo-stars-counter-star"
aria-label="138393 users starred this repository"
data-singular-suffix="user starred this repository"
data-plural-suffix="users starred this repository"
data-turbo-replace="true"
title="138,393"
data-view-component="true"
class="Counter js-social-count"
>138k</span
>
Star 数直接写在 HTML 里。这是因为服务器在返回页面之前,实时查了数据库把这个数字塞进去。
下一个用户访问时如果有人刚点了 Star,数字就变了。
Star 数是实时变化的,服务器必须在每次请求时重新查数据库,不可能提前生成,必须用 SSR。
SSR 对 SEO 和 GEO 的效果和 SSG 一样好,代价是服务器每次请求都要实时计算。
ISR:增量静态再生成
ISR(Incremental Static Regeneration)是 Next.js 独有的模式,介于 SSG 和 SSR 之间。页面第一次是静态生成的,但可以设定定期自动重新生成。
「今日热门文章」榜单是典型场景。排名每小时根据阅读量自动更新,不是人工触发部署的。设定 revalidate = 3600,Next.js 每小时自动重新生成一次,10 万次访问全部命中缓存,接口一天只被调用几百次。
ISR 的核心价值是用「允许的延迟」换服务器压力。
四种渲染方式的对比:
Next.js 混合渲染:在同一个项目里用对每种页面
理解了四种渲染方式之后,下一个问题是:一个真实产品有很多页面,每种页面的需求不同,怎么统一管理?
纯 CSR 的 SPA 项目做不到这一点,所有页面只能是同一种渲染方式。
Next.js 的核心价值是混合渲染,同一个项目里每个页面独立决定渲染方式,不需要拆成多个项目。
判断渲染方式,问三个问题就够了:
第一问:这个页面需要被搜索引擎或 AI 找到吗?
不需要,直接 CSR,结束。需要,继续问。
第二问:内容会变吗?
不变,直接 SSG。会变,继续问。
第三问:内容变化的频率是多少?
系统自动定期更新,ISR。实时变化或依赖用户身份,SSR。
在 Next.js App Router 里,默认就是 SSG,什么都不写就是构建时生成静态文件。有需要才往上加复杂度。
SSG:文档站、官网、博客文章
// app/docs/[slug]/page.tsx
// 什么都不加,默认就是 SSG
export default async function DocsPage({ params }) {
const doc = await fetch(`https://your-cms.com/docs/${params.slug}`).then(r =>
r.json()
)
return (
<article>
<h1>{doc.title}</h1>
<div>{doc.content}</div>
</article>
)
}
Docusaurus、VitePress 这类主流文档框架,背后就是这套逻辑:
内容存在 Markdown 文件或 CMS(Content Management System,内容管理后台)里,构建时拉取数据生成静态 HTML,部署到 CDN。内容需要更新时,改完触发重新部署就行,不需要设 revalidate。
ISR:内容系统自动定期变化的页面
和 SSG 的写法几乎一样,唯一的区别是加一行 revalidate,告诉 Next.js 每隔多少秒重新生成一次这个页面:
// app/trending/page.tsx
export const revalidate = 3600 // 每小时自动重新生成一次
export default async function TrendingPage() {
const articles = await fetch('https://your-api.com/trending').then(r =>
r.json()
)
return (
<section>
{articles.map(article => (
<div key={article.id}>
<h2>{article.title}</h2>
<span>{article.views} 次阅读</span>
</div>
))}
</section>
)
}
ISR 和 SSG 的本质区别:SSG 是人工触发重新部署来更新内容,ISR 是系统定时自动重新生成。如果内容不会自动变化,SSG 就够了,设 revalidate 是多余的。
SSR:实时数据或依赖用户身份的页面
// app/repos/[owner]/[repo]/page.tsx
export default async function RepoPage({ params }) {
const repo = await fetch(
`https://api.github.com/repos/${params.owner}/${params.repo}`,
{ cache: 'no-store' } // 每次请求都重新拉,不缓存
).then(r => r.json())
return (
<div>
<h1>{repo.full_name}</h1>
<span>★ {repo.stargazers_count.toLocaleString()}</span>
</div>
)
}
CSR:登录后的私有页面
'use client'
export default function Dashboard() {
const [data, setData] = useState(null)
useEffect(() => {
fetchUserData().then(setData)
}, [])
return <div>{data ? <UserStats data={data} /> : '加载中...'}</div>
}
一个完整产品的渲染策略,大概是这个样子:
已有 SPA 项目怎么办
很多产品是在 Vibe coding 还没流行之前做的,用纯 CSR 的 SPA 框架搭了一套完整的应用,对外的官网和产品介绍页,和登录后的功能区,全部都是 CSR。
这类项目的问题很明确:官网和介绍页需要被搜索引擎和 AI 找到,但因为是 SPA,爬虫拿到的是空壳。
整体迁移到 Next.js 成本太高——很多人的第一反应也是这个。整体迁移意味着所有路由、状态管理、组件都要重写,对已有项目来说基本等于重来一遍。
最低风险的路径是切割:把需要被索引的对外页面单独起一个 Next.js 项目,用 Nginx 或 CDN 路由规则挂在同一域名下,原来的 SPA 项目继续维护登录后的功能区。
myproduct.com/ → Next.js(SSG,对外官网)
myproduct.com/app/* → 原有 SPA 项目(CSR,登录后功能区)
用户感知是同一个网站,技术上是两套独立部署。对外页面解决了 SEO 和 GEO 的问题,功能区不受影响。
进了候选池,怎么让 AI 选你
SSR/SSG 解决的是能不能被爬虫看到,让你进入 AI 的候选池。
接下来我们要讨论的是「进了候选池之后,凭什么被选中引用」。
还是回到那个自动化生图 Skill 的介绍页。
AI 拿到了你的页面,接下来会切内容,按段落和逻辑块切成若干个片段,每个片段独立参与竞争。
你写的介绍,AI 可能只抽了其中几个块,其他的完全被忽略。
内容结构:让每段能被干净地摘出来
每段聚焦一个意思,开头给结论,后面给支撑。一段混了三件事,切出来的块没法用。
标题直接说这段讲什么,不要玩悬念。AI 用标题层级来建立内容地图,知道每一块在讲什么主题。
数据支撑:有数字才值得引用
「这个工具生图速度很快」,AI 不感兴趣。「平均生图时间 3.2 秒,支持 10 个并发任务」,这个值得引用。
有具体数字、有来源的句子,是最容易被 AI 摘录进回答的内容单元。这不是写作技巧,是 AI 选择引用的底层逻辑:有数据的内容可信度更高。
FAQ 块:和用户提问格式直接对齐
FAQ(Frequently Asked Questions,常见问题)块就是在页面里加一组问答结构,问题用标题写,回答紧跟在后面。
为什么 FAQ 对 GEO 特别有效?
用户问 AI 的方式是问句,AI 在你的页面里找到了一样格式的问句和答案,直接拿走,不需要再做任何转换。
FAQ 结构直接把你的内容变成了和用户提问形式一致的格式,提取成本最低。
<section>
<h2>常见问题</h2>
<h3>这个工具支持哪些图片格式输出?</h3>
<p>
支持 PNG、JPEG、WebP 三种格式,默认输出 PNG,
可在配置文件里修改。生图分辨率最高支持 2048×2048。
</p>
<h3>和其他 AI 生图工具相比有什么优势?</h3>
<p>
完全本地运行,不依赖任何外部 API,没有调用次数限制,
数据不会上传到第三方服务器。
</p>
</section>
JSON-LD:给 AI 一张名片
JSON-LD 是一段放在页面 <head> 里的结构化数据,专门给机器读,不影响页面显示。
它的作用是主动告诉 AI 这个页面是什么类型、作者是谁、内容讲什么,不让它猜:
// app/page.tsx(工具介绍页)
export default function HomePage() {
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'SoftwareApplication',
name: 'AutoGen Image Skill',
description: '自动化 AI 生图工具,本地运行,无需外部 API',
author: {
'@type': 'Person',
name: '你的名字',
url: 'https://你的网站.com',
},
applicationCategory: 'DesignApplication',
datePublished: '2025-03-20',
}
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<main>{/* 页面内容 */}</main>
</>
)
}
其中 @type 字段告诉 AI 这个页面的内容类型。产品介绍页用 SoftwareApplication,博客文章用 TechArticle,FAQ 页面用 FAQPage。
AI 爬虫看到这段数据,不需要猜这个页面是什么,出现在引用里的概率就高了一截。
怎么验证 GEO 有没有生效
验证分三步,从最快的开始。
第一步:直接去问 AI。
列出 10 个和你工具相关的问题,用户做决策时会问的那种,比如「有没有好用的本地 AI 生图工具」「不依赖外部 API 的 AI 生图方案有哪些」。分别去几款主流 AI 工具里问一遍,记录你的工具有没有出现、引用的是你哪个页面。
第二步:确认 AI 爬虫来没来。
每次有人或程序访问你的网站,都会在 HTTP 请求里附上一段「自我介绍」,叫 User Agent,相当于访客的身份证。
普通用户用浏览器访问时有,AI 爬虫来抓页面时也有。
GPTBot 的 User Agent 是 GPTBot/1.1,ClaudeBot 是 ClaudeBot/0.1,PerplexityBot 是 PerplexityBot/1.0。
服务器会把每一次访问记下来,包括时间、访问的页面、User Agent 是什么,这个记录叫服务器日志。
在日志里过滤 AI 爬虫的 User Agent,就能看到它们来没来、抓了哪些页面:
# 找出所有 GPTBot 的访问记录
grep "GPTBot" /var/log/nginx/access.log
# 统计 GPTBot 抓了哪些页面、各抓了多少次
grep "GPTBot" /var/log/nginx/access.log \
| awk '{print $7}' | sort | uniq -c | sort -rn
输出大概是这样,输出的每一行是「抓取次数 + 页面路径」,数字越大说明这个页面被抓得越频繁:
142 /docs/getting-started
89 /
34 /pricing
以这个输出例子来讲,说明 GPTBot 最常抓的是文档页,首页和定价页也抓过。
如果你的网站用 Vercel 或 Cloudflare 部署,后台有现成的可视化面板,可以直接看每家 AI 爬虫的访问趋势,不需要手动分析日志。
第三步:看引荐来源里有没有 AI 平台。
GEO 真正生效之后,你会在网站分析工具(Google Analytics、Plausible 等访客统计工具)的流量来源里看到 chatgpt.com、perplexity.ai 作为引荐来源出现。用户在 AI 回答里看到了你的工具,点进来了。这是最直接的验证,不需要任何额外工具。
最后总结一下
渲染方式是入场券,内容结构是竞争力。前者决定 AI 爬虫能不能抓到你的页面,后者决定抓到之后值不值得引用。两件事都做对了,你的工具才有机会出现在 AI 给出的推荐名单里。
新项目直接上 Next.js,默认 SSG,按需加复杂度。已有的 SPA 项目,把对外页面单独剥出来用 Next.js 管,比整体迁移代价低得多。
入场券拿到之后,介绍页的内容写清楚、加上 JSON-LD、加一个 FAQ 块,这些事不复杂,做了就有效果。
下次有人问 AI「有没有好用的 XX 工具」,你的产品名字出现在回答里,不是运气,是可以做到的事。
延伸阅读
-
GEO: Generative Engine Optimization(普林斯顿大学等,2023)— GEO 概念的原始论文,有完整的实验数据和九种优化策略的效果对比 arxiv.org/abs/2311.09…
-
The Rise of the AI Crawler(Vercel + MERJ,2024)— 5 亿次 GPTBot 请求分析,包含各 AI 爬虫行为差异的完整数据 vercel.com/blog/the-ri…
感谢您的阅读。
这里会持续记录我对技术、工程实践与新趋势的思考,可关注微信公众号 前端Fusion 获取后续更新。
如果您喜欢这篇文章,欢迎点赞或分享。