结构化数据(JSON-LD):让 AI 引擎引用你的最短路径
模型读一段 HTML 时,要自己猜哪段是标题、哪个是作者、哪句是问答。JSON-LD 的作用是直接告诉它,不用猜。对希望被引用的站点,这是投入产出比最高的一项技术改动。
01为什么它对 AI 特别有用
结构化数据不是新东西,SEO 时代就有。但它对生成式引擎的价值更大:搜索摘要只需要展示,AI 需要理解并重组内容。字段越明确,重组时出错越少。
举个具体例子。一段问答在 HTML 里只是两个段落,模型得靠语序推断"这是问题、这是答案"。加了 FAQPage 之后,question 和 acceptedAnswer 是显式字段,抽取几乎零成本。
02三种最值得先做的类型
schema.org 有八百多种类型,不要贪多。对绝大多数站点,先把下面三种做对,收益就覆盖了八成。
| 类型 | 用在哪 | 关键字段 | 收益 |
|---|---|---|---|
| Article | 每篇文章详情页 | headline / datePublished / author | 明确作者与时效,利于被引用 |
| FAQPage | FAQ 区块或问答页 | mainEntity / acceptedAnswer | 问答对被直接抽取 |
| Organization | 全站(layout) | name / url / sameAs | 品牌实体归一,减少歧义 |
03Article 的完整写法
下面是一篇文章详情页里可直接使用的 JSON-LD。注意 datePublished 必须是 ISO 8601 带时区的格式,只写日期会被部分校验器判为不合规。
author 建议写成 Person 并给 url,指向作者介绍页。模型对"有明确作者的页面"信任度更高,这一点在多轮实测里反复出现。
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "结构化数据(JSON-LD):让 AI 引擎引用你的最短路径",
"description": "JSON-LD 是把页面里的实体关系用机器可读的方式再讲一遍。",
"datePublished": "2026-11-11T00:00:00+08:00",
"dateModified": "2026-11-11T00:00:00+08:00",
"inLanguage": "zh-CN",
"author": {
"@type": "Person",
"name": "Point",
"url": "https://fhgeo.u3sa.com/#top"
},
"publisher": {
"@type": "Organization",
"name": "风火GEO",
"url": "https://fhgeo.u3sa.com"
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://fhgeo.u3sa.com/docs/structured-data-jsonld"
}
}04FAQPage:把问答对显式化
FAQPage 的结构是 mainEntity 数组,每一项是一个 Question,Question 下挂 acceptedAnswer。写的时候注意答案要用完整句子,不要只写"是"或"否"。
一个常见坑是页面上显示的问答与 JSON-LD 不一致。Google 明确要求两者必须一致,不一致会被判为作弊,反而降低信任。
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "llms.txt 会被 AI 引擎读取吗?",
"acceptedAnswer": {
"@type": "Answer",
"text": "部分引擎会读取,但没有强制标准,它更多是降低读取成本的辅助手段。"
}
}
]
}05在 Next.js 里怎么注入
App Router 里最直接的方式是在页面组件里渲染一个 script 标签,type 为 application/ld+json。用 JSON.stringify 序列化,不要手拼字符串。
如果站点有多个页面都要 Article,把它抽成一个函数,参数是文章对象,返回 JSON-LD 对象,页面里只负责渲染。这样字段口径统一,改一处全站生效。
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: article.title,
datePublished: article.date + 'T00:00:00+08:00',
author: { '@type': 'Person', name: 'Point' },
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
);06三个最容易踩的坑
第一个坑是脚本没渲染。用客户端 useEffect 注入 JSON-LD,爬虫和 AI 拿到的 HTML 里根本没有这段内容。判断方法很简单:curl 拉原文,grep 一下 ld+json,搜不到就是没渲染。
第二个坑是字段类型写错。datePublished 写成 "2026年11月11日"、author 写成一个字符串而不是对象,这类错误在浏览器里看不出任何异常,只有校验器会报。上线前必须过一遍校验。
第三个坑是多段 JSON-LD 互相冲突。首页同时有 Organization、WebSite、FAQPage,如果两个脚本里都声明了同一个 @id 却给了不同 url,解析器会任选其一,结果不可预期。给每个实体固定一个 @id,全站复用。
# 检查线上 HTML 里到底有没有渲染出 JSON-LD
curl -sS https://fhgeo.u3sa.com/docs/structured-data-jsonld \
| grep -o 'application/ld+json' | wc -l
# 抽出 JSON 部分做语法校验(去掉 script 标签后交给 jq)
curl -sS https://fhgeo.u3sa.com/docs/structured-data-jsonld \
| sed -n "/ld+json/,/<\/script>/p" | sed "1d;$d" | jq .07自检清单
写完不等于生效。上线前按下面的清单过一遍,能挡掉九成问题。
- 用 schema.org 的校验器确认没有必填字段缺失。
- 确认 JSON 能被 JSON.parse 解析——常见错误是中文引号或多了一个逗号。
- 确认页面上可见的问答与 FAQPage 里的完全一致。
- 确认 url / @id 是绝对地址,且与 canonical 一致。
- 用 curl 拉线上 HTML,确认 script 标签真的渲染出来了(客户端注入的抓不到)。
要点
- JSON-LD 的价值是让模型不用猜:标题、作者、时间、问答全是显式字段。
- 先做 Article、FAQPage、Organization 三种,覆盖八成收益。
- datePublished 用 ISO 8601 带时区格式,作者给 Person 加 url。
- 页面上显示的问答必须与 JSON-LD 一致,否则会被判为作弊。