🌅 Horizon 项目深度研究报告
你只需享受新闻,剩下交给 Horizon。
Enjoy the News itself. Leave others to Horizon
项目来源: Thysrael/Horizon
Star数: 持续增长中
许可证: MIT
官方文档: https://thysrael.github.io/Horizon/
一、项目概述
1.1 核心定位
Horizon 是一款AI驱动的个性化新闻雷达系统,它将散落在互联网各处的优质内容汇聚起来,通过AI智能评分、去重合并、背景补充、社区评论收集等处理,最终生成一份结构化的双语日报。
1.2 核心价值主张
好新闻分散在各处,坏信息却源源不断。
Horizon 为你先完成第一轮筛选。
Horizon不仅仅是摘要工具,它保留了人类品味:
- 你信任哪些信息源
- 哪些评论改变了你对事件的理解
- 哪些小众来源值得被更多人看见
1.3 功能特性一览
| 功能模块 | 描述 |
|---|---|
| 📡 多源抓取 | Hacker News、RSS、Reddit、Telegram、Twitter/X、GitHub |
| 🤖 AI评分 | 0-10分智能评分,自动过滤低价值内容 |
| 🔗 智能去重 | 跨平台合并相同故事 |
| 🔍 背景补充 | Web研究陌生概念、公司、技术术语 |
| 💬 评论收集 | 收集HN、Reddit等社区讨论并摘要 |
| 🌐 双语输出 | 英文+中文日报 |
| 📝 多渠道发布 | GitHub Pages、邮件、Webhook、MCP |
二、架构设计
2.1 整体架构图
┌─────────────────────────────────────────────────────────────────┐
│ ⚙️ 配置层 │
│ 信息源配置 │ AI模型 │ 过滤阈值 │ 输出渠道 │ 语言设置 │
└───────────────────────────┬─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 📥 抓取层 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ RSS │ │ HN │ │ Reddit │ │Telegram │ │ GitHub │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└───────────────────────────┬─────────────────────────────────────┘
│ asyncio.gather 并发抓取
▼
┌─────────────────────────────────────────────────────────────────┐
│ 🧹 去重层 │
│ 合并指向同一故事/URL的跨平台内容 │
└───────────────────────────┬─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 🤖 评分层 │
│ AI批量评分(0-10分)+ 超过阈值过滤 │
└───────────────────────────┬─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 🔎 富化层 │
│ 概念识别 → DuckDuckGo搜索 → 结构化背景补充 │
└───────────────────────────┬─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 📝 生成层 │
│ Markdown日报 + 标签 + 参考链接 │
└───────────────────────────┬─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 📤 输出层 │
│ 🌐 Pages │ 📧 邮件 │ 🔔 Webhook │ 🧩 MCP Server │
└─────────────────────────────────────────────────────────────────┘
2.2 模块划分
src/
├── __main__.py # 入口点
├── cli.py # 命令行接口
├── config.py # 配置加载与验证
├── pipeline.py # 核心处理管道
├── types.py # 类型定义
│
├── scrapers/ # 信息源抓取器
│ ├── base.py # BaseScraper 基类
│ ├── hackernews.py # Hacker News
│ ├── github.py # GitHub
│ ├── rss.py # RSS/Atom
│ ├── reddit.py # Reddit
│ ├── telegram.py # Telegram
│ └── twitter.py # Twitter/X
│
├── ai/ # AI处理模块
│ ├── scorer.py # 评分器
│ ├── enricher.py # 内容富化
│ └── summarizer.py # 日报生成
│
├── deduplicator.py # 去重逻辑
├── outputs/ # 输出处理器
│ ├── markdown.py # Markdown输出
│ ├── email.py # 邮件发送
│ ├── webhook.py # Webhook推送
│ └── pages.py # GitHub Pages
│
├── mcp/ # MCP服务器
│ ├── server.py # MCP主服务
│ ├── tools.py # 工具定义
│ └── resources.py # 资源定义
│
└── wizard.py # 交互式配置向导
2.3 配置系统
Horizon 使用JSON配置文件 + 环境变量的双层配置体系:
{
"version": "1.0",
"ai": {
"provider": "openai",
"model": "gpt-4",
"api_key_env": "OPENAI_API_KEY",
"temperature": 0.3,
"max_tokens": 4096
},
"sources": {
"github": [...],
"hackernews": {...},
"rss": [...],
"reddit": {...},
"twitter": {...}
},
"filtering": {
"ai_score_threshold": 7.0,
"time_window_hours": 24
},
"email": {...},
"webhook": {...}
}
环境变量注入:支持${VAR_NAME}语法,保护敏感信息。
三、核心机制详解
3.1 AI评分算法(0-10分)
评分流程
- 批量处理:每批10条,进度条显示
- 内容准备:有评论截断800字符,无评论截断1000字符
- 元数据组装:HN分数、Reddit点赞率等
- AI分析:temperature=0.3的系统提示词
- 响应解析:JSON提取(支持代码块包裹的JSON)
- 重试机制:最多3次,指数退避2-10秒
评分标准
| 分值区间 | 等级 | 描述 |
|---|---|---|
| 9-10 | Groundbreaking | 重大突破、范式转变、重大版本发布 |
| 7-8 | High Value | 重要进展、深度技术内容、新方法 |
| 5-6 | Interesting | 增量改进、有用教程、中等社区关注 |
| 3-4 | Low Priority | 小更新、常识内容、过度营销 |
| 0-2 | Noise | 垃圾信息、离题、琐碎 |
评分因素
Horizon的AI评分考虑以下维度:
- 技术深度与创新性:原创思想、新技术方法、研究贡献
- 潜在影响:对软件工程、AI/ML、系统研究的影响广度
- 内容质量:写作清晰度、文章结构、内容完整性
- 社区讨论:评论洞察力、观点多样性、实质性辩论
- 参与信号:高点赞 + 实质性讨论
3.2 去重机制(跨平台合并)
Horizon采用多层去重策略:
- URL精确匹配:相同URL的内容合并
- 域名+标题匹配:同一域名 + 标题相似度匹配
- 标题文本相似度:编辑距离计算
典型效果:100条原始内容 → 约40条核心故事
3.3 背景补充(Web研究)
富化流程:
- 概念提取:AI识别需要解释的1-3个技术概念
- Web搜索:DuckDuckGo搜索每个概念
- 结构化分析:结合搜索结果生成背景信息
3.4 评论收集与摘要
| 平台 | 评论收集 | 说明 |
|---|---|---|
| Hacker News | ✅ | 最多5条热门评论 |
| ✅ | 最多5条热门评论 | |
| Twitter/X | ✅ | 回复线程(需Apify) |
| RSS | ❌ | 无评论 |
| GitHub | ❌ | 无评论 |
四、来源抓取实现
4.1 Scraper架构
所有Scraper继承自BaseScraper,共享异步HTTP客户端:
class BaseScraper(ABC):
def __init__(self, config: dict, http_client: httpx.AsyncClient):
self.config = config
self.http = client
@abstractmethod
async def fetch(self, since: datetime) -> List[ContentItem]:
"""抓取since之后的内容"""
pass
4.2 各平台Scraper实现
Hacker News Scraper
数据源: Firebase HN API
GET /v0/topstories.json— 获取热门故事ID列表GET /v0/item/{id}.json— 获取故事/评论详情
GitHub Scraper
数据源: GitHub REST API
GET /users/{username}/events/public— 用户公开事件GET /repos/{owner}/{repo}/releases— 仓库发布
认证: 设置GITHUB_TOKEN可获得更高配额(5000 req/hr vs 60)
RSS/Atom Scraper
数据源: feedparser库,支持任意RSS或Atom订阅源
Reddit Scraper
数据源: Reddit公共JSON API
速率限制处理: 检测HTTP 429,读取Retry-After头,等待后重试
Twitter Scraper
数据源: Apify平台(需API Token)
4.3 并发抓取策略
使用asyncio.gather并发抓取所有已配置的信息源:
async def fetch_all_sources(config: Config) -> List[ContentItem]:
async with httpx.AsyncClient() as client:
tasks = []
# 收集所有抓取任务...
results = await asyncio.gather(*tasks, return_exceptions=True)
# 合并结果...
return items
4.4 容错机制
带指数退避的重试机制:
- 速率限制(429):读取Retry-After头等待
- 服务器错误(5xx):指数退避2^n秒
- 最多重试3次
五、MCP集成
5.1 MCP Server设计
Horizon内置MCP服务器,将原生pipeline暴露为分阶段工具和只读资源。
设计原则
- 单一业务逻辑源:MCP不重新实现Horizon业务逻辑
- 阶段性重入:run可以从中间产物继续
- 默认无副作用:除非明确请求,否则不产生额外副作用
5.2 工具接口定义
| 工具 | 功能 |
|---|---|
hz_validate_config | 验证配置和环境变量 |
hz_fetch_items | 抓取并去重到raw阶段 |
hz_score_items | 评分到scored阶段 |
hz_filter_items | 过滤到filtered阶段 |
hz_enrich_items | 富化到enriched阶段 |
hz_generate_summary | 从某阶段生成markdown |
hz_run_pipeline | 运行完整pipeline |
hz_list_runs | 列出最近的run产物 |
hz_get_run_meta | 读取run元数据 |
hz_get_run_stage | 读取run某阶段items |
hz_get_run_summary | 读取生成的摘要 |
hz_get_metrics | 读取服务端指标 |
5.3 Run产物结构
data/mcp-runs/{run_id}/
├── meta.json # 运行元数据
├── raw_items.json # 原始抓取内容
├── scored_items.json # 评分后内容
├── filtered_items.json # 过滤后内容
├── enriched_items.json # 富化后内容
└── summary-zh.md # 中文摘要
└── summary-en.md # 英文摘要
5.4 与AI助手集成
Cursor集成示例:
{
"mcpServers": {
"horizon": {
"command": "uv",
"args": ["run", "horizon-mcp"],
"cwd": "/absolute/path/to/Horizon"
}
}
}
六、部署与自动化
6.1 GitHub Actions定时任务
Horizon支持作为GitHub Actions cron job运行,自动生成日报并部署到GitHub Pages:
name: Daily Horizon Summary
on:
schedule:
- cron: '0 0 */2 * *' # 每2天00:00 UTC
workflow_dispatch: # 支持手动触发
jobs:
daily-summary:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: astral-sh/setup-uv@v3
- run: uv sync
- run: uv run horizon --hours 48
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
publish_branch: gh-pages
6.2 Docker部署
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
COPY pyproject.toml uv.lock ./
COPY src ./src
COPY data ./data
RUN uv sync --frozen --no-dev
VOLUME ["/app/data"]
ENTRYPOINT ["uv", "run", "horizon"]
运行命令:
# 默认24小时窗口
docker-compose run --rm horizon
# 自定义48小时窗口
docker-compose run --rm horizon --hours 48
6.3 邮件系统实现
Horizon支持SMTP/IMAP邮件分发,自动处理订阅与退订。
- SMTP发送:日报推送给订阅者
- IMAP监听:检测 SUBSCRIBE/UNSUBSCRIBE 关键字
- 订阅管理:维护订阅者列表
6.4 Webhook通知
支持推送到多种平台:
- 飞书/Lark:Card消息格式
- 钉钉:Markdown消息
- Slack:Block Kit
- Discord:Webhook消息
- Generic:自定义JSON格式
七、与知识库的结合思考
7.1 评分机制对每日精选的启发
Horizon的0-10分AI评分机制对知识库的「每日精选」功能有重要启发:
可借鉴的设计
- 多维度评分:
- 技术深度权重30%
- 创新性权重25%
- 实用价值权重25%
- 社区影响权重20%
- 阈值过滤:
- 默认7.0分为阈值
- 9.0分以上进入「今日重磅」
- 可根据用户偏好动态调整
- 自动化+人工:AI做第一轮筛选,编辑推荐补充
7.2 双语输出方案
Horizon的双语(中文+英文)日报生成机制值得借鉴:
- 标题:中文主标题 + 英文副标题
- 摘要:中文摘要 + 英文摘要
- 标签:中文标签 + 英文标签
- 代码:保留英文注释
八、快速开始指南
8.1 安装方式
方式A:本地安装
git clone https://github.com/Thysrael/Horizon.git
cd horizon
uv sync
方式B:Docker
git clone https://github.com/Thysrael/Horizon.git
cd horizon
cp .env.example .env
cp data/config.example.json data/config.json
docker-compose run --rm horizon
8.2 配置向导
推荐使用交互式向导生成配置:
uv run horizon-wizard
8.3 手动配置示例
{
"ai": {
"provider": "openai",
"model": "gpt-4",
"api_key_env": "OPENAI_API_KEY"
},
"sources": {
"rss": [
{ "name": "Simon Willison", "url": "https://simonwillison.net/atom/everything/" }
],
"hackernews": {
"enabled": true,
"fetch_top_stories": 30,
"min_score": 100
}
},
"filtering": {
"ai_score_threshold": 6.0,
"time_window_hours": 24
}
}
8.4 运行
# 默认24小时窗口
uv run horizon
# 自定义48小时窗口
uv run horizon --hours 48
九、项目亮点总结
9.1 技术亮点
| 亮点 | 说明 |
|---|---|
| 异步架构 | 全程async/await,支持并发抓取 |
| 模块化设计 | 各模块职责清晰,易于扩展 |
| 配置驱动 | JSON配置+环境变量,灵活可控 |
| 容错机制 | 重试、速率限制处理、断点续传 |
| MCP集成 | 与AI助手深度集成 |
| 双语支持 | 中文+英文日报 |
9.2 产品亮点
| 亮点 | 说明 |
|---|---|
| 零信息疲劳 | AI过滤+评分,只看有价值内容 |
| 跨平台去重 | 合并同一故事的多来源报道 |
| 背景补充 | Web研究陌生概念 |
| 社区声音 | 收集HN、Reddit评论 |
| 多渠道分发 | Pages、邮件、Webhook、MCP |
| 配置向导 | 交互式生成个性化配置 |
9.3 适用场景
- 个人新闻消费:打造专属AI新闻雷达
- 团队情报收集:跟踪竞品动态、技术趋势
- 内容聚合平台:构建垂直领域资讯网站
- AI助手集成:作为AI的新闻查询后端
十、参考资料
- GitHub仓库: https://github.com/Thysrael/Horizon
- 官方文档: https://thysrael.github.io/Horizon/
- 在线演示: https://thysrael.github.io/Horizon/
- 配置指南: https://thysrael.github.io/Horizon/configuration
- 评分机制: docs/scoring.md
- 抓取器: docs/scrapers.md
- MCP工具: src/mcp/README.md
深度研究完成日期: 2026-05-08
研究范围: 架构设计、核心机制、来源抓取、MCP集成、部署自动化、与知识库结合思考
建议后续研究: MCP协议深入实现、多源去重算法优化、AI评分Prompt调优