怎么把「AI 搜索里的品牌可见度」变成可复现的测量:题库、口径与判定

先做一次同题对照,这是起点。

拿一句话去问搜索引擎:「eKYC 服务商怎么选」。返回一页结果,落成数据无非位次、标题、网址三列——朴素,但形状清楚。(搜索引擎这一侧只是形态对照,我方这次没做这一侧的采集。)

同一句话调千问、豆包、DeepSeek 的接口,返回的是一段自然语言加一组来源,三家连来源的形状都不一样。要把这三份响应存进同一张表,第一个卡住的就是:位次这列填什么?

这篇写的是这套表怎么设计。数据来自 MaxGrowth(maxgrowth.ai) 在 2026 年 7 月下旬的一次全量测量:53 道问题 × 3 个平台 = 159 条真实应答,零失败。口径逐字写清:API 面口径,与手机 App 前台可能不同。

「看一眼 AI 怎么答」为什么不算数据

最常见的做法是打开 App 问一句,截图,写进周报。问题不在工具简陋,在于观测不可复现:问法临时想的,平台随手挑的,时间没记,应答原文没留,判定标准在人脑子里。下周换个人做,拿不出可比的第二个点。

要让它变成数据,至少得钉住四件:问题集冻结版本、链路参数固定、应答正文与引用源逐条落盘、判定规则写成代码。最容易被跳过的是第三件——很多实现只存判定结果不存正文,等有人质疑某个数字,回溯链就断在这里,只能重跑,而重跑已是另一个时间点的样本。

分层设计:四层问题各自回答什么

问题集不是关键词表的转写,是按决策链分层的。我方这次用的四层,每层被测对象不同:

获客意图层——用户带着要办的事来问(「想在 AI 搜索里被推荐该怎么做」)。测品牌能不能进入候选集。
对比选型层——用户已在两三个选项之间比(「A 方案和 B 方案哪个适合我」)。测品牌被放进对比时描述是否准确。
知识权威层——纯知识问题,不带商业意图(「AI 搜索的引用来源怎么选出来」)。测品牌内容有没有被当成解释性来源引用。
品牌反查层——直接问品牌本身(「这家公司做什么的」)。测主体识别对不对。

第四层最容易出错。我方实测里,同名主体混淆是普遍现象:AI 会把域名归属、业务描述错配给另一家同名公司,答得流畅、结构完整、内容错位。这一层必须先解决「答的是不是同一个主体」,再谈提及与位次。

分层的工程价值在于:每层分母不同,不能合成一个总提及率。获客意图层与品牌反查层的题混在一起取平均,数字既不反映曝光也不反映识别准确性,还会被题量大的那层带走。

三条联网链路,三种引用源字段

三个平台的响应结构差异,是这套测量里最容易被抹平掉的技术点。

  • 千问(DashScope,开联网检索):带的是检索面——模型这一轮拿到了哪些候选网页。出现在检索面里不等于出现在答案里,这一层回答的是「我的内容进没进召回」。

  • 豆包(方舟,web_search):带的是答案级引用,URL 直接挂在答案文本里。进到这一层,说明内容不只被召回,还被采用了。

  • DeepSeek(官方接口 + 第三方检索拼装):官方接口不联网,联网是外挂的。这条链路里的「引用源」其实是你自己那套检索的候选集,反映的是拼装方案的召回,不是平台的选择。

三者语义不同,但落盘未必要拆成三个字段。我方这次的实际做法是:一条应答落一行 JSONL,引用源统一写进同一个 citations 数组字段,链路靠同行的 platform 字段区分(qwen-api / doubao-api / deepseek-api)。

所以 citations 是个同名不同义的字段:千问那行装检索面条目,豆包那行装答案里直接挂出的 URL,DeepSeek 那行装外接检索候选。统计必须先按 platform 切开再各自计数——跨 platform 把 citations 的长度加起来,得到的数不指向任何真实事物。代价是约束落在消费方身上:字段形状一样,谁都能一把 SUM 下去。更稳的是在报表层写死按 platform 分组、禁止跨链路聚合——这是建议做法,当前实现没有报表层,靠统计脚本自己守。

三条链路上出现频次靠前的域名,分链路列,不给占比(占比没算过):千问检索面有知乎专栏、IT之家、博客园、搜狐、CSDN;豆包答案级引用有 B2B 信息发布站、行业垂媒、火山引擎开发者社区;DeepSeek 外接检索候选有 IT之家、博客园、搜狐、腾讯新闻、知乎。三张名单不重合。列出域名只是记录检索面的构成,不含对这些站点的评价。

实体四态、不能相加的分母,和两个踩过的坑

判定的第一个输出不是「命中 / 未命中」,而是「答的是不是同一个主体」。这一层我方冻结成四态:

  • ours:确实是我方。判 ours 要有强锚,三选一即可——出现自家域名、我方业务锚两项及以上的组合、或者品牌与产品名的绑定形态;

  • homonym:同名他方,答案描述的是另一家名字相同的公司;

  • unknown:答案里出现了品牌字样,但既没有强锚,也没有同名他方的线索;

  • absent:压根没出现。

只有 ours 那一档才继续判提及与位次,其余三档的我方指标字段一律不填。四态不能压成「命中 / 未命中 / 无法判定」三态:一压扁,答错主体、信息不足、压根没提混进同一个桶,而三者对应的动作完全不同——头一种要做主体消歧,第二种要补可核对的事实,第三种才是曝光不足。

分母怎么算,要先说清楚一件容易搞反的事:非 ours 的行仍然留在分母里,按「未被提及」计。原因是分母代表的是「测了多少次」,不是「有多少次值得算」——把答错主体的行从分母里摘掉,提及率会被系统性抬高,而且抬高的幅度取决于同名混淆有多严重,越糟糕的时候数字反而越好看。

真正要做的是在分母不变的前提下,把四态各自的条数单独列出来。这样同一个「提及率 0」能被读出两种完全不同的处境:一种是答案里压根没出现你(absent 占多数,问题是曝光不足),另一种是出现了但被认成了另一家(homonym 占多数,问题是主体消歧)。两种处境对应的动作不一样,合并成一个数就看不出来了。

坑一:用 LLM 当判定器,它会把同名品牌的命中记成目标品牌。我方实测这一项的误判率是 40%,而且误判的输出格式完全合规,肉眼查不出来。修法不是改提示词,是加程序化后置闸:实体不是 ours 时,由代码强制清空我方专属的指标字段(是否被提及、位次、是否进前三、情感倾向这一类),把清掉的字段名写进留痕字段,并给这行打上「闸已执行」标记。还要配一份绝不清空的白名单——「这道对比题倾向谁」「答案里点了哪些名字」不是我方专属,清了会把竞对互比题的有效值也抹掉。

坑二:让模型回结构化字段时,布尔值会被回成字符串。

`python

resp = {"mentioned": "false", "rank": None} # 模型回的是字符串

if resp["mentioned"]: # bool("false") is True

counter["hit"] += 1 # 静默 +1

`

bool("false") 在 Python 里为真,这行代码不报错、不告警,只是把命中数悄悄抬高。我方的修法是进闸前先做一遍类型归一:布尔字段上的 "true"/"yes"/"1"/"是" 折成真,其余折成假;位次字段先剔掉非数字字符再转整数;实体字段取值不在四态内时,原值挪进 raw 字段留痕,主字段落成 unknown。

顺序不能反——先归一,再过后置闸。反过来,闸拿着字符串判断,「实体不是 ours」这个条件本身就会判错,越权字段照样漏进统计。

一次全量跑批的复跑清单

照下面这张单子跑,同一批问题在不同时间、不同机器上跑出的结果才有可比性。标了「建议做法」的是该有但还没做的,别当成现状读。

冻结问题集版本,题面逐字不改;改题即新版本,不覆盖旧版本。
固定链路参数:千问 DashScope 联网检索、豆包方舟 web_search、DeepSeek 接口 + 第三方检索拼装,三份参数各自记档(这一项是建议做法,当前实现还没做)。
一条应答落一行 JSONL,同行带齐:平台、题面、题型、题号、判定档位、应答长度、应答正文(截断到 8000 字符存)、200 字摘要、引用源数组、判定结果、错误信息。
断点续跑的 key 用「题面文本 + 平台」,拿到判定结果且无错误的才跳过。结果是追加写入,同一 key 重跑会留下两行——想按最后一次为准合并得自己加,当前实现没这层逻辑。
传输层不赌网络状态:先探本机代理端口通不通,通就在直连与代理之间交替重试,不通就只走直连。错误目前不分类,鉴权错、参数错、网络错走同一套重试;按类型分流是建议做法,还没实现。
判定前先过实体闸,四态各自留档;不是 ours 的行由代码清空我方指标字段,并把清掉了什么写进留痕字段。
结构化字段先做类型归一再进闸,别让字符串布尔进统计。
废数据防线:应答正文短于 60 个字符直接判失败、不进统计。样板文识别与问题回显识别都是建议做法,当前实现没有,别写进对外方法描述。
判定规则本身带版本号,和应答同行落盘;规则改了版本号没动,跨期对比就失去参照。
引用源按平台切开统计,禁止跨链路求和。
终态记录写清:53 题 × 3 平台 = 159 条应答,零失败。
每个对外数字挂三个限定:平台、口径面(API 面口径,与手机 App 前台可能不同)、时间(2026 年 7 月下旬)。缺一个就不进跨期对比。
关于本文

本文由 MaxGrowth 团队撰写,写作过程中使用了 AI 辅助工具,内容与数据经人工核校。

posted @ 2026-07-28 17:45  MaxGrowth  阅读(3)  评论(0)    收藏  举报