跳到主要内容

产品边界:Folo 为什么不是一个 RSS 阅读器

一、从“订阅源”转向“信息入口”​

Folo 的产品叙事是把 RSS、RSSHub、自定义列表、分享页和 AI 能力放进一个统一时间线。代码里最重要的变化是:feed 不再是唯一一级对象。

至少有五类对象会出现在同一个用户体验里:

对象用户看到的东西代码里的稳定标识
Feed一个可更新的信息源feeds.id
Subscription用户对 Feed/List/Inbox 的订阅关系subscriptions.id + type
Entry信息源中的一条内容entries.id
List多个 Feed 的组合与分享单元lists.id
Inbox面向收件的特殊订阅入口inboxes.id

这解释了为什么 Store 不是一个 useRssStore:它按领域拆成 feed、subscription、entry、list、inbox、unread、collection、summary、translation 等模块。

二、Folo 的四个产品承诺​

1. 统一入口​

用户不需要先判断“这是一条 RSS、一个视频还是一个分享列表”。入口层把不同来源统一成 Feed/Entry/Subscription 语义,视图层再根据 view、媒体和内容形态选择卡片。

2. 低噪声​

read、unread、hideFromTimeline、收藏/Collection 和列表分组都是一等状态。它们不是 UI 临时变量,而是跨设备同步的用户事实。

3. 内容增强​

原始内容不被直接覆盖。翻译、摘要、Readability 抽取、图片颜色、AI Chat 都有独立字段或表,既能缓存,也能回退到原始内容。

4. 多端连续​

桌面、移动端、Web 分享页面向不同场景,但业务模型保持同构。平台代码主要负责启动、导航、权限、通知、存储适配和发布,而不是重新实现 Feed 业务。

三、核心用户旅程​

注意这条链路没有“请求成功后才渲染”的单一闸门。Folo 更接近“本地投影先恢复,网络结果再修正”的模型。

四、产品概念与技术概念的对应​

Subscription 是真正的导航锚点​

在数据库里,Subscription 可以指向 feedId、listId 或 inboxId,并用 type 区分。未读数、视图类型、隐藏时间线和分类都挂在订阅关系上,而不是简单地挂在 Feed 上。这让同一 Feed 可以被不同列表、不同用户偏好以不同方式使用。

Entry 是跨功能的“载体”​

Entry 的主表只保存原始内容和可展示元数据;摘要、翻译、可读正文、收藏、媒体和 AI 对话通过独立模块接入。一个 Entry 因此能被阅读器、搜索、分享页、AI 助手和通知共同消费。

List 是内容关系,而不是文件夹​

lists.feedIds 保存聚合关系,同时 List 还具备 owner、description、view、subscriptionCount 和 purchaseAmount 等产品属性。它可以被订阅、分享、发现,因而不能只用本地 UI 分组来解释。

五、设计取舍​

这种产品边界带来的收益是组合能力强:新增一个来源或视图,通常只需扩充协议、解析和展示组件。代价是领域关系比传统 RSS 客户端复杂,尤其是未读、列表、Inbox 和跨端同步之间的语义必须持续保持一致。

一个有用的判断标准是:

如果一个状态需要在设备之间同步,或者会影响多个页面,它就不应该只存在于组件 state;如果一个结果可以重新计算或重新请求,它就不应该覆盖原始事实。