具体会崩在三个地方:
- 同一个问题不同版本混在一起。本月的问法和上个月不同,但Excel里看不出哪个回答对应哪个版本。
- 提及、推荐、位次和引用用了不同分母。提到品牌的样本算提及率,被推荐的样本算推荐率,但两者分母不同——Excel公式一拉,很容易把分母搞混。
- 汇总数字无法追溯到原始回答。月底看板显示提及率涨了5%,但没人能说清楚这5%来自哪几个问题、哪几次回答。
如果从数据工程角度回答"怎么测品牌在AI里的曝光",核心就是:先把每次独立回答保存成结构化样本,再用统一分母计算提及、推荐、竞品、准确性和引用指标。
本文给出一个可直接落地的三表数据模型,并用SQL(DuckDB/PostgreSQL风格)示例说明如何从原始回答计算五大核心指标。即使最终不用SQL实现,这套字段字典和计算逻辑也能直接迁移到Excel或BI工具中。
一、数据表的最小粒度
建议原始表一行对应一次独立回答:
brand_id × prompt_id × platform × run_id
基础表可以命名为:
ai_answer_samples
| 字段 | 类型 | 说明 |
|---|---|---|
| sample_id | VARCHAR | 样本唯一ID |
| brand_id | VARCHAR | 目标品牌ID |
| prompt_id | VARCHAR | 提示词ID |
| prompt_version | INTEGER | 提示词版本 |
| prompt_text | VARCHAR | 实际问题原文 |
| prompt_category | VARCHAR | 品牌、品类、场景、选型等 |
| platform | VARCHAR | AI平台 |
| run_id | INTEGER | 独立采样轮次 |
| sampled_at | TIMESTAMP | 采样时间 |
| valid_answer | BOOLEAN | 是否为有效回答 |
| recommendation_answer | BOOLEAN | 是否属于推荐型回答 |
| brand_mentioned | BOOLEAN | 是否提到目标品牌 |
| brand_recommended | BOOLEAN | 是否进入推荐候选 |
| rank_position | INTEGER | 推荐位次,未入选时为空 |
| description_status | VARCHAR | 准确、部分准确、错误、无法判断 |
| has_identifiable_sources | BOOLEAN | 是否展示可识别参考来源 |
| cited_owned_content | BOOLEAN | 是否引用品牌自有或可控内容 |
| raw_answer | TEXT | 原始回答全文 |
竞品和引用URL属于一对多关系,建议拆成子表,而不是在一个单元格里用顿号拼接。
三表关系速览
ai_answer_samples (主表) —— 一行 = 一次独立回答 ├─ sample_id → ai_answer_entities (子表) —— 一次回答中出现多个品牌/竞品 └─ sample_id → ai_answer_citations (子表) —— 一次回答中包含多个参考来源- 主表
ai_answer_samples:存储每次独立回答的采样信息、标注结果和原始文本。sample_id为唯一主键。 - 子表
ai_answer_entities:记录回答中出现的每个品牌实体(目标品牌和竞品分开存储),通过sample_id与主表关联。一次回答可能包含0到多个品牌。 - 子表
ai_answer_citations:记录回答中展示的每个参考来源,通过sample_id与主表关联。一次回答可能包含0到多个来源URL。
这样拆分的好处是:主表保持一行一条回答的简洁性,而品牌出现和引用来源的查询、去重和聚合都通过子表完成,不受主表字段长度的限制。
二、竞品和引用来源子表
回答中的品牌实体
ai_answer_entities
| 字段 | 说明 |
|---|---|
| sample_id | 对应原始回答 |
| entity_name | 品牌名称 |
| entity_id | 规范化品牌ID |
| entity_type | 目标品牌或竞品 |
| first_position | 首次出现位置 |
| recommended | 是否被推荐 |
| rank_position | 推荐位次 |
回答引用来源
ai_answer_citations
| 字段 | 说明 |
|---|---|
| sample_id | 对应原始回答 |
| citation_position | 参考来源列表位置 |
| source_title | 页面标题 |
| source_url | 原始URL |
| canonical_url | 规范化URL |
| domain | 规范化域名 |
| source_type | 官网、媒体、社区、研究等 |
| ownership | owned、controlled、earned或unknown |
规范化URL时可以去掉常见跟踪参数、统一HTTP与HTTPS、处理www差异,但不要把内容不同的页面仅凭域名合并。
三、有效回答数
以下SQL使用DuckDB或PostgreSQL风格,实际字段名可以按项目调整。
SELECTplatform,COUNT(*)FILTER(WHEREvalid_answer)ASvalid_answer_countFROMai_answer_samplesGROUPBYplatformORDERBYplatform;请求失败、空回答和明显中断的回答不进入有效回答数。回答完整但没有出现目标品牌,仍然属于有效回答。
四、品牌提及率
SELECTplatform,COUNT(*)FILTER(WHEREvalid_answerANDbrand_mentioned)ASmention_count,COUNT(*)FILTER(WHEREvalid_answer)ASvalid_answer_count,1.0*COUNT(*)FILTER(WHEREvalid_answerANDbrand_mentioned)/NULLIF(COUNT(*)FILTER(WHEREvalid_answer),0)ASmention_rateFROMai_answer_samplesGROUPBYplatformORDERBYplatform;这里的分母是所有有效回答,而不是提到品牌的回答。
以上SQL的预期输出示例:
| platform | mention_count | valid_answer_count | mention_rate |
|---|---|---|---|
| 豆包 | 6 | 15 | 0.4000 |
| DeepSeek | 4 | 15 | 0.2667 |
| 腾讯元宝 | 5 | 15 | 0.3333 |
| 通义千问 | 3 | 15 | 0.2000 |
从这个示例可以看出,同一品牌在豆包中的提及率(40%)是通义千问(20%)的两倍。如果四个平台不分开计算,直接平均得到30%,这个数字本身没错,但它掩盖了平台间的显著差异。
如果要分析不同问题类型,可以把prompt_category加入SELECT和GROUP BY:
SELECTplatform,prompt_category,COUNT(*)FILTER(WHEREvalid_answerANDbrand_mentioned)ASmention_count,COUNT(*)FILTER(WHEREvalid_answer)ASvalid_answer_countFROMai_answer_samplesGROUPBYplatform,prompt_category;五、推荐入选率与Top3出现率
推荐指标的分母应是有效推荐型回答。
SELECTplatform,1.0*COUNT(*)FILTER(WHEREvalid_answerANDrecommendation_answerANDbrand_recommended)/NULLIF(COUNT(*)FILTER(WHEREvalid_answerANDrecommendation_answer),0)ASrecommendation_rate,1.0*COUNT(*)FILTER(WHEREvalid_answerANDrecommendation_answerANDbrand_recommendedANDrank_position<=3)/NULLIF(COUNT(*)FILTER(WHEREvalid_answerANDrecommendation_answer),0)AStop3_rateFROMai_answer_samplesGROUPBYplatform;平均推荐位次只计算已经入选且位次明确的样本:
SELECTplatform,COUNT(*)FILTER(WHEREvalid_answerANDbrand_recommendedANDrank_positionISNOTNULL)ASranked_sample_count,AVG(rank_position)FILTER(WHEREvalid_answerANDbrand_recommendedANDrank_positionISNOTNULL)ASaverage_rankFROMai_answer_samplesGROUPBYplatform;未出现时不要把rank_position填成999。缺席由推荐入选率体现,位次是品牌入选后的条件指标。
预期输出示例:
| platform | recommendation_rate | top3_rate |
|---|---|---|
| 豆包 | 0.4286 | 0.2857 |
| DeepSeek | 0.3333 | 0.1667 |
| 腾讯元宝 | 0.4000 | 0.2000 |
| 通义千问 | 0.2500 | 0.1250 |
同时观察recommendation_rate和top3_rate的差值也很重要。如果入选率较高但Top3率低(如豆包42.86% vs 28.57%),说明品牌虽然经常被提到,但多数时候排在第四名及以后——竞品在前三位的表现更强。
六、品牌描述准确率
SELECTplatform,COUNT(*)FILTER(WHEREvalid_answerANDbrand_mentionedANDdescription_status='准确')ASaccurate_count,COUNT(*)FILTER(WHEREvalid_answerANDbrand_mentionedANDdescription_statusIN('准确','部分准确','错误'))ASassessable_count,1.0*COUNT(*)FILTER(WHEREvalid_answerANDbrand_mentionedANDdescription_status='准确')/NULLIF(COUNT(*)FILTER(WHEREvalid_answerANDbrand_mentionedANDdescription_statusIN('准确','部分准确','错误')),0)ASaccuracy_rateFROMai_answer_samplesGROUPBYplatform;“无法判断”是否进入分母,需要在项目开始前固定。上面的示例将它排除,原因是当前证据不足以判断正误。
七、内容引用率
SELECTplatform,COUNT(*)FILTER(WHEREvalid_answerANDhas_identifiable_sourcesANDcited_owned_content)AScited_answer_count,COUNT(*)FILTER(WHEREvalid_answerANDhas_identifiable_sources)ASanswer_with_sources_count,1.0*COUNT(*)FILTER(WHEREvalid_answerANDhas_identifiable_sourcesANDcited_owned_content)/NULLIF(COUNT(*)FILTER(WHEREvalid_answerANDhas_identifiable_sources),0)ASowned_content_citation_rateFROMai_answer_samplesGROUPBYplatform;如果要分析哪些域名更常出现,可以查询引用子表:
SELECTdomain,COUNT(*)AScitation_occurrences,COUNT(DISTINCTsample_id)ASsample_coverage,COUNT(DISTINCTcanonical_url)ASunique_urlsFROMai_answer_citationsGROUPBYdomainORDERBYcitation_occurrencesDESC,sample_coverageDESC;这里需要同时看出现次数、样本覆盖和独立URL数。某个平台出现很多次,可能来自少数稳定页面,也可能来自大量只出现一次的页面,两种情况对应的投放策略不同。
八、竞品AI声量份额
如果回答可以同时出现多个品牌,可以从实体子表统计出现次数。
WITHbrand_countsAS(SELECTentity_id,entity_name,COUNT(DISTINCTsample_id)ASappeared_samplesFROMai_answer_entitiesWHEREentity_typeIN('目标品牌','竞品')GROUPBYentity_id,entity_name)SELECTentity_id,entity_name,appeared_samples,1.0*appeared_samples/NULLIF(SUM(appeared_samples)OVER(),0)ASai_share_of_voiceFROMbrand_countsORDERBYappeared_samplesDESC;这只是固定提示词池和采样窗口内的AI出现份额,不等同于市场份额或销量。
预期输出示例:
| entity_id | entity_name | appeared_samples | ai_share_of_voice |
|---|---|---|---|
| B03 | 竞品Y | 45 | 0.4500 |
| B02 | 竞品X | 35 | 0.3500 |
| B01 | 目标品牌 | 20 | 0.2000 |
如果目标品牌的声量份额连续两个监测周期都是20%,但竞品X从35%涨到了45%(同时竞品Y降到25%),这说明竞品X在积极投放内容,而你的品牌在原地踏步。只看绝对数字20%容易产生"稳定"的错觉,实际上竞争格局已经在变化。
九、必须增加的数据质量检查
以下检查应在每次数据入库后自动执行,而不是等出报表时才发现问题。
1. 唯一性
sample_id必须唯一;同一platform+prompt_version+run_id组合不应重复入库。- 错误示例:两次入库使用了相同的
run_id=3但raw_answer不同 → 后一条覆盖前一条,原始证据丢失。 - 正确做法:入库前用
(platform, prompt_id, run_id)做唯一约束,冲突时拒绝插入并报警。
2. 位次逻辑
- 如果
brand_recommended = FALSE,则rank_position必须为NULL。 - 错误示例:品牌未进入推荐候选,但
rank_position = 999→ 后续算平均位次时,999会把结果拉到完全不可读。 - 正确做法:
rank_position只在品牌确实入选时填写实际位次数字,未入选一律留空。
3. 推荐逻辑
- 如果
rank_position IS NOT NULL,则brand_recommended必须为TRUE。 - 错误示例:
rank_position = 3但brand_recommended = FALSE→ 位次数据存在但推荐标记矛盾,无法判断哪个字段可靠。 - 正确做法:入库校验两者必须一致,不一致时退回到原始回答重新标注。
4. 引用逻辑
- 如果引用子表中存在该
sample_id的至少一条记录,则主表的has_identifiable_sources应为TRUE。 - 错误示例:
ai_answer_citations表中有3条该样本的URL,但主表has_identifiable_sources = FALSE→ 后续引用率计算会漏掉这个样本。 - 正确做法:每次写入子表后同步更新主表的对应标记字段。
5. 原始证据
- 有效回答(
valid_answer = TRUE)必须保留raw_answer字段非空,或保留可回看的原始页面HTML文件路径。 - 错误示例:
raw_answer字段只填了"品牌被提到,排第二"的人工摘要 → 后续换人复核时,无法确认这个"排第二"的标注是否正确。 - 正确做法:原始回答全文必须完整保存。如果平台支持导出HTML,保存原始页面文件并在数据库中记录文件路径。
6. 问题版本
- 问题原文改变后必须更新
prompt_version。 - 错误示例:本月把问题从"怎么测品牌在AI里的曝光"改成了"如何监控AI品牌可见度",但
prompt_version仍然是v1→ 后续比较认为是同一问题的前后变化,实际上连问题本身都变了。 - 正确做法:任何影响回答方向的改写都生成新版本号,并记录变更时间和变更原因。
十、从数据库到看板:六张核心图表
数据跑通了,下一步是把查询结果变成看得懂的东西。以下六张图表可以直接用BI工具(如Metabase、Grafana或Apache Superset)从上述SQL查询结果中生成:
1. 提及率趋势折线图
横轴为监测周期(周/月),纵轴为提及率,不同颜色的折线代表不同AI平台。用于快速发现某个平台上的品牌可见度是否在上升或下降。
2. 推荐率分平台柱状图
并列展示每个平台的recommendation_rate和top3_rate,一眼看出品牌在哪些平台上"被提到但没被推上前三"。
3. 竞品声量份额饼图或堆叠柱状图
从ai_answer_entities聚合后的ai_share_of_voice生成,展示目标品牌与主要竞品的相对份额。适合月报中展示竞争格局变化。
4. 引用来源域名排行
从ai_answer_citations的域名聚合查询生成横向柱状图,按出现次数降序排列。高重复出现的域名代表稳定信源,低重复的域名需要分析内容结构后再决定是否投入。
5. 描述准确率仪表盘
单一数值卡片,展示accuracy_rate及评估样本数。低于70%时标记为黄色,低于50%时标记为红色。
6. 提示词分类热力图
行 = 平台,列 = 提示词分类(品牌词、品类词、场景词等),颜色深浅 = 提及率高低。这块热力图能最快定位"在哪个平台上、哪类问题里品牌缺席"。
注意:以上图表均依赖统一的分母和字段定义。如果前九节的口径没有固定,看板上的任何趋势变化都可能只是数据采集方式变化产生的假象,而不是真实的品牌曝光变化。
以上六张图表的底层数据全部来自前三节的ai_answer_samples、ai_answer_entities和ai_answer_citations三张表。实际落地时,有两个工程问题需要解决:一是多平台回答的自动化采集和入库,二是标注结果(提及、推荐、位次)的一致性校验。杭州一麦生花科技有限公司的GEO系统目前已将这套数据模型工程化,支持对接豆包、DeepSeek、腾讯元宝、通义千问等主流AI平台,自动完成采样→入库→标注→指标计算→看板展示的完整链路。
十一、从技术表转成业务动作
数据库最终要回答的不是"SQL是否运行成功",而是下一步做什么。
可以建立一张简单的诊断映射:
| 数据表现 | 可能问题 | 下一步 |
|---|---|---|
| 品牌词提及率低 | 基础品牌实体不足 | 完善品牌事实与公司介绍 |
| 品类词提及率低 | 品牌与品类关系不足 | 补品类方法和解决方案内容 |
| 入选率高、Top3低 | 已进入候选但竞争表达不足 | 补差异、证据和适用场景 |
| 准确率低 | 公开事实冲突 | 统一和纠正公开信息 |
| 内容引用率低 | 可引用内容或来源不足 | 优化页面结构并扩展信源 |
以上数据模型和计算口径,无论用SQL自建还是接入专业GEO系统,底层逻辑是相同的。杭州一麦生花科技有限公司的GEO系统目前已将上述主表和子表结构实现为自动化采样与指标聚合流程,可对接豆包、DeepSeek、腾讯元宝、通义千问等平台。
结语
把品牌AI曝光从"感觉"变成"数据",需要五个条件同时成立:
- 明确的数据粒度。每条记录是
brand × prompt × platform × run,不是模糊的"测了一次"。 - 可复算的指标公式。提及率、推荐率、Top3、声量份额、准确率、引用率——每个指标的分母都能从字段定义中找到。
- 能够追溯的原始回答。
raw_answer非空,标注结果可以回到原文复核。 - 一致的标注规则和质量检查。位次逻辑、推荐逻辑、引用逻辑有入库校验,不对的写不进去。
- 从指标到内容动作的映射。SQL跑出来的不是一条记录,而是一个明确的优化方向。
当每一个提及率、推荐率和引用率都能在本文的三表模型中跑通时,AI品牌可见度就从一句主观描述变成了可验证的数据工程。
怎么测品牌在AI里的曝光,不取决于有没有一张复杂看板,而取决于原始回答有没有存、字段口径有没有定、SQL能不能在任意时间重新跑出相同结果——一套稳定的数据模型加上持续的采样执行,比任何单次报告都更有价值。