Skip to content

hsrxr/The-Feed

Repository files navigation

Personal Feed · 个人编辑部

你的专属高质量信息流。用 GitHub Actions 取代算法投喂,用编辑部杂志的克制取代抖音的廉价。

这是一个完全代码化的个人信息系统。后端是一条由 GitHub Actions 驱动的 Python 数据管道,前端是一个翻页式杂志阅读器。每 6 小时自动从你订阅的博客、X、arXiv 与机构研报里抓取新内容,由 LLM 提炼成可独立站立的"信息卡片",呈现在你的私人电子杂志里。

设计哲学

Editorial Newsstand——灵感来自 The New Yorker × Monocle × Substack。奶油白底(#FBF8F3)+ 深墨黑(#1A1A1A)+ 酒红(#7C2D12),Playfair Display 装饰大引号 + Source Serif & Noto Serif SC 正文。每张卡片占据整屏,Scroll Snap 翻页吸附,配合 spring 物理动画,像翻一本好杂志。

系统架构

┌──────────────────┐    ┌────────────────────┐    ┌──────────────────┐
│  RSS / Atom Sources    │  GitHub Actions    │    │  Next-style React │
│  Sam Altman / arXiv    │ ─→ Python Pipeline ─→  │  Magazine Reader │
│  Anthropic / NVIDIA    │    LLM 卡片化提取   │    │  (无限翻页)        │
└──────────────────┘    └────────────────────┘    └──────────────────┘
                                  │
                                  ▼
                         client/public/data/feed_items.json

后端管道运行后会直接 commit 回仓库,前端通过 /data/feed_items.json 读取,无需任何数据库或 API 服务器。

项目结构

personal-feed/
├── pipeline/                       # 后端数据管道
│   ├── config/sources.yaml         # 信息源配置(在这里加/删源)
│   ├── requirements.txt
│   └── src/
│       ├── fetcher.py              # 并发 RSS 抓取
│       ├── llm_processor.py        # LLM 卡片化(不做摘要,提取金句)
│       ├── main.py                 # 主调度
│       └── seed_data.py            # 示例种子数据生成
├── client/                         # 前端阅读器
│   ├── public/data/feed_items.json # 卡片数据(由管道生成)
│   └── src/
│       ├── pages/Home.tsx          # 主信息流页面
│       ├── components/
│       │   ├── FeedCardView.tsx    # 单张卡片
│       │   ├── FeedHeader.tsx      # 顶部刊头
│       │   └── SettingsDrawer.tsx  # 设置/收藏抽屉
│       ├── hooks/usePreferences.ts # 本地偏好与权重学习
│       └── lib/
│           ├── feed-engine.ts      # 加权抽样 + Fisher-Yates 洗牌
│           └── types.ts
├── .github/workflows/
│   └── daily_pipeline.yml          # 定时工作流(每 6 小时)
└── README.md

快速开始

1. 配置信息源

编辑 pipeline/config/sources.yaml

sources:
  - id: sam_altman
    name: Sam Altman
    type: rss
    url: https://blog.samaltman.com/posts.atom
    category: blog
    extract_mode: insights      # insights / summary / news

每条源的 extract_mode 控制 LLM 的提炼风格——insights 用于博客金句,summary 用于论文研报,news 用于公司动态。

2. 在 GitHub 仓库添加 Secrets

Settings → Secrets and variables → Actions 下添加:

  • LLM_API_KEY:你的 OpenAI / OpenRouter / DeepSeek API Key
  • LLM_BASE_URL(可选):兼容 OpenAI 协议的 base URL(例如使用 OpenRouter / DeepSeek 时)

也可以在 Variables 下设置:

  • LLM_MODEL:默认 gpt-4o-mini,可改为 claude-3-5-sonnet-20241022deepseek-chat

3. 本地试跑(可选)

cd pipeline
pip install -r requirements.txt

# 不调用 LLM,先用种子数据预览前端
python src/seed_data.py

# 调用 LLM 生成真实卡片
LLM_API_KEY=sk-xxx python src/main.py

4. 启动前端

pnpm install
pnpm dev

打开 http://localhost:3000,向下滑动即可。

5. 部署

后端不需要部署——.github/workflows/daily_pipeline.yml 会自动 commit 数据。 前端是纯静态站点,可一键部署到 Cloudflare Pages、Vercel、或 GitHub Pages。

关键设计决策

为什么用 GitHub Actions 而不是 n8n? GitHub Actions 是代码、是版本化的工作流定义、是免费的(每月 2000 分钟足够日跑十几次)。不需要服务器,不需要管理界面,所有逻辑都是 Python 函数,可以单元测试、可以本地复现。

为什么把数据 commit 回仓库? 因为这是世界上最便宜也最可靠的"数据库"。文件历史就是数据快照,git diff 就是变更日志。前端只需 fetch 一个静态 JSON,CDN 缓存命中率接近 100%。

为什么是"卡片化"而不是"摘要"? 摘要让你必须读完整段,卡片让你扫一眼就能决定是否深入。Sam Altman 一篇博客可能只有一句话值得记住——那就让 LLM 把这一句挑出来,放在杂志引言区的位置。

为什么不用算法推荐? 因为算法推荐是抖音的灵魂,而我们要做的恰好是它的反面。这里所有内容都是你亲自挑选的源,权重学习只在你已选的池子里轻微调整顺序——你看到的内容总是你想看的,惊喜感来自顺序的不可预测,而不是池子被算法操纵。

添加更多信息源

对于没有原生 RSS 的源(X、YouTube、邮件订阅),推荐配合:

源类型 解决方案
X / Twitter RSSHub: https://rsshub.app/twitter/user/AnthropicAI
YouTube RSSHub: https://rsshub.app/youtube/channel/UC...
Newsletter 邮件 Kill the Newsletter!: 创建专用收件邮箱 → 输出 RSS
GitHub Trending RSSHub: https://rsshub.app/github/trending/daily/javascript

把它们的 RSS URL 直接加进 sources.yaml 即可。

路线图

  • 增加左滑跳过 / 右滑收藏的手势交互
  • 收藏卡片同步到 Obsidian / Flomo
  • 每日邮件简报(Resend API)
  • PWA 离线阅读
  • 支持 YouTube 字幕抓取与提炼

License

MIT

About

一个 TikTok 式的高质量信息流阅读器。后端通过 GitHub Actions 定时抓取精选信息源(博客、X、arxiv、Newsletter 等),调用 LLM 提取金句和洞察,输出结构化 JSON;前端实现全屏卡片式无限下滑阅读体验,每张卡片支持跳转原文。 · 使用 Manus 构建

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors