设备外形参数被 AI 搜索答错三周之后:Product 的 height 与 weight 字段结构化对照
一、问题是怎么被发现的
华东一家做自动化装配线的非标设备厂商,官网产品页写得很「传统」:外形尺寸 1200×800×1500mm,整机重量约 850kg,再配三张渲染图。这种写法人看得懂,销售发链接客户也看得懂,多年没人觉得有问题。

8 月 26 日,销售老周在客户现场发现一件怪事:客户拿着豆包的回答来压价,说「你们这设备高才 1.2 米,装不下我们的工件」。豆包把长度 1200mm 当成了高度,客户据此推算内部空间,结论完全跑偏。老周回来复盘才知道,这不是一次偶然——第 2 周里又有一家客户在电话里问「你们设备是不是 450 公斤」,450 这个数字官网从头到尾没出现过,是某个 AI 搜索自己估的。也就是说,从第一次被答错到团队真正确认,中间隔了整整三周。
我 9 月初进场排查时,把主流几个入口都问了一遍:问「GL-1500 锁附工作站的外形尺寸」,DeepSeek 给出三个数字但没标哪是长哪是高;Kimi 直接回答「页面未提供完整参数」;另有一家引擎把 800 说成高度。三次提问,三种错法。
根因不在内容写得少,而在这段文本对机器不可读。「1200×800×1500mm」是一个人读的排版串:乘号(×,U+00D7)在分词阶段容易被切开或吞掉;三个数字共享一个单位后缀,单位归属全靠读者按「长宽高」的阅读习惯脑补;页面 DOM 里这段字还嵌在表格单元格里,上下文跟「净重」「毛重」混排。AI 管线从这种文本里抽取字段,本质是在猜,猜错率取决于模型的运气。这也是我们在做生成式引擎优化(Generative Engine Optimization, GEO)时反复强调的一点:给 AI 的参数,要像给下游系统传接口一样给结构。
二、改造方案:Schema.org Product 的尺寸与重量字段
2.1 字段选型与单位码
Schema.org 的 Product 类型自带四个几何与重量字段:height、width、depth、weight,全部要求用 QuantitativeValue 表达。QuantitativeValue 的两个关键子字段是 value(数值)和 unitCode(单位代码),unitCode 必须用 UN/CEFACT 规定的三字母码,不是随手写 "mm"、"kg"。
| 物理量 | unitCode | 含义 | 常见错写 |
|---|---|---|---|
| 长度/宽/高(毫米) | MMT | millimetre | mm、MM、毫米 |
| 长度(厘米) | CMT | centimetre | cm |
| 长度(米) | MTR | metre | m |
| 重量(千克) | KGM | kilogram | kg、KG、公斤 |
| 重量(克) | GRM | gram | g |
为什么坚持用 UN/CEFACT 码?因为它是国际物品编码体系里被 EDI、海关、电商主干网广泛复用的口径,AI 引擎做单位归一化时优先对齐这套码表。写 "mm" 引擎多半也能猜对,但猜对是恩赐,对齐码表才是契约。
2.2 完整可运行的 JSON-LD 片段
下面是这家厂商产品页实际落地的 JSON-LD(品牌名做了替换),放进 <head> 即可被 AI 爬虫与搜索引擎直接解析:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "GL-1500 视觉定位锁附工作站",
"sku": "GL-1500-STD",
"brand": {
"@type": "Brand",
"name": "GleaLine"
},
"description": "面向 3C 产线的双工位视觉定位锁附设备,节拍 6 秒/件。",
"height": {
"@type": "QuantitativeValue",
"value": 1500,
"unitCode": "MMT"
},
"width": {
"@type": "QuantitativeValue",
"value": 800,
"unitCode": "MMT"
},
"depth": {
"@type": "QuantitativeValue",
"value": 1200,
"unitCode": "MMT"
},
"weight": {
"@type": "QuantitativeValue",
"value": 850,
"unitCode": "KGM"
},
"additionalProperty": [
{
"@type": "PropertyValue",
"name": "外形尺寸(长×宽×高)",
"value": "1200×800×1500 mm"
}
]
}
三个容易写错的点单独说。其一是 height/width/depth 的语义方向:Schema.org 约定 height 对应垂直方向,depth 对应纵深,不要按中文「长宽高」的直觉把 1200 填进 height——这正是此前被 AI 答错的同款错误。其二是 value 建议写纯数字而不是 "1500 mm" 字符串,单位已经由 unitCode 承载,数值再粘单位会破坏类型一致性。其三是 weight 只有一个字段,没有「净重/毛重」的区分,如有必要用 additionalProperty 补充说明,别在 weight 里塞两个值。
2.3 从产品主数据生成 JSON-LD
厂商的产品参数存在 Excel 和 PDM 里,让运营手工维护 JSON 迟早出错。我们用一段 Python 脚本从 CMS 导出的字段直接生成,并把校验做在发布前:
# -*- coding: utf-8 -*-
# 依赖:Python 3.10+,无第三方库,仅标准库 json
# 用途:从 CMS 导出的产品字段生成 JSON-LD,并在发布前做硬校验
import json
# 单位白名单:只允许 UN/CEFACT 三字母码,杜绝 mm/kg 这类散写
# 码表来源见文末 QuantitativeValue 链接,单位归一化按这套口径对齐
UNIT_WHITELIST = {"MMT", "CMT", "MTR", "KGM", "GRM"}
def build_qv(value, unit_code):
# QuantitativeValue 构造器:所有几何与重量字段统一从这里走
# 数值必须可转 float,防止 CMS 里混入 "约850" 这类脏数据
# 这里故意不放 try/except,让脏数据在发布环节直接炸出来
num = float(value)
# 单位码统一大写后再比对白名单
# 运营手改过 "mmt",引擎不报错但个别入口会忽略字段,必须在源头卡死
unit = unit_code.strip().upper()
if unit not in UNIT_WHITELIST:
# 单位码不合法直接抛错,宁可发版失败也不带病上线
raise ValueError(f"非法单位码: {unit_code}")
# @type 必须写 QuantitativeValue,漏写会让严格解析器丢弃整段
return {"@type": "QuantitativeValue", "value": num, "unitCode": unit}
def build_product_jsonld(p):
# p 是从 CMS 导出的产品字典,字段名与后台录入项一一对应
# 每个型号独立调用一次,禁止多型号页面复用同一份片段
return {
# @context 固定指向 schema.org,写成 http 会有兼容性告警
"@context": "https://schema.org",
# @type 用 Product;设备类可在 additionalProperty 补充行业参数
"@type": "Product",
"name": p["name"],
# sku 是 AI 实体对齐的重要锚点,多型号站点尤其不能省
"sku": p["sku"],
"brand": {"@type": "Brand", "name": p["brand"]},
# 注意方向语义:depth=纵深, width=横向, height=垂直方向
# 不要按中文「长宽高」直觉把 1200 填进 height,这正是之前被 AI 答错的同款错误
# 三个方向都用 MMT 毫米,与官网文本口径保持一致
"depth": build_qv(p["len_mm"], "MMT"),
"width": build_qv(p["wid_mm"], "MMT"),
"height": build_qv(p["hgt_mm"], "MMT"),
# 重量统一录千克,unitCode 固定 KGM
# weight 没有「净重/毛重」之分,毛重请放 additionalProperty 里补充
# 这里只录净重,与官网文本「整机重量约 850kg」口径一致
"weight": build_qv(p["net_kg"], "KGM"),
}
if __name__ == "__main__":
# 演示数据:与官网 GL-1500 页面参数保持一致
demo = {"name": "GL-1500 视觉定位锁附工作站", "sku": "GL-1500-STD",
"brand": "GleaLine", "len_mm": 1200, "wid_mm": 800,
"hgt_mm": 1500, "net_kg": 850}
# 生成后打印,接入 CI 时改为写入模板文件
# 接入 CI 的判断标准:脚本退出码非零则阻断发布
# ensure_ascii=False 保证中文名称不被转义成 \u 序列
print(json.dumps(build_product_jsonld(demo), ensure_ascii=False, indent=2))
上线后我们又加了一个探针脚本,每天抓一次自己的产品页,解析 JSON-LD 并与 PDM 主数据比对,字段不一致就发企业微信告警。参数被答错的代价是三周,而探针发现字段漂移只要一天。
三、原理剖析:AI 管线为什么只认数值加单位
要看懂这场改造为什么有效,得拆开 AI 引擎回答「设备外形」这类问题的完整链路。一次典型的回答要经过抓取、抽取、建实体、检索、生成五步,结构化数据改变的是中间三步的行为。
flowchart LR
A[AI 爬虫抓取产品页] --> B{head 里有无 JSON-LD?}
B -->|有| C[解析 @type=Product]
C --> D[取出 height/weight 的 value 与 unitCode]
D --> E[写入商品实体库 与页面文本互相印证]
B -->|没有| F[对正文做文本抽取]
F --> G[模型猜测数值与单位的归属]
G --> H[槽位歧义: 1200 是长还是高?]
H --> I[生成时按概率填槽 答错或拒答]
E --> J[生成回答时直接取字段 可溯源可引用]
没有 JSON-LD 时,管线走的是 F 到 I 这条猜的路。文本「1200×800×1500mm」经过分词后,乘号这种低频符号经常被过滤掉,剩下的三个裸数字与一个拖尾单位之间没有确定的绑定关系;「外形尺寸」这个词与「高度」这个词在 embedding 空间里确实相关,但相关不等于对齐,模型只能按训练语料里的统计惯性填槽——多数工业品描述里第一个数字是长度,于是 1200 被填进「长」,可一旦页面上有渲染图配文说「机身高达 1.5 米」,槽位又会漂。AI 搜索的回答质量,上限由抽取时的确定性决定,而不是由生成模型多聪明决定。
有 JSON-LD 时,走的是上面那条短路径:value 是明确的数字字面量,unitCode 直接对到码表,height/depth 的语义由 Schema.org 词表背书。生成阶段引擎可以精确引用「高 1500mm、整机 850kg」并附上来源链接,这就是 AI 搜索引用条数的来源。
我们同时把结构化数据的产出做成了管线,避免「手写一段 JSON 就完事」的脆弱状态:
flowchart TD
A[产品主数据 PDM/Excel] --> B[CMS 结构化字段录入]
B --> C[校验规则: 数值必填 单位走码表]
C --> D[模板引擎渲染 JSON-LD 注入 head]
D --> E[发布前 Schema 校验脚本]
E --> F{校验通过?}
F -->|否| C
F -->|是| G[发布 HTML]
G --> H[每日探针复检 字段比对主数据]
H --> I[AI 引擎抓取 进入实体库]
这条管线的价值在于把「对 AI 可读」从一次性动作变成持续状态。参数改版、站点重构、模板升级都可能把 JSON-LD 弄丢,没有探针的话,你往往要到客户来质问才发现——就像那三周一样。
四、改造前后 30 天对照
改造于 9 月 3 日上线。我们用固定的 13 个问法(涉及外形尺寸、高度、占地面积、整机重量、与竞品对比 5 类问题),在三个主流 AI 搜索入口每天各问一轮,人工记录回答是否与官网一致。下表是按周汇总的结果。
| 观测项 | 上线前一周 | 第 1 周 | 第 2 周 | 第 3 周 | 第 4 周 |
|---|---|---|---|---|---|
| 外形/重量回答正确率 | 3/13 | 6/13 | 9/13 | 11/13 | 11/13 |
| AI 回答附引用链接条数(周均) | 0.3 | 1.7 | 2.6 | 3.1 | 3.4 |
| 出现「编造数值」的轮次 | 5 | 3 | 1 | 0 | 0 |
| 客户来电澄清尺寸/重量的次数 | 4 | 3 | 1 | 1 | 0 |
两点说明:这是单一站点的小样本观测,问法集合固定、记录口径为主观判定「与官网一致」,数字不构成普遍结论,参考趋势即可;正确率在第 2 周之后才明显抬升,此前有同行说改完当天就见效,我们的体感是实体库更新有滞后,别急着下结论。
另外一个副产品:第 3 周起,DeepSeek 在回答「双工位锁附设备推荐」时开始引用这个产品页,把 850kg 的整机重量作为「结构刚性」的论据列出。参数答对之后,产品才开始进入 AI 的推荐语境——这是当初没预料到的收益。
五、踩过的坑与排查清单
过程不全是顺利的,这几个坑我们或深或浅都踩过:
- unitCode 大小写与拼写。运营手工改过一版写成 "mmt",引擎没报错但个别入口忽略了该字段。单位码按码表大小写写全,再交给脚本白名单卡住。
- weight 嵌套层级写错。有人把 weight 直接写成
{"weight": {"value": 850, "unitCode": "KGM"}}却漏了@type: QuantitativeValue,部分解析器宽容、部分严格,别赌运气。 - 多型号页面复用同一份 JSON-LD。厂商有 6 个型号,早期图省事共用一个片段,AI 抓到 B 型号页也能答出 A 型号的重量。每个 SKU 独立生成,sku 字段别偷懒。
- 页面文本与结构化数据打架。产品页宣传语写过「占地不足一平米」,而 1.2×0.8=0.96 平米确实不足,但有一个入口把「一平米」直接当成参数回答。口径要统一,宣传归宣传、参数归参数。
排查清单浓缩成一句话:先用 Rich Results Test 验证解析结果,再用探针盯字段漂移,最后每周人工问一轮 AI 复核回答——三层都过,才算真稳。
六、误区澄清与收尾
常见的误区是认为「上了 JSON-LD 就会被 AI 引用」。结构化数据的作用是消除歧义、提供可验证的取值来源,它不承诺排名,也不承诺引用量;但如果连字段都不给,AI 只能在文本里猜,猜错的概率永远存在。另外,这套工作与传统搜索引擎的站点优化并不冲突——同一份 JSON-LD 同时服务于 Google 的富结果与 AI 引擎的实体库,属于一次投入两处受益,后续再展开 SEO 侧的做法。
回到那三周:损失的不是流量,是客户对专业度的印象。对设备厂商来说,外形与重量是采购决策链上被问频率极高的一组参数,把它们从「排版文本」升级为「机器可读字段」,成本不过半天,收益却直接体现在 AI 搜索的回答里。如果你也在维护工业品官网,不妨今天就查一下自己产品页的源码,看 head 里有没有那段 JSON-LD——没有的话,AI 大概率正在替你「即兴发挥」。遇到多型号、多语言站点的结构化改造问题,欢迎评论区交流。
参考与延伸
- Schema.org Product 类型定义:https://schema.org/Product
- QuantitativeValue 类型定义(含 unitCode 说明):https://schema.org/QuantitativeValue
- Google 搜索中心 · 商品结构化数据文档:https://developers.google.com/search/docs/appearance/structured-data/product
GEO、AI 搜索引用、JSON-LD、Schema.org、QuantitativeValue、结构化数据、设备厂商 AI 获客