Refine OpenClaw payloads and reorganize docs

This commit is contained in:
zhuyongxin
2026-03-26 10:20:07 +08:00
parent cecf4d3ae7
commit 27fe1e8882
155 changed files with 8999 additions and 87 deletions
+476
View File
@@ -0,0 +1,476 @@
# 阅读流方案讨论纪要
## 参考来源
- Shawn Xie, 《Read Flow 2026》: <https://shawnxie.top/blogs/tools/read-flow-2026.html>
## 1. 当前目标
本项目的目标不是直接复刻文章里的整套实现,而是先按下面这条链路,逐步做出一套接近文章效果的阅读流系统:
1. 通过一层 RSS 聚合获取文章
2. 通过一个 `skill` 或 `mcp` 获取文章摘要
3. 基于规则对摘要结果进行过滤
4. 将过滤后的内容推送到知识库或其他文档组件
5. 完成消息推送
6. 最后再考虑与 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:
- `feed`
- `converted_feed`
- `event_feed`
- `page_watch`
- `custom_source`
同时再给每个 source item 增加一个 `content_kind` 字段,用来表达内容形态:
- `article`
- `thread`
- `release`
- `changelog`
- `video`
- `mixed`
这样可以把“来源渠道”和“内容形态”拆开,后面的摘要与过滤规则会更稳定。
### 2.5 当前阶段建议先支持的来源
为了降低复杂度,第一阶段建议只支持两类:
- `feed`
- `converted_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` 适合作为“能力接口层”。
### 当前建议
推荐顺序:
1. 先做 `summary-core`
2. 再暴露成 `MCP`
3. 最后根据需要加 `Skill`
不建议一开始只做 `Skill`。
---
## 5. 页面摘要能力应输出什么
页面摘要不要只输出一段自然语言摘要,而应该输出结构化结果,方便后面的过滤、入库和推送。
建议输出结构:
```json
{
"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 个子能力:
1. 获取页面内容
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. 推荐的演进路线
建议按下面顺序推进:
1. `RSS 聚合`
- 先通过 FreshRSS 或现有聚合器获取文章链接
2. `summary-core`
- 输入 URL,输出结构化摘要
3. `rule-engine`
- 对摘要 JSON 执行过滤规则
4. `sink`
- 先落 Markdown,再做 webhook 推送
5. `MCP server`
- 暴露 `summarize_url`、`filter_summary`、`store_note` 等工具
6. `OpenClaw Skill`
- 让 OpenClaw 负责编排、人工确认或附加动作
7. `OpenClaw 集成`
- 最后再接入完整自动化流程
这样每一层都可以独立测试,不会过早被某个平台或代理框架绑定。
---
## 11. 当前阶段的明确判断
### 不建议的方向
- 一开始只做 Skill
- 一开始把 OpenClaw 当成底层依赖
- 一开始就直接绑死 Notion 一类单一知识库
- 让过滤完全依赖 LLM 自由发挥
### 建议优先做的方向
- 先定义 `summary-core` 的输入输出
- 摘要结果必须结构化
- 过滤规则优先基于确定性逻辑
- 入库优先选择 Markdown
- 对外优先暴露成 MCP,而不是先做纯 Skill
---
## 12. 后续讨论建议
后面可以基于这份文档继续讨论以下问题:
1. `summary-core` 的最小可用接口如何定义
2. `MCP` 版和 `Skill` 版分别暴露哪些能力
3. 正文抽取链路是否需要分层回退
4. 规则引擎使用配置文件还是代码实现
5. Markdown sink 的目录结构怎么设计
6. Webhook / 推送层先接哪一个目标
7. OpenClaw 在整条链路里承担“调度器”还是“人工审核入口”
---
## 13. 当前阶段的一句话结论
当前阶段最合理的方向是:先把“页面摘要”做成一个独立、结构化、可复用的能力内核,再优先封装为 `MCP`,最后再用 `Skill` 和 OpenClaw 做编排与集成。