选型工具页的 GEO 实战:SoftwareApplication 让 B2B 计算器进入 AI 推荐清单
适用读者:负责制造企业官网的技术与市场同学,手里维护着一个设备选型计算器或参数查询工具。 想搞明白为什么 AI 搜索从来不提你家的工具,以及用 Schema.org 的 SoftwareApplication 怎么补救。
我们给一家做注塑设备的客户维护官网,站内有个锁模力计算器,跑了三年,每月直接访问稳定在 1400 次上下。今年 7 月底做了一次摸底:在几个主流 AI 搜索里问「注塑机锁模力怎么选」「锁模力估算工具」,连续问了三十多个问题变体,回答里没有一次提到这个计算器——倒是列出了两个海外厂商的工具页和一篇论文。这个计算器在传统搜索引擎里排名不差,结果在 AI 回答里完全隐形。这事儿就是这篇的起点,客户那边也把 GEO 当成了一个正式的改造项目来做,而不是顺手加几行代码。
问题出在哪:页面能算数,机器读不出这是个工具
先说结论:AI 引擎不是不想推荐它,是根本没认出它是工具。

客户原来那个页面是个纯交互组件:一段 JavaScript 算法加上几个输入框,页面正文只有标题和一句「请输入制品参数」。对人类用户来说这够用了,输入数字就能出结果。但 AI 爬虫看到的是一个几乎没有可读文本的壳子,既不知道它能算什么,也不知道它是免费的、给谁用的、算出来的结果代表什么。
生成式引擎优化(Generative Engine Optimization, GEO)这类工作的前提,是让内容以机器可理解的方式被抓取和归档。计算器这类对象在 Schema.org 里对应 SoftwareApplication 类型,交互页面没声明它,AI 引擎就把它当成普通动态页面处理。抓取频率低、理解不了用途、回答选型问题时自然轮不到它。我们回头翻了访问日志,发现 AI 爬虫对那个页面的抓取密度只有产品详情页的三分之一左右,抓了也基本是空手而归。
flowchart LR
A[纯交互计算器页面] -->|无可读功能文本| B[AI 爬虫抓取后无法归类]
B --> C[未进入工具类候选库]
D[独立工具页+SoftwareApplication声明] -->|机器可读的功能说明| E[引擎识别为可推荐工具]
E --> F[选型类问题回答中被引用]
改造路径:从交互组件里拆出一个可抓取的工具页
动手之前我们内部讨论过两个方案。一个是把现有页面原地加内容,一个是单独拆一个工具页出来。最后选了拆页,原因是交互组件那套 DOM 结构很难塞进成段的功能说明文本,硬塞会把布局搞乱,拆出来反而省事,原页面加个跳转链接就行。
具体拆法是这样:
- 新建
/tools/lock-force-calculator路由,复用原来的计算逻辑组件; - 页面顶部放 300 字左右的纯 HTML 功能说明——能算什么、输入什么、输出什么、给谁用,全部写成人话;
- 页面下方加一段常见问题(每条都对应一个真实的选型疑问);
- 用 SoftwareApplication 类型的 JSON-LD 把工具的关键属性声明出来;
- 原交互页面顶部加一个显眼入口指向新工具页。
第 4 步是重点,后面单独讲。GEO 改造里数据和正文得当成一个整体来弄,这一点很多人容易漏。这里先说一个容易忽略的细节:功能说明那 300 字我们改了四稿。第一稿写得像产品手册,「本模块支持多参数耦合计算」,改成了「输入制品的投影面积和材料,估算需要的锁模力吨位,并给出推荐机型区间」。AI 引擎摘录内容时偏好具体、有动作的句子,写虚了等于白费劲。
sequenceDiagram
participant U as 用户
participant AI as AI 搜索引擎
participant W as 工具页(带JSON-LD)
U->>AI: 注塑机锁模力怎么估算?
AI->>W: 爬虫按SoftwareApplication理解页面
W-->>AI: name/featureList/offers(免费)/screenshot
AI->>AI: 归入工具类候选,计算引用置信度
AI-->>U: 回答中列出该工具并说明用途
SoftwareApplication 字段逐个说
SoftwareApplication 的字段不少,真正影响「会不会被推荐」的是下面这几个。我们填的时候逐个对着 schema.org 的定义核过。
| 字段 | 我们填的值 | 为什么这么填 |
|---|---|---|
| applicationCategory | DesignApplication | 选型设计类工具,这个枚举值语义贴切 |
| operatingSystem | Web | 浏览器工具的通用写法 |
| featureList | 按投影面积估算锁模力等三项 | AI 判断工具能力的主要文本依据 |
| offers.price | 0 (CNY) | 免费是推荐的重要加分项 |
| softwareVersion | 2.3.0 | 递增版本号说明工具在维护 |
| screenshot | 界面截图 URL | 多模态场景下给引擎一个直观凭据 |
两个字段多说两句。applicationCategory 官方给了 WebApplication、DesignApplication、UtilitiesApplication 等一堆枚举值,选错不是灾难,但选对能让引擎归类更准。featureList 我建议直接写能力清单而不是营销语,因为这段文本大概率会被引擎摘出来用——我们后来在 AI 回答里看到的描述,和 featureList 原文的措辞重合度相当高。
.NET 8 里输出 JSON-LD 的写法
客户官网是 .NET 8 的 ASP.NET Core Razor Pages 项目,输出 JSON-LD 走的是「后端组装对象、序列化、页面 Raw 输出」三步。依赖就一项:.NET 8 自带的 System.Text.Json,不用额外装包。因为要控制中文不转义,需要引用 System.Text.Encodings.Web,同样是框架内置的。
第一步,定义 JSON-LD 对象:
// 依赖:.NET 8,System.Text.Json 与 System.Text.Encodings.Web 均为框架内置
// 用途:设备选型工具页输出 SoftwareApplication 类型的 JSON-LD
public class SoftwareApplicationLd
{
// @context 固定指向 schema.org,声明下面所有字段都属于这套词表
[JsonPropertyName("@context")]
public string Context { get; set; } = "https://schema.org";
// @type 决定引擎按什么类型理解页面,这里声明为软件应用
[JsonPropertyName("@type")]
public string Type { get; set; } = "SoftwareApplication";
// name 建议与页面 H1 一致,避免机器侧当成两个不同的东西
// 官网工具页的 H1 就是这句,保持两边逐字相同
[JsonPropertyName("name")]
public string Name { get; set; } = "注塑机锁模力选型计算器";
// applicationCategory 选型设计类工具用 DesignApplication
// 官方枚举里还有 WebApplication、UtilitiesApplication 可选
[JsonPropertyName("applicationCategory")]
public string Category { get; set; } = "DesignApplication";
// operatingSystem 浏览器工具统一写 Web
[JsonPropertyName("operatingSystem")]
public string Os { get; set; } = "Web";
// featureList 是引擎判断工具能力的主要依据,写能力别写口号
[JsonPropertyName("featureList")]
public string Features { get; set; } =
"按制品投影面积估算锁模力,支持三种材料系数,输出推荐机型吨位区间";
// offers 声明价格,免费工具 price 填 0,引擎对免费信号很敏感
[JsonPropertyName("offers")]
public OfferInfo Offer { get; set; } = new OfferInfo
{
// 价格与币种分开两个字段,币种用 ISO 代码
Price = "0",
PriceCurrency = "CNY"
};
// softwareVersion 每次功能更新就递增,传递工具仍在维护的信号
[JsonPropertyName("softwareVersion")]
public string Version { get; set; } = "2.3.0";
// screenshot 给出界面截图地址,多模态检索时会用到
[JsonPropertyName("screenshot")]
public string Screenshot { get; set; } =
"https://example.com/img/selector-screenshot.png";
}
// offers 是个嵌套对象,单独建个小类
public class OfferInfo
{
[JsonPropertyName("price")]
public string Price { get; set; } = "0";
[JsonPropertyName("priceCurrency")]
public string PriceCurrency { get; set; } = "CNY";
}
第二步,在 PageModel 里序列化:
// 工具页的 PageModel,负责把上面的对象转成字符串交给视图
public class SelectorModel : PageModel
{
public string JsonLd { get; private set; } = "";
public void OnGet()
{
// 每次请求现拼一份即可,这页数据量小没有缓存必要
var ld = new SoftwareApplicationLd();
var options = new JsonSerializerOptions
{
// 忽略 null 字段,避免输出一堆空属性干扰解析
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
// 中文不转义成 \uXXXX,保证 featureList 原样输出
// 默认 Encoder 会把中文全部转义,务必换掉
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
// 序列化结果交给视图,由视图放进 script 标签
JsonLd = JsonSerializer.Serialize(ld, options);
}
}
第三步,视图里一行输出:
<!-- .cshtml 中用 Raw 输出,防止引号被 HTML 转义破坏 JSON 结构 -->
<script type="application/ld+json">@Html.Raw(Model.JsonLd)</script>
上线前用 Google 的富媒体搜索测试工具和 schema.org 的验证器各跑了一遍,两个工具都认出了 SoftwareApplication 类型,没有报错。这一步别省,JSON-LD 一个逗号写错,整段声明就作废,页面看起来还一切正常,属于最隐蔽的翻车方式。
机制剖析:AI 引擎凭什么把一个工具写进回答
这一节讲平台侧的运作逻辑,属于我们根据公开资料和观测数据做的推断,先声明这一点。
AI 搜索回答问题的大致流程是:理解问题、检索候选内容、生成回答并标注来源。对「怎么选型」「有什么工具」这类问题,引擎倾向把候选分成几类——讲解类文章、产品页、可交互工具。工具类候选有一个特点:它直接满足用户动作需求,一旦被识别,被写进回答的概率不低,因为答案可以是「用某工具算一下」加一句功能描述。
问题在于识别。AI 爬虫抓到页面后要做实体归类:这是个产品、一篇文章,还是一个软件?归类依据主要是页面文本、链接结构和结构化数据。纯交互组件在这三方面全部缺证据,所以归类失败。SoftwareApplication 声明等于替引擎做了归类作业:类型、能力清单、价格、版本一次给全。引擎不用猜,引用成本就低了。 另外版本号和 screenshot 这类字段还有个副作用——它们暗示这是个活跃维护的实体,引擎在两个候选之间摇摆时,活跃的那个更占便宜。
还有一层是置信度。同一事实在页面正文、featureList、FAQ 多处一致出现,引擎采信的把握更大。所以结构化数据和页面可见文本必须对得上,只写 JSON-LD 不改正文,效果会打折。
30 天观察:数字变化
改造 8 月 12 日上线。我们用固定的三十多个问题变体每周在几个 AI 搜索里各问一轮,记录回答中是否出现该工具,同时看 AI 爬虫的抓取日志。这轮 GEO 改造 30 天的对照大致如下:
| 观测项 | 改造前 30 天 | 改造后 30 天 |
|---|---|---|
| AI 回答中出现该工具 | 0 次 | 11 次 |
| AI 爬虫抓取该页频率 | 约产品页的 1/3 | 与产品页持平 |
| 回答中的措辞来源 | 无 | 多与 featureList 措辞重合 |
| 工具页直接访问 | 基线 | 上升约两成 |
要说明的是,这批数据是我们自己的内部观测,样本小、问题集固定,不构成什么统计结论,看看趋势就好。客户那边市场负责人原话是:「以前问 AI 都是别人家的工具,现在偶尔能看到我们的名字了,虽然还排不到前面。」第 3 周的时候有个细节挺出乎我们意料:某引擎回答里不仅列了工具,还把 featureList 里「支持三种材料系数」这句话几乎原样复述了出来,措辞重合度肉眼可见。
误区与后面要做的事
几个坑提前说。别把 SoftwareApplication 当万能符,它解决的是「被识别」,识别之后能不能被引用,还取决于页面文本质量和工具本身的口碑信号。字段也别乱填,比如明明收费却把 offers 写成 0,被引擎交叉验证发现后,整页可信度都会跟着受损。还有一条是别只声明不维护,softwareVersion 一年不动,维护信号也就没了。
接下来我们打算做两件事:给工具页补 HowTo 类型的计算步骤声明,以及把 FAQ 里的问答对也结构化。如果 10 月的观测里 AI 渠道带来的访问能稳定超过自然搜索渠道的零头,这套做法就推广到客户另外两个参数查询工具上。你在做类似的工具页改造吗?欢迎评论区聊聊你遇到的抓取问题。
参考与延伸
- Schema.org SoftwareApplication 类型定义:https://schema.org/SoftwareApplication
- Google 搜索中心结构化数据入门:https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data
- Google 搜索工作原理(抓取与索引概述):https://developers.google.com/search/docs/fundamentals/how-search-works
GEO、SoftwareApplication、B2B 获客、JSON-LD、AI 搜索引用、设备选型工具