本站的「AI 热点」栏目没有人工编辑,全靠一个定时跑的机器人。这篇把它的做法完整讲一遍,你可以照着搭一个自己的。
整体流程
每 6 小时跑一轮,每轮做五件事:
- 采集:抓 20 个 RSS 信源,再抓一批 X(推特)账号的最新推文
- 去重:按链接和标题去掉重复条目
- 聚类:把不同媒体报道的同一件事合成一个「事件」
- 打分:交给大模型打质量分、写中文标题和摘要
- 发布:结果写成 JSON 提交回仓库,网站自动重新构建
另外每天北京时间 08:05 再跑一次,把前一天的精选汇总成日报。
第一步:选信源
信源清单放在 scripts/sources.json,一条一行,写清楚名字、RSS 地址和所属主体。现在用的 20 个:
- 官方:OpenAI、Anthropic、Google DeepMind、Google AI、Hugging Face、NVIDIA、AWS 机器学习博客
- 媒体:TechCrunch AI、The Verge AI、MIT 科技评论、机器之心、量子位、InfoQ、36氪
- 个人和社区:Simon Willison、Latent Space、Hacker News
- 论文:arXiv cs.CL、arXiv cs.AI、Hugging Face 每日论文
微信公众号没有官方 RSS,可以用开源的 WeWe RSS 在自己的服务器上把公众号转成 RSS,再像普通信源一样接进来。
选信源的原则只有一条:要原始出处,不要二手搬运。很多热点聚合站的数据只允许个人阅读,公开展示需要授权,自己采原始信源最稳妥。
「所属主体」这个字段很重要。比如 Google DeepMind 和 Google AI 都算 Google,同一件事被它俩同时发了,只能算一家报道,不然交叉验证会被刷分。
第二步:把同一件事合成一个事件
同一条新闻,TechCrunch、The Verge、量子位可能各写一篇。聚类的做法是两两比较标题的相似度,够像就合并。合并之后:
- **「N 家报道」**就是交叉验证:报道的主体越多,越说明这事是真的、是大的,每多一家加 10 分,最多加 20 分
- X 上相关的推文挂到事件下面,算作「讨论热度」
- 每个事件有固定链接,后面合并进来的新报道不会让旧链接失效
第三步:让大模型打分
我用的是火山方舟上的豆包模型(兼容 OpenAI 接口,换别家也只改地址和模型名)。每条内容让模型按五个维度各打 0–10 分,再加权成 0–100:
| 维度 | 权重 | 看什么 |
|---|---|---|
| 影响力 | 35% | 影响多少人、多大范围 |
| 新颖度 | 20% | 是不是新东西 |
| 实用性 | 20% | 读者能不能拿来用 |
| 可信度 | 15% | 出处靠不靠谱 |
| 时效性 | 10% | 新不新鲜 |
权重写在配置文件里,想调随时调。和 AI 无关的内容、广告直接压到 15 分以下丢掉;60 分以上进「精选」,其余放进「全部」。
高分内容还会让模型写一份结构化解读:一句话结论、发生了什么、关键信息、背景、为什么重要、原话、后续看点。
一个关键设计:模型挂了也不能停。 接口失败时自动退回规则打分(按信源权重和关键词),保证每轮都有结果。
第四步:热度和质量分开算
质量分决定「值不值得看」,热度决定「现在大家在聊什么」,两者分开:
- 精选列表按质量分排
- 热点榜按报道家数、X 讨论量和新鲜度排,热度 24 小时衰减一半,所以昨天的大新闻会自然往下走
- 事件超过 48 小时没有新报道,就标成「已收束」
第五步:交给 GitHub Actions 定时跑
工作流文件是 .github/workflows/hot.yml,关键就是两行定时:
on:
schedule:
- cron: '0 */6 * * *' # 每 6 小时采集一轮
- cron: '5 0 * * *' # UTC 00:05 = 北京时间 08:05 生成日报
API 密钥放在仓库的 Secrets 里,脚本从环境变量读,代码里不出现任何密钥。跑完把新数据提交回仓库,托管平台检测到提交就会自动重新部署网站。
踩过的坑
- 提交冲突:采集跑的时候如果 main 有新提交,推送会失败。提交前先变基再推。
- 外文标题:直接展示英文标题读者不爱看,让模型翻成中文显示,原文用小字保留。
- 额度:GitHub 免费账户每月 2000 分钟,一天 4 轮再加日报,每轮十来分钟,一个月会很紧,要盯着用量。