1. 当"日报"变成流水线:AI资讯聚合的真实工程账
做AI资讯日报这件事,外行看热闹,内行看门道。很多人第一反应是"不就是把新闻抓下来拼一拼吗",真动手做过的人都知道,一个能每天稳定产出、内容不重复、重点不跑偏的资讯日报,背后是一整套从采集、清洗、去重、分类到摘要生成的工程链路。我前后折腾过三版日报系统,第一版纯手工,第二版半自动,第三版才勉强算得上"流水线",中间踩的坑足够写一本小册子。
这篇内容适合三类人看:一是想给自己或团队搭一套资讯聚合管道的开发者;二是做内容运营、需要每天追踪行业动态但不想被信息淹没的从业者;三是对"AI自动生成内容"这套流程好奇、想了解真实落地难点的技术爱好者。我会把整个系统的设计思路、关键取舍、参数配置和实测经验全部摊开讲,不藏私。
先说一个反直觉的结论:日报系统里最难的部分不是抓取,也不是生成,而是"判断什么值得进日报"。抓取有现成的库,生成有大模型兜底,唯独"价值判断"这件事,机器做起来最别扭,人做起来最累。我第三版系统的核心精力,几乎全花在怎么让机器学会"筛"上面。
另外要提前说明,本文讨论的所有采集行为,都建立在公开信息、合规渠道、尊重来源站点规则的前提下。任何绕过访问限制、高频冲击目标站点的做法都不在讨论范围内,那既不稳妥也不长久。我们追求的是"可持续地获取公开信息",而不是"想尽办法薅数据"。
2. 资讯源的分层策略:为什么我放弃了"大而全"
2.1 第一版踩的坑:贪多嚼不烂
我第一版系统接了将近四十个来源,心想"来源越多覆盖越全"。结果跑了一周就崩了。问题出在三个地方:第一,不同来源的更新频率差异巨大,有的每小时好几条,有的三天才一条,统一轮询导致大量无效请求;第二,来源质量参差不齐,一半以上的内容跟AI核心议题关系不大,全是蹭热度的标题党;第三,格式五花八门,光是解析正文就写了十几种规则,维护成本高到离谱。
最要命的是,来源一多,日报就变成了"信息垃圾场"。读者打开一看,三十条链接,真正有价值的可能就三五条,剩下的全是噪音。这跟日报的初衷完全背道而驰——日报的价值在于"帮你省时间",而不是"把信息堆给你"。
2.2 分层模型:把来源分成三个梯队
第二版我彻底重构了来源管理,核心思路是分层。把来源按"信噪比"和"更新频率"两个维度打分,分成三个梯队:
| 梯队 | 特征 | 处理策略 | 占比建议 |
|---|---|---|---|
| 核心源 | 信噪比高、更新稳定、内容权威 | 每2小时轮询,全量入库 | 20% |
| 补充源 | 信噪比中等、偶有亮点 | 每6小时轮询,按关键词过滤 | 50% |
| 观察源 | 新发现、质量待验证 | 每天轮询一次,只记录不入选 | 30% |
这个分层不是拍脑袋定的。核心源的判断标准很实在:连续两周,它产出的内容里有超过60%能进入最终日报,那它就是核心源。补充源是那些"十篇里能挑出一两篇好的"的来源。观察源则是新加入的、还没经过时间检验的,先观察着,表现好了再升级。
提示:分层不是一劳永逸的。我每个月会跑一次"来源健康度报告",统计每个来源的入选率、平均质量分、更新稳定性,动态调整梯队归属。有的来源一开始是核心,后来质量下滑,就得降级;有的观察源表现惊艳,就该升级。
2.3 轮询频率背后的计算逻辑
为什么核心源是2小时、补充源是6小时?这不是随便定的。假设一个核心源平均每天产出10条有效内容,分布在24小时里,那么平均每2.4小时出一条。如果我用2小时轮询,基本能做到"不漏";如果用4小时,就可能漏掉一些时效性强的内容。
补充源每天可能就2-3条有效内容,6小时轮询一次,一天4次,足够覆盖。观察源一天一次,纯粹是为了"看看它最近在发什么",不追求时效。
这里有个经验公式可以参考:轮询间隔 ≈ 24小时 ÷ 该来源日均有效内容数 ÷ 2。除以2是留个安全余量,防止内容扎堆发布时漏抓。当然,这个公式只适用于更新相对均匀的来源,遇到那种"憋一周然后集中爆发"的来源,还得单独处理。
3. 去重这件事,比想象中复杂得多
3.1 为什么简单的标题去重不够用
最开始我用的是最朴素的办法:标题完全一样就判为重复。结果发现,同一个事件,不同来源的标题写法千差万别。比如某模型发布,有的写"XX模型正式发布",有的写"重磅!XX模型来了",有的写"XX模型今日上线,性能提升显著"。标题去重完全失效,日报里同一个事件出现三四次,读者体验极差。
后来我升级到"标题相似度"去重,用编辑距离算相似度,超过阈值就判重。好了一阵子,又出问题了:有些不同事件的标题恰好很像,被误判成重复,导致真正重要的内容被吞掉。误杀比漏放更可怕,因为漏放你还能从别处看到,误杀是直接消失。
3.2 三层去重:标题、正文指纹、语义
第三版我用了三层去重,层层递进:
第一层:标题归一化。把标题里的标点、空格、特殊符号全部去掉,转成小写,再做一次编辑距离比对。阈值设在0.85,也就是相似度超过85%才判重。这一层能干掉大部分"换汤不换药"的重复。
第二层:正文指纹。对正文做SimHash,生成一个64位的指纹,两个指纹的汉明距离小于3就判为重复。SimHash的好处是对局部修改不敏感,同一篇文章改几个字、调一下段落顺序,指纹基本不变。这一层能抓住"标题不同但内容相同"的情况。
第三层:语义去重。前两层都是"字面"层面的,遇到"同一事件的不同报道"就无能为力了。第三层我用了一个轻量的句向量模型,把标题和摘要编码成向量,算余弦相似度,超过0.9的判为同一事件。这一层最贵,所以只在前两层没判重的情况下才跑。
# 三层去重的简化逻辑示意 def is_duplicate(new_item, existing_items): # 第一层:标题归一化比对 if title_similarity(new_item.title, existing_items) > 0.85: return True # 第二层:SimHash指纹比对 if simhash_distance(new_item.content, existing_items) < 3: return True # 第三层:语义向量比对 if cosine_similarity(new_item.embedding, existing_items) > 0.9: return True return False3.3 去重的"时间窗口"设置
去重不能无限期地比。如果拿今天的条目跟三个月前的比,很容易误判。我的做法是设置一个时间窗口,默认是72小时。也就是说,只跟最近三天内的条目做去重比对。超过三天的,即使内容相似也放行,因为那可能是"旧事重提",本身就有新闻价值。
这个窗口大小是可以调的。如果某段时间热点事件特别密集,可以缩短到48小时;如果是行业淡季,可以放宽到一周。我一般让它自适应:统计最近一周的日均条目数,条目多就缩短窗口,条目少就放宽。
注意:去重阈值不要设得太激进。我一开始把语义相似度阈值设到0.85,结果把"同一模型的不同功能更新"也判重了,损失了不少有价值的内容。后来调到0.9,才找到平衡点。阈值这东西,一定要拿真实数据反复调,不能拍脑袋。
4. 摘要生成:怎么让机器写出"人话"
4.1 抽取式 vs 生成式:我为什么选混合方案
摘要生成有两条路:抽取式(从原文里挑句子)和生成式(让模型重新组织语言)。抽取式的好处是"不会胡说",坏处是"读起来像拼凑";生成式的好处是"流畅自然",坏处是"可能编造原文没有的信息"。
我最后用的是混合方案:先用抽取式挑出原文里信息密度最高的2-3个句子作为"事实骨架",再让模型基于这个骨架重新组织语言,生成一段通顺的摘要。这样既保证了事实准确,又保证了可读性。
具体操作上,抽取阶段我用的是TextRank的变体,给每个句子打分,分数由三个因素决定:句子位置(开头和结尾的句子权重高)、关键词密度(包含核心术语的句子权重高)、句子长度(太短太长都降权)。挑出Top 3句子后,把它们和原文标题一起喂给模型,让模型"用一句话说清楚这件事"。
4.2 提示词设计的几个关键点
让模型写摘要,提示词设计是成败关键。我试过几十版提示词,总结出几个要点:
第一,明确字数范围。不要只说"写个摘要",要说"用80到120字概括"。范围太宽,模型会偷懒写短;范围太窄,模型会硬凑。
第二,指定信息优先级。我会在提示词里写清楚:"优先保留事件主体、核心动作、关键数据,次要的背景信息可以省略。"这样模型知道该抓什么。
第三,给风格示例。与其描述"要写得专业简洁",不如直接给一两个示例摘要,让模型照着风格写。示例的力量远大于形容词。
第四,明确禁止事项。比如"不要添加原文没有的信息""不要使用夸张的形容词""不要以'据悉''据报道'开头"。这些禁止项能挡掉大部分常见的"AI味"。
提示词模板示例: 请基于以下内容,写一段80-120字的中文摘要。 要求: 1. 优先保留事件主体、核心动作、关键数据 2. 语言简洁客观,不使用夸张形容词 3. 不添加原文没有的信息 4. 不以"据悉""据报道""近日"开头 5. 风格参考示例:[示例摘要] 原文标题:{title} 原文内容:{content}4.3 摘要质量的自动评估
摘要生成完,怎么知道写得好不好?人工看太累,我搞了一套自动评估。核心指标有三个:
- 事实一致性:摘要里提到的实体、数字,是否都能在原文里找到。这个用实体抽取+字符串匹配就能做,准确率挺高。
- 信息覆盖度:原文的核心关键词,有多少出现在了摘要里。覆盖度太低说明摘要漏了重点。
- 可读性:用困惑度(perplexity)衡量,困惑度太高说明句子不通顺。
三个指标加权算一个总分,低于阈值的摘要会被标记出来,进入"人工复核队列"。实测下来,这套自动评估能挡掉80%以上的低质量摘要,人工只需要复核剩下那20%。
5. 分类与排序:决定读者先看到什么
5.1 分类体系的设计
日报里的内容不能一锅炖,得分类。我一开始用的是"模型发布、融资并购、产品更新、行业观点、技术论文"这五类,跑了一段时间发现不够用,又加了"政策法规""开源项目""硬件芯片"三类,变成八类。
分类这件事,类目不是越多越好,也不是越少越好。太少,读者找不到重点;太多,每条都不知道该归哪类。我的经验是,类目数量控制在6-10个之间,每个类目每天至少有1-2条内容,否则就该合并。
分类的实现,我用的是"关键词规则+模型分类"的混合方式。关键词规则处理那些特征明显的(比如标题里有"融资""轮"就归到融资类),模型处理那些模糊的。模型用的是一个小型的文本分类器,训练数据是我过去半年手工标注的几千条内容。
5.2 排序算法:热度、时效、质量的三角平衡
分类完了,每类里面的条目怎么排?我用了三个维度的加权分:
| 维度 | 权重 | 计算方式 |
|---|---|---|
| 热度 | 40% | 来源权重 × 互动量归一化 |
| 时效 | 30% | 发布时间距现在的小时数,越新分越高 |
| 质量 | 30% | 摘要质量分 × 来源历史入选率 |
热度占大头,因为读者最关心"大家都在看什么"。时效其次,保证新鲜度。质量兜底,防止低质内容靠热度冲上来。
权重不是固定的。我做过A/B测试,发现不同读者群体偏好不同:技术背景的读者更看重质量,运营背景的读者更看重热度。所以后来我做了两套权重方案,读者可以自己切换"技术视角"或"行业视角"。
5.3 一个容易被忽略的细节:类目内的多样性
排序时还有个坑:如果某一类里全是同一个来源的内容,读起来会很单调。我加了一个"来源多样性惩罚":如果某来源在某一类里已经出现了2条,第3条的分数会被打八折。这样能保证每个类目里的内容来源相对分散,读者能看到不同视角。
这个惩罚系数我设的是0.8,试过0.7和0.9,0.8最平衡。太低会导致优质来源的内容被过度压制,太高又起不到分散作用。
6. 定时调度与容错:让日报每天准时出现
6.1 调度框架的选择
日报系统需要定时跑,我用的是轻量的调度方案,没有上重型的工作流引擎。核心就一个定时任务,每天早上6点触发,跑完整个流水线:采集→清洗→去重→分类→摘要→排序→渲染→推送。
为什么选6点?因为大部分读者是早上8-9点看日报,6点跑完,留出2小时缓冲。万一中间某个环节出问题,还有时间人工干预。
调度频率上,采集是全天候的(按前面说的分层轮询),但"生成日报"这个动作一天只跑一次。这样设计的好处是,采集可以慢慢来,不用赶时间,降低了被目标站点限流的风险。
6.2 容错设计:每个环节都要能"优雅降级"
流水线最怕的是"一个环节挂了,全盘皆输"。我的做法是每个环节都有降级方案:
- 采集环节:某个来源抓取失败,跳过它,用缓存的上次数据顶上,同时发告警。
- 去重环节:语义去重模型加载失败,降级到只用前两层,虽然准确率下降,但不影响出报。
- 摘要环节:模型调用超时,降级到纯抽取式摘要,可读性差一点,但事实准确。
- 渲染环节:模板渲染失败,降级到纯文本输出,至少保证内容能看。
这套降级机制救过我好几次。有一次摘要模型的接口临时不可用,系统自动切到抽取式,日报照常发出,读者根本没察觉。
6.3 监控与告警:别等读者告诉你出问题了
监控这块,我盯三个指标:采集成功率、去重后条目数、摘要平均质量分。采集成功率低于90%告警,去重后条目数低于20条告警(说明可能采集出问题了),摘要质量分低于阈值告警。
告警渠道我用的是最朴素的邮件+即时消息,没搞复杂的。关键是告警要" actionable",也就是收到告警的人知道该干什么。所以每条告警我都会附上"可能原因"和"建议操作",而不是只甩一个"XX指标异常"。
提示:告警阈值不要设得太敏感,否则天天告警,人就麻木了。我一开始把采集成功率阈值设到95%,结果每天都有来源波动,告警响个不停。后来降到90%,并且加了"连续两次低于阈值才告警"的条件,噪音少了很多。
7. 实测数据与踩坑复盘
7.1 三版系统的关键指标对比
| 指标 | 第一版 | 第二版 | 第三版 |
|---|---|---|---|
| 日均采集条目 | 约300条 | 约200条 | 约150条 |
| 去重后条目 | 约120条 | 约80条 | 约45条 |
| 最终入选日报 | 约40条 | 约30条 | 约25条 |
| 人工复核耗时 | 2小时/天 | 1小时/天 | 20分钟/天 |
| 读者满意度 | 一般 | 较好 | 好 |
从数据能看出来,第三版采集的条目反而少了,但最终质量高了,人工耗时大幅下降。这说明**"少而精"远胜"多而杂"**。第一版那种"什么都抓"的思路,纯粹是给自己找麻烦。
7.2 几个印象深刻的坑
坑一:时区问题。有些来源用的是UTC时间,有些用的是本地时间,我没统一处理,导致排序时"最新"的内容其实是几小时前的。后来强制所有时间戳统一转成UTC存储,展示时再转本地时区。
坑二:编码问题。部分来源的页面编码不是UTF-8,抓下来全是乱码。后来在解析前加了一步编码检测,用chardet自动识别,识别不准的再人工指定。
坑三:模型幻觉。早期用生成式摘要时,模型偶尔会"编造"原文没有的数据,比如把"提升20%"写成"提升30%"。后来加了事实一致性校验,摘要里的数字必须能在原文找到,找不到就打回重写。
坑四:重复告警疲劳。前面提过,告警太频繁导致麻木。后来加了告警聚合,同一类告警5分钟内只发一次,并且区分"警告"和"严重"两个级别。
7.3 一个提升明显的小改动
有个改动效果特别好,但特别简单:在摘要开头加一个"一句话结论"。比如"某团队发布新模型,推理速度提升明显"这样一句话,放在摘要最前面,用加粗显示。读者扫一眼就知道这条讲什么,感兴趣再往下看。
这个改动让日报的"扫读效率"提升了一大截。很多读者反馈说,现在看日报就是先扫加粗的那句话,有感兴趣的再点进去。这其实就是"倒金字塔"结构在日报场景的应用——最重要的信息放最前面。
8. 后续可以继续打磨的方向
这套系统跑了大半年,基本稳定了,但还有几个地方我想继续优化。一个是个性化,现在所有人看到的是同一份日报,未来想根据读者的阅读历史做个性化排序,让每个人看到的顺序不一样。另一个是多语言,现在只处理中文内容,英文来源的优质内容还没纳入,这块需要加翻译和跨语言去重。
还有个想法是把日报变成"可追问"的。现在日报是静态的,读者看完就完了。如果能做一个对话入口,读者可以对某条内容追问"这个模型的参数是多少""这个融资的金额是多少",系统基于原文回答,那价值就大不一样了。这个方向技术上可行,但需要把原文都存好、索引好,工程量不小,得慢慢来。
最后分享一个我踩了无数次才悟出来的道理:做资讯聚合,克制比贪婪重要。来源不是越多越好,条目不是越多越好,功能不是越多越好。每加一个东西,都要问自己"这真的让读者更省时间了吗"。如果答案是否定的,那就不加。日报的本质是"帮读者做减法",而不是"替读者堆信息"。想清楚这一点,很多设计决策就顺了。