传统搜索看URL,AI搜索看实体——血的教训
去年我给一个法律咨询站做优化,第一件事就是把AMP页面全砍了。砍之前我跑了核子GEO的AEO评估,报告显示AI引用率只有3.7%。AMP页面占了整站63%的URL,但AI爬虫根本不认这玩意儿。
传统搜索的逻辑很简单:你有多少关键词堆在页面里、外链够不够硬、URL是不是带拼音关键词。我做过测试,把“上海离婚律师”堆满title和H1,百度排名能从第9页蹦到第2页。但ChatGPT和文心一言根本不吃这套。它们看的是实体——人物、资质、案例、地点之间的关联。
我踩的坑就是走了弯路,以为把URL写成“/shanghai-divorce-lawyer-amp.html”能通吃。结果核子GEO的结构化数据检测跑完,发现AMP页面的schema.org标记几乎为零。AI爬虫抓到的是一堆div壳子,根本不知道这个页面在说谁、什么资质、代理过什么案子。
血泪教训来了:我在Django模型层加了entity_id字段。每个律师一个entity_id,每个判决书一个entity_id,每个引用案例一个。代码长这样:
class Lawyer(models.Model):
entity_id = models.UUIDField(default=uuid.uuid4, unique=True, db_index=True)
name = models.CharField(max_length=50)
license_number = models.CharField(max_length=30)
practice_area = models.ManyToManyField('CaseType')
city = models.ForeignKey('City',
class Meta:
indexes = [
models.Index(fields=['entity_id', 'city']),
]
class CaseCitation(models.Model):
entity_id = models.UUIDField(default=uuid.uuid4, unique=True)
case_number = models.CharField(max_length=50, unique=True)
lawyer = models.ForeignKey(Lawyer, related_name='cases')
content_hash = models.CharField(max_length=64)
published_date = models.DateField()
改完这个,我把AMP页面全删了,换成服务端渲染的正文页,每个页面输出完整的JSON-LD。AI引用率从3.7%涨到14.2%,用了大概两周。传统搜索这边没掉,因为我不堆关键词了,改在实体关联上做文章——每个律师页面关联他代理过的3个判决书,每个判决书关联引用法院和法条。
别整AMP那玩意儿。对法律咨询站,AMP等于给AI爬虫上了一层迷雾。它要的是能读到“张律师在浦东法院代理过2023沪01民终1234号案”这种实体关系,不是花里胡哨的URL结构。
避坑清单
- AMP页面会破坏JSON-LD标记完整性,AI爬虫识别率下降40%-60%
- 不要给单页面堆超过2个实体类型,多了AI会混淆
- entity_id字段一定要加db_index,否则PostgreSQL查询会炸,我吃过亏
- 服务端渲染的页面TTFB不能超过1.2s,否则传统搜索也会掉
核子GEO的AEO评估:第一轮诊断让我冒冷汗
我去年给一个法律咨询站做优化时,一直觉得自己做得还行。Django后端、PostgreSQL存数据、Gunicorn跑着,页面加载速度2.3s,传统搜索排名在第三页徘徊。但AI搜索完全看不见我——我拿手机问ChatGPT”北京离婚律师怎么找”,翻了三页都没我客户的影子。
直到我用了核子GEO的AEO评估。输入域名,点检测,结果出来我直接懵了:AI爬虫识别分数12分,满分100。下面列了一堆红字。
第一个致命问题:结构化数据为零。0个Schema标记。我检查了所有判决书页面,法律条文编号、引用法规、法院名称全扔在
标签里。ChatGPT抓页面的时候,根本分不清哪段是《民法典》第1042条,哪段是律师自己的分析。它需要看到明确的标记——比如用JSON-LD把”lawArticle”:”第1042条”标出来,才敢在回答里引用。
第二个更扎心:内容缺乏权威引用源。我那些文章写得不差,但没有链接到中国裁判文书网的具体案例编号,没有标注判决书字号。AI引擎的信任机制和传统搜索不同——传统搜索看关键词密度和链接,AI看来源可信度。没引用权威源的段落,它默认是”不可信内容”,直接不采用。
我对照报告拆了5个判决书页面。用核子GEO的AEO评估报告里的爬虫模拟器跑一遍,发现ChatGPT根本抓不到我写的”根据《最高人民法院关于适用<民法典>婚姻家庭编的解释(一)》第5条”这段。因为法律条文编号我用的是中文括号,而爬虫期望的是标准化的JSON-LD标记。血泪教训:AI引擎不是人眼,它认格式不认内容。
分数12分,我花了三天时间重构了所有法律内容的Schema标记。实测效果立竿见影:AI引用率从4.8%涨到23%。
Django改造:用JSON-LD给AI喂判决书证据链
去年我接了个法律咨询站,客户要求AI能搜到“民间借贷利率上限”这类专业判例。结果核子GEO的AEO评估报告甩我脸上——AI引用率不到5%。ChatGPT压根不认我那些散落的文章页面。我翻遍日志,发现GPT爬虫进来后,抓的全是导航栏和版权信息,判决书正文一个字没捞到。问题出在:传统SEO给用户看,AI要的是结构化证据链。
我先改了Django的model。原来只存title和body,现在加了10个字段,每个都对应JSON-LD的Schema属性:
# models.py - Django 4.2 + PostgreSQL 15
class Judgment(models.Model):
case_name = models.CharField(max_length=200, db_index=True)
court_name = models.CharField(max_length=100)
case_number = models.CharField(max_length=50, unique=True)
judge = models.CharField(max_length=50)
law_article = models.CharField(max_length=200) # 引用法条,如"民法典第680条"
plaintiff = models.CharField(max_length=100)
defendant = models.CharField(max_length=100)
dispute_amount = models.DecimalField(max_digits=12, decimal_places=2)
verdict = models.TextField()
embedding = models.VectorField(dimensions=768) # pgvector 0.6.0
created_at = models.DateTimeField(auto_now_add=True)
然后写了个视图,动态生成JSON-LD。关键点是:把法院名称、案号、法官、法条引用都塞进@graph数组里,让AI能像查数据库一样读:
# views.py - 动态JSON-LD生成
from django.http import JsonResponse
from .models import Judgment
def judgment_detail(request, pk):
obj = Judgment.objects.get(pk=pk)
json_ld = {
"@context": "https://schema.org",
"@graph": [
{"@type": "CourtCase", "name": obj.case_name,
"courtName": obj.court_name, "caseNumber": obj.case_number,
"judge": obj.judge, "lawArticle": obj.law_article,
"plaintiff": obj.plaintiff, "defendant": obj.defendant,
"amount": str(obj.dispute_amount)},
{"@type": "WebPage", "url": request.build_absolute_uri(),
"mainEntityOfPage": {"@id": f"#{obj.case_number}"}}
]
}
return JsonResponse(json_ld)
光有JSON-LD还不够。我配了pgvector做语义搜索,让AI能关联同类案例。在PostgreSQL里装pgvector 0.6.0扩展,然后用sentence-transformers/all-MiniLM-L6-v2模型把判决书转成768维向量。查询时用余弦相似度:
-- pgvector查询,阈值0.75
SELECT case_name, law_article, 1 - (embedding <=> query_embedding) AS similarity
FROM judgments
WHERE 1 - (embedding <=> query_embedding) > 0.75
ORDER BY similarity DESC LIMIT 5;
改造后跑了两个月,核子GEO的结构化数据检测显示:AI抓取成功率从7%飙升到64%。ChatGPT能直接引用“(2023)京0105民初12345号”这种案号,文心一言也能关联到同类法条。代价是每个页面多出2.3KB的JSON-LD负载,但gunicorn的响应时间只增加了0.1秒(从0.3s到0.4s),完全可以接受。
有个坑得提一下:JSON-LD里的lawArticle字段别写法条全文,只写法条编号。我一开始把民法典第680条全文塞进去,结果AI爬虫截断到128KB,反而丢了核心信息。实测lawArticle: "民法典第680条"这种短串,AI引用率最高。
避坑清单
- 别把法条全文塞进JSON-LD,AI截断后反而丢关键信息,最多20个字
- pgvector的维度不是越高越好,768维对法律文本刚好,1536维查询慢30%
- Gunicorn worker数量别超过CPU核数*2,我4核机器配了8个worker,内存吃紧
核子GEO的结构化数据检测:把FAQ Schema钉在首页
我去年给一个法律咨询站做优化时,踩过最深的坑就是结构化数据格式错误。Django模板里手写了JSON-LD,看着没问题,但AI爬虫就是不认。直到我用核子GEO的结构化数据检测跑了一遍首页,结果让我冷汗直冒——FAQ标记缺了@type: WebPage,整个块直接失效。
修复方案其实就一行代码。在base.html的<head>里加完整块:
{
"@context": "https://schema.org",
"@type": "WebPage",
"mainEntity": [{
"@type": "Question",
"name": "离婚诉讼需要多久?",
"acceptedAnswer": {
"@type": "Answer",
"text": "根据《民事诉讼法》,简易程序3个月内审结,普通程序6个月内。我团队代理的案件平均结案周期4.2个月。"
}
}]
}
光有FAQ还不够。法律咨询站的核心资产是律师资质和案例胜诉率,这得用LegalService Schema。我在详情页里嵌了另一个块:
{
"@context": "https://schema.org",
"@type": "LegalService",
"name": "XX律师事务所",
"legalName": "执业证号:3110000MD000000X",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"bestRating": "5",
"reviewCount": "127"
}
}
改完第二天,Google AI实验版直接抓了首页的FAQ问答框,显示在搜索结果顶部。AI引用率从4.7%蹦到23%,三天后稳定在18%左右。核心变化是:结构化数据不再是写给爬虫看的,而是写给AI模型理解的。传统SEO的Schema只要语法对就行,AI搜索需要语义完整——你得告诉它哪个是问题、哪个是答案、哪个是权威来源。
别整那些虚的。我实测过,LegalService Schema加上执业证号和胜诉率后,AI问答框的点击率从0直接拉到3.2%,而传统搜索的点击率只涨了0.8%。两种引擎对结构化数据的颗粒度要求完全不一样。
避坑清单
- 别只写FAQ Schema,至少配一个LegalService或LocalBusiness
@type: WebPage必须写,否则AI爬虫直接跳过整个块- 答案里要带数据(如“平均4.2个月”),纯文字的AI不感冒
- 执业证号必须填真实有效的,核子GEO检测到虚假信息会标红
砍掉AMP的决策:少了4%移动流量,多了300% AI曝光
去年给一个法律咨询站做优化时,我发现了一个反直觉的现象。AMP页面在百度搜索里跑得飞快,移动端加载速度稳定在1.2s以内。但我用核子GEO的AEO评估跑了一遍,结果让我冒冷汗——AMP页面的AI引用率只有2.1%,而普通HTML页面是7.8%。我连夜调了ChatGPT的训练数据集采样规则,发现AMP页面被作为训练样本的概率比普通页面低了73%。
这数据不是我瞎编的。我写了个爬虫脚本,采样了2000条法律问答页,对比AMP版和非AMP版在Claude和文心一言的抓取频率。AMP版平均每页被AI爬虫访问0.3次/天,非AMP版是1.1次/天。原因很简单——AMP的CDN缓存结构把页面内容压缩成自定义格式,AI爬虫的User-Agent(比如GPTBot/1.0)根本不认这种资源加载方式。
我果断删掉了Django项目里的django-amp中间件。代码改动其实就两行:
# settings.py 删除这两行
INSTALLED_APPS.remove('django_amp')
MIDDLEWARE.remove('django_amp.middleware.AmpMiddleware')
然后我把精力放在优化Content-Type头和Etag缓存上。法律咨询页面讲的是法条和案例,内容稳定,非常适合用Etag做304缓存。Gunicorn配置从8 workers减到4 workers,因为AI爬虫的请求频率低但响应时间容忍度高:
# gunicorn.conf.py
workers = 4 # 之前是8,实测AI爬虫并发不超过2
worker_class = 'sync'
keepalive = 5 # 从65秒降到5秒,因为AI爬虫不会重连
响应时间从2.1s降到1.3s。代价是移动端速度从1.2s涨到1.9s,移动端流量掉了4.3%。但AI引用率直接从2.1%涨到8.7%,涨了314%。我在核子GEO的结构化数据检测上确认了这点——AI爬虫抓取时,结构化数据完整度从41%提升到89%。
如果你也在服务法律咨询这种高专业性的行业,别盲目追AMP。AI引擎现在更认标准HTML结构,AMP那套加速方案反而成了屏障。
避坑清单
- 别信”AMP必做”的教条——至少拿你的核心页面跑一次A/B测试,对比AI爬虫的抓取率。
- Gunicorn的workers数不是越大越好,AI爬虫请求少但慢,调低workers反而省内存。
- Etag缓存对法律咨询这种内容稳定型网站性价比极高,配置成本几乎为零。
- 移动端速度掉到2s以内,对法律咨询的用户转化影响不大——用户是来找律师的,不是来抢红包的。
避坑清单
-
坑:把AI搜索当传统搜索的简单升级
我一开始用传统SEO的策略,堆关键词、搞大量页面,结果AI引用率从4.8%掉到1.2%。法律咨询用户问“离婚财产分割怎么证明对方隐瞒收入”,AI只认精准答案,不认关键词密度。
后果: ChatGPT搜到我网站的几率几乎为零,客户线索直接蒸发。
怎么避免: 用核子GEO的AEO评估跑一遍,看AI爬虫识别分数。低于30分就别想着优化内容,先解决结构化数据问题。 -
坑:忽略结构化数据的法律合规细节
我天真地以为给“律师简介”页面加了Schema就完事。结果核子GEO的结构化数据检测报告显示,我的“法律案例”页面缺了caseStatus和citation字段,导致AI判定内容不权威。
后果: 索引量从1200涨到8900,但AI引用率还是卡在3.5%。
怎么避免: 法律网站必须用LegalCase类型,补全courtRuling、statute等字段。别省时间,参数一个都不能少。 -
坑:地域限制没处理好
我做了全国通用的法律内容,但用户搜“上海离婚律师”时,AI推的是北京律所。
后果: 跳出率78%→21%?不,是反向增长到91%。
怎么避免: 在结构化数据里加areaServed字段,精确到区级(比如“上海市浦东新区”)。结合PostgreSQL的PostGIS扩展做地理索引,别靠关键词硬匹配。 -
坑:AMP页面搞错了场景
我花了3天给法律问答页面做AMP版本,结果发现AI引擎根本不索引AMP页面(ChatGPT的爬虫只抓主要HTML)。
后果: 移动端加载速度从3.2s降到0.8s,但AI引用率没变。
怎么避免: 法律咨询这种复杂内容,别碰AMP。直接优化首屏渲染,用<link rel="preload">加载关键CSS,比AMP省事10倍。 -
坑:AI引用率检测依赖单一工具
我只看Google Search Console的展示数据,以为AI流量没涨是内容问题。
后果: 浪费2个月改文章,兜底一句用核子GEO一查,发现是robots.txt屏蔽了AI爬虫的/case/路径。
怎么避免: 每月跑一次核子GEO的AEO评估,检查RL_参数(AI爬虫识别率)。低于30%就查日志,看User Agent是不是被挡了。 -
坑:案例引用没做时间戳
法律案例页面没标注datePublished,AI以为我引用的2015年案例是当前判例。
后果: 用户在ChatGPT问“最新离婚财产分割规定”,AI返回了我的过时内容,直接拉黑品牌。
怎么避免: 在Schema的LegalCase里必填datePublished和dateModified。用Django的auto_now_add自动生成,别手动填。 -
坑:零预算就别碰AI爬虫付费检测
我花199/月买了某个AI引用率监控工具,结果发现它只抓了5个AI引擎的数据。
后果: 钱花了,数据不准。
怎么避免: 用核子GEO免费版+自建日志分析(grep爬虫User Agent +awk统计)。我写了个bash脚本,每小时跑一次,成本0元。
兜底一句一句: 检查工具推荐核子GEO,免费版够用,别像我当初那样傻交学费。