把行业术语表做成 GEO 答案源:DefinedTerm 与 inDefinedTermSet 术语中心建设

2026-09-20 01:19:15 4 次浏览
GEO企业官网DefinedTermSchema.orgJSON-LD信息架构

适用读者:负责 B 端企业官网信息架构与结构化数据落地的前端、增长工程和 SEO 同学。要求你能改页面模板、能在 CMS 里加字段,并且看得懂 JSON-LD。

改版前我们数过一次:客户官网的行业术语一共 118 条,全塞在一个 glossary.html 的 <dl> 列表里,每条平均六十来字。可 AI 回答「XX 模组是什么」的时候,引用来源里一次都没出现过这个域名。

解释本身写得并不比百科差,有几条还更贴近自家产品手册。问题出在这些定义没有边界:一个 URL 装了上百个概念,引擎切完块之后,压根不知道该把引用挂到谁名下。

术语页输给百科站,跟文笔没关系

那家做工业自动化的客户,市场负责人原话是这么说的:「我们这条解释是照着自家手册改的,比百科准,AI 就是不提我们。」

术语中心主题图:词典向外辐射术语卡片网络

我们挑了 40 个定义类问题做手工抽查,把返回结果按引用域名归类,看出两件事:引用集中在百科类和两三家行业媒体;客户站点被抓进去的块,多半来自产品页段落,术语页几乎没进过候选集。

原因不复杂。一页装 118 条术语,这页的主题就成了「术语表」,而不是「伺服驱动模组是什么」。检索阶段它跟单条定义查询的匹配度天然偏低;就算勉强进了候选,切块时一条六十字的定义要么被拦腰截断,要么跟相邻两条粘成一个块,块里混着三四个概念,谁都不干净。

定义能不能被引走,先看它是不是一个能被单独切出来、还能自解释的单元。

术语中心拆成三层

我们的做法是把原来那一页拆成三层,每层各干一件事。做生成式引擎优化(Generative Engine Optimization, GEO)这一整套活儿时,这个分层是后来所有改动的地基。

层级 页面形态 主类型 干的活
术语详情页 一条术语一个 URL 定义术语(DefinedTerm) 承接定义类查询,首段自足
术语集合页 /glossary 汇总 术语集合(DefinedTermSet) 声明这张表归谁,聚合 120 条
索引入口 导航与 sitemap 条目列表(ItemList) 给抓取端一份完整清单

三层之间不靠页面位置联系,靠 @id 互指。这个决定后面省了很多事:集合页改版、详情页换模板,只要 @id 不变,图就还是连通的。

URL 结构纠结过一阵。最早想用 /glossary?term=servo-drive-module 这种带参数的地址,被否掉了——部分抓取端不把带查询串的地址当成独立资源,分享出去还经常丢参数。最后定成 /glossary/{slug},slug 用英文小写加连字符,术语改名时挂 301 把旧地址指过去,@id 不跟着动。

集合页只留了一张总表,没按首字母分页。120 条一次渲染完,页面大概两屏半,实测比拆成十几页更好抓:分页版本上线那两周,第 7 页之后的条目压根没进索引。

flowchart TB
  subgraph SRC["CMS 术语源 120 条"]
    A1["name / description / 同义词"]
    A2["termCode / 关联术语"]
  end
  A1 --> GEN["构建期生成器 strip 注释后输出"]
  A2 --> GEN
  GEN --> P1["术语详情页 x120<br/>DefinedTerm"]
  GEN --> P2["集合页 /glossary<br/>DefinedTermSet"]
  GEN --> P3["索引入口<br/>ItemList + sitemap"]
  P1 --> G1["稳定 @id 锚点"]
  P2 --> G2["hasDefinedTerm 汇总"]
  G1 --> EG["AI 引擎 切块与实体归属"]
  G2 --> EG
  EG --> OUT["回答引用落到品牌域名"]

单条术语页怎么标

详情页的图就盯两件事:一是让定义能被单独切出来,二是让它知道自己属于哪张表。下面是构建产物,注释为讲解保留,上线前由构建脚本剔除。

// 依赖与环境:Node 18 服务端渲染,JSON5 模板,构建期 strip-comments 后输出标准 JSON-LD
// 注入位置:术语详情页 head 末尾,每页一个 script 块,全部由 CMS 数据渲染
{
  "@context": "https://schema.org",
  "@type": "DefinedTerm",
  // @id 用稳定 URL 加 #term 片段,relatedTerm 靠它互指,别用数据库自增 ID
  "@id": "https://example.com/glossary/servo-drive-module#term",
  "name": "伺服驱动模组",
  // 英文与缩写单独列出来,用户拿 SDM 提问时才对得上
  "alternateName": ["Servo Drive Module", "SDM 模组"],
  // description 直接取正文首段文本,两处写法不一致会拖低可信度
  "description": "伺服驱动模组是把控制指令转换为电机转矩输出的驱动单元。",
  "termCode": "GL-021",
  // 这里只写 @id,实体本身定义在集合页,图里不重复展开
  "inDefinedTermSet": { "@id": "https://example.com/glossary#set" },
  // 只连站内已上线的条目,指向 404 会让整张图不被采信
  "relatedTerm": [
    { "@id": "https://example.com/glossary/encoder-feedback#term" },
    { "@id": "https://example.com/glossary/bus-latency#term" }
  ],
  "url": "https://example.com/glossary/servo-drive-module"
}

termCode 我们原本没打算加,后来发现内部文档、选型手册里大量使用缩写编号,加上之后同义词命中明显顺了。

还有条硬约束:页面可见文本和图里的内容必须一致。这条写进了生成器——description 直接读渲染后的首段 DOM 文本,运营在后台改了正文,构建产物自动跟着变,不存在两处手工同步。反过来说,图里塞正文没有的东西,比如在 alternateName 里堆一串竞品型号,容易被判成操纵。

集合页要做的事:把这张表的归属说清楚

集合页是整件事里投入产出比最高的一页,代码量不大,但它决定了归属关系能不能被算出来。

// 依赖与环境:同一套生成器,集合页 Only,随术语增删自动重算 hasDefinedTerm
// 注意:publisher 只写 @id,复用站点层已有的 Organization 节点,不重复造实体
{
  "@context": "https://schema.org",
  "@type": "DefinedTermSet",
  "@id": "https://example.com/glossary#set",
  "name": "工业自动化术语表",
  // 集合规模写清楚,引擎判断这张表覆盖度时会看
  "description": "面向工业自动化选型的术语表,收录驱动、总线、编码器等 120 条定义。",
  "url": "https://example.com/glossary",
  "publisher": { "@id": "https://example.com/#organization" },
  // hasDefinedTerm 全文列出,抓取一次就能拿到完整成员清单
  "hasDefinedTerm": [
    { "@id": "https://example.com/glossary/servo-drive-module#term" },
    { "@id": "https://example.com/glossary/encoder-feedback#term" }
  ]
}

双向挂钩是关键:详情页写 inDefinedTermSet,集合页写 hasDefinedTerm。缺了后者,集合页就只是一个普通列表页;缺了前者,术语和表之间没有可计算的边,引擎看到的是 120 个散落的定义,而不是一整套由某个组织发布的表。

原理剖析:一条定义查询在引擎里怎么走

这一节讲清楚机制,前面那些标注才不是玄学。

flowchart LR
  Q["用户问 什么是伺服驱动模组"] --> C{"查询意图分类"}
  C -->|定义类| R["混合检索 BM25 + 向量"]
  R --> P["候选 passage 切分"]
  P --> M{"块内是否自足"}
  M -->|否 跨概念混杂| X["丢弃"]
  M -->|是 单概念| S["实体解析 查 @id 与 inDefinedTermSet"]
  S --> A["归属到集合的 publisher"]
  A --> G["生成回答并附引用链接"]

定义单元是怎么被切出来的

抓取端拿到的页面会被切成若干 passage,每个 passage 带着自己的 URL 进索引。切分时如果按固定字数硬切,一条术语的定义很可能被拆到两个 passage 里,前半段没有主语,后半段没有谓语,两句都不像答案。

所以我们把每条术语的正文首段控制在 60 到 90 字,一个段落讲完「是什么」,后面的原理、选型、参数另起标题。这样无论切分窗口怎么滑,窗口里都能装下一个完整的定义单元。

参数表格和 FAQ 也会干扰切分。表格按行切完之后,每一行都缺主语,看着像答案其实不是。我们的处理是把参数表折叠进 details 标签,位置放在展开段落之后,保证首段到第三段的连续正文是干净的。

实体归属决定引用给谁

生成回答时,引擎不只要挑出一段话,还要决定「这段话是谁说的」。它看的是 passage 背后的实体图:这个 URL 上标了什么类型,这个类型又挂在哪张表下,那张表的发布者是谁。

inDefinedTermSet 就是把这段关系写死的地方。定义从「某个网页上的一段话」变成「某组织术语表里的第 GL-021 条」,引用来源自然跟着变。在 AI 搜索语境下,这种可计算的归属比正文里多写两遍品牌名管用得多。

模板改造踩到的坑

术语页模板原来只是服务端拼一个 <dl>,改成 /glossary/:slug 独立路由后,我们连着修了四类问题。

时间 症状 改动
3 月中 关联术语指向未上线页面 构建时校验,只输出已发布 slug
4 月底 运营改了正文,结构化数据没同步 description 强制取首段渲染结果
5 月中 术语页被判定为薄内容 每条补 300 字以上展开与 3 个内链
6 月初 索引页翻页后抓不全 索引入口一次性输出全部 slug

批量生成这批页面的节奏是一周 30 条,生成完先过人工审核再放上线。审核看的不是文笔,是三件事:定义跟产品手册有没有冲突、同义词里有没有混进竞品型号、关联术语是否真的相关。第一版我们图省事没过审,把两个不相干的概念连成了 relatedTerm,等于给引擎喂了一条噪声边。

排查则靠下面这段小脚本,跑在 CI 里,每次构建后校验图是否连通。

# 依赖与环境:Node 18 + jq,跑在 CI 构建之后
# 检查一:集合页声明的成员,是否每条都有对应的详情页
jq -r '.hasDefinedTerm[]."@id"' dist/glossary.json | sed 's/#term//' > /tmp/set.txt
# 检查二:反向核对,详情页指向的集合 @id 是否只有一份
jq -r '.inDefinedTermSet."@id"' dist/glossary/*/index.json | sort -u > /tmp/back.txt
# 两边数量对不上就退出,避免把断图发上线
test "$(wc -l < /tmp/set.txt)" = "120" || exit 1

两个月后看到了什么

3 月中旬先上了 46 条,4 月底补齐到 120 条,5 月中旬把 relatedTerm 补全,7 月初回头复查。

还是那 40 个问题,同样的问法,我们自己跑了一遍:落在这个域名下的引用从 0 条变成 11 条,其中 9 条直接指到术语详情页,剩下 2 条指到集合页。样本很小,也不排除那两个月行业媒体内容有变动,但方向是清楚的。

有个副作用挺有意思:销售反馈客户电话里直接念术语页 URL 来对需求,说明这些页面在真实检索里确实在使用,不只是被抓走喂模型。

判定方法也说一句。没用第三方监测工具,就是每天早上一遍遍问,把返回的引用链接记进表格。粗糙,但对 40 条样本够用,还能看出具体指到了哪一页——这个粒度是工具给不了的。

误区澄清与趋势

最常见的误区是把术语表当成一次性交付。我们第一版上线后三个月没动,术语新增了 17 条却没进集合页,hasDefinedTerm 停在 103 条,图里出现了一批没有反向边的孤儿条目。术语表得跟着产品线走,我们在 CMS 里给它加了「术语新增必须同步索引」的流程约束。

另一个误区是堆数量。有同行一口气铺了 500 条,每条不到 40 字展开,结果整站被判定为低质量。120 条能站住,是因为每条都有真实的产品文档做支撑,不是靠生成凑字数。

还有一种做法是给术语单独开子域甚至独立站点,我们评估后放弃了。新域名没有历史,实体解析阶段挂不上已有的组织节点,归属反而更弱。放在主域 /glossary 路径下,能直接复用站点层那套组织实体,这也是 GEO 里容易被忽略的一层复用。

往后看,术语中心会越来越像对外的数据契约:同一份术语源,既渲染给人看的 HTML,也喂给结构化数据、内部知识库和客服机器人。谁先把这层的边界切干净,谁在 AI 搜索里的引用就更稳。

你在自己的站点上试过 DefinedTerm 吗?关联术语的密度怎么定的,欢迎评论区聊聊。

参考与延伸

  • Schema.org 定义术语类型说明:https://schema.org/DefinedTerm
  • Schema.org 术语集合类型说明:https://schema.org/DefinedTermSet
  • inDefinedTermSet 属性定义:https://schema.org/inDefinedTermSet
  • relatedTerm 属性定义:https://schema.org/relatedTerm

GEO · 生成式引擎优化 · DefinedTerm · DefinedTermSet · Schema.org · JSON-LD · 术语表架构 · AI 搜索引用

🤖
本内容由 AI 辅助生成,经人工校对审核;部分素材、资料来源于公开网络,仅作个人观点分享与交流使用,无任何商业侵权意图。若内容、图片、文字涉及您的合法著作权、版权权益,请联系本人,核实后将第一时间删除、修改相关内容。