11 KiB
阅读流方案讨论纪要
参考来源
- Shawn Xie, 《Read Flow 2026》: https://shawnxie.top/blogs/tools/read-flow-2026.html
1. 当前目标
本项目的目标不是直接复刻文章里的整套实现,而是先按下面这条链路,逐步做出一套接近文章效果的阅读流系统:
- 通过一层 RSS 聚合获取文章
- 通过一个
skill或mcp获取文章摘要 - 基于规则对摘要结果进行过滤
- 将过滤后的内容推送到知识库或其他文档组件
- 完成消息推送
- 最后再考虑与 OpenClaw 结合
这里的 skill / mcp 只是整条链路中的一个组件,当前讨论的重点是第 2 步“页面摘要能力”的设计,而不是一次性把整套系统全部落地。
2. 内容来源分类
为了便于后续实现,内容来源建议按两个维度分类:
- 按来源类型分类:这个内容来自什么渠道
- 按接入方式分类:系统用什么技术手段把它纳入统一流水线
这样做的原因是:
- 同一种来源类型,可能有不同接入方式
- 同一种接入方式,可能服务多种来源
- 后面的摘要、过滤、入库更适合依赖标准化后的 source schema,而不是依赖渠道名称
2.1 按来源类型分类
建议定义以下几类:
-
feed- 原生 RSS / Atom 源
- 典型例子:博客、新闻站、技术周刊、文档更新
-
converted_feed- 原本不是 RSS,但通过第三方或自建转换后变成 feed
- 典型例子:微信公众号、部分社区栏目、社交平台账号流
-
event_feed- 更偏事件流而不是传统文章流
- 典型例子:GitHub Releases、Commits、Discussions、Changelog
-
page_watch- 没有现成 feed,需要定时轮询某个页面的更新
- 典型例子:专题页、导航页、榜单页、产品更新页
-
custom_source- 无法直接归类,需要为特定站点写专门抓取逻辑
- 典型例子:结构特殊的网站、内部页面、非标准内容源
2.2 按接入方式分类
建议定义以下几类:
-
feed_direct- 直接消费 RSS / Atom
-
feed_converted- 通过 RSSHub、wewe-rss、RSS-Bridge 等方式先转成 feed,再统一消费
-
api_backed- 通过平台 API 获取内容,再标准化成内部 item
-
html_scraped- 直接抓取 HTML 页面,自己解析列表页和正文页
-
hybrid- 先消费 feed 元信息,再按需回源抓正文
2.3 你当前关心的几类内容如何归档
-
RSS 文章
- 来源类型:
feed - 接入方式:
feed_direct - 优先级:最高
- 来源类型:
-
微信文章
- 来源类型:
converted_feed - 接入方式:通常是
feed_converted - 优先级:高
- 来源类型:
-
其他文章
- 如果是社区栏目、论坛专题:通常归到
converted_feed或page_watch - 如果是普通网站更新页:通常归到
page_watch - 如果是 GitHub 项目更新:通常归到
event_feed - 如果是特殊站点:归到
custom_source
- 如果是社区栏目、论坛专题:通常归到
结论:
“其他文章”不应作为最终系统里的正式分类,因为它过于宽泛,后续规则过滤会很难维护。
2.4 建议的实现级分类
如果进入实现阶段,建议系统内部只保留下面这 5 类 source type:
feedconverted_feedevent_feedpage_watchcustom_source
同时再给每个 source item 增加一个 content_kind 字段,用来表达内容形态:
articlethreadreleasechangelogvideomixed
这样可以把“来源渠道”和“内容形态”拆开,后面的摘要与过滤规则会更稳定。
2.5 当前阶段建议先支持的来源
为了降低复杂度,第一阶段建议只支持两类:
feedconverted_feed
原因:
- 它们最接近当前目标链路
- 接入成本最低
- 最容易验证第 2 步摘要和第 3 步过滤是否成立
- 暂时不需要引入复杂的页面轮询和定制抓取逻辑
3. 系统边界的核心结论
当前最重要的不是先决定做 Skill 还是 MCP,而是先定义一个可复用的“摘要内核”。
建议的能力分层:
RSS 聚合 -> summary-core -> rule-engine -> sink -> push -> OpenClaw 编排
其中:
summary-core:负责抓取页面、抽取正文、生成结构化摘要rule-engine:负责根据规则和评分过滤内容sink:负责将结果写入知识库或文档系统push:负责消息通知OpenClaw:最后作为编排层或自动化入口接入
结论:先做“能力内核”,再决定用 MCP 还是 Skill 进行封装。
4. Skill 和 MCP 的定位
Skill
适合:
- 人工触发
- 代理式工作流
- 提示词编排
- 让 Agent 在上下文里决定何时调用摘要流程
优点:
- 实现快
- 适合探索和半自动流程
缺点:
- 不适合做稳定的批处理基础设施
- 不适合承载缓存、重试、队列、状态管理
结论:
Skill 更像“编排层”,不适合作为底层基础能力的唯一实现。
MCP
适合:
- 将摘要能力标准化成可调用工具
- 给 OpenClaw、ChatGPT、Claude 等 Agent 统一接入
- 为后续自动化编排预留稳定接口
优点:
- 接口标准化
- 易于被 Agent 调用
- 后续接 OpenClaw 更自然
缺点:
- 仍然需要自己实现抓取、抽取、摘要、缓存等能力
结论:
MCP 适合作为“能力接口层”。
当前建议
推荐顺序:
- 先做
summary-core - 再暴露成
MCP - 最后根据需要加
Skill
不建议一开始只做 Skill。
5. 页面摘要能力应输出什么
页面摘要不要只输出一段自然语言摘要,而应该输出结构化结果,方便后面的过滤、入库和推送。
建议输出结构:
{
"url": "https://example.com/article",
"title": "文章标题",
"source": "站点名",
"author": "作者",
"published_at": "2026-03-23T08:00:00Z",
"language": "zh",
"summary": "3-5句摘要",
"highlights": ["要点1", "要点2", "要点3"],
"keywords": ["rss", "mcp", "knowledge-base"],
"topics": ["AI tools", "workflow"],
"quality_flags": {
"is_paywalled": false,
"is_truncated": false,
"is_low_content": false
},
"scores": {
"readability": 0.84,
"novelty": 0.72,
"relevance": 0.91
},
"content_hash": "xxx"
}
这样做的价值:
- 规则过滤直接使用结构化字段
- 知识库入库更稳定
- 推送内容可按场景裁剪
- 后续可以追踪质量、去重和打分
6. 第 2 步“页面摘要能力”的技术拆分
页面摘要不是单一步骤,而是 3 个子能力:
- 获取页面内容
- 抽取正文
- 生成摘要
5.1 获取页面内容
有两条常见路径:
- 直接使用 RSS item 里的
content:encoded或summary - 根据 RSS item 的
link回源抓取页面
建议策略:
- 先使用 RSS 已提供的内容
- 如果内容过短、质量不够,再回源抓页面正文
这样能平衡速度和完整度。
5.2 正文抽取
这是稳定性的关键环节。
候选技术:
-
trafilatura- 对博客、新闻、文档类页面较稳
- Python 生态成熟
-
readability-lxml- 经典轻量方案
- 覆盖面广
-
Playwright + Readability- 适合 JS 动态页面
- 成本最高,但兜底能力最强
建议组合:
- 第一层:
httpx/requests + trafilatura - 第二层:
Playwright作为兜底方案
不建议一开始就默认使用 Playwright。
5.3 摘要生成
有两类方向:
-
抽取式摘要
- 成本低
- 稳定
- 可读性通常一般
-
生成式摘要
- 更接近最终想要的“知识流”效果
- 可读性更好
- 需要更严格的结构化约束
建议:
- 采用生成式摘要
- 强制模型输出 JSON Schema
- 不允许自由散文式输出
这样后续流程会稳定很多。
7. 过滤层设计
过滤层不要完全依赖 LLM 的自由判断,建议采用“两层过滤”。
第一层:确定性规则
例如:
- 来源白名单 / 黑名单
- 关键词规则
- 主题规则
- 语言过滤
- 最低字数要求
- 重复检测
- 发布时间窗口
- relevance 阈值
第二层:可选的 LLM 判断
例如:
- 是否值得进入知识库
- 更偏资讯还是方法论
- 是否符合个人关注主题
- 是否值得推送
结论:
先规则,后智能,不要反过来。
8. 知识库与推送层设计
第 4、5 步可以统一抽象为 sink 和 push。
第一阶段建议优先做的 sink
-
Markdown sink- 输出到本地目录或 Git 仓库
- 适合第一版
- 可审计、易迁移
-
Webhook sink- 推送到 Telegram、企业微信、飞书、OpenClaw 或其他自动化入口
- 扩展性最好
后续可扩展的 sink
- Notion
- Obsidian Vault
- Logseq
- 数据库
结论:
第一版不建议直接绑死在单一平台上,优先本地 Markdown + Webhook。
9. 现在真正该先定义的接口
摘要内核建议先定义统一接口,而不是先定义 UI 或 Agent 提示词。
建议输入:
url- 可选
raw_html - 可选
rss_content - 可选
user_profile - 可选
summary_style
建议输出:
- 结构化摘要 JSON
- 原始正文文本
- 元信息
- 错误状态
只要这个接口稳定:
- CLI 可以调用
- HTTP 服务可以调用
- MCP 可以调用
- OpenClaw Skill 也可以调用
这一步是整个系统里最关键的抽象。
10. 推荐的演进路线
建议按下面顺序推进:
RSS 聚合- 先通过 FreshRSS 或现有聚合器获取文章链接
summary-core- 输入 URL,输出结构化摘要
rule-engine- 对摘要 JSON 执行过滤规则
sink- 先落 Markdown,再做 webhook 推送
MCP server- 暴露
summarize_url、filter_summary、store_note等工具
- 暴露
OpenClaw Skill- 让 OpenClaw 负责编排、人工确认或附加动作
OpenClaw 集成- 最后再接入完整自动化流程
这样每一层都可以独立测试,不会过早被某个平台或代理框架绑定。
11. 当前阶段的明确判断
不建议的方向
- 一开始只做 Skill
- 一开始把 OpenClaw 当成底层依赖
- 一开始就直接绑死 Notion 一类单一知识库
- 让过滤完全依赖 LLM 自由发挥
建议优先做的方向
- 先定义
summary-core的输入输出 - 摘要结果必须结构化
- 过滤规则优先基于确定性逻辑
- 入库优先选择 Markdown
- 对外优先暴露成 MCP,而不是先做纯 Skill
12. 后续讨论建议
后面可以基于这份文档继续讨论以下问题:
summary-core的最小可用接口如何定义MCP版和Skill版分别暴露哪些能力- 正文抽取链路是否需要分层回退
- 规则引擎使用配置文件还是代码实现
- Markdown sink 的目录结构怎么设计
- Webhook / 推送层先接哪一个目标
- OpenClaw 在整条链路里承担“调度器”还是“人工审核入口”
13. 当前阶段的一句话结论
当前阶段最合理的方向是:先把“页面摘要”做成一个独立、结构化、可复用的能力内核,再优先封装为 MCP,最后再用 Skill 和 OpenClaw 做编排与集成。