企业信息怎么让 AI 说对:Organization 画像字段补全的 45 天对照
适用读者:负责企业官网改版的技术同学、管官网内容的运营、后端工程师,以及所有纳闷「为什么 AI 把我们公司介绍错了」的人。
上个月接到一个老客户的电话,语气挺激动:他在某 AI 对话引擎里问「某某阀门公司规模多大」,AI 张口就是「约 2000 人,1998 年成立,主营管道安装工程」。真实情况:87 个人,2016 年注册,只做工业阀门。AI 把另一家同名公司的资料,原封不动安到了客户头上。 市场部当场就慌了——现在越来越多的采购方拿 AI 当搜索用,第一印象错了,后面解释起来成本很高。
我们接手排查后发现,客户官网的 JSON-LD 里只有 logo 和 name 两个字段,企业画像瘦得可怜。AI 引擎回答「这家公司多大、做什么的、成立多久」时,靠的是一套实体解析流程,官网给出的结构化数据(Structured Data)在其中权重很高,你不说清楚,它就自己去别处拼凑。这篇文章讲我们补全 Organization 画像字段、45 天后复测的完整过程。所有数据都是人工采样的自测口径,后面如实摆出来。
问题出在哪:画像太瘦,AI 只能到处猜
先把结论放前面:AI 引擎不是故意说错,而是它手里关于「这家公司」的证据太碎,拼错了。

生成式引擎优化(Generative Engine Optimization, GEO)这个概念这两年被讨论得很多,多数文章在讲内容怎么写、段落怎么排。但对企业实体这类「事实型问题」,内容的文采帮不上忙——AI 需要的是可以交叉验证的硬字段。我们复盘了客户被说错的三个点:
- 公司规模说成 2000 人:抓的是某招聘平台上同名集团的数据;
- 成立时间说成 1998 年:抓的是行业里另一家老牌企业的词条;
- 主营业务说成管道安装:从客户三年前一篇转载文章里抽的词。
三个错误,三个来源,没有一个是官网。说白了,官网自己没把话说清楚,AI 只好满世界找料,找到什么用什么。
实体解析(Entity Resolution)的过程大概是这样的:
flowchart LR
A["爬虫抓取网页"] --> B["抽取实体候选信息"]
B --> C{"同名或简称冲突?"}
C -->|"页面有结构化数据"| D["按 identifier 等硬字段对齐"]
C -->|"没有结构化数据"| E["按上下文相似度猜"]
D --> F["写入实体画像库"]
E --> F
F --> G["回答问题时填充事实槽位"]
这条链路上,第 3 步是分水岭。有结构化数据时,信用代码、注册全称这类硬字段能把实体钉死;没有的时候,引擎退回到「上下文相似度猜测」,同名公司一多,出错概率直线上升。
补了哪些字段:Organization 画像逐个拆
schema.org 的 Organization 类型下可填的属性有几十个,我们没贪多,挑的是 AI 回答「企业事实类问题」时实际会用的画像属性。任务边界也划清楚:这篇只谈企业画像字段,availableChannel、hasOfferCatalog 那类服务渠道字段是另一个话题,不在这里展开。
| 字段 | 类型 | AI 用它判断什么 | 我们填的示例 |
|---|---|---|---|
| legalName | 文本 | 注册主体是谁,做实体对齐 | 工商注册全称 |
| identifier | PropertyValue | 消歧,信用代码不重复 | 18 位统一社会信用代码 |
| foundingDate | Date(ISO 8601) | 成立多久 | 2016-03-18 |
| numberOfEmployees | QuantitativeValue | 公司规模多大 | 区间 50-99 |
| naics | 文本 | 主营行业归类 | 332911(工业阀门制造) |
| address | PostalAddress | 属地、注册地 | 省市区三段 |
| slogan | 文本 | 品牌主张(辅助) | 一句品牌话术 |
| sameAs | URL 数组 | 交叉验证「就是这家」 | 2 个权威外链 |
逐个说下填的时候踩过的坑。
legalName 与 identifier:消歧的两根钉子
legalName 填工商注册全称,一个字都别改。客户一开始想填品牌简称,理由是「简称好听」。问题在于简称是最容易撞车的:全国叫某个两个字牌子的公司一大把,AI 拿简称做对齐等于没对齐。全称里带着「制造有限公司」这类后缀,跟登记机关的公示数据是逐字对应的。
identifier 是这次改造里效果最明显的单个字段。用 PropertyValue 结构填 18 位统一社会信用代码,同名公司再多,信用代码全市场不会重复。这就把前面流程图里第 3 步的判断从「猜」变成了「查」。
foundingDate:格式比值更重要
foundingDate 必须是 ISO 8601 格式,2016-03-18 这种。我们第一版填的是「2016 年 3 月」,校验器直接报类型错误。日期格式不标准时,不少解析器会静默丢弃这个字段——页面看着没问题,AI 那边等于没收到。
numberOfEmployees:写区间,别写死数字
schema.org 允许 numberOfEmployees 用 QuantitativeValue 给出区间。人数是波动的,客户上月刚招了 6 个人,写死 87 过仨月就过期了。区间 50 到 99 能撑一年以上,而且对 AI 来说,「50-99 人」这个量级足够它回答「这家公司是小型企业吗」这类问题。区间比精确值更耐用,量级对了,回答就对了一半。
naics:给行业一个可查证的编码
naics 填北美行业分类编码(North American Industry Classification System),阀门制造对应 332911。国内企业用这个编码没障碍——主流 AI 引擎的实体库里都认识它。比起在 description 里自吹「技术实力强劲」,一个能被公开数据库查证的行业编码可信度高得多。这里顺带提一句 GEO 的实操心得:可验证的事实字段,优先级高于一切形容词。
sameAs:帮 AI 串起证据链
sameAs 指向能交叉验证的权威页面,我们填了两个:登记机关公示页和词条页。作用是让引擎把「官网这个 Organization」和「公示系统那个主体」连成同一个实体。链路串起来之后,前面那个抓错招聘平台数据的问题就消掉了——证据链有冲突时,硬字段会赢。
JSON-LD 怎么写:一段可以直接抄的示例
环境说明:schema.org 词汇表,无需任何运行时依赖,输出位置在页面 <head> 内。下面的注释行仅用于讲解,上线前要把注释整体删掉,发布版必须是合法 JSON:
// 示例基于 schema.org 词汇表,输出到 <head> 的 application/ld+json 脚本里
// 所有 // 注释行仅用于讲解,上线前必须删除
{
"@context": "https://schema.org",
"@type": "Organization",
"legalName": "示例阀门制造有限公司",
// legalName:工商注册全称,逐字对应公示系统,用于实体对齐
"name": "示例阀门",
// name:品牌简称,给人看的,对齐靠 legalName 和 identifier
// 简称全市场重复率高,单独靠它对齐约等于没对齐
"foundingDate": "2016-03-18",
// foundingDate:必须 ISO 8601 精确到日,格式错会被解析器静默丢弃
// 我们第一版填「2016 年 3 月」就被校验器打回过
"numberOfEmployees": {
"@type": "QuantitativeValue",
"minValue": 50,
"maxValue": 99
// numberOfEmployees:用区间,人数波动时不用频繁改页面
},
"naics": "332911",
// naics:北美行业分类编码,工业阀门制造,可被公开数据库查证
"identifier": {
"@type": "PropertyValue",
"name": "统一社会信用代码",
"value": "91350200MA000000XX"
// identifier:18 位信用代码,实体消歧的关键,示例值为占位
},
"address": {
"@type": "PostalAddress",
"addressRegion": "福建省",
"addressLocality": "泉州市",
"addressCountry": "CN"
// address:属地三段,别和注册地址互相打架
},
"slogan": "只做工业阀门,件件出厂检测",
// slogan:品牌话术,辅助性质,别写和事实字段冲突的数字
"sameAs": [
"https://www.gsxt.gov.cn/",
"https://baike.baidu.com/"
// sameAs:指向可交叉验证的权威页,帮引擎确认就是这家
]
}
注入与验证:一段 Node 代码加两条命令
客户官网是 Node 技术栈,我们没把 JSON-LD 写死在模板里,而是从 CMS 读画像数据动态拼装。环境:Node.js 20.x,Express 4.19,无其他第三方包:
// 依赖:Node.js 20.x,express 4.19,无需其他第三方包
// 用途:从 CMS 读企业画像,动态拼装 Organization JSON-LD 并注入页面
import express from "express";
const app = express();
// 画像数据统一从 CMS 读,别写死在模板里
// 写死的后果:改一次地址要发一次版,运营改不了,技术背锅
// CMS 字段更新后结构化数据随之更新,不用重新部署
const profile = await loadProfileFromCms();
// 字段白名单:CMS 里的脏数据不能直接进结构化数据
const allowedFields = [
"legalName",
"name",
"foundingDate",
"numberOfEmployees",
"naics",
"identifier",
"address",
"slogan",
"sameAs",
];
function buildOrganizationLd(p) {
const ld = {
"@context": "https://schema.org",
"@type": "Organization",
};
// 逐字段拷贝,顺手过滤空值
// 空字符串进 JSON-LD 比不写还糟,等于声明这个字段是空的
for (const key of allowedFields) {
if (p[key] === undefined || p[key] === null || p[key] === "") continue;
ld[key] = p[key];
}
return ld;
}
// 中间件:序列化后挂到 res.locals,模板里再输出
// JSON.stringify 会原样输出合法 JSON,注意别再手动格式化
app.use((req, res, next) => {
res.locals.orgLd = JSON.stringify(buildOrganizationLd(profile));
next();
});
// 输出位置必须在 <head> 内且尽量靠前,别塞页脚
app.get("/", (req, res) => {
res.send(`<!doctype html>
<html>
<head>
<script type="application/ld+json">${res.locals.orgLd}</script>
</head>
<body>页面内容</body>
</html>`);
});
app.listen(3000);
上线后做两步验证。环境:任意类 Unix shell,curl 8.x:
# 环境要求:类 Unix shell,curl 8.x,python3 任意 3.x 版本
# 第一步:确认页面里确实输出了 JSON-LD
curl -s https://www.example.com/ | grep -c "application/ld+json"
# 输出应为 1,为 0 说明注入中间件没生效
# 第二步:把 JSON-LD 抠出来做语法体检
# 注释没删干净这里会直接报 JSONDecodeError
# 正常输出 json ok 才算这步过了
curl -s https://www.example.com/ | python3 -c "import sys,re,json; m=re.search(r'application/ld\+json\">(.*?)</script>', sys.stdin.read(), re.S); json.loads(m.group(1)); print('json ok')"
除了本地体检,schema.org 官方校验器和 Google 的富媒体测试工具都可以贴 URL 在线跑一遍,两边的报错信息都比肉眼看靠谱。
机制剖析:画像属性如何变成 AI 嘴里的事实
这一节解释为什么补字段能纠偏。整条链路分三层:页面声明、知识三元组、回答时的事实槽位(fact slot)。
flowchart TD
subgraph SG1["官网声明的画像属性"]
F1["identifier 信用代码"]
F2["foundingDate 成立日期"]
F3["numberOfEmployees 规模区间"]
F4["naics 行业编码"]
end
subgraph SG2["引擎侧的知识三元组"]
T1["公司X - 注册于 - 2016年"]
T2["公司X - 规模 - 50至99人"]
T3["公司X - 行业 - 阀门制造"]
end
subgraph SG3["AI 回答里的事实槽位"]
S1["成立多久"]
S2["公司多大"]
S3["做什么的"]
end
F2 --> T1
F3 --> T2
F4 --> T3
F1 --> T1
T1 --> S1
T2 --> S2
T3 --> S3
第一层是页面声明,就是上面的 JSON-LD。爬虫抓到后按 schema.org 的类型定义解析成结构化数据。
第二层是知识三元组。引擎把结构化数据拆成「主体—谓词—客体」形式的事实,比如「示例公司—注册于—2016 年」,存进实体画像库。知识图谱(Knowledge Graph)本质上就是这类三元组的集合。单个字段对应一条三元组,字段缺失意味着对应的三元组根本不存在,而不是「引擎没采用」。 这是很多人对 GEO 的误解——以为内容写够多 AI 自然会学到,但事实型字段不是从长文里学出来的,是从结构化声明里抽出来的。
第三层是事实槽位。AI 回答「这家公司多大」这类问题时,会先识别问题里的槽位类型(规模?时间?行业?),再去实体画像里取对应三元组填充。槽位有值且经过交叉验证,回答就稳;槽位空缺,引擎从全网文本里抽相似内容补位,同名公司的资料、过期的转载文都是在这个环节混进来的。
补全字段之所以能纠偏,就是把三个空槽位填上了可验证的值,让引擎在第三步没有「自由发挥」的空间。
45 天前后对照:一组人工采样的数据
改造分两周做完,之后我们等了 45 天再复测。采样口径如下,如实交代:人工提问,3 家主流 AI 对话引擎,每家 20 个问题(覆盖规模、时间、业务、主体名、行业五类),每类问题在改造前(第 1 周)和改造后(第 6 周起)各采一轮,回答逐条人工判读「说对 / 说错 / 含糊」。判读标准是答案与工商公示和官网声明是否一致。
| 提问维度 | 改造前说对(20 题) | 改造前比例 | 45 天后说对(20 题) | 45 天后比例 |
|---|---|---|---|---|
| 公司规模 | 3 | 15% | 14 | 70% |
| 成立时间 | 2 | 10% | 15 | 75% |
| 主营业务 | 7 | 35% | 17 | 85% |
| 注册主体全称 | 4 | 20% | 16 | 80% |
| 行业归类 | 5 | 25% | 15 | 75% |
几个值得单独说的观察:
- 主营业务改善最快,第 20 天左右就能看到变化,因为行业编码和官网描述是引擎最容易重新抓取的内容;
- 成立时间改善最慢,我们怀疑实体画像里旧快照的刷新周期长,个别引擎到第 40 天才把 1998 年那个错误换掉;
- 「含糊不作答」的比例从 22% 降到 6%,这个没进表,但意义不小于说对率——AI 拿不准时宁可少说,也算画像起效的表现。
样本量 60 题、人工判读,肯定不算严谨的实验,但五类维度方向一致地往上走,足够支撑「补字段有效」这个结论了。
误区澄清:三个我们自己也犯过的错
误区一:字段加了就一劳永逸。 引擎对实体的快照有刷新周期,短的两周,长的一个多月。上线后第 10 天去看回答没变化就下结论「没用」,为时过早。我们自己的数据里,多数指标在第 25 到 40 天之间才明显爬坡。
误区二:字段越多越好。 我们第一版把 foundingDate(工商注册日)和 slogan 里「深耕行业二十年」的话术同时放上去,日期互相打架。AI 对事实字段和营销话术是分开处理的,话术里出现和事实字段冲突的数字,反而降低整体可信度。后来把 slogan 改成了不带数字的版本。
误区三:官网写了就等于 AI 看到了。 JSON-LD 注释没删、输出位置在页脚、被前端框架延迟渲染——这三种情况爬虫都可能拿不到。上线后务必用校验器从外部视角确认一遍,别只看浏览器里的页面源码。
趋势上多说一句:AI 对话引擎对企业实体的回答正在从「全网文本拼接」转向「实体画像优先」,GEO 的重心会越来越像给知识图谱喂数据,而不是写更漂亮的文章。早一天把画像字段补齐,就早一天进入引擎的实体库。
参考与延伸
- schema.org Organization 类型与属性定义:https://schema.org/Organization
- schema.org 官方结构化数据校验器:https://validator.schema.org/
- Google 搜索中心的结构化数据入门文档:https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data
- 美国人口普查局 NAICS 官方查询页:https://www.census.gov/naics/
AI 优化、GEO、AI优化AIO、企业信息被 AI 说错、Organization、numberOfEmployees、naics、JSON-LD