用 n8n 打造 AI 新闻自动聚合工作流
用 n8n 打造 AI 新闻自动聚合工作流
Frank Dum前言
AI 领域的信息密度已经到了"靠刷时间线会漏掉关键变化"的程度:官方发布、融资并购、开源动态、论文更新、监管动向,任何一块缺口都会让判断失真。信息源越多,重复越多,标题党越多,筛选成本直线上升。
这个项目做的事情很朴素:把每天的 AI 新闻收敛成一份可读、可回溯、可二次加工的 Top 15。不追求大而全,追求稳定、低成本、少踩坑。
最终效果:每天早上 9 点,飞书多维表格里自动新增 15 条 AI 新闻的中文摘要记录,包含重拟标题、原文链接、发布日期、结构化摘要和分类标签。
环境准备
- n8n 2.9.4(自部署,服务器位于亚太地区)
- Jina AI — 免费额度 100 万 tokens/月,负责网页正文抓取(HTML 转 Markdown)
- Google Gemini API — 两处调用:Gemini Flash-Lite 做标题评分,Gemini 2.5 Flash 做摘要生成
- 飞书开放平台 — 写入多维表格(Bitable),需要配置应用凭证
Jina AI Reader 在这里承担"网页转 Markdown"的角色:RSS 只给标题、摘要和链接,真正有价值的信息在正文里。直接抓 HTML 再清洗又脏又累,Reader 把主内容抽出来输出 Markdown,交给 LLM 做摘要会稳定很多。
工作流全局架构
工作流名为 get_news_final,节点链路如下:
1 | Schedule Trigger |
按阶段拆成 4 段:
- 采集 — 定时触发 + RSS 源列表 + 批量读取
- 评分筛选 — 日期过滤 + LLM 打分 + 去重 + 取 Top 15
- 内容处理 — 正文抓取 + 空值跳过 + 截断保护 + 中文摘要
- 输出 — 字段整理 + JSON 转义 + 写入飞书多维表格
第一阶段:RSS 数据源配置
9 个 RSS 源
| # | 来源 | RSS 地址 | 定位 |
|---|---|---|---|
| 1 | Google AI Blog | https://blog.google/technology/ai/rss/ |
Google 产品发布(Gemini 等) |
| 2 | TechCrunch AI | https://techcrunch.com/category/artificial-intelligence/feed/ |
综合科技媒体 AI 板块 |
| 3 | The Decoder | https://the-decoder.com/feed/ |
AI 垂直媒体,更新频率高 |
| 4 | MIT Tech Review | https://www.technologyreview.com/topic/artificial-intelligence/feed/ |
深度分析,偏政策和影响 |
| 5 | arXiv cs.CL | https://export.arxiv.org/rss/cs.CL |
NLP/LLM 前沿论文 |
| 6 | OpenAI Blog | https://openai.com/blog/rss.xml |
GPT/Sora 等第一手发布 |
| 7 | Hugging Face Blog | https://huggingface.co/blog/feed.xml |
开源 AI 生态核心 |
| 8 | Google DeepMind | https://deepmind.google/blog/rss.xml |
Gemini 背后的研究团队 |
| 9 | NVIDIA Blog | https://blogs.nvidia.com/feed/ |
AI 算力/硬件动态 |
选源逻辑:官方博客 + 科技媒体 + 学术论文 + 开源社区四类组合,覆盖面够用,不被单一叙事带偏。
两个调整点值得记录:
- VentureBeat 被移除 — 实测发现其 RSS 已连续 40 天没有更新,留着只增加空跑和噪音
- arXiv 从 cs.AI 切到 cs.CL — cs.AI 量太大且泛化题材多,cs.CL 更贴近 NLP/LLM 方向,噪音显著下降
set rss AI source 节点
用一个 Code 节点输出结构化的 RSS 源列表,下游 RSS Read 节点循环读取:
1 | return [ |
第二阶段:LLM 智能评分与去重
这一段的目标:把所有 RSS 条目收敛成当天最值得看的 15 条。速度和稳定性比"评分精准"更重要,所以选 Gemini Flash-Lite 来打分。
日期过滤
Build scoring prompt 节点先做一轮时间过滤,只保留最近 24 小时内发布的文章,避免旧闻混入。过滤窗口不能设太短(会漏跨时区发布),也不能太长(会把前天旧闻混进来)。
构建评分提示词
评分阶段只喂标题,不喂正文。把所有标题编号后发给 LLM,要求按 1-10 分评分并标记重复:
1 | const prompt = `你是AI新闻编辑。以下是今日RSS聚合的${items.length}条新闻标题。 |
关键词 fallback 机制
LLM 评分的失败形态很现实:偶发超时、输出非标准 JSON、服务抖动。为了不让链路因为一次评分失败直接断掉,做了一个 fallback——用关键词命中做粗糙评分:
1 | // LLM 解析失败时降级为关键词评分 |
这个 fallback 不追求精准,只保证"LLM 挂了工作流不断"。实际跑下来,大部分时候 LLM 评分正常工作,fallback 只在极少数情况下被触发。
第三阶段:内容抓取与摘要
Top 15 选出来后,每条新闻进入循环处理。
Jina AI Reader 抓取正文
把原始 URL 交给 Jina AI Reader,返回干净的 Markdown 内容。正文质量直接影响摘要质量:正文干净、结构清晰,摘要就稳;正文夹杂导航和推荐区块,LLM 输出就会飘。
If Content Check
跳过抓取失败的文章。失败原因通常是:站点反爬、需要 JS 渲染、403、Reader 返回空内容。处理策略简单粗暴——判断 content 是否非空,不满足就跳回循环处理下一条,避免把空内容丢给 LLM 让它凭空编造。
Truncate Content
LLM 最容易炸的情况之一是正文过长导致 token 超限。这里做硬截断,阈值 30000 字符:
1 | const MAX_LENGTH = 30000; |
30000 字符是经验值,足够覆盖大部分文章主内容,又不会撑爆模型输入。
摘要提示词设计
摘要用 Gemini 2.5 Flash,重点不是"写得好",而是输出格式稳定。提示词采用固定四段式模板(【标题】【摘要】【要点】【标签】),强制 LLM 做"填模板"而非"自由发挥":
1 | 你是一位专业的AI行业新闻编辑。请严格按照下方固定模板输出新闻摘要, |
第四阶段:写入飞书
输出侧选飞书多维表格(Bitable)有几个现实优势:既能当数据库,又能当运营表;同事可以直接筛选、评论、补充;后续做周报月报直接在表里透视。
字段映射
| 飞书字段 | 数据来源 | 说明 |
|---|---|---|
| 新闻主题 | LLM 重拟的中文标题 | 15 字以内 |
| 链接 | 原文 URL | 可直接点击跳转 |
| 新闻日期 | RSS pubDate | ISO 格式 |
| 新闻内容 | LLM 生成的中文摘要 | 包含摘要+要点+标签 |
| 新闻分类 | RSS categories | 原始分类标签 |
踩坑记录与优化
坑 1:飞书写入特殊字符导致 API 报错
问题
新闻内容里经常出现引号、反斜杠、换行符等特殊字符,直接拼进飞书 API 的 JSON body,轻则字段丢字符,重则 JSON 解析失败返回 400。
错误做法
最初的实现用正则粗暴删除特殊字符:
1 | // 错误示例:直接删除,信息损失严重 |
这既删不干净,又误删了内容中的合法字符——技术文章里的路径、代码片段、引用文本全被破坏。
正确做法
新增 Escape for Feishu Code 节点,用 JSON.stringify 做标准转义:
1 | function escapeForFeishu(str) { |
原理一句话:JSON.stringify 负责"正确转义",比正则删字符靠谱得多。
坑 2:摘要提示词过于复杂,输出格式不一致
问题
原始 system prompt 堆了大量层级和装饰符号:
1 | 🔥 **爆点标题**(<15字,含「关键数据」) |
结果 LLM 输出格式经常不一致:有时有 emoji 有时没有,层级结构不固定,字数要求被忽略。
原因
LLM 更擅长"填空",不擅长"遵守一堆规则"。规则越多,模型越容易挑自己理解的一部分执行。提示词里混杂风格装饰(各种 emoji 标记),稳定性进一步下滑。
解决方案
换成固定模板 + 严格四段式输出(【标题】【摘要】【要点】【标签】),让模型做"填模板"而不是"自由发挥"。详见上文摘要提示词设计章节。
关键原则:给 LLM 一个明确的输出模板,比给一堆规则更有效。
坑 3:定时触发时间不合理
问题
原始 Schedule Trigger 设置在凌晨 3:20 触发(服务器时区 UTC+8)。实际效果是经常漏掉大量美国当天的发布内容。
原因
9 个源中大部分位于美国(OpenAI、Google、NVIDIA、TechCrunch 等),发布高峰在美西 9:00-18:00 PT。换算到 UTC+8 对应次日 1:00-10:00。凌晨 3:20(UTC+8)触发时,美西才上午 11:20 左右,大半天的内容还没发出来。
解决方案
触发时间改为上午 9:00(UTC+8)。此时美西约 17:00,当天内容基本发布完毕,RSS 列表更完整,评分筛选更像"当日总结"而非"半天快照"。
补充:arXiv 周末不更新(RSS 里有 skipDays: Saturday, Sunday),但其他 8 个源周末仍有内容,保持每天触发即可,不需要为单一源做特殊处理。
坑 4:中文 RSS 源生态崩塌
问题
一开始尝试把中文 AI 媒体也纳入 RSS 采集(机器之心、量子位、新智元等),想把中文视角的内容一起聚合。
实测结果
| 中文媒体 | RSS 状态 |
|---|---|
| 机器之心 | RSS 地址重定向到飞书表单,已废弃 |
| 量子位 | 无 RSS,仅微信公众号 |
| 新智元 | 无 RSS,仅微信公众号 |
这不是技术问题,是生态问题。中文 AI 媒体几乎全部迁移到微信公众号封闭分发,RSS 入口被主动放弃。
替代方案
唯一靠谱的方向是自建 RSSHub 实例,把公众号等来源转成 RSS 再接入 n8n。代价是维护成本变高、稳定性要自己兜底。对"每天自动 Top 15"的目标来说,先把英文源跑顺更划算,中文源是后续增强项。
总结
get_news_final 这条工作流的价值不在"用到了多少 AI",而在几个关键设计决策:
- 源选择 — 官方 + 媒体 + 论文 + 开源,覆盖面够,噪音可控
- 评分策略 — 标题级评分 + 去重 + Top 15,跑得快、成本低,LLM 失败有 fallback 兜底
- 内容抓取 — Jina AI Reader 把正文变成干净 Markdown,摘要稳定性提升明显
- 输出落地 — 飞书多维表格作为可检索的数据底座,后续做周报月报有抓手
- 工程兜底 — 特殊字符转义解决写入稳定性,固定模板解决输出格式一致性
成本也很友好:Jina AI 免费额度足够覆盖正文抓取,Gemini 按每天 Top 15 的调用量算费用基本可以忽略。真正的投入是一次性把流程打磨稳定。
可扩展方向:
- 增加输出渠道 — 企业微信、Slack、邮件推送
- 接入中文源 — 通过 RSSHub 转换微信公众号
- 增强后处理 — 主题聚类、相似新闻合并、自动生成周报
