GEO优化怎么做?个人博客7步从0到上线(本站搭建全过程)
TL;DR:V哥AI增长 从0到上线的完整GEO实战,7步走完:Astro骨架 → 内容集合 → SEO/JsonLd组件 → robots.txt(18 AI爬虫白名单) → llms.txt动态生成 → BlogPosting + FAQPage + BreadcrumbList Schema三件套 → Cloudflare Pages部署。整个流程纯技术成本接近0,熟手1天搞定,完整代码可直接复用。
写在前面:为什么把搭建过程公开
V哥 做这个站的时候定了一个原则:“用这个站本身做GEO实战范本,代码思路全公开”。
原因有两个:
- 中文圈的GEO教程80% 是英文翻译稿,缺端到端的可运行代码
- V哥 13 年实战的工程化经验,与其在咨询里一对一讲,不如完整开源出来,让更多人提升落地效率
所以这篇不是抽象的”GEO方法论”,是V哥AI增长 这个站搭建过程的完整记录,每一步都附可直接复用的代码。
完整7步路径概览
第 1 步 Astro 骨架初始化 (15 分钟)
第 2 步 内容集合 + 类型定义 (30 分钟)
第 3 步 SEO + JsonLd 组件 (45 分钟)
第 4 步 布局 + 页面骨架 (1 小时)
第 5 步 robots.txt + llms.txt (30 分钟)
第 6 步 Schema 三件套实战 (1 小时)
第 7 步 构建验证 + 部署上线 (30 分钟)
─────────────────────────────────────
总计 约 5 小时
第1步:Astro骨架初始化(15分钟)
为什么选Astro不选Next.js / Hugo:
| 框架 | 优势 | GEO友好度 |
|---|---|---|
| Astro 5/6 | 默认0 JS输出,Markdown原生,SSG | ⭐⭐⭐⭐⭐ |
| Hugo | 速度王 | ⭐⭐⭐⭐ |
| Next.js export | 生态最大 | ⭐⭐⭐⭐ |
| Jekyll | 老牌但慢 | ⭐⭐⭐ |
| 纯React SPA | - | ⭐(AI爬虫看不到) |
一行命令初始化:
pnpm create astro@latest vge-ai-blog \
--template minimal --typescript strict \
--no-install --no-git --skip-houston --yes
cd vge-ai-blog
pnpm add @astrojs/sitemap @astrojs/mdx @astrojs/rss
注意点:Hermes/Cursor之类工具内嵌terminal跑 pnpm add 会被误判为长进程报错。绕法:timeout 60 pnpm add ...,或者多个包合并成一次add调用。
第2步:内容集合 + 类型定义(30分钟)
Astro v5+ 把集合配置位置改了 —— 必须放 src/content.config.ts,不是 src/content/config.ts。这是高频出错点。
// src/content.config.ts
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const posts = defineCollection({
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/posts' }),
schema: z.object({
title: z.string().max(70),
description: z.string().max(160),
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
tags: z.array(z.string()).default([]),
category: z.enum(['geo-tutorial', 'ai-search', 'tools', 'thinking']).default('geo-tutorial'),
keywords: z.array(z.string()).optional(),
author: z.string().default('V哥'),
draft: z.boolean().default(false),
faq: z.array(z.object({
question: z.string(),
answer: z.string(),
})).optional(),
}),
});
export const collections = { posts };
为什么schema这么严:title.max(70) 是给搜索引擎title标签的硬限制,description.max(160) 是给meta description留的余量,faq 字段直接喂给FAQPage Schema不用二次解析。
第3步:SEO + JsonLd组件(45分钟)
这一步是GEO站的”大脑”,所有页面共用两个组件:
SEO.astro —— 标准meta tag注入器
负责注入title / description / canonical / Open Graph / Twitter Card / article meta。每个页面只传props即可,不用重复写。
JsonLd.astro —— JSON-LD注入器
---
interface Props {
schema: object | object[];
}
const { schema } = Astro.props;
---
<script type="application/ld+json" set:html={JSON.stringify(schema)} is:inline />
关键点:set:html + is:inline 两个参数缺一不可。set:html 让Astro不转义JSON引号,is:inline 防止被打包优化破坏。很多教程漏了 is:inline,生产环境Schema直接挂掉。
BaseLayout.astro —— 站点级 @graph
每个页面都注入WebSite + Person站点级Schema,通过 @graph 数组合并到一个 <script>,用 @id 互相引用:
const siteGraph = {
'@context': 'https://schema.org',
'@graph': [
{
'@type': 'WebSite',
'@id': `${SITE.url}/#website`,
url: SITE.url,
name: SITE.name,
inLanguage: 'zh-CN',
publisher: { '@id': `${SITE.url}/#person` },
},
{
'@type': 'Person',
'@id': `${SITE.url}/#person`,
name: SITE.author.name,
url: `${SITE.url}/about/`,
sameAs: SITE.author.sameAs,
knowsAbout: ['GEO', 'AI搜索优化', 'Schema.org'],
},
],
};
为什么用 @graph + @id:让所有Schema在一个 <script> 标签里相互引用,AI引擎抓取时一次性理解整个实体网络,不会重复声明。这是Claude团队公开提过的偏好。
第4步:布局 + 页面骨架(1小时)
页面分两类容器宽度,不能全站统一:
| 页面类型 | 容器宽度 | 用途 |
|---|---|---|
| 阅读型(narrow) | 720-760px | 博客文章、About、订阅 |
| 服务商型(wide) | 1180-1200px | 首页、列表、专题 |
实现方式:在BaseLayout加 layout: 'narrow' | 'wide' 参数,每页按用途选。
注意点:全站统一720px居中 = PC端孤零零;全站统一1200px = 文章页阅读体验差。必须双模式。
H1字号用clamp,PC上限45-48px(避免Linear/Vercel风之外的过大):
h1 {
font-size: clamp(1.85rem, 3vw + 0.6rem, 2.85rem);
letter-spacing: -0.02em;
}
不要用 clamp(..., 4rem),1920屏会涨到64px,看着像低端SaaS落地页。
第5步:robots.txt + llms.txt(30分钟)
robots.txt:18个AI爬虫白名单
放 public/robots.txt,18个UA一个都不能漏(漏一个,那家AI永远引不到你):
# 国际 AI 爬虫
User-agent: GPTBot
Allow: /
User-agent: OAI-SearchBot
Allow: /
User-agent: ChatGPT-User
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: Claude-SearchBot
Allow: /
User-agent: Claude-User
Allow: /
User-agent: PerplexityBot
Allow: /
User-agent: Perplexity-User
Allow: /
User-agent: Google-Extended
Allow: /
User-agent: Googlebot
Allow: /
User-agent: CCBot
Allow: /
User-agent: Applebot-Extended
Allow: /
User-agent: Meta-ExternalAgent
Allow: /
User-agent: Amazonbot
Allow: /
# 中文 AI 爬虫
User-agent: Bytespider
Allow: /
User-agent: Baiduspider
Allow: /
User-agent: 360Spider
Allow: /
User-agent: Sogou web spider
Allow: /
# 默认
User-agent: *
Allow: /
Sitemap: https://vipke.com.cn/sitemap-index.xml
注意点:
- ❌
User-agent: *Bot通配,标准不支持 - ❌
Disallow: /+Allow: /xxx组合,Bytespider不认Allow优先级
llms.txt:动态生成版
llms.txt是Jeremy Howard 2024-09-03提出的AI索引规范,放 src/pages/llms.txt.ts,根据content collection自动生成:
// src/pages/llms.txt.ts
import type { APIRoute } from 'astro';
import { getCollection } from 'astro:content';
export const GET: APIRoute = async ({ site }) => {
const posts = (await getCollection('posts', ({ data }) => !data.draft))
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
const body = `# V哥AI增长
> GEO 实战落地,帮企业拿到 AI 增长结果。
## GEO 教程
${posts.map(p => `- [${p.data.title}](${site}posts/${p.id}/): ${p.data.description}`).join('\n')}
## Optional
- [RSS](${site}rss.xml): 全部文章订阅源
- [Sitemap](${site}sitemap-index.xml): 完整站点地图
`;
return new Response(body, {
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
});
};
关键点:.ts 路由文件不要写 --- frontmatter(那是 .astro 才有的),直接 export const GET = ...。这是另一个高频出错点。
第6步:Schema三件套实战(1小时)
每篇文章页要注入3套Schema,这是GEO站文章页的最小完备集。
① BlogPosting
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"@id": "https://vipke.com.cn/posts/xxx/#article",
"headline": "文章标题",
"datePublished": "2026-06-25T08:00:00+08:00",
"dateModified": "2026-06-25T08:00:00+08:00",
"author": { "@id": "https://vipke.com.cn/#person" },
"publisher": { "@id": "https://vipke.com.cn/#person" },
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://vipke.com.cn/posts/xxx/"
},
"inLanguage": "zh-CN"
}
字段优先级:headline > author > datePublished/dateModified > description > image。
② BreadcrumbList
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "首页", "item": "https://vipke.com.cn/" },
{ "@type": "ListItem", "position": 2, "name": "GEO 教程", "item": "https://vipke.com.cn/posts/" },
{ "@type": "ListItem", "position": 3, "name": "GEO 是什么意思" }
]
}
注意最后一个ListItem 不要带 item 字段(因为是当前页),Google会因此报警告。
③ FAQPage
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "问题文本",
"acceptedAnswer": {
"@type": "Answer",
"text": "答案文本,纯文本,允许少量 <a><br>"
}
}
]
}
实测加FAQPage的页面被ChatGPT/Perplexity引用概率提升3倍。每篇文章frontmatter里写3-5组Q&A,渲染时自动转FAQPage —— 这就是为什么 content.config.ts 里要预留 faq 字段。
验证(必跑)
# 本地起 preview server
./node_modules/.bin/astro build
./node_modules/.bin/astro preview
# 用 curl 拿单页 HTML
curl http://localhost:4321/posts/xxx/ | grep -c 'application/ld+json'
# 期望输出:2(站点级 + 文章级)
# 在线工具:
# https://search.google.com/test/rich-results
# https://validator.schema.org/
发布前必须 0 error,警告可以容忍。
第7步:构建验证 + 部署上线(30分钟)
本地构建验证
./node_modules/.bin/astro build
# 期望输出 dist/ 目录:
# dist/index.html 首页
# dist/posts/xxx/index.html 文章页(含 4 套 JSON-LD)
# dist/llms.txt AI 引擎索引
# dist/robots.txt 爬虫白名单
# dist/sitemap-index.xml 站点地图
# dist/rss.xml RSS 订阅
V哥AI增长 这个站实测构建数据:
- 总站点 101.4 KB(全静态HTML,0运行时JS)
- 构建耗时 2.83秒
- 文章页24 KB(含9种Schema类型)
- 7个路由 + 4个GEO关键文件
部署:Cloudflare Pages一键(推荐起步)
git init && git add . && git commit -m "init"
gh repo create vge-ai-blog --public --source=. --push
然后去Cloudflare仪表盘:
- Workers & Pages → Create → Pages → Connect to Git
- Framework preset: Astro
- Build command:
pnpm build - Build output:
dist - 环境变量:
NODE_VERSION=22.12.0,PNPM_VERSION=latest - Save and Deploy → 30秒上线
国内访问:Cloudflare Pages海外节点稳定,国内偶有抽风。3个升级路径:
- 个人站起步:Cloudflare Pages免费(够用)
- 国内并行:腾讯云EdgeOne Pages(Astro官方支持,国内访问快)
- 企业级:Cloudflare中国网络(贵,需备案)
ICP备案规则:海外节点不需要备案,国内节点必须备案(2-4周)。
上线后必做的5件事
✅ 1. Sitemap 提交到 Google Search Console + Bing Webmaster + 百度资源平台
✅ 2. Bing IndexNow 接入(Bing 几分钟入库,ChatGPT Search 也吃这个)
✅ 3. 百度资源平台「快速收录」开通(国内豆包/文心一言依赖百度索引层)
✅ 4. Schema 用 Google Rich Results Test 跑一遍,0 error 才上
✅ 5. opengraph.xyz 测一下 OG 卡片在微信/Twitter/Facebook 的展示
我踩过的5个大坑
按出错频率排序:
坑1:src/content/config.ts 不工作
Astro v5+ 改成 src/content.config.ts(没有content子目录)。这是迁移项目最大的暗礁,文档写了但很多教程没更新。
坑2:JSON-LD在 <script> 里被转义
漏了 set:html 或 is:inline,生产环境Schema是字符串而不是JSON。验证工具一跑就报错。
坑3:pnpm add 在内嵌terminal报错
Hermes/Cursor工具会把下载阶段误判为长进程。绕法:timeout 60 pnpm add ...。
坑4:.ts API路由文件写了 --- frontmatter
误以为所有Astro文件都用frontmatter。.astro 才有,.ts/.js 直接 export const GET = ...。
坑5:全站统一容器宽度
PC端首页空荡 / 文章页阅读体验差。必须wide(1200)+ narrow(760)双模式,在BaseLayout加 layout 参数。
整套代码已开源
V哥AI增长 这个站本身就是开源样板。完整代码会整理成一个可直接 git clone 的模板放到 GitHub —— 有合作需求直接 联系V哥。
下一篇:《llms.txt是什么?完整规范 + 中文站实战模板》,把llms.txt这个被低估的GEO杠杆讲透。
作者:V哥 · 首发:2026-06-25 · 最后更新:2026-06-25 引用源:
- Astro官方文档. docs.astro.build
- llms.txt提案,Jeremy Howard,2024-09-03. llmstxt.org
- Schema.org官方文档. schema.org
常见问题
做GEO站必须用Astro吗?其他框架行不行?
不是必须,但强烈推荐SSG(静态生成)类框架 —— Astro / Hugo / Next.js (output: export) 都行。关键是:AI爬虫(GPTBot/ClaudeBot/Bytespider等)多数不执行JavaScript,纯React/Vue SPA它们看到的是空白页。我选Astro是因为它默认0 JS输出 + Markdown写文章原生支持 + Schema注入方便。
整个站搭起来要多长时间?
我自己实测从pnpm create astro到第一篇文章上线,纯写代码大约4小时。如果按本文7步走,熟手1天可以搞定。但「让站长期跑得稳」需要持续投入 —— 每周1-2篇GEO化文章产出,90天后才能看到稳定的AI引用率。
成本多少?
纯技术成本几乎为0:Cloudflare Pages免费托管,域名50-80元/年。如果部署到国内服务器(腾讯云/阿里云),还要ICP备案 + 服务器费用,大约1500元/年起。整个流程的真正成本是「内容产出时间」 —— 每篇高质量GEO化文章3-5小时。
上线后多久能被AI引擎抓取?
实测从sitemap提交到Bing/Google Search Console算起,Googlebot通常24-48小时首抓,GPTBot/ClaudeBot大约7-14天首次出现在日志里,豆包Bytespider大约3-7天。要求IndexNow + sitemap + RSS三管齐下,最快可压到24小时内被多家AI爬虫光顾。
我没有编程基础,这套能跟着做吗?
前3步(域名 + Cloudflare + 一键部署)零基础可以跟着做。第4步开始(写组件 + Schema)需要会基本的HTML/JS。如果纯不懂代码,建议:① 用WordPress + Yoast SEO + Schema Pro插件可以达到60% 的效果;② 或者直接用本站的Astro骨架(完整代码见后文),把内容填上去就行。