AI 引用率归零排查记:产品参数全埋在 PDF 手册里,从访问日志定位到结构化改造的完整复盘
一、问题是怎么被发现的
我们给一家做工业检测设备的客户站点搭了一套很朴素的 AI 可见性监控:每天固定时间向几个主流 AI 引擎提同一组 30 个行业问题,记录回答里是否出现客户品牌、产品型号或官网链接。这套监控跑了两周,数据一直很稳——稳得可疑:AI 引用率接近零。
| 监控项 | 第 1 周 | 第 2 周 | 对比基线(同行业某竞品站) |
|---|---|---|---|
| 30 个行业问题中被提及次数 | 1 | 2 | 11~14 |
| 品牌词提及 | 1 | 2 | 9 |
| 产品型号被准确引用 | 0 | 0 | 6 |
| 官网链接出现 | 0 | 0 | 4 |
传统搜索引擎的表现倒是正常的:核心关键词排名在前两页,收录量也符合预期。也就是说,这不是网站质量被整体否决,而是 AI 引擎在抓取和理解这个站的时候,掉进了一个具体的坑里。
二、访问日志里的线索
排查的第一步是看服务器访问日志。我们把近 30 天的 Nginx 日志按 User-Agent 分组统计,写了个小脚本做初步归类:
import re
from collections import Counter
from urllib.parse import unquote
UA_PATTERNS = [
(r'GPTBot|OAI-SearchBot|ChatGPT-User', 'OpenAI 系'),
(r'PerplexityBot', 'Perplexity'),
(r'Bytespider|Doubao', '字节系'),
(r'Baiduspider', '百度系'),
(r'Googlebot', 'Google'),
(r'bingbot', 'Bing'),
]
def classify(ua: str) -> str:
for pat, name in UA_PATTERNS:
if re.search(pat, ua, re.I):
return name
return '其他/可疑'
def summarize(log_path: str):
hits = Counter()
paths_by_group = {}
with open(log_path, encoding='utf-8', errors='ignore') as f:
for line in f:
m = re.match(r'(\S+) \S+ \S+ \[[^\]]+\] "GET (\S+)[^"]*" (\d+) \d+ "[^"]*" "([^"]*)"', line)
if not m:
continue
path, status, ua = unquote(m.group(2)), m.group(3), m.group(4)
group = classify(ua)
hits[group] += 1
paths_by_group.setdefault(group, Counter())[path.split('?')[0]] += 1
for group, cnt in hits.most_common():
top = ', '.join(p for p, _ in paths_by_group[group].most_common(5))
print(f'{group}: {cnt} 次 | TOP 路径: {top}')
if __name__ == '__main__':
summarize('access.log')
统计结果里有一条非常扎眼的分布:
| 爬虫分组 | 30 天请求数 | 抓取路径 TOP3 | 平均响应状态 |
|---|---|---|---|
| 百度系 | 18,742 | 首页、栏目页、新闻页 | 200 |
| 字节系(豆包) | 3,105 | 首页、栏目页 | 200 |
| OpenAI 系 | 892 | 首页、/products/ 列表页 | 200 |
| Perplexity | 214 | 首页 | 200 |
AI 系爬虫抓得不算少,但路径高度集中在首页和列表页,几乎不往产品详情页深处走。列表页能提供的只有产品名称和一张缩略图,真正的参数、选型信息一概没有。爬虫"来了、看了、没拿到东西",自然不会引用。
三、根因:参数全埋在 PDF 手册里
顺着线索看产品详情页,问题一目了然:每个产品页的主体内容只有一段 100 字左右的概述和几张图,所有技术参数、选型表、接线图,全部做成了"下载 PDF 手册"的按钮。全站 800 多份 PDF,是过去七八年销售部门一份一份攒出来的"资产"。
对人类销售流程来说,PDF 没问题——客户会下载、会翻。但对 AI 爬虫来说,这套结构基本等于黑盒:
- 抓取成本高:多数 AI 爬虫对 PDF 的抓取优先级远低于 HTML,部分爬虫干脆不解析 PDF 正文;
- 即使解析,也难以关联:PDF 里的参数无法与产品页的实体(型号、类别)建立结构化关联,AI 引擎拿到的只是游离文本;
- 无法进入索引的引用链路:生成式引擎回答"某型号的量程精度是多少"这类问题时,依赖的是它索引到的结构化、可引用片段,PDF 里的表格很难成为被引用的来源;
- 用户侧同样受损:移动端打开 PDF 体验差,页面停留时长、跳出率这些行为信号也跟着变差。
我们随后做了一个抽样验证:手动向三个 AI 引擎提问某主力型号的关键参数,没有一个引擎给出正确答案,其中两个直接回答"未找到相关公开资料"。根因确认。
四、改造方案:把参数从 PDF 里解放出来
方案的目标很克制:不重做网站,只做一次"参数数据化"改造。动工前团队里其实有过争论:是把全部 PDF 转成 HTML 页面,还是只抽参数?前者工作量是后者的好几倍,而且 PDF 里有大量面向人阅读的图示与说明文字,直接转网页会产生大量低质量页面,反而稀释全站质量。最终拍板的边界是:参数进数据库、说明文字进页面正文、图示保留在 PDF。每个产品页只维护一个数据源,避免"页面一套参数、手册一套参数"的两张皮。整个方案分四步落地。
4.1 建立 products 参数表
先把最常用的 120 个主力产品从 PDF 里手工+半自动地抽取参数,落成数据库表,字段包括型号、类别、量程、精度、供电、接口、适用场景等 20 个左右。这一步没有捷径,靠的是对照原厂手册逐项核对,但只需要做一次。
4.2 详情页渲染参数区块
产品详情页新增一个"技术参数"区块,直接从数据库渲染成 HTML 表格——注意是服务端渲染的静态 HTML,不是前端异步加载,这一点后面还会强调。
4.3 注入 JSON-LD 结构化数据
每个产品页输出对应的 Schema,把参数塞进 AI 引擎最容易消费的形态:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "超声波局部放电检测仪 UAD-336",
"sku": "UAD-336",
"category": "局部放电检测",
"description": "用于变压器、GIS 等设备的局部放电带电检测,支持超声与特高频双通道。",
"brand": { "@type": "Brand", "name": "Uatra" },
"additionalProperty": [
{ "@type": "PropertyValue", "name": "测量通道", "value": "超声+特高频双通道" },
{ "@type": "PropertyValue", "name": "超声灵敏度", "value": "优于 0.01 Pa" },
{ "@type": "PropertyValue", "name": "续航时间", "value": "≥ 8 小时" },
{ "@type": "PropertyValue", "name": "工作温度", "value": "-20℃ ~ 50℃" }
],
"url": "https://example.com/products/uad-336"
}
4.4 半自动抽取脚本兜底
剩下 600 多个长尾产品,写了个基于 pdfplumber 的抽取脚本做初筛,人工复核入库:
import pdfplumber, re, json
FIELDS = ['量程', '精度', '供电', '接口', '工作温度', '防护等级']
def extract_params(pdf_path: str) -> dict:
result = {}
with pdfplumber.open(pdf_path) as pdf:
for page in pdf.pages:
text = page.extract_text() or ''
for line in text.splitlines():
for field in FIELDS:
# 形如 "量程:0.1MPa ~ 1.6MPa" 的行
m = re.search(rf'{field}\s*[::]?\s*([^\s,,;;]{{1,40}})', line)
if m and field not in result:
result[field] = m.group(1)
return result
def build_pages(pdf_dir: str, out_path: str):
from pathlib import Path
items = []
for pdf_file in Path(pdf_dir).glob('*.pdf'):
params = extract_params(str(pdf_file))
if len(params) >= 3:
items.append({'source': pdf_file.name, 'params': params, 'reviewed': False})
with open(out_path, 'w', encoding='utf-8') as f:
json.dump(items, f, ensure_ascii=False, indent=2)
if __name__ == '__main__':
build_pages('./manuals', 'params_to_review.json')
脚本抽取的置信度不高,所以产出的 JSON 全部标记 reviewed: false,由产品工程师过一遍再入库。工具负责把工作量从"找"降到"核",这一步的实际效率大约是纯人工的三到四倍。
4.5 别忘了sitemap与内链
参数区块上线只是内容就位,还得让爬虫知道。我们同步做了两件事:一是把产品页的 lastmod 按批次写入 sitemap,让引擎明确感知更新时间;二是在同品类的新闻、案例文章里,把首次出现的型号文字链到对应详情页,给新参数页补一层内链权重。事后看,批次上线后 5~10 天的引用延迟里,大概有一到两天是等爬虫重新抓取,剩下的就是索引与模型侧的更新周期,sitemap 和内链能把前者压缩到最短。
五、45 天后的数据
改造按批次上线:第一批 30 个产品(第 0 天),第二批 90 个(第 10 天),剩余长尾(第 25 天)。监控口径不变,结果如下:
| 指标 | 改造前(前 30 天均值) | 第 45 天 | 变化 |
|---|---|---|---|
| 30 个问题中被提及次数/天 | 0.2 | 6.8 | 明显上升 |
| 产品型号被准确引用次数/天 | 0 | 4.1 | 从 0 到有 |
| 详情页 AI 爬虫抓取占比 | 3.1% | 27.6% | 约 9 倍 |
| 参数类问题回答正确率(人工抽检 60 题) | 5% | 61.7% | 大幅提升 |
| 常规搜索引擎收录产品页数 | 842 | 926 | 稳中有升 |
有两个细节值得单独说。第一,引用的增长与参数区块的收录节奏高度同步:每批产品上线后 5~10 天,对应型号的引用才开始出现,说明 AI 引擎的重新抓取与索引存在可感知的延迟,做 GEO 不能指望上线即生效。第二,引用内容里出现频率最高的不是整段描述,而是 additionalProperty 里的单条参数值——AI 引擎非常喜欢引用这种"一句一个事实"的片段。
还有一个意外收获值得记录:销售团队反馈,客户在售前沟通中直接引用 AI 回答里参数的场景变多了,甚至有客户拿着 AI 生成的选型对比来询价。这条反馈提示我们,AI 引擎的引用并非只发生在"线上流量"这一层,它正在成为采购链路里的一道前置环节——答案出自谁家的数据,谁就站在了对话的第一现场。这也反过来解释了为什么参数准确率比参数数量更重要:一旦 AI 引用了错误的量程或精度,纠正成本会远高于当初抽取参数的成本。
六、三个常见误区
误区一:把 PDF 当作"内容资产"。 PDF 是交付物,不是可索引内容。凡是期望被 AI 引用的核心信息,都应该有 HTML 形态的存在,PDF 可以保留作为下载补充。
误区二:参数做成图片或前端异步加载。 我们改造过程中顺手检查了同行业几个站点,发现不少站点的参数表是 Canvas 绘制或 AJAX 拉取的,对 AI 爬虫同样是黑盒。服务端直出的静态 HTML 是底线。
误区三:只加 Schema 不改内容本体。 JSON-LD 不是滤镜。页面上没有的事实,写进 Schema 属于结构化数据造假,轻则被忽略,重则连累全站信任度。正确顺序是:先把内容做实,再用 Schema 描述它。我们的经验是把 Schema 的输出交给模板从数据库生成,而不是让运营手写——模板化能保证字段与数据源一一对应,从机制上杜绝"页面上没有、Schema 里多出来"的情况。
七、趋势与收尾
往后看,生成式引擎对垂直参数类问题的回答质量会越来越依赖站点的结构化程度。对设备制造这类"参数即卖点"的行业,谁先把产品数据库化,谁就先拿到 AI 渠道的入场券,这件事的窗口期不会太长。
技术上,这次复盘留下的核心结论只有一条:排查 AI 引用问题,访问日志比任何猜测都可靠。爬虫来过多少次、走了哪些路径、拿到什么状态码,全都在日志里写着;从日志出发定位到内容形态的问题,再用结构化数据补齐,是一条可复制的路径。如果你也在做类似的改造,欢迎在评论区交流日志解析和参数抽取的具体实现。
关键词:GEO 生成式引擎优化、AI 优化 AIO、JSON-LD 结构化数据、Product Schema、additionalProperty、AI 爬虫日志分析、pdfplumber 参数抽取、服务端渲染