许多企业都有这样的需求:批量向多个AI平台提问,收集它们的回复,然后从中解析出自身品牌被提及和推荐的情况。听起来很直接,对吧?但实际执行时,一系列数据工程难题便会浮现。

AI返回的是非结构化文本,品牌名称可能以全称、简称、英文名甚至错别字出现;同一个品牌在不同平台、不同轮次中的写法也可能截然不同。至于“推荐”的表达方式——从“首选”、“值得考虑”到“也可以了解”、“排名靠前”——更是五花八门,都需要被准确识别和归类。
本文从一个真实的数据处理需求出发,详细梳理从原始AI回答到品牌推荐率输出的完整数据工程链路。重点涵盖五个环节:无效样本过滤、品牌别名合并、推荐倾向识别、场景标签分类以及指标聚合。同时提供一套基于阿里云DataWorks + MaxCompute的可复用实现方案。
二、整体数据链路
整个流程可拆分为六个阶段:
阶段 核心任务 输出
① 采集 多平台API调用,原始回答入库 原始回答表
② 清洗 剔除拒答、过短、异常回答 有效样本表
③ 品牌归一化 别名识别与合并,标准化品牌名称 标准化样本表
④ 推荐识别 判断品牌是否被推荐及推荐强度 带推荐标签的样本表
⑤ 场景分类 按用户意图打标签 带场景标签的样本表
⑥ 指标聚合 按品牌、场景、平台维度计算提及率和推荐率 指标输出表
每个阶段都必须记录处理状态,确保最终指标可一路追溯到原始回答。这是数据可信度的根基,缺少它,后续的争议和复核将难以说清。
三、无效样本过滤
3.1 需要过滤的样本类型
采集回来的回答中,总有一定比例无法直接使用。常见类型有以下几种:
类型 特征 示例
明确拒答 含拒答信号 “无法回答这个问题”“我不能提供”
内容过短 长度不足 少于20个字符
语义偏离 与问题无关 回答内容明显跑题
格式异常 乱码、截断、重复 连续重复同一段落
3.2 清洗实现
在MaxCompute中通过UDF执行清洗逻辑:
INSERT OVERWRITE TABLE valid_samples PARTITION (dt='${bizdate}')
SELECT
id, platform, question, answer, intent_category
FROM raw_answers
WHERE is_valid_answer(answer) = TRUE;
清洗函数的核心判断逻辑:
public class AnswerValidator {
public boolean validate(String answer) {
// 空值或过短
if (answer == null || answer.trim().length() < 20) {
return false;
}
// 拒答信号匹配(需持续维护)
String[] rejects = {"无法回答", "不能提供", "无法提供",
"cannot answer", "I cannot", "sorry"};
for (String kw : rejects) {
if (answer.toLowerCase().contains(kw.toLowerCase())) {
return false;
}
}
return true;
}
}
有一个维护要点必须强调:不同AI平台的拒答表达方式各不相同,同一平台的模型版本更新后,拒答模式也可能发生变化。因此定期抽查被过滤的样本,补充新的拒答模式,是必不可少的。
四、品牌别名合并
4.1 为什么这是关键环节
同一个品牌在AI回答中的呈现方式实在太过丰富。如果不做别名归一化,后续计算的提及率和推荐率基本等于无效。来看典型的场景:
全称与简称:“绿雪智能科技有限公司” vs “绿雪智能” vs “绿雪”
中文与英文:“阿里巴巴” vs “Alibaba”
产品名与公司名:“通义千问” vs “阿里云”
错别字或变体:用户输入错误导致的变体
隐性指代:“这家公司”、“该品牌”——这类只能依赖上下文推测
4.2 别名映射方案
实际操作中,推荐采用“自动发现 + 人工确认”的两阶段策略。
自动发现:基于品牌名称共现分析、编辑距离计算、拼音相似度匹配,从回答文本中自动发现候选别名对。
人工确认:对置信度较低的候选对进行人工复核,确认是否合并。同时,对同名不同实体的情况(例如“苹果”指科技公司还是水果)进行消歧标注。
映射表的表结构大致如下:
CREATE TABLE brand_alias_mapping (
canonical_id STRING COMMENT '标准品牌ID',
canonical_name STRING COMMENT '标准名称',
alias_name STRING COMMENT '别名',
alias_type STRING COMMENT '简称/英文/产品名/错别字',
status STRING COMMENT 'active/pending/rejected'
);
4.3 ETL中执行合并
-- 品牌名称归一化
SELECT
COALESCE(m.canonical_id, 'UNKNOWN') AS brand_id,
COALESCE(m.canonical_name, extracted.brand_raw) AS brand_name,
extracted.sample_id,
extracted.platform
FROM brand_extraction_results extracted
LEFT JOIN brand_alias_mapping m
ON extracted.brand_raw = m.alias_name
AND m.status = 'active';
五、推荐倾向识别
5.1 推荐的定义
“推荐”在AI回答中并非二值状态,程度差异很大,需要分级处理:
推荐等级 判断依据 示例表述
强推荐 明确首选、最佳、第一 “首选推荐A品牌”“A是最好的选择”
一般推荐 列入推荐列表 “可以考虑A品牌”“A品牌值得了解”
弱推荐 作为备选或补充提及 “另外也可以了解A品牌”
不推荐 未提及或给出负面评价 未出现 / “不推荐A品牌”
5.2 推荐识别方法
推荐识别通常结合两种方式:
规则匹配:基于关键词和句式模式。例如出现“首选”、“最推荐”、“强烈建议”这些强信号词,则判定为强推荐;包含“可以考虑”、“值得了解”这类中等信号词,则判定为一般推荐。
位置权重:在结构化推荐列表中,排名越靠前,推荐权重越高。在非结构化回答中,品牌出现的位置也会影响推荐判断。
-- 推荐识别示例
SELECT
sample_id,
brand_name,
CASE
WHEN answer REGEXP '首选|最佳|最推荐|强烈推荐|第一选择' THEN 'strong'
WHEN answer REGEXP '值得推荐|可以考虑|不错的|值得了解' THEN 'normal'
WHEN answer REGEXP '也可以|备选|作为补充' THEN 'weak'
ELSE 'none'
END AS recommendation_level
FROM valid_samples_with_brands;
5.3 推荐率计算
推荐率 = 品牌被推荐的有效样本数 / 有效样本总数 × 100%
实际计算时可灵活处理,例如将“强推荐率”和“总推荐率”分开统计:前者只计算强推荐样本,后者计算所有带有推荐倾向的样本。
六、场景标签分类
6.1 场景定义
不同问题类型对应不同的用户意图,品牌在不同场景下的表现需要分开观察。常用分类如下:
场景代码 场景名称 典型问题
REC 推荐决策 “有哪些值得推荐的XX?”
CMP 对比分析 “A和B有什么区别?”
PUR 购买意图 “选XX时应该优先考虑哪个?”
SCN 场景发现 “XX场景下有什么解决方案?”
NA V 信息导航 “XX品牌主要是做什么的?”
6.2 标签生成
这里推荐“规则匹配优先 + 分类模型兜底”的策略:
SELECT
sample_id,
question,
CASE
WHEN question REGEXP '推荐|选哪个|哪家好|值得买|选什么' THEN 'REC'
WHEN question REGEXP '区别|对比|相比|哪个更|差异' THEN 'CMP'
WHEN question REGEXP '购买|价格|多少钱|下单|采购' THEN 'PUR'
WHEN question REGEXP '场景|适合|怎么用|解决方案' THEN 'SCN'
WHEN question REGEXP '是什么|什么意思|介绍|定义' THEN 'NA V'
ELSE model_predicted_scene(question) -- 模型兜底
END AS scene_tag
FROM valid_samples;
场景标签的价值在于:同一个品牌在“推荐决策”类问题中的推荐率,与在“信息导航”类问题中的提及率,反映的是完全不同的信息呈现维度——这一点在设计指标时尤其需要留意。
七、指标聚合
7.1 多维度聚合
在MaxCompute中按品牌、场景、平台三个维度进行聚合:
SELECT
brand_id,
brand_name,
scene_tag,
platform,
COUNT(DISTINCT sample_id) AS sample_count,
COUNT(DISTINCT CASE WHEN is_mentioned = 1 THEN sample_id END) AS mention_count,
COUNT(DISTINCT CASE WHEN is_recommended = 1 THEN sample_id END) AS recommend_count,
ROUND(mention_count 100.0 / sample_count, 2) AS mention_rate,
ROUND(recommend_count 100.0 / sample_count, 2) AS recommend_rate
FROM labeled_samples
WHERE is_valid = 1
GROUP BY brand_id, brand_name, scene_tag, platform;
7.2 综合评分
综合评分是对多维度指标的加权汇总,权重根据测评目标确定:
场景类型 提及率权重 推荐率权重 稳定性权重
推荐决策类 0.2 0.6 0.2
品牌认知类 0.5 0.2 0.3
综合测评 0.3 0.4 0.3
-- 综合评分计算
SELECT
brand_id,
brand_name,
(0.3 overall_mention_rate
0.4 overall_recommend_rate
0.3 * stability_score) AS composite_score
FROM brand_aggregates;
八、数据质量保障
8.1 全链路可追溯
每个处理阶段都要记录状态,支持从指标一路追溯到原始回答:
CREATE TABLE pipeline_audit (
sample_id STRING,
stage STRING COMMENT '采集/清洗/归一化/推荐识别/场景分类/聚合',
status STRING,
detail STRING,
created_at DATETIME
) PARTITIONED BY (dt STRING);
8.2 质量检查点
准确率抽查:每周抽取100条样本,人工复核清洗、归一化、推荐识别的准确性。
一致性校验:同一批数据在不同执行批次中的结果是否一致。
稳定性监控:同一品牌在不同采样周期中的推荐率波动是否在合理范围内。
8.3 人工复核触发条件
以下几种情况必须触发人工复核:
品牌名称存在明显歧义。
自动推荐识别的置信度低于阈值。
某品牌推荐率出现异常大幅波动(环比变化超过50%)。
新增品牌不在现有别名映射表中。
九、总结
从原始AI回答到品牌推荐率输出,数据工程的核心工作集中在三个环节:
品牌别名合并:这是数据归一化的基础。别名合并做不好,所有按品牌维度统计的指标都会偏离真实情况。自动发现加人工确认的混合策略,是目前比较务实的做法,关键在于建立一张可持续维护的映射表。
推荐倾向识别:“推荐”不是一个二值状态,而是一个有强度区分的语义判断。强推荐、一般推荐和弱推荐对品牌的实际意义不同,计算指标时必须区别对待。推荐识别需要结合关键词规则和位置权重,单一方法很难覆盖所有场景。
场景标签分类:不同问题场景下的推荐率含义完全不同。在推荐决策类问题中被推荐,价值远高于在信息导航类问题中被提及。通过场景标签拆分,可以让指标分析更加精准。
在技术实现层面,上述流程基于阿里云DataWorks进行任务编排调度,MaxCompute承担核心ETL计算,OSS用于原始数据归档。这套架构能支撑从数十个品牌到数千个品牌的数据处理需求,关键在于ETL任务的稳定性和数据质量检查的完备性。
数据的价值不仅在于最终产出的指标,更在于指标背后的可追溯性。一个无法追溯到原始回答的推荐率,在面临复核或争议时很难立得住。因此,每个环节的处理状态记录,不只是工程规范,更是数据可信度的保障。
