做电商运营或者产品经理的朋友,大概率都经历过被几千条评论淹没的绝望。翻了一下午评论,最后总结出来的结论还经常被质疑“你是不是只看了好评”。我做的这个产品评论总结器,就是专门解决这个问题的:一个基于AI的智能优缺点提取系统。把任意一批商品评论丢进去,系统自动吐出一份结构清晰的结果——有哪些优点、有哪些缺点、用户最在意什么,而且每一条结论都能对应到具体评论原文。
这套系统的定位不是做一个简单的“好评差评分类器”,而是把非结构化的评论文字,变成结构化的、可被商业决策直接使用的优缺点清单。它适合三类人参考:一是电商运营,需要快速掌握用户对产品的真实反馈;二是产品经理,做迭代规划时想知道下一代产品该改哪里;三是做数据分析和NLP应用的开发者,想了解大模型在真实业务场景里怎么落地、怎么避坑。接下来我把整个项目的设计思路、技术实现、调优过程和踩过的坑完整拆开讲。
1. 项目思路与总体架构:先想清楚“提取”到底要提取什么
1.1 评论数据里最有价值的信息是什么
很多人做评论分析,第一步就想着给评论打正负标签。这其实是个误区。评论数据里最有价值的不是“这条是好评还是差评”,而是“用户到底因为什么给了好评、因为什么给了差评”。
举一个很典型的例子:某款无线耳机,有用户写“音质很好,续航一般,戴久了耳朵疼”,这短短一句话里同时存在一个优点(音质好)和两个缺点(续航差、佩戴不舒适)。如果只做情感极性判断,这条评论算正向还是负向?怎么归都不对。即便勉强大类分对了,信息也丢了一大半——运营者真正想知道的是产品具体强在哪、弱在哪,而不是一句笼统的“还行”。
所以我当时给这个系统定的核心目标非常明确:从一批评论中提取出“多个维度上的优点和缺点”,并且支持按出现频次排序、按维度聚合。比如音频类产品,要能拆出音质、续航、连接稳定性、佩戴舒适度、降噪效果、软件体验等维度;每一维里,用户夸了什么、骂了什么,都要清清楚楚。
1.2 技术路线对比与选型
明确了目标之后,就是技术选型。市面上可选的路线大致有三档,我列了一个对比表:
| 路线 | 成本 | 语义理解能力 | 维护成本 | 适用场景 |
|---|---|---|---|---|
| 规则+情感词典 | 低 | 弱,只能匹配关键词 | 高,词典要长期维护 | 关键词简单、维度固定的场景 |
| 传统机器学习(分类/序列标注) | 中 | 中等,依赖标注数据 | 较高,模型需要定期重训 | 有充足标注样本、任务稳定的场景 |
| 大语言模型(LLM) | 较高 | 强,能理解上下文和隐含观点 | 较低,主要迭代提示词 | 观点多样、表达灵活、需要快速上线的场景 |
我最终选了以LLM为核心的混合方案,但不是无脑把全部文本丢给LLM。这个系统真正的设计思路是:规则负责“挡住”低质量输入,LLM负责“读懂”高质量输入,再叠加聚类和统计逻辑来“汇总”结果。
关于低成本,这里需要诚实说明:LLM单次调用有成本,但并不是所有评论都需要送到LLM。我采用的策略是分级处理——先用规则把明显的广告、无意义文本、过短评论全部过滤掉,剩下的有效评论再送进分析模块。大多数商品的有效评论比例在60%到80%之间,也就是说LLM处理的已经是“挤干水分”后的数据,整体成本可控。
1.3 整体架构与数据处理流水线
整个系统分四层,每层职责单一,方便单独替换和调试:
- 数据层:对接多个评论来源,完成字段标准化、清洗、去重。
- 分析层:调用LLM,对评论做优缺点抽取、维度分类。
- 聚合层:对抽取出的观点做归一化、聚类、频次统计,生成总结。
- 展示层:输出结构化的JSON、Excel或网页报表。
这四个层次必须解耦。最开始我犯过一个错误:把清洗逻辑和分析逻辑写在同一个函数里,后面想单独调清洗策略就得把整块代码翻出来重跑。分层之后,每一层都可以独立测试,排查问题时的定位速度快很多。后面具体每一层的实现细节我会在第2章和第3章展开。
2. 数据接入与清洗:不要急着送进大模型
2.1 先统一评论数据模型
评论来源五花八门。有些来自电商平台的后台导出,有些来自应用商店的评论接口,有些来自爬虫抓取的社交媒体提及。不同来源的字段命名、字段粒度差异非常大,但落到我们的数据模型里,只需要保留几个关键字段:
| 字段 | 说明 | 示例 |
|---|---|---|
| comment_id | 评论唯一标识 | C10001 |
| product_id | 商品ID,用于分组分析 | P20240701 |
| rating | 评分,1~5星 | 3 |
| comment_title | 评论标题,可空 | 一般般 |
| comment_body | 评论正文 | 用了一个月,降噪效果明显下降 |
| comment_time | 评论时间 | 2025-03-12 |
| platform | 来源平台标识 | 某电商平台A |
统一字段的目的是让下游代码只依赖一套结构。尤其要注意:评分字段经常会出现字符串和数字混合的情况,比如某些来源导出的是“五星好评”而不是“5”,在标准化阶段一定要转成统一类型。另外用户ID、订单ID这类涉及隐私的字段不到万不得已不要入库,既没必要也有合规风险。我们做分析只需要评论本身和它关联的商品,不需要知道用户是谁。
2.2 评论清洗的五个关键环节
清洗阶段是整个系统里最不起眼但影响最大的部分。我给这套流程归纳了五个关键环节,每一步都有坑。
第一,去掉HTML标签和富文本残留。部分评论来源是网页抓取,正文里混着换行符、``、 之类的东西。清洗时用正则一次性处理掉,注意不要误删正常内容。
第二,表情符号和特殊字符的处理。这里要区分目标模型。如果后续走规则匹配,表情信息其实挺重要,比如“很好用😄”里的表情是正向信号;但如果走LLM,表情带来的信息增益有限,反而会让JSON输出解析时偶尔出错。我的做法是LLM分析前统一把Emoji转成文字描述或者直接移除,因为大模型本身能识别上下文的情绪,不差一个笑脸。
第三,广告、水军、无意义文本过滤。评论里经常混着“加微信领优惠券”“复制这条去另一家店看看”“拼单找我”这类噪音,还有那种整个正文就是几个标点符号或者一段乱码的。这些内容不先过滤掉,LLM会被带偏,甚至把广告词当成产品特点总结出来。我用的方法是关键词规则加长度阈值双重过滤:含广告特征词的直接丢,正文少于3个有效字符的也直接丢。
第四,近似重复检测。同一个用户短期内多次提交内容几乎一样的评论,或者不同的营销账号发同一套模板,都会造成某一观点在统计时被严重放大。我用SimHash做文本指纹,把相似度超过阈值的评论合并成一条,保留最早或信息量最全的那条。
第五,中文评论还要额外处理英文和数字混排的问题。比如“airpods平替”“usb接口松了”这类评论,清洗时不要想着把英文去掉,因为“USB”“AI”这些词本身就是产品特征词,强行清理反而丢信息。
2.3 准备一套人工验证集
很多开发者忽略这步,但我强烈建议:在系统上线前,先准备200到500条带人工标注的评论作为验证集。
怎么标注?格式很简单,每条评论标注三类信息——涉及的维度(如音质、续航、外观)、是否为优点表达、是否为缺点表达。如果一条评论同时含多个观点,就多标几行。这套验证集会用在后面第4章讲到的效果测评环节,没有它,你根本无法判断模型是变好了还是变差了,全靠感觉调提示词就是赌博。
标注用不着花钱请专业公司,团队内部两三个人花半天就能完成。关键是覆盖要多样:好评、差评、中评都要有,短评长评都要有,最好再包含一些特殊的、带讽刺意味的评论(比如“这续航,简直是给手机充电宝做慈善”,字面正向实际负向),这类样本最考验模型的理解力。
3. 核心功能实现:提示词设计、结构化输出与自动聚合
3.1 核心提示词设计与结构化输出
整个系统的技术核心其实是提示词工程。我设计提示词时坚持一个原则:让模型输出结构化JSON,而不是自然语言段落。原因很简单——自然语言输出后面还要做实体识别和关系抽取,麻烦且容易出错,直接让模型按固定JSON格式返回,后处理代码写起来干净利落。
下面是我实际使用的提示词模板(框架部分做了脱敏精简):
你是一名资深产品评论分析专家。请对给定的商品评论列表进行优缺点提取。 要求: 1. 每条结论都必须有评论原文作为依据,禁止推测和脑补。 2. 将同一维度的相似观点合并为一条,不要重复罗列。 3. 明确区分“优点”“缺点”“中性描述”。 4. 如果某个维度没有对应的评论依据,不要输出该维度。 5. 按观点出现频次从高到低排序。 输出格式(仅输出JSON,不要输出任何多余文字或解释): { "优点": [ {"观点": "观点描述", "依据": "评论原文摘录", "频次": 数量} ], "缺点": [ {"观点": "观点描述", "依据": "评论原文摘录", "频次": 数量} ] }这里面的几个细节我要特别说明。
第一,“频次”这个字段,我并不会完全信任模型数出来的数字。大模型在做精确计数时经常出错,尤其是同一个观点出现在几十条评论里的场景。我的做法是让模型先抽取观点和依据,回到代码里对相似观点做归并,用真实统计数量覆盖模型的估计值,模型输出的频次只作为参考。
第二,JSON输出解析要做得足够健壮。模型偶尔会多输出一个逗号、漏掉一个括号或者在外面包一层Markdown代码块。我写了一个容错解析函数:先把输出里的```json代码块标记去掉,再尝试直接json.loads,失败的情况下用正则抽取大括号之间的内容再试一次。多写这几行代码,能免掉整个系统90%的解析崩溃问题。
第三,提示词里加了“禁止推测和脑补”这条负面约束,比单纯说“请忠实原文”效果要好得多。实测下来,加了显式的负面指令后,幻觉率能下降差不多一半。后面调优时我又把这条扩展成“如果评论中没有明确提到,请直接判定为无此观点”,进一步压缩了模型自由发挥的空间。
3.2 大批量评论的分批抽取与全局合并
单个商品往往有成百上千条有效评论。一次把全部评论丢给LLM会直接爆掉上下文窗口,就算塞得下,模型也会因为信息过载丢掉细节。
我采用了两级处理模式,类似MapReduce的思路:
- 第一级(Map):每批取20到30条评论,调用LLM做局部抽取,产出每批的优缺点列表。
- 第二级(Reduce):把所有批次的抽取结果合并,做观点去重、维度对齐和频次累加,再调用一次LLM做全局总结。
批次大小为什么定在20到30条?这条经验来自多次实验。少于10条时,单批抽取的上下文太稀疏,很多跨评论的共同维度归纳不出来;多于40条时,模型的输出质量明显下滑,会开始漏掉一些低频但重要的观点。30条左右是信息密度和输出质量平衡得最好的区间。
在合并阶段,我让LLM做的是“归纳”而不是“重新抽取”。给它输入所有批次已经抽取好的优点、缺点列表,让它把同义表述合并成更概括的结论。这样既规避了长上下文的质量问题,也让最终报告具备全局视角。
3.3 观点去重与缺陷聚类
这是聚合层最容易忽视的环节。模型抽取出来的原始观点重复度很高,比如“屏幕容易碎”“屏幕太脆弱”“碎屏概率高”“屏幕质量不行”,这几条在语义上高度重合,但在文本字面上完全不同。
我的做法分两步。第一步,用本地embedding模型把观点文本向量化,然后计算两两相似度,相似度超过0.85的归入同一组,选出现频次最高或表述最完整的作为代表观点。为什么用本地小模型而不是交给大模型做?因为聚类是一个高频批量计算过程,每次调用大模型代价高,而本地embedding模型跑几百条观点也就几秒钟,性价比完全不是一个量级。
第二步,把这些代表观点再映射到预定义的业务维度上。我维护了一张维度词典,比如“电池”“续航”“耗电快”映射到续航维度,“音质”“低音”“破音”映射到音质维度。词典覆盖不到的直接归入“其他”维度,由人工定期补充。这么做的好处是可以生成维度级的汇总表,例如“在全部196条缺陷观点中,续航相关占38%,佩戴舒适度相关占22%”,这才是做竞品分析时真正能用的输出。
3.4 结果导出与报告呈现
最终报告我做了两种格式。一种是JSON原始结构,供后续数据分析和可视化使用;另一种是导出的Excel表格,运营和产品团队可以直接用,不需要写代码。
Excel表的列结构大致是:维度、观点类型(优点/缺点)、观点描述、代表用户原话、出现频次、占全部评论比例。有了频次和占比,团队内部做优先级排序就非常直观。比如某款耳机,用户在“佩戴舒适度”维度上的负面频次达到42%,那下一代产品这个点就是第一优先级,根本不需要等销量数据来验证。
报告中还需要附上“数据可信度”说明:有效评论总量、清洗掉的评论量、覆盖的评论时间范围。这个细节一开始我没做,后来发现运营团队拿着报告去开会时经常被问“你这个结论看了多少条评论、数据是什么时候的”,于是专门加了这层说明,报告的可信度和落地效果提升不少。
4. 效果测评与参数调优:没有评测就没有迭代
4.1 评价指标怎么定
做软件的人都知道“无法度量就无法改进”,这个系统也一样。我设计了四个核心指标,全部可以自动或半自动计算:
| 指标 | 定义 | 计算方式 |
|---|---|---|
| 提取准确率 | 抽取出的观点是否有评论原文依据 | 抽样50条,人工核对“依据”是否与原文一致 |
| 维度覆盖率 | 真实评论主题中被系统命中的比例 | 将人工标注的验证集维度与系统输出比对 |
| 幻觉率 | 模型输出的观点在原文中找不到依据 | 人工检查输出结论,无依据的就计为幻觉 |
| 事实一致性 | 最终总结是否与抽取观点的细节一致 | 对比总结报告与抽取层输出的观点摘要 |
前三个指标都要人工参与,听上去有点重,但实际操作起来很快。我每周抽一次样,每次花20分钟检查50条评论对应的输出,足够发现大部分问题。
维度覆盖率是这里面最值得关注的指标。比如人工验证集里30条评论提到了“价格”,但系统输出完全没有价格维度,说明抽取层漏掉了价格类观点,需要补充提示词里的示例或调整维度词典。这项指标本质上在衡量系统的“召回”能力,对业务价值影响最大。
4.2 关键参数与提示词迭代
在LLM抽取任务中,temperature和top_p的设置很重要。我把temperature设为0.1,top_p设为0.85。这个组合在“稳定输出”和“避免完全机械复读”之间比较平衡。做过对比实验:temperature调到0.7时,模型开始出现明显的发挥型表述,虽然表达更丰富,但经常冒出来原文没提过的内容,幻觉率直接翻倍。对于提取类任务,稳定压倒一切。
max_tokens也不要无限放大。单批输出结果一般300到800个token就够,设一个2000的合理上限。上限太大不仅浪费钱,还会诱导模型写出更多格式外的废话。
提示词的迭代要像改代码一样留档。我给每个版本的提示词都加了版本号,并在测试集上跑同一批数据做对比。很多时候微调几个字的差异就能带来5个点以上的准确率变化。比如我曾在提示词里把“合并相同观点”改成“用概括性语言合并相同观点,避免直接拼接原文”,输出结果的冗余度立刻降低了很多。
4.3 成本控制与性能优化
大模型调用成本是这个项目绕不开的话题。除了第2章提到的清洗预过滤,我还在三个地方做了优化。
第一个是结果缓存。同一商品的评论在短期内变化不大,我按product_id加7天有效期做缓存,重复分析直接读缓存,不重复调用模型。这个优化把很多运营团队的日常重复查询成本直接降到了零。
第二个是分级模型策略。抽取阶段用轻量级模型就够了,因为任务是局部的、边界清晰的;最后全局总结阶段信息密度高、需要更强的归纳能力,再用更强的主力模型。这个组合比全程都用最强模型省了大约40%的成本,而且最终报告质量没有明显下降。
第三个是批量并发控制。每批评论是互相独立的,天然适合并发调用。我用异步任务池同时跑4到6路请求,整体吞吐提升明显。但这里有坑:需要控制并发数,太多会触发限流或超时,太少又浪费多张卡。实测4到6路是成本和延时都比较合适的区间。
5. 实战踩坑与经验总结
5.1 常见问题速查表
这个系统从原型到稳定运行,中间踩了不少坑。我把最典型的几个整理成速查表,方便你在做类似项目时直接对号入座:
| 现象 | 可能原因 | 排查思路 | 解决方案 |
|---|---|---|---|
| 输出JSON解析失败 | 上下文过长导致截断 | 查看原始输出末尾是否完整 | 缩短批次评论数,增大max_tokens上限 |
| 某一维度观点被大量遗漏 | 该维度在评论中的表达与示例差异大 | 验证集上检查该维度的覆盖率 | 补充提示词示例,扩展维度词典 |
| 低频但重要的缺陷被忽略 | 模型按频次排序时压低了长尾观点 | 查看抽取层是否漏取 | 合并阶段增加“高严重性低频观点”识别规则 |
| 总结中出现原文没有的观点 | 幻觉 | 对比总结报告与抽取层观点 | 降低temperature,强化“禁止推测”约束 |
| 正面评论里提取出奇怪的“缺点” | 讽刺、反讽表达被字面理解 | 检查该条评论的上下文 | 在提示词里加入识别讽刺和反讽的要求 |
| 多批次合并后结论前后矛盾 | 不同批次抽取粒度不一致 | 对比各批次的输出风格 | 统一提示词模板,抽取阶段固定使用同一模型版本 |
这里面最让我印象深刻的坑是“讽刺表达”。某款高价产品有一条评论写着“这价格,真是良心到让人流泪,建议所有厂家都来学学”。从字面上看全是夸奖,实际上用户是在骂价格太离谱。模型一开始把这条当成了正面评价提取。后来在提示词里加了一条“注意识别讽刺和反讽表达,不要仅凭字面情感判断”,情况才改观。遇到这类文化语境的表达,模型还有提升空间,但通过提示词约束,至少不会再犯低级错误。
5.2 几条值得长期遵守的实操经验
第一,清洗阶段的过滤宁可激进,不要保守。漏掉一条正常评论影响不大,但混进一条广告或垃圾文本,很可能污染整个批次的抽取结果,而且这种污染很难在后期修正。我后来加了一条“被过滤评论日志”,定期抽查被丢掉的评论,防止把正常内容误伤。
第二,永远保留评论原文和抽取结果之间的可追溯性。报告中每一个优点、缺点结论,都必须链回具体的评论原文。这一点不仅是为了人工复核方便,更是为了向业务方解释结果时不被挑战。没有依据的AI结论在业务场景里等于没有价值。
第三,不要迷信模型输出的频次,所有频次做一次真实统计。模型对“出现了几次”这个问题天生不擅长,但人对数字非常敏感,一旦报告里的频次算错,整个系统的公信力就崩了。真实性优先,宁可统计逻辑多写几行代码。
第四,提示词版本要留档、结果要复现。我一开始调提示词时完全靠记忆,改来改去最后忘了是哪个版本效果最好。后来启用版本号加测试集回归,每次修改必须保证之前修复过的问题不复发,系统质量才真正稳定下来。
我在实际使用这个系统时还有一个明显的体会:它最出彩的场景不是“监控差评”,而是“发现意外惊喜”。比如某款产品在“包装质感”这个维度反复出现正面评价,而这个点设计师原本根本没有刻意设计,是供应链无意中做出来的。这类信息藏在几百条评论里,人工翻很容易漏掉,聚类统计可以轻松捕捉。很多时候,用户已经替我们把产品的真实卖点写在评论里了,AI总结器做的只是把它们捞出来、排列好,让人一眼看懂。这个项目后续要扩展的方向我已经想好了:把社区讨论、客服工单、退货原因也纳入分析范围,让“用户声音”的全链路都能自动沉淀成结构化洞察。