Horizon 完整教學
把多源新聞(Hacker News / Reddit / Twitter / RSS / GitHub / Telegram / OpenBB)一鍵變成「個人化每日中英雙語簡報」的開源 AI 雷達工具。架在自家機器、用自家的 LLM key,從此不再被資訊洪流追趕。
1. 專案定位
一句話:Horizon 是 self-hosted (自架) 版 Hacker News + The Information + 個人 Twitter list 的 AI 整合層,用 LLM (large language model;大型語言模型) 評分後輸出 Markdown 並推播到 GitHub Pages / Email / Feishu / Slack / Discord / MCP endpoint。
1.1 為什麼會出現 Horizon?
| 痛點 | Horizon 的解法 |
|---|---|
| 新聞太多,看不完 | 多源拉資料 + 去重 + AI 0-10 分篩選,只留高分項 |
| 同一則新聞在 HN/Reddit/Twitter 重複出現 | 跨平台 dedup (去重),merge 成單一條目 |
| 標題吸睛但不知道是什麼 | AI 補背景說明(找 web 上的 context) |
| 想看 community discussion 但要翻論壇 | HN/Reddit 留言自動 summarize |
| 英中雙語讀者 | 同源產 English + 中文兩份簡報 |
| 工具用了一週就懶得開 | 推 Feishu/Email/GitHub Pages,讓資訊自動來找你 |
1.2 適用情境
- 個人 RA / 投資 / 研究:把 5-30 個 RSS + HN + Reddit 自動 summarize
- 公司情資:訂閱 competitor blog + Twitter list,每天推到 Slack
- 媒體編輯:multi-source dedup 找熱度上升的故事
- 學術 follow:arXiv RSS + 領域大佬 Twitter(透過 Apify)→ 每日精選
1.3 不適用情境
- 不要拿來做 paywall 內容(HN/Reddit 留言可能僅見摘要)
- 不要拿來做即時新聞 push(pipeline 設計給 daily / hourly,非秒級)
- 不要替代專業 NLP 系統(情緒分析、命名實體都靠 LLM 推理,無 fine-tune)
1.4 它不是
- ❌ 不是搜尋引擎:不主動找新東西,只處理你訂閱的 source
- ❌ 不是聊天機器人:briefing 是被動產出,不對話
- ❌ 不是抓取爬蟲:法律邊界內、走官方 API / RSS / Apify,不刷頁面
2. 安裝指南
2.1 系統需求
- Python ≥ 3.11
- uv(package manager,不可用 pip / poetry)
- Docker / Docker Compose(推薦部署方式)
- 至少 1 個 LLM API key(推薦 DeepSeek 或 Ollama,便宜或免費)
- (選)Apify token 給 Twitter scraping
- (選)GitHub PAT 給高頻率 GitHub source
2.2 三條安裝路徑
A. 一鍵 Docker(推薦)
1git clone https://github.com/Thysrael/Horizon.git
2cd Horizon
3cp .env.example .env
4# 編輯 .env 填入至少一個 API key
5# 編輯 data/config.json 設 sources / outputs
6docker compose run --rm horizon --hours 24
B. uv 本機跑
1git clone https://github.com/Thysrael/Horizon.git
2cd Horizon
3uv sync # 不可用 pip install -r
4cp .env.example .env
5uv run horizon-wizard # 互動式建立 config
6uv run horizon --hours 24
C. GitHub Action(每日自動跑,輸出到 GitHub Pages)
fork repo → Settings → Secrets 加 ANTHROPIC_API_KEY(或其他)→ 啟用 Action deploy-docs.yml。每天 cron 觸發 → action 跑 horizon → push 到 gh-pages branch → 自動發佈到 https://<your-username>.github.io/Horizon/。
2.3 安裝流程圖
flowchart TD
A[使用者] --> B{怎麼跑?}
B -->|本機試試| C[git clone + uv sync]
B -->|生產部署| D[docker compose]
B -->|自動推 GitHub Pages| E[fork + Action]
C --> F[uv run horizon-wizard]
F --> G[編輯 data/config.json]
D --> H[編輯 .env + data/config.json]
E --> I[Settings/Secrets 設 API key]
G --> J[uv run horizon --hours 24]
H --> K[docker compose run --rm horizon]
I --> L[每日 cron 自動產 briefing]
J --> M[輸出 Markdown / 推播]
K --> M
L --> M
2.4 推薦的 LLM 選擇(成本對照)
| Provider | 強項 | 成本(每日 briefing 約 200 items) |
|---|---|---|
| DeepSeek | 中文好、便宜 | ~$0.05 / 天 |
| Ollama (llama3.1:8b) | 完全免費、無 network | $0、需 8GB+ RAM |
| Doubao (火山引擎) | 中國境內快 | ~$0.10 |
| Claude Sonnet 4 | 評分品質最好 | ~$1.50 |
| GPT-4o-mini | 雙語都不錯 | ~$0.30 |
| Gemini 2.5 Flash | Google 生態好 | ~$0.10 |
3. 核心架構解析
3.1 6 個 pipeline 階段
flowchart LR
A[Sources] -->|httpx| B[Fetch]
B --> C[Deduplicate]
C -->|LLM 0-10 score| D[Score & Filter]
D -->|web search| E[Enrich]
E -->|LLM| F[Summarize]
F --> G[GitHub Pages]
F --> H[Email]
F --> I[Webhook]
F --> J[MCP server]
K[data/config.json] -.設定.-> B
K -.threshold.-> D
K -.model 選擇.-> F
L[SQLite data/horizon.db] -.state.-> C
3.2 五大模組
| 模組 | 路徑 | 一句話用途 |
|---|---|---|
| orchestrator | src/orchestrator.py (23K) | 主 pipeline 調度,串連 fetch / dedup / score / enrich / summary |
| scrapers | src/scrapers/ | 8 個 source 適配(HN / Reddit / RSS / Telegram / Twitter / GitHub / OSSInsight / OpenBB) |
| ai | src/ai/ | LLM provider 抽象(同一介面接 Claude/GPT/Gemini/DeepSeek/Doubao/MiniMax/Ollama) |
| services | src/services/ | 輸出 channel(webhook / email / GitHub Pages publisher) |
| storage | src/storage/ | SQLite + 去重 + 已讀 state |
3.3 一份 config 走完所有設定
data/config.json 一張表設定:
| 段 | 控制什麼 |
|---|---|
sources.hacker_news | HN top stories 限制數 / min score |
sources.rss | RSS feed 清單 + per-feed weight |
sources.reddit | subreddit 清單 + sort(hot/top) |
sources.twitter | Apify actor / user list |
sources.github | watch repos / users |
ai.score_model | 評分用哪個 LLM |
ai.summary_model | 總結用哪個 LLM |
filters.min_score | 0-10 評分門檻 |
outputs.markdown | 寫到本地檔 |
outputs.webhook | Feishu / Slack 等 |
outputs.email | SMTP/IMAP 訂閱 |
outputs.pages | GitHub Pages publish |
3.4 Setup wizard 簡化第一次設定
1uv run horizon-wizard
2# → 問你: 興趣領域? 語言? 想看 HN? Reddit? 推薦的 RSS?
3# → 自動產 data/config.json(可手動再改)
4. CLI 與工具腳本詳細用法
4.1 4 個 CLI 入口
| 命令 | 用途 |
|---|---|
uv run horizon | 主執行(讀 config,跑 pipeline,輸出 briefing) |
uv run horizon-wizard | 互動式生成 / 修改 data/config.json |
uv run horizon-mcp | 啟動 MCP server(讓 AI agent 透過 MCP 讀 briefing) |
uv run horizon-webhook | 直接測試 webhook 推播(debug 用) |
4.2 常用 flag
1# 抓最近 24 小時內容
2uv run horizon --hours 24
3
4# 抓最近 7 天(週報)
5uv run horizon --hours 168
6
7# 跳過 enrichment(省 LLM 成本)
8uv run horizon --skip-enrich
9
10# 只跑單一 source(除錯用)
11uv run horizon --only hn
12
13# 模擬模式(不真的呼叫 LLM、不真的推 webhook)
14uv run horizon --dry-run
4.3 環境變數對照表(.env.example)
| 變數 | 必要 | 說明 |
|---|---|---|
ANTHROPIC_API_KEY | 至少 1 個 | Claude |
OPENAI_API_KEY | 至少 1 個 | GPT |
GOOGLE_API_KEY | 至少 1 個 | Gemini |
AZURE_OPENAI_API_KEY + _ENDPOINT | 至少 1 個 | Azure OpenAI |
MINIMAX_API_KEY | 選 | MiniMax |
DASHSCOPE_API_KEY | 選 | 阿里通義 |
HORIZON_WEBHOOK_URL | 選 | 推 Feishu/Slack 用 |
GITHUB_TOKEN | 選但推薦 | GitHub rate limit 60→5000/hr |
APIFY_TOKEN | 選 | Twitter scraping |
EMAIL_PASSWORD | 選 | SMTP newsletter |
4.4 daily-run.sh
scripts/daily-run.sh 是給 GitHub Action / cron 用的入口,內部 sequence:
11. uv run horizon --hours 24 # 跑 pipeline
22. mv data/briefing-*.md docs/_posts/ # 移到 Jekyll posts 目錄
33. git add . && git commit -m "daily: ..." # commit
44. git push # 觸發 gh-pages 重 build
5. 應用場景
| 場景 | 怎麼設定 |
|---|---|
| AI 工程師日報 | sources: HN + arxiv RSS + GitHub trending (Python+ML); score model: DeepSeek; output: Email |
| 生技公司情資 | sources: bioRxiv RSS + Endpoints News RSS + clinicaltrials.gov + 競爭對手 Twitter; output: Feishu |
| 校園研究組共讀 | sources: 領域 paper RSS + faculty Twitter; output: GitHub Pages |
| 創投早報 | sources: techcrunch + a16z blog + 主要 founder Twitter + GitHub releases; output: Slack |
| 學生 weekly digest | --hours 168,每週日跑一次,輸出 Markdown 自己讀 |
| 多人共用 source pool | 多人 fork 同 config repo,每人改自己的 outputs |
| 整合進 Claude / Cursor | uv run horizon-mcp → MCP server → AI agent 透過 MCP 讀今日 briefing |
6. 資安掃描報告
工具:手動 grep
eval/exec/subprocess/pickle/secret/api_key/tokenoversrc/+scripts/+.env.example對照。
6.1 結果總表
| 風險等級 | 項目 |
|---|---|
| 🟢 低 | API key 全部走環境變數 |
| 🟢 低 | 無 eval / exec / subprocess shell=True / pickle.loads |
| 🟢 低 | HTTP 全用 httpx,URL 為固定 endpoint |
| 🟡 中 | Twitter scraping 走 Apify (第三方雲端):你的 token 與 user list 都會發到 api.apify.com |
| 🟡 中 | Apify URL 把 token 放 query string (?token=...),被 proxy log 風險高於 header auth |
| 🟢 低 | data/config.json 含 user 興趣設定,請別 commit 含 token 的版本 |
| 🟢 低 | LLM 評分 + 總結會把 source 內容送到 LLM provider(與 ChatGPT 等同等風險) |
| 🟢 低 | MIT license,無 CLA、無企業限制 |
6.2 詳細說明
🟢 API key 環境變數
src/main.py:97-130、src/models.py:62-305 顯示所有 API key 都用 api_key_env: str(環境變數名稱字串)做配置,實際 key 由 os.environ.get(...) 讀。.env.example 不含真實 key。✅
🟢 無 dangerous 函式
grep -rn -E "eval\(|exec\(|os\.system|shell=True|pickle\.loads|__import__" 結果只在註解 / 字串中出現,無實際呼叫。✅
🟡 Twitter scraping 走 Apify
src/scrapers/twitter.py:77/91/111/145 用:
1url = f"{_APIFY_BASE}/acts/{self.config.actor_id}/runs?token={token}"
風險:
- token 在 URL query string,被 reverse proxy log / WAF rule 抓到的機率高於 header auth
- Apify 是雲端服務,你監看的 Twitter user list 會被 Apify 看到
緩解:
- 不想用 Apify 就把 config 內 twitter source 關掉
- 想用就接受「Twitter scraping 必然走第三方」這個事實
🟢 data/config.json 已 gitignore
issue #71 / #72 已修:data/config.json 加進 .gitignore,避免使用者個人化設定被 git pull 覆蓋或被誤 commit。
🟢 LLM 內容傳送
任何 source 抓回來的內容會送給 LLM 評分 / 總結。與你用 ChatGPT 貼新聞讓它總結是同等的隱私風險。要 air-gap 用 Ollama 即可(localhost LLM)。
6.3 部署建議
| 情境 | 建議 |
|---|---|
| 個人 home server | 直接用,建議用 Ollama 完全離線 |
| 公司內部 | 用 Azure OpenAI(資料留在公司租戶內)+ 不 expose webhook 到外網 |
| 學校研究組 | DeepSeek 便宜 + GitHub Pages public 發佈 |
| 機密情境 | 不用 Apify、不用 webhook、改本地 markdown only + Ollama |
7. FAQ
Q1. 為什麼一定要 uv?不能用 pip 嗎?
A: pyproject.toml 與 uv.lock 強綁定 uv(hatchling build backend)。pip 仍可裝但會跳過 lockfile,依賴版本不確定。維持 uv 一致。
Q2. 一定要 Docker 嗎?
A: 不必,但 Docker 處理掉 Python 環境、cron 時區、volume mount 三件事。本機 uv run horizon 一樣可跑。
Q3. 我沒有 GitHub Pages 怎麼用?
A: 把 outputs.pages 關掉,留 outputs.markdown(寫本地檔)+ outputs.webhook(推 Feishu/Slack)。
Q4. Twitter 一定要花錢嗎?
A: Apify 是付費(有 free tier $5 額度可用一陣)。完全不想花錢就把 twitter source 關掉,Telegram + Reddit + RSS 已涵蓋 80% 內容。
Q5. 中文評分品質如何?
A: DeepSeek / Doubao / Qwen 中文都不錯;Claude / GPT 中英都好但貴。建議先用 DeepSeek 試一週再決定要不要升級。
Q6. 跟 Feedly / Inoreader 比有什麼差別?
A: Feedly 只給你 raw RSS feed;Horizon 多了 dedup + LLM 評分 + 補背景 + 雙語輸出 + 自架 webhook,是「reader」前的 pipeline。
Q7. 為什麼會有 OpenClaw badge?
A: Horizon 跟 OpenClaw(AI agent SDK)有整合可能;目前 issue #74 提到 MyClaw.ai partnership inquiry。
Q8. 跑壞了怎麼除錯?
A: 加 --dry-run 看流程;加 --only hn 限制 source;用 --skip-enrich 跳過 LLM enrich(最大宗 cost & error 來源)。
8. 進階技巧
8.1 雙模式 cron(issue #75 預告)
未來 v0.2 預計支援:
- 高頻 cron(每小時):只跑 fetch + dedup,存 SQLite
- 低頻 cron(每天 8AM):跑 score + enrich + summarize + deliver
目前可手動拆:horizon --skip-enrich --skip-summary 跑 fetch only。
8.2 自訂 LLM provider
src/ai/ 提供 base class,要加新 provider(例如 Cohere、xAI)只需 ~50 行 subclass。
8.3 自訂 source scraper
src/scrapers/ 8 個適配是 reference impl。要加新 source(例如 Lobsters、Mastodon)照 rss.py pattern 寫 ~100 行 async class,註冊到 orchestrator。
8.4 整合進 Claude Desktop / Cursor
1# Claude Desktop config (~/.config/claude_desktop_config.json)
2{
3 "mcpServers": {
4 "horizon": {
5 "command": "uv",
6 "args": ["run", "horizon-mcp"],
7 "cwd": "/path/to/Horizon"
8 }
9 }
10}
Claude 就能 @horizon 拉今日 briefing 進對話。
8.5 Email newsletter 訂閱
uv run horizon-webhook 啟 SMTP/IMAP 服務:
- 訂閱者寄
subscribe@your-domain→ 自動加進名單 - 每日 briefing 自動寄出(HTML + 退訂連結)
- 退訂寄
unsubscribe@your-domain→ 自動移除
8.6 多語言 briefing 雙簡報
config.json 設 languages: ["en", "zh"] → 跑一次 pipeline 出兩份輸出,省一份 fetch cost。
8.7 跟本 AI-knowledge_template 整合
| 整合方向 | 怎麼做 |
|---|---|
| Horizon → ai-save | Horizon 輸出 markdown 到 inbox/(webhook 寫 file) |
| Horizon briefing → quarkdown | qd from: <horizon-output.md> 出漂亮 HTML 報告 |
| Horizon MCP → Claude session | Claude 可隨時查今日 briefing |
9. 整合進其他工作流
| 上游 / 下游 | 整合方式 |
|---|---|
| GitHub Action cron | .github/workflows/deploy-docs.yml 已附 |
| Jekyll / GitHub Pages | docs/_posts/ 落點,自動 build |
| Feishu / Lark | webhook,message card with 高分 items |
| Slack | webhook,threaded by score tier |
| Discord | webhook,embed with screenshot |
| Apple Mail / Outlook | SMTP newsletter |
| n8n / Zapier | webhook trigger 後接更多自動化 |
本 repo gh-tutorial-qd | 把 Horizon 產的 briefing 變團隊內部教學 |
本 repo quarkdown Layer 7 | 把 briefing.md 轉漂亮 HTML 報告分享 |
本 repo ai-notebooklm Layer 5 | 把多日 briefing 變 NotebookLM 來源做深度問答 |
10. 重點摘要 Checklist
- Horizon 是 self-hosted 多 source AI 新聞雷達,輸出英中雙語 daily briefing
- 安裝必用 uv(不可 pip)
- 至少設 1 個 LLM API key(推薦 DeepSeek 便宜、Ollama 免費)
- config 全寫在
data/config.json一個檔 -
horizon-wizard幫你互動式建 config - 8 個 source scraper(HN / Reddit / RSS / Telegram / Twitter / GitHub / OSSInsight / OpenBB)
- 5 種 output(Markdown / GitHub Pages / Email / Webhook / MCP)
- 資安:🟢 低風險、API key 走 env,但 Twitter 走 Apify 雲端(🟡 中度資料外流)
- MIT license,企業內可商用
- 無 release tag,main 滾動更新
11. 進一步閱讀
- 官方 Live Demo: https://thysrael.github.io/Horizon/
- Configuration Guide: https://thysrael.github.io/Horizon/configuration
- Hub design doc(社群 source hub):
docs/horizon-hub-design.md - Scoring 細節:
docs/scoring.md - Scrapers 細節:
docs/scrapers.md - 簡中 README:
README_zh.md - 議題追蹤: https://github.com/Thysrael/Horizon/issues
- HelloGitHub 收錄頁: https://hellogithub.com/repository/Thysrael/Horizon
Comments