
我在做一个每天自动跑的社区情报流水线:抓 Reddit 和 Hacker News 的创业、技术热帖,生成中文摘要。跑了两周之后发现,直接看 top 榜根本没法用。
一、热榜的三个问题
- 热度不等于价值。一条"求安慰"的帖子能拿 2000 赞,但零信息量
- 单源霸榜。HN 的分数体系天然低于 Reddit,混排时会被完全压住
- 极值碾压。一个 5000 赞的帖子能把其他所有帖子压到接近 0
所以我定义了一个"信号分",用三个维度重新排序。
二、信号分怎么算
text
signal = 0.5 * norm(score) # 帖子自身热度
+ 0.3 * norm(comments) # 讨论密度
+ 0.2 * norm(top_comment) # 最高赞评论的赞数
三个权重对应三个判断:
| 维度 | 权重 | 代表什么 |
|---|---|---|
| 帖子分 | 0.5 | 基本盘,但不能占满 |
| 评论数 | 0.3 | 有人在讨论,说明有真实争议 |
| 热评赞数 | 0.2 | 帖子里有金句或硬核回答 |
归一化必须用对数
直接线性归一会被极值带偏。所以每个维度先取对数再归一:
python
import math
def norm(values):
logs = [math.log1p(v) for v in values]
lo, hi = min(logs), max(logs)
if hi == lo:
return [0.5] * len(values)
return [(v - lo) / (hi - lo) for v in logs]
HN 需要单独加权
HN 一条 100 分就算爆款,Reddit 100 分很普通。所以给 HN 一个系数:
python
HN_BOOST = 1.3
单源占比上限
不加这个限制,某一源必然霸榜:
python
MAX_SOURCE_SHARE = 0.6 # top10 里,单一来源最多 6 条
三、数据流
flowchart LR
A[Reddit 板块] --> C[合并去重]
B[Hacker News] --> C
C --> D[计算信号分]
D --> E[单源占比约束]
E --> F[Top 10]
四、踩到的三个坑
1. Cookie 30 天过期,而且是静默失败
Reddit 的 session cookie 约 30 天过期。过期后脚本不报错,只是抓到 0 条。如果没有"抓取数为 0 就告警",你会连续几天发出空报告。
python
if not posts:
raise RuntimeError("抓取为 0,疑似 cookie 过期")
静默失败比崩溃危险得多。
2. 跨源匹配不能靠字符串相等
我想标注"这条热点是否被多个源同时提及"。一开始用 title in other_title,误报率极高。
后来改成"精确词或 ≥5 字符子串"匹配,并维护 STOPWORDS 过滤泛词。
3. LLM 摘要的输出不稳定
同一个 prompt,模型有时输出 JSON、有时输出 markdown、有时带前言。
我的做法是不在 prompt 里"请求"格式,而是在代码里解析、校验、失败重试。
格式约束交给代码,不要交给模型。
五、小结
热榜是给所有人看的,信号分是给我自己看的。
排序算法本身不复杂,难的是想清楚要过滤掉什么。我的答案是三样:
- 无信息量的高赞帖
- 单源霸榜
- 看起来热闹、但没人认真讨论的内容
欢迎交流你们的过滤策略。