本地服务页 GEO 实战:ProfessionalService 与 LocalBusiness 怎么选,AI 引擎实体归类对照
适用读者:给律师事务所、设计工作室、咨询公司这类本地专业服务机构做官网与 SEO 的人。你的结构化数据可能还在用 LocalBusiness 一把梭,甚至压根没写。这篇把类型选型、字段改造到效果验证的完整过程拆开讲。
8 月 14 日,做家事法律咨询的老周(化名)给我发微信:「我问 AI『附近有没有专门做遗产继承的律师』,它给我推了一家企业管理咨询公司,我执照上写得明明白白是律师事务所。」他的站去年帮着调过一轮速度和 TDK,都没毛病,毛病出在另一个地方——页面 JSON-LD 里 @type 写的是 LocalBusiness,一个不带任何行业信号的泛型。
从那天起我花了一个半月,把两家本地服务机构(老周的律所,加上朋友小郑的设计工作室)做了类型选型和改造,每天用固定的 12 条 query 在三款 AI 搜索产品里记录命中情况。做生成式引擎优化(Generative Engine Optimization, GEO)这几年我有个越来越强的体感:AI 搜索在推荐门店时,先做的是行业归类,其次才轮到距离和口碑。实体归类错一档,行业匹配就差一个身位,后面再怎么堆内容都是白费劲。这篇把决策过程、字段差异和 45 天的数据变化摊开讲。
问题出在类型没选对
先说结论:老周的站不是内容不行,是引擎读不懂他是干什么的。

AI 搜索回答「附近有没有 XX 服务」这类 query 时,内部大致走三步:解析意图,把 query 拆成行业槽位、细分服务槽位和地理槽位;在候选实体里做行业匹配;最后按距离、评价、内容置信度排序。行业匹配这一步的依据之一,就是实体在 schema.org 类型树上的位置。LocalBusiness 是个筐,什么都往里装,等于什么都不是。
老周站上的结构化数据只有四个字段:LocalBusiness、name、address、telephone,全是通用信息,行业线索只剩店名里的「法律」两个字。引擎做行业归类时抓不到明确信号,只能靠正文文本兜底,置信度低,被引用自然不稳定。
我的验证办法很土:整理 12 条真实用户口吻的 query,比如「附近有没有家事律师」「厦门婚姻财产咨询找谁」,每天在豆包、Kimi 和一个接入搜索的对话产品里各问一遍,记录有没有引用他的门店名。改造前 30 天,12 条里只有 2 条偶尔被提到,而且隔几天又掉了。
两类字段到底差在哪
翻 schema.org 的定义能看到关系:ProfessionalService 是 LocalBusiness 的子类,父类型的字段它全继承,实战里它更依赖那组「专业属性」。两类在字段用法上的差别,我整理成下面这张表。
| 对照项 | LocalBusiness | ProfessionalService | 实战含义 |
|---|---|---|---|
| 类型定位 | 泛型本地商家 | 专业服务专用子类 | 类型本身就是行业信号 |
| knowsAbout | 可用但页面很少写 | 高频核心字段 | 声明你懂哪些领域 |
| availableService | 一般靠 makesOffer 绕 | 直接挂 Service 列表 | 单项服务可被单独引用 |
| hasOfferCatalog | 少见使用 | 做服务目录常用 | 支撑「你们能做什么」类回答 |
| 常见子类型 | Store、Restaurant、Hotel 等 | LegalService、AccountingService 等 | 子类型越细,归类越准 |
| 适合对象 | 餐饮、零售等实体门店 | 律所、会计师事务所、咨询、设计 | 行业属性强的机构都该往这走 |
差别说白了就一句:LocalBusiness 回答「这是个什么店」,ProfessionalService 回答「这是个什么行业的什么店」。AI 搜索做实体归类时,类型路径上的每一层都在贡献置信度,子类多走一层,行业槽位的匹配就多一分把握。
我是怎么一步步做选型的
选型不能拍脑袋,我按三个问题往下走:机构有没有行业监管资质;schema.org 里有没有对应的细分类型;页面正文能不能撑起这个类型。画成图是这样。
flowchart TD
A["本地服务机构做类型选型"] --> B{"有行业监管资质"}
B -->|"有"| C["走 ProfessionalService 子类型"]
B -->|"没有"| D["走 ProfessionalService 本体"]
C --> E{"存在更细的子类型"}
E -->|"有"| F["用 LegalService 或 AccountingService"]
E -->|"没有"| G["直接用 ProfessionalService"]
D --> H["补 knowsAbout 与服务字段"]
F --> I["正文与执照信息互相印证"]
H --> I
G --> I
老周的律所有执业许可,schema.org 里正好有 LegalService 这个子类型,类型路径是 LocalBusiness 到 ProfessionalService 再到 LegalService,三层行业信号,就选它。小郑的设计工作室没有强制资质,设计行业也没有更细的官方子类型,就落在 ProfessionalService 本体上,靠字段补行业信息。
有人会问,那我不换类型,直接在 LocalBusiness 上加 knowsAbout 行不行。我给老周站先做了这个中间状态:类型不动,只补字段。后面数据会说明,这条路能走,但贡献的大头不在这。
改造前后代码长什么样
两段代码都是 WordPress 环境,JSON-LD 注入。改造前那段全站统一输出,改造后按页面类型分发。
<!-- 环境:WordPress 6.x 主题,child theme 的 footer.php -->
<!-- 位置:body 结束标签之前,整站输出 -->
<!-- 改造前:全站统一用 LocalBusiness 兜底 -->
<!-- 问题:类型本身不带行业信号,AI 引擎只能泛化处理 -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "明理家事法律咨询",
"address": "厦门市思明区莲前西路 88 号 601 室",
"telephone": "+86-592-00000000"
}
</script>
<!-- 四个字段全是通用信息,行业线索只剩店名里的法律两个字 -->
<!-- 环境:同上,改到 functions.php 里挂 wp_head 钩子输出 -->
<!-- 改造后:类型换成 LegalService,补齐专业属性 -->
<!-- knowsAbout 声明专业领域,availableService 挂具体服务项 -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LegalService",
"name": "明理家事法律咨询",
"knowsAbout": ["离婚诉讼", "遗产继承", "抚养权纠纷"],
"availableService": [{
"@type": "Service",
"serviceType": "婚姻家事法律服务"
}],
"priceRange": "$$",
"openingHours": "Mo-Fr 09:00-18:00"
}
</script>
<!-- priceRange 与营业时间是通用字段,照旧保留 -->
<!-- knowsAbout 与 availableService 是细分行业归类的关键信号 -->
改造过程里有几个执行细节值得记下来。第一件事是正文同步:类型换成 LegalService 之后,我把首页 H1 和服务页标题里补上了「律师事务所」的明确表述,让正文、执照展示页和 JSON-LD 互相印证,单改代码不动正文,效果出得慢。第二件事是老周原话提醒我的——「你们写的那堆字段,得跟工商登记对得上」,所以他站上 name 用的就是执照上的字号,没玩任何简称花样。
类型继承树与实体消歧的机制
这一节讲底层原理,搞明白就不会再纠结选型。
schema.org 的类型是一棵继承树,LocalBusiness 挂在 Organization 下面,ProfessionalService 是它的子类,LegalService 再挂在 ProfessionalService 下面。画出来是这样。
flowchart TD
A["Thing"] --> B["Organization"]
B --> C["LocalBusiness"]
C --> D["ProfessionalService"]
D --> E["LegalService"]
D --> F["AccountingService"]
C --> G["Store"]
C --> H["FoodEstablishment"]
AI 引擎在构建自己的知识层时,会把抓到的实体往这棵树上挂。挂的位置决定了两件事。
一是行业槽位匹配。用户问「附近有没有离婚律师」,意图解析出行业槽位是法律、细分槽位是婚姻家事、地理槽位是本地。候选实体的类型路径如果能走到 LegalService,行业槽位直接命中;如果停在 LocalBusiness,引擎只能拿 name 和正文文本来凑,这个匹配是低置信度的,命中就看运气。类型路径的深度,约等于行业判断的把握度。
二是同名消歧。一个城市往往有好几家带「明理」字号的机构,引擎要判断哪个实体才是用户要的那个。类型、地理、资质类字段凑在一起才能锁定。老周站改造前就吃过这个亏:AI 搜索把他和一家同名的企业管理咨询公司搅在一起,行业槽位又没信号,错配就这么发生了。消歧机制还解释了另一个现象——泛型 LocalBusiness 不是完全没机会被引用,但那是低置信度下的兜底,命中率和稳定性都差一截,这跟我们在 45 天数据里看到的完全对得上。
45 天跑下来的数据变化
交代一下口径:老周站 8 月 14 日上线改造,当天只换了 @type 和补了三个专业属性;小郑的站 8 月 20 日接手,9 月 2 日完成改造。每天固定 12 条 query、三款 AI 搜索产品,记录当天有没有引用门店名。下表是核心 5 条 query 改造前后各 30 天的日均命中数(满分 3)。
| 测试 query | 改造前 30 天日均命中 | 改造后 30 天日均命中 | 首次变化出现在 |
|---|---|---|---|
| 附近有没有家事律师 | 0.1 | 2.7 | 第 11 天 |
| 厦门婚姻财产咨询找谁 | 0 | 2.3 | 第 14 天 |
| 遗产继承律师推荐 | 0 | 2.0 | 第 26 天 |
| 附近设计工作室 | 0.3 | 2.3 | 第 19 天 |
| 口碑好的 logo 设计推荐 | 0.3 | 1.7 | 第 31 天 |
三个观察值得单独说。
只换类型不补字段的那个中间状态,第 6 天就开始出现零星命中,说明类型切换贡献的是大头,字段补全是增量。这跟前面原理部分对得上:类型路径决定能不能进池子,专业属性决定在池子里排多前。
长尾 query 的变化来得晚。「遗产继承律师推荐」这种细分服务词,第 26 天才稳定命中,因为引擎要重新积累这个实体在细分槽位上的证据,knowsAbout 里的词要和正文、服务页标题反复对上号才算数。
对照组那边,给老周引流的那家企业管理咨询公司页面到现在还挂着 LocalBusiness,45 天里 12 条 query 的命中曲线几乎一条直线。变量就在类型上,不是玄学。
几个容易踩的误区
第一个误区是觉得子类型越细越好,硬往上造。schema.org 里不存在的类型,引擎解析不了,等于没写。选型只在官方类型清单里挑,挑不到更细的就用 ProfessionalService 本体加字段。
第二个误区是代码和正文两张皮。JSON-LD 写得再标准,正文里通篇不提行业关键词和服务细分,引用率照样上不来。结构化数据是给引擎的索引,正文才是证据链。
趋势上说一句我的判断:生成式引擎对本地实体的行业归类会越来越依赖资质和细分服务字段,纯泛型页面的推荐权重会继续往下走。对做本地服务页的人来说,把类型选对是 GEO 里门槛最低的一步,改一个字段加几行属性的事,别在别处白费劲。你所在的行业归到哪个类型,欢迎评论区一起对一对。
参考与延伸
- ProfessionalService 类型定义与继承关系:https://schema.org/ProfessionalService
- LocalBusiness 父类型与可用字段:https://schema.org/LocalBusiness
- 律所常用的 LegalService 子类型:https://schema.org/LegalService
- 本地商家结构化数据官方规范:https://developers.google.com/search/docs/appearance/structured-data/local-business
LocalBusiness、ProfessionalService、实体归类、Schema.org、JSON-LD、AI搜索