1. 项目概述:一个本地优先的AI摘要RSS阅读器
如果你和我一样,每天被海量的信息源淹没——十几个技术博客、几个新闻网站、还有社区动态,光是挨个点开看标题就够呛,更别说深度阅读了。传统的RSS阅读器解决了聚合问题,但信息过载的痛点依然存在。最近,我把自己的信息流管理工具换成了Feedclaw,一个用 TypeScript 写的命令行 RSS/Atom 阅读器。它的核心卖点很直接:不仅帮你把订阅源的文章抓取下来,存进本地的 SQLite 数据库,还能调用 Claude 或 GPT 的 API,自动为这些文章生成一份精炼的 AI 摘要简报。
这工具完美契合了“本地优先”和“AI增强”两个趋势。你的所有订阅数据和文章内容都躺在自己电脑的~/.feedclaw/目录下,隐私和安全自己掌控。然后,你可以命令它:“把过去24小时‘AI’这个分类下的新文章,用 Claude 总结成一份适合终端阅读的简报。” 它就会默默工作,最后给你一份过滤掉噪音、提炼出核心的 digest。对于开发者、内容创作者或者任何需要高效摄入信息的人来说,这相当于雇了一个不知疲倦的助理编辑。
2. 核心设计思路与技术选型解析
2.1 为什么是“本地SQLite + 命令行CLI”?
Feedclaw 的架构选择反映了其清晰的产品哲学:简单、可控、可脚本化。
首先,SQLite作为数据存储层是神来之笔。它无需任何外部数据库服务,一个文件 (feedclaw.db) 搞定所有数据(订阅源、文章、抓取状态)。这带来了几个关键优势:
- 零部署成本:用户安装即用,没有数据库安装、配置的烦恼。
- 极致便携:整个数据目录可以轻松备份、迁移或同步(比如用 Syncthing 或 Dropbox),你的阅读历史完全属于你。
- 开发友好:Node.js 社区有
better-sqlite3这样优秀的原生绑定库,性能好,同步API写起来也直观,非常适合CLI工具这种“运行-结束”的生命周期。
其次,命令行接口 (CLI)是其灵魂。这并非简陋,而是为了自动化和集成。通过 CLI,你可以用cron或systemd timer在后台定时执行fetch和digest,让信息摘要像收邮件一样成为日常流程。更重要的是,--json输出标志让它可以无缝被其他脚本或 AI Agent(比如其兄弟项目 OpenClaw)调用,成为更大自动化工作流中的一个可靠模块。
2.2 条件抓取与摘要生成的工作流拆解
整个工具的核心工作流可以拆解为两个松耦合的管道:
管道一:抓取与存储
- 订阅源管理:支持通过
add命令添加 RSS/Atom 链接,或通过init加载预置的分类订阅包(AI、开发、新闻等)。 - 智能抓取:执行
fetch时,工具会为每个订阅源记录其ETag和Last-Modified头。下次抓取时,会带上这些信息发起“条件请求”。如果服务器返回304 Not Modified,则跳过该源,极大节省了网络流量和抓取时间,对服务器也友好。 - 结构化存储:抓取到的新文章会被解析,标题、链接、发布时间、摘要(或全文内容,取决于订阅源提供情况)等字段被规整化后存入 SQLite 数据库。每篇文章都有一个
read状态标记,初始为0(未读)。
管道二:过滤与摘要
- 查询过滤:当执行
digest命令时,工具会根据--since(如24h)、--category等参数,从数据库中查询出符合条件的、未读的文章。 - 内容组装:将这些文章的标题、链接和内容摘要(或截取的部分正文)按一定格式组装成一份给 AI 的“提示词(Prompt)”。这里通常会有长度控制(
--max-articles),以防 token 数超标。 - AI 处理:将组装好的提示词通过配置的 API(Anthropic 或 OpenAI)发送给指定模型(如 Claude 3 Sonnet),请求其生成一份连贯、精炼的摘要。
- 输出与标记:将 AI 返回的结果按指定格式(终端、Markdown、HTML、JSON)输出。成功后,将涉及的文章标记为已读(
read=1),避免下次重复摘要。
这个设计将“数据收集”和“信息消费”解耦,非常灵活。你可以一天抓取多次,但只在早上生成一次摘要;也可以只为某个特定分类生成摘要。
注意:AI 摘要的质量和成本高度依赖于提示词工程和所选模型。Feedclaw 内置的提示词模板需要足够聪明,能指导 AI 区分新闻、技术教程、观点文章等不同体裁,并做出恰当归纳。这是项目隐含的核心竞争力之一。
3. 从零开始的详细部署与配置指南
3.1 环境准备与项目安装
Feedclaw 要求 Node.js 版本 22 或更高,并推荐使用pnpm作为包管理器。如果你还在用 npm 或 yarn,我强烈建议趁此机会切换到pnpm,它的磁盘空间和安装速度优势在管理 Monorepo 或需要大量依赖的项目时非常明显。
# 1. 确保Node.js版本 node --version # 应 >= v22.0.0 # 2. 全局安装pnpm (如果尚未安装) npm install -g pnpm # 3. 克隆项目并安装依赖 git clone https://github.com/psandis/feedclaw.git cd feedclaw pnpm installWindows 用户特别注意:因为依赖的better-sqlite3需要编译原生模块,你必须安装Visual Studio Build Tools并确保包含“使用 C++ 的桌面开发”工作负载。这是一个常见的坑,没有它,pnpm install会在编译阶段失败。
安装完成后,需要构建 TypeScript 源码:
pnpm build这会在项目根目录生成dist文件夹,里面是编译好的 JavaScript 可执行文件。
3.2 核心配置:API密钥与数据目录
Feedclaw 的 AI 功能需要 API 密钥。它支持 Anthropic (Claude) 和 OpenAI (GPT) 两家。根据你的偏好和预算选择其一即可。
1. 设置环境变量(推荐)这是最安全、最灵活的方式,特别是当你打算设置定时任务时。
# 如果你使用 Anthropic export ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxx # 或者,如果你使用 OpenAI export OPENAI_API_KEY=sk-xxxxxxxxxx为了让这个变量永久生效,你可以把它加到 shell 的配置文件中(如~/.bashrc,~/.zshrc或~/.bash_profile)。
2. 或者,使用配置文件Feedclaw 会在数据目录 (~/.feedclaw/) 下寻找config.json文件。你可以手动创建并配置:
# 首先,初始化数据目录(运行任何cli命令都会自动创建) pnpm cli --help # 然后,创建配置文件 cat > ~/.feedclaw/config.json << EOF { "defaultProvider": "anthropic", "defaultModel": "claude-3-5-sonnet-20241022", "defaultFormat": "terminal", "digestSince": "24h" } EOF关于数据目录:所有数据(数据库、配置、缓存)默认存放在~/.feedclaw/。你可以通过设置FEEDCLAW_HOME环境变量来修改这个路径,这在你想为不同项目或用途隔离数据时非常有用。
export FEEDCLAW_HOME=/path/to/my/feedclaw_data3.3 初始化订阅源与首次抓取
项目贴心地提供了一组预分类的默认订阅源,涵盖了 AI、开发、科技新闻等领域。这是快速上手的绝佳方式。
# 1. 初始化,添加所有默认订阅源(ai, dev, news, openclaw) pnpm cli init # 2. 也可以只初始化特定分类 pnpm cli init --bundle ai pnpm cli init --bundle dev,news # 3. 执行首次抓取,获取文章 pnpm cli fetchinit命令执行后,你会看到终端输出一系列成功添加的订阅源名称。此时,这些源的信息(URL、分类)已经存入数据库。接着运行fetch,工具会开始网络抓取。根据订阅源数量和网络状况,首次抓取可能需要几十秒到几分钟。你会看到每个源的抓取状态和获取到的新文章数量。
实操心得:首次
fetch后,建议立刻运行pnpm cli list查看一下。你会发现之前只有 URL 的订阅源,现在有了从 feed 中解析出来的正式名称。这个细节体现了工具的完整性——它不仅在后台干活,还完善了数据展示。
4. 日常使用:命令详解与高效工作流
4.1 订阅源管理:增删改查
基础的 CURD 操作是信息流的源头管理。
查看订阅列表 (list)
pnpm cli list这是最常用的命令之一,用于概览所有订阅源。输出按分类分组,并显示每个源的最后抓取时间、ID 和 URL。使用--category ai可以过滤只看某个分类。
添加订阅源 (add)
# 添加一个订阅源,并指定分类 pnpm cli add https://blog.rust-lang.org/feed.xml --category dev # 添加但不指定分类,会进入‘default’分类 pnpm cli add https://example.com/feed.xml添加成功后,该源会获得一个唯一的数字 ID。记住,URL 必须是有效的 RSS 或 Atom feed 地址。很多网站会在首页<head>部分通过link标签注明 feed 地址。
移除订阅源 (remove)
# 通过ID移除 pnpm cli remove 5 # 通过URL移除 pnpm cli remove https://example.com/feed.xml移除操作会从数据库中删除该订阅源及其所有历史文章,请谨慎操作。
导入/导出 OPML (opml-import/opml-export)这是迁移订阅列表的行业标准方式。你可以从 Feedly、Inoreader 等在线服务导出 OPML 文件,然后用 Feedclaw 导入。
# 导出当前所有订阅源到文件 pnpm cli opml-export > my_feeds.opml # 从OPML文件导入订阅源 pnpm cli opml-import my_feeds.opml导入时,工具会尝试解析 OPML 中的分类(category)信息。这是一个从其他阅读器无缝迁移过来的关键功能。
4.2 核心操作:抓取与生成摘要
定时抓取 (fetch)信息更新的动力源。如前所述,它利用条件请求,非常高效。
# 抓取所有订阅源 pnpm cli fetch # 只抓取特定ID或URL的订阅源 pnpm cli fetch --feed 3 pnpm cli fetch --feed https://blog.rust-lang.org/feed.xml我个人的习惯是在后台设置一个每小时的定时任务(通过cron或launchd)来运行fetch,这样数据始终是最新的。
生成AI摘要 (digest)这是整个工具的精华所在,参数也最丰富。
# 生成过去24小时内‘ai’分类的摘要,输出到终端(默认) pnpm cli digest --since 24h --category ai # 生成过去一周‘dev’分类的摘要,输出为Markdown文件 pnpm cli digest --since 7d --category dev --format markdown > weekly_dev_digest.md # 使用OpenAI的GPT-4模型生成摘要,并限制最多20篇文章 pnpm cli digest --provider openai --model gpt-4 --max-articles 20 # 生成JSON格式的摘要,供其他脚本处理 pnpm cli digest --format json --since 48h关键参数解析:
--since: 时间窗口。支持h(小时)、d(天)、w(周) 的单位组合,如12h、3d、2w。它决定了摘要涵盖的文章时间范围。--max-articles:非常重要的安全阀。AI API 的调用有 token 数限制和成本考量。如果过去一段时间新文章太多,这个参数可以防止提示词过长导致 API 调用失败或费用激增。默认值 50 是一个比较平衡的设置。--format: 输出格式。terminal适合在命令行快速阅读;markdown和html适合保存或分享;json则是为了程序化处理。
注意事项:
digest命令只会处理未读 (read=0) 的文章,并且在成功生成摘要后,会自动将这些文章标记为已读。这个设计保证了摘要的“新鲜度”,你每次读到的都是新内容。如果你希望重新摘要某些文章,目前需要在数据库层面手动重置read状态,或者设计更复杂的工作流。
4.3 构建自动化工作流
命令行工具的威力在于自动化。下面是一个结合cron的每日摘要示例:
创建脚本
~/scripts/daily_feedclaw.sh:#!/bin/bash export ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxx export PATH=$PATH:/path/to/your/node_modules/.bin # 如果feedclaw未全局安装 cd /path/to/feedclaw # 抓取新文章 pnpm cli fetch # 生成AI摘要并保存为Markdown,附带日期 TODAY=$(date +%Y-%m-%d) pnpm cli digest --since 24h --format markdown > ~/Documents/feed_digests/digest_$TODAY.md # (可选) 生成特定分类的摘要 pnpm cli digest --since 24h --category ai --format terminal赋予执行权限:
chmod +x ~/scripts/daily_feedclaw.sh添加到cron(
crontab -e):# 每天上午9点运行 0 9 * * * /bin/bash /home/yourname/scripts/daily_feedclaw.sh
这样,每天上午你就能在指定目录下收到一份前24小时的新闻摘要Markdown文件,同时在终端看到AI分类的简报。
5. 高级集成:作为OpenClaw技能与JSON API
Feedclaw 不仅仅是一个独立工具,它被设计成OpenClaw 生态系统中的一个“技能”(Skill)。OpenClaw 是一个开源的 AI Agent 框架,你可以把它想象成一个可编程的、本地的“AI助手操作系统”。
5.1 如何作为OpenClaw技能运行
首先,你需要全局安装 Feedclaw,以便 OpenClaw Agent 能直接调用它:
npm install -g feedclaw # 或使用你构建的本地版本 pnpm install -g ./feedclaw-1.0.0.tgz # 假设你打包了然后,在你的 OpenClaw 工作区(workspace)中,创建一个SKILL.md文件来描述这个技能:
--- name: feedclaw description: Fetch RSS feeds and generate AI news digests version: 1.0.0 requires_binaries: - feedclaw --- When the user asks about news, feeds, or digests, use the `feedclaw` CLI: - To check feeds: `feedclaw --json fetch` - To get a digest: `feedclaw --json digest --format markdown` - To add a feed: `feedclaw --json add <url>`当 OpenClaw Agent 运行时,它会加载这个技能描述。之后,你可以用自然语言对 Agent 说:“帮我看看今天 AI 领域有什么新闻?” Agent 会理解你的意图,在后台执行类似feedclaw --json digest --since 24h --category ai --format markdown的命令,获取结构化的摘要信息,然后再用自然语言回复你。这就实现了通过对话来管理信息流。
5.2 利用--json标志进行脚本集成
即使你不使用 OpenClaw,--json标志也极大地提升了 Feedclaw 的可编程性。几乎所有命令都支持这个标志,它会将输出从人类可读的文本转换为结构化的 JSON。
# 获取订阅源列表的JSON pnpm cli --json list # 获取抓取结果的JSON pnpm cli --json fetch # 获取摘要的JSON(需要--format json) pnpm cli --json digest --format json --since 12h这让你可以轻松地用 Python、Node.js 或其他任何语言编写脚本,来消费 Feedclaw 的数据。例如,你可以写一个脚本,将每日摘要 JSON 中的重点内容提取出来,自动发布到你的团队 Slack 频道或 Notion 页面。
// 一个简单的Node.js脚本示例 const { execSync } = require('child_process'); const result = execSync('feedclaw --json digest --format json --since 24h --category dev', { encoding: 'utf8' }); const digest = JSON.parse(result); console.log(`今日开发领域摘要 (${digest.generatedAt}):`); digest.articles.forEach(article => { console.log(`- ${article.title}: ${article.summary}`); });6. 故障排除与性能优化实践
6.1 常见问题与解决方案
在实际使用中,你可能会遇到以下问题:
1. 抓取失败或超时
- 现象:
fetch命令卡住或报错FetchError。 - 排查:
- 网络连接:检查你的网络是否能正常访问目标订阅源 URL。可以尝试用
curl -I <feed_url>测试。 - 订阅源格式:确认 URL 是有效的 RSS/Atom。有些网站需要特定路径。尝试在浏览器中打开该 URL,看返回的是否是 XML。
- 服务器限制:某些网站可能对频繁抓取有速率限制或需要 User-Agent。Feedclaw 使用的
fetch库通常会设置合理的默认 UA,但如果遇到问题,可能需要查看其源码,考虑修改请求头。
- 网络连接:检查你的网络是否能正常访问目标订阅源 URL。可以尝试用
- 解决:对于不稳定的源,可以考虑将其移除,或寻找更稳定的镜像源。
2. AI摘要生成失败或返回空
- 现象:
digest命令执行后无输出,或输出错误信息如Invalid API Key、Context length exceeded。 - 排查:
- API密钥:首先确认
ANTHROPIC_API_KEY或OPENAI_API_KEY环境变量已正确设置且未过期。可以用echo $ANTHROPIC_API_KEY简单验证。 - Token超限:这是最常见的原因。如果
--since时间窗口内未读文章太多,即使有--max-articles限制,所有文章的标题和内容摘要加起来仍可能超过模型上下文窗口。 - 模型不可用:检查
config.json或命令行中指定的模型名称是否正确且你有权限访问(例如,你是否订阅了 Claude API 的相应模型层)。
- API密钥:首先确认
- 解决:
- 缩短
--since时间窗口(如从7d改为24h)。 - 降低
--max-articles的数量(如从50改为20)。 - 分分类生成摘要,而不是一次性生成所有分类。
- 缩短
3. 数据库文件损坏或锁死
- 现象:任何命令都报 SQLite 相关错误,如
SQLITE_BUSY。 - 解决:
- 关闭可能占用它的进程:确保没有其他 Feedclaw 实例或工具在访问
~/.feedclaw/feedclaw.db。 - 备份与重置:最彻底的方法是备份后重置。关闭所有相关进程,然后
cp ~/.feedclaw/feedclaw.db ~/.feedclaw/feedclaw.db.backup,接着删除原文件rm ~/.feedclaw/feedclaw.db。再次运行pnpm cli init会创建新的空数据库。但你会丢失所有历史数据和订阅列表,所以需谨慎。
- 关闭可能占用它的进程:确保没有其他 Feedclaw 实例或工具在访问
6.2 性能调优与使用建议
1. 抓取频率优化不要过于频繁地运行fetch。对于新闻类订阅源,每小时一次足矣;对于技术博客,每天一次甚至每周一次都可能没问题。过度抓取既浪费资源,也可能触发目标网站的防爬机制。合理设置cron计划。
2. 摘要生成成本控制AI API 调用是主要成本。务必合理使用--since和--max-articles。对于高产出的新闻源(如 Hacker News),建议单独为其设置更短的时间窗口和文章上限。你也可以考虑在非高峰时段(如 API 费用较低的时段)运行摘要生成任务。
3. 数据目录管理定期检查~/.feedclaw/目录的大小。SQLite 数据库会随着时间增长。虽然文章内容通常不大,但长期积累也可能达到几百MB。你可以考虑:
- 定期归档:写一个脚本,将超过一定时间(如3个月)的已读文章从主表中移动到归档表或导出为 JSON 后删除。
- 清理未订阅源的文章:当你移除一个订阅源时,其历史文章可能仍留在数据库中。可以手动清理或等待工具未来提供更精细的数据管理功能。
4. 自定义默认订阅源项目自带的feeds/default.json文件是预置订阅源的来源。你可以直接编辑这个文件,添加你喜欢的源,或者创建自己的 JSON 文件,然后通过pnpm cli init --from my-feeds.json来初始化。这是打造个性化信息起点的最佳方式。