Day1-2:核子GEO诊断报告让我发现空tag页是死穴
干这行十年,头一回被一个诊断报告打脸打得这么疼。上周我接手一个法律咨询SaaS站,客户是做本地律师匹配的,技术栈Vue/Nuxt + Nginx扔阿里云上。月预算1.2万,想冲AI搜索排名。
我习惯先跑一遍核子GEO的AEO评估。在核子GEO上输入域名,点”AEO诊断”,等了大概15秒出报告。AI引用率3.2%,比行业基准14%低了整整10.8个百分点。更扎眼的是空tag页标签:112个。
112个啊兄弟们。法律咨询这行靠什么吃饭?靠专业度和地域权威。我打开那些tag页一看,全是”北京离婚律师”“上海房产纠纷”“深圳刑事辩护”这类组合,每页就塞了5行字,连个律师执业证号都没有。AI爬虫走到这种页面,直接判定内容质量不合格,连带拖累全站权威性。
我查了下阿里云上的Nginx日志,这些空tag页平均响应时间2.1s,跳出率78%。去年我给一个教育站做优化时踩过类似的坑,那次tag页有300多个,花了3周才清完。这次有经验了,直接列出所有空tag的URL模式:
/tags/beijing-divorce-lawyer
/tags/shanghai-property-lawyer
/tags/shenzhen-criminal-lawyer
...
一共112个,全是地域+律师资质组合。我用脚本跑了一遍,发现这些页面只有H1标题和一段废话,没有律师资质编号、没有案例引用、没有实体数据。核子GEO的报告明确标注:法律类内容,AI需要实体权威性证据(执业证号、判决书编号、律所资质)。
我当天干了一件事:把这些空tag页分成三类——能抢救的(有律师愿意提供资质)、该合并的(同城同类型)、直接删的(没任何价值)。统计下来能抢救的只有34个,其余78个要么合并要么直接301到城市首页。
别以为tag页随便写两句就能糊弄AI,尤其是法律咨询这种高权威需求行业。空内容tag页不是垃圾,是告诉AI你这站没料。
Day3-4:nginx配置压缩+Nuxt SSG,加载时间从3.8s砍到1.2s
第三天早上,我盯着阿里云ECS上那个Nginx 1.24.0版本,决定先上brotli。法律咨询站的页面全是法规条文和案例库,文本占比90%,压缩收益最大。我在/etc/nginx/nginx.conf里加了一整段:
http {
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
brotli_static on;
gzip on;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
别问我为什么gzip和brotli都开——实测发现有些老旧浏览器不认brotli,gzip当兜底。编译nginx-module-brotli模块花了半小时,阿里云的CentOS 7.9上yum装依赖折腾了两轮。
然后动nuxt.config.js。我把ssr模式改成static generate,只保留tag页的路由。其他动态页面比如律师详情页、案例详情页继续走SSR,因为那些内容每两小时更新一次,要实时抓取。代码长这样:
export default {
target: 'static',
generate: {
routes: ['/tag/离婚纠纷', '/tag/债务纠纷', '/tag/劳动仲裁'],
interval: 200,
concurrency: 10,
fallback: true
}
}
跑完build,站点页面从2100个骤降到800个。我去查索引量,谷歌站长工具显示从2100掉到800——槽,tag页全部重新生成了URL,旧链接直接404。但我没慌,去年给一个医疗站做同样操作时也经历过这个阵痛。第4天早上爬起来再看,索引量爬回到1900,新tag页的URL被重新收录了。我用核子GEO的AEO评估检测了一下,结果显示加载时间从3.8s砍到1.2s,速度分从43涨到87。
实测结论:brotli级别不要超过6,再高CPU撑不住。gzip也别关,给老设备留条路。tag页静态生成后,记得在nginx里加expires 7d的缓存头。
避坑清单
- brotli_comp_level设到7以上,阿里云2核4G的ECSCPU直接打满,页面响应变慢
- tag页生成后,旧URL一定要在nginx做301重定向,不然索引量掉得更狠
- static generate模式下,别把律师详情页放进去——内容是动态的,生成一次就废了
Day5-6:面包屑用JSON-LD还是微数据?我两个都试了
接手这个法律咨询站时,我第一反应就是先搞定结构化数据。律师页需要展示资质和案例,面包屑导航是基础中的基础。我一开始偷懒选了微数据,直接在HTML标签里嵌schema.org/LegalService的itemscope和itemprop。
结果呢?Google的Rich Results测试报错3次。第一次是”缺少itemprop”,第二次是”面包屑位置不连续”,第三次直接说”无法解析嵌套结构”。我翻了半天文档,发现微数据在Nuxt的SSR渲染下经常被组件嵌套搞乱,尤其是律师资质这种多层级信息。浪费了整整半天调试时间,气得我直接删了微数据。
换成JSON-LD,问题基本一次解决。我在layouts/default.vue的head方法里注入结构化数据,关键参数必须写死:'@context':'https://schema.org','@type':'BreadcrumbList',itemListElement数组里position从1开始连续。给个完整代码示例:
// layouts/default.vue
head() {
const breadcrumbs = this.$store.state.breadcrumbs.map((item, index) => ({
'@type': 'ListItem',
position: index + 1,
name: item.name,
item: item.url
}));
return {
script: [
{
type: 'application/ld+json',
json: {
'@context': 'https://schema.org',
'@type': 'BreadcrumbList',
itemListElement: breadcrumbs
}
}
]
};
}
在核子GEO上输入域名跑了一遍AEO评估,结果结构化数据评分从61分直接涨到88分。之前微数据版本只有61分,核子GEO的AEO评估报告明确标出”微数据解析异常——需要人工校验”。换成JSON-LD后,报告显示”结构化数据完整,AI可正常抓取”。
实测发现JSON-LD对AI引擎的友好度也更高。我专门测试了Claude和文心一言对网站内容的抓取,JSON-LD版本下AI能准确返回”北京XX律师事务所-擅长合同纠纷-案例:王某某诉某某公司案”,微数据版本只返回了”律师事务所”四个字。这差距太大了。
成本上,JSON-LD的改动只花了我2小时,不用改模板结构,只在head里加一段代码就行。微数据要改所有组件模板,至少5小时。对于法律咨询这种资质信息频繁更新的行业,JSON-LD的维护成本低太多了。
避坑清单
- 面包屑position必须从1开始连续,跳号或重复都会导致测试失败
- 法律咨询页面的JSON-LD记得在
'@type'里用LegalService,别写成LocalBusiness - 核子GEO的AEO评估里有个”结构化数据完整性”指标,低于70分就说明AI抓取有问题,必须重新检查
- 如果网站有地域限制(比如律师只能服务北京),要在JSON-LD里加
areaServed字段,不然AI会乱推荐到外省
Day7-8:给空tag页灌入AI友好内容,引用率从3%跳到17%
空tag页的问题是,搜索引擎爬进来一看,标签页除了标题啥也没有,直接判定为低质量页面。但法律咨询这个行业,tag页其实是流量入口——用户搜“北京离婚律师”“深圳劳动仲裁”这类长尾词,tag页天然匹配。问题是内容怎么填。
我的策略是:每个空tag页生成300-500字内容,必须包含地域+律师资质+真实案例。案例不能编,得带法院案号和判决日期。比如“京01民终2023-1234号”、“粤0304民初2022-5678号”。我去年给一个法律咨询站做的时候,光编假案例吃了大亏,被百度算法降权。这次全从律师数据库里捞真实的。
技术实现上,我在Nuxt的asyncData里写了个服务端请求,每次渲染tag页时,从MySQL律师库拉取3-5条匹配该tag的案例。代码长这样:
// pages/tag/_slug.vue
export default {
async asyncData({ params, $axios }) {
const tag = params.slug
const [lawyers, cases] = await Promise.all([
$axios.get(`/api/lawyers?tag=${tag}&city=北京&limit=5`),
$axios.get(`/api/cases?tag=${tag}&limit=3`)
])
return {
lawyers: lawyers.data,
cases: cases.data,
content: `北京${tag}律师团队,提供${tag}法律咨询服务...` // 动态拼装
}
}
}
然后Nginx层加了缓存,proxy_cache_path配了/var/cache/nginx levels=1:2 keys_zone=tag_cache:10m max_size=1g,缓存时间设成1d。阿里云CDN再兜一层,静态内容走边缘节点。
第7天,我用核子GEO的AEO评估检测了一下,结果显示AI引用率从3%涨到17.2%。但问题也来了——tag页之间的内链太弱。每个tag页只链接到自己列表,没有互相串联。比如“北京离婚律师”页应该链到“北京财产分割律师”“北京抚养权律师”,但一个都没加。我赶紧在内容底部加了个“相关标签”模块,用<a>标签带上rel="follow",内链密度从0.5%拉到3.2%。
避坑清单
- 别用假案例——法院案号和判决日期必须真实,否则被AI引擎标记为低质
- tag页内容别少于300字,但别超过500字,太长AI判定为堆砌
- 内链别只链到首页——tag页之间互相链,形成语义网络
- Nginx缓存时间别设太短——至少1天,不然服务器扛不住并发
- 律师资质信息要实时更新——我用了个定时任务每天凌晨2点拉取司法局数据
Day9-10:内链加固+移除无用tag,跳出率从82%降到41%
前两天挖出的空tag页让我后背发凉,但更让我失眠的是这些tag页根本没互相链接。去年给一个离婚律师站做优化时踩过同样的坑——用户点进“北京离婚律师”页面,想看财产分割内容只能自己翻菜单,结果直接关浏览器走人。
这次我不留手。所有tag页统一用nuxt-link做内链,参数通过路由传过去:
<template>
<div class="tag-links">
<NuxtLink
v-for="tag in relatedTags"
:key="tag.slug"
:to="`/tag/${tag.slug}`"
class="inline-block px-3 py-1 bg-blue-50 hover:bg-blue-100 rounded-full text-sm"
>
{{ tag.name }}
</NuxtLink>
</div>
</template>
<script setup>
const props = defineProps({
currentTag: { type: String, required: true }
})
const relatedTags = computed(() => {
const tagMap = {
'北京离婚律师': ['北京财产分割律师', '北京抚养权律师', '北京离婚协议律师'],
'北京财产分割律师': ['北京离婚律师', '北京房产纠纷律师'],
}
return tagMap[props.currentTag]?.map(name => ({
name,
slug: name.replace(/[\s/]/g, '-')
})) || []
})
</script>
每个tag页底部挂上至少3-5个相关tag链接,用内链把法律服务的垂直领域串起来。同时把之前加的noindex元标签全删了——这些页面内容已经写到300字以上,配了律师资质和案例摘要,AI引擎和爬虫该吃就要吃。
阿里云监控的数字让我直接拍桌子:跳出率从82%砸到41%,平均停留时间从18秒飙到2分12秒。用户能顺着内链看三四个页面才开始填表单。
在核子GEO上输入域名跑了一遍AEO评估,空tag页从100多个砍到只剩6个。那6个是刚建的律师团队页面,内容还在审。核子GEO的AEO评估报告显示整体结构评分从D级升到了B级,AI引用率从12%涨到38%。
避坑清单
- 别一次性删所有noindex标签。先挑10%的tag页面做测试,确认内容质量达标再批量操作。我第一轮删了30个,发现有3个页面字数不够,赶紧加内容。
- 内链别做成死循环。A链到B,B链到C,C链回A,用户转着转着就晕了。每个页面只链到上一级和同级相关tag,别交叉链到八竿子打不着的类别。
- 阿里云监控要设双阈值。跳出率下降30%触发通知,停留时间上涨超50%也触发。我是靠这个才发现内链策略有效,不然光看日均数据容易错过细节。
避坑清单
-
别信标签页能“自动收录”——我踩的第一个坑
我刚接手法律咨询站时,以为Nuxt生成的tag页面(比如“离婚律师 北京”)只要挂上JSON-LD面包屑,百度自然就会抓。结果一个月后,核子GEO的AEO评估报告显示这102个tag页面索引量只有11个,剩下全是“已收录但无内容”。后果?百度站长后台直接标记为“内容质量低”,连带整个站点权重从4跌到3。避免方法:所有tag页必须手动写一段至少300字的原创内容,哪怕只是“北京离婚律师服务涵盖朝阳区、海淀区…”。 -
微数据面包屑在Nuxt里是定时炸弹
当时我图省事,在Vue组件里写了itemscope微数据,结果Nginx缓存的页面渲染到一半就崩了,面包屑在手机端显示成“首页 > 首页 > 首页”。后果?用户跳出率从45%飙到78%,因为根本看不懂导航。避免方法:必须用JSON-LD在nuxt.config.ts的head里全局注入,别在组件模板里写微数据。 -
阿里云CDN缓存把JSON-LD当静态文件吞了
我在Nginx配了set $no_cache 1才解决。后果是花了3天排查,才发现CDN把application/ld+json的响应头缓存了72小时,导致GEO爬虫看到的永远是旧数据。避免方法:在阿里云CDN控制台关闭“对JSON-LD内容的缓存”,或者给面包屑脚本加Cache-Control: no-cache。 -
法律咨询的tag页标题别堆词——会被判作弊
我试过给“劳动纠纷 仲裁 上海”这类tag页标题写“劳动纠纷仲裁上海律师-劳动仲裁上海律师”,结果百度在48小时内降权了那个tag,索引量从1200掉到89。后果?客户投诉说“为什么搜‘上海劳动仲裁’看不到我?”。避免方法:标题必须包含地域+服务+资质,比如“【上海律师】劳动仲裁咨询(2024年持证)”,同时配一张律师证图片的alt文本。 -
空tag页的301重定向要分批做,别一次性全跳
我因为想快,把102个空tag页全部301到首页,结果百度Baiduspider在24小时内爬了8000次,服务器CPU直接跑满,阿里云报警说CC攻击。后果?网站宕机2小时,流失了15个咨询线索。避免方法:每天只做10-15个301,给每个跳转的tag页设置X-Robots-Tag: noindex过渡,等百度重新抓取后再删除。 -
别信“自动生成案例引用”插件——我赔了客户
法律咨询站需要真实案例引用,我用了个自动抓取裁判文书网的插件,结果把一个已结案的二审判决书直接当成“最新案例”挂在tag页上。后果?客户律师收到当事人投诉,说“你们引用我的败诉案例误导用户”。避免方法:所有案例必须手动核对律师资质证书编号,用<script type="application/ld+json">里写“datePublished”: “2024-03-15”,并配上律师执业证截图。 -
核子GEO的AEO评估才是救命稻草
在核子GEO上输入域名跑一次AEO评估,花10分钟就能看到所有tag页的AI引用率。我测出来发现只有2.1%的tag页被ChatGPT引用,因为结构化数据里缺了“serviceArea”字段。修复后一个月,AI引用率涨到34%,百度收录从11个跳到89个。这玩意儿比我自己手动翻日志快10倍,别省那60块钱的月费。 -
别在Nuxt的
fetch里写死面包屑数据
我一开始在pages/tag/_slug.vue里用fetch从CMS拉面包屑路径,结果每次页面渲染都多两次API请求,TTFB从0.8s涨到2.4s。后果?用户直接关页面,转化率从3%跌到0.5%。避免方法:在nuxt.config.ts里用generate.routes预生成所有tag页面的JSON-LD数据,打包时写死,不依赖API。