讓 AI 成為您的專屬編輯部:一套基於 Linux 的自動化報紙系統設計
#
在資訊爆炸的時代,每天手動去檢查監控數據、搜集新聞簡直是浪費生命。作為工程師,我們應該追求極致的自動化。今天分享一套我親手打造的 Pollo AI News 自動化生產線。
這套系統不只是個腳本,它是一套具備「職位分工」與「pipeline 解耦」設計的生產流程。
實測結果
#
核心設計理念:解耦與職責分離 (SoC)
#
不同於將所有邏輯塞進一個腳本,我將整個新聞系統拆解為三個核心職位,分別處理不同的業務邏輯。這種設計的好處在於:若某個環節掛掉,不會導致系統崩潰,且方便隨時擴充新的業務邏輯。
1. 職位定義
#
- 記者 (Reporter):負責資料收集 (Data Acquisition)。它只管把世界各地的數據(如 Prometheus 指標、API、RSS)轉化為 Markdown 草稿。
- 總編 (Editor-in-Chief):負責彙整與校對 (Aggregation & Formatting)。它不關心資料怎麼來,只關心如何將所有草稿整合,產出最終的 MD 文件。
- 郵差 (Mailman):負責派送 (Distribution)。它唯一的任務就是把最終檔案送到讀者手中。
系統架構圖 (Project Structure)
#
1
2
3
4
5
6
7
|
/home/hermes/news-paper/
├── daily-draft/yyyy-mm-dd/ # 記者存放的 raw markdown 產出
├── news/yyyy-mm-dd.md # 總編產出的最終報紙成品
└── scripts/ # 職位 SOP 腳本
├── collect_data.sh # 記者 SOP
├── editor_merge.sh # 總編 SOP
└── send_mail.sh # 郵差 SOP
|
實作細節:職位 SOP (Shell Scripts)
#
記者 SOP (collect_data.sh)
#
利用 curl 與 jq 直接從 Prometheus 撈取即時監控數據,並生成 Markdown。
1
2
3
4
5
6
7
|
# 抓取並計算數據後,輸出至草稿資料夾
cat << EOF > "$DRAFT_DIR/01_weather.md"
## 現在氣溫
* 目前溫度: $TEMP °C
* 目前濕度: $HUMID %
* 體感溫度: $FEELS_LIKE °C
EOF
|
總編 SOP (editor_merge.sh)
#
這是系統的靈魂。不管記者產出多少份草稿,總編只透過 cat 進行線性彙整。這意味著您隨時可以增加 02_news.md、03_stock.md,系統完全不需要修改任何程式碼。
郵差 SOP (send_mail.sh)
#
結合專用的 CLI 工具進行郵件寄送。
精準的排程調度 (Cron Pipeline)
#
我們利用 Linux Cron 來控制業務節奏,確保資訊流按時湧動:
1
2
3
4
5
6
7
8
|
# 07:30 記者截稿:開始搜集所有數據
30 07 * * * /home/hermes/news-paper/scripts/collect_data.sh
# 07:40 總編彙整:將所有 MD 檔案併入最終稿
40 07 * * * /home/hermes/news-paper/scripts/editor_merge.sh
# 08:00 郵差派送:準時把當日報紙寄出
00 08 * * * /home/hermes/news-paper/scripts/send_mail.sh
|
為什麼我要這樣做?
#
- 高度擴充性:明天如果想加一個「財經快訊」,只需再寫一個記者腳本,並在 07:30-07:40 之間塞進排程,總編會自動幫你彙整。
- 極致容錯:如果記者蒐集失敗,總編會發現草稿目錄是空的或不完整;如果最終稿不存在,郵差會自動放棄派送,不會寄出空信件給讀者。
- 無痛維運:純 Linux 原生工具(Bash, Curl, JQ),沒有複雜的框架依賴,極輕量,極穩定。
這就是我每天早上 8 點準時收到客製化報紙的秘密。想玩轉自動化的朋友,不妨也打造一套屬於自己的「編輯部」吧!
腳本內容
#
- /home/hermes/news-paper/scripts/collect_data.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#!/bin/bash
DATE=$(date +%Y-%m-%d)
DRAFT_DIR="/home/hermes/news-paper/daily-draft/$DATE"
mkdir -p "$DRAFT_DIR"
TEMP=$(curl -s -u "http://127.0.0.1:9090/prometheus/api/v1/query?query=j18_temperature_celsius" | jq -r '.data.result[0].value[1]')
HUMID=$(curl -s -u "http://127.0.0.1:9090/prometheus/api/v1/query?query=j18_humidity_percent" | jq -r '.data.result[0].value[1]')
FEELS_LIKE=$(python3 -c "import math; t=$TEMP; rh=$HUMID; print(f'{t + 0.33 * ((rh/100) * 6.105 * math.exp(17.27 * t / (237.7 + t))) - 4.00:.2f}')")
cat << EOF > "$DRAFT_DIR/01_weather.md"
## 現在氣溫
* 目前溫度: $TEMP °C
* 目前濕度: $HUMID %
* 體感溫度: $FEELS_LIKE °C
EOF
|
- /home/hermes/news-paper/scripts/editor_merge.sh
1
2
3
4
5
6
7
8
9
10
11
|
#!/bin/bash
DATE=$(date +%Y-%m-%d)
DRAFT_DIR="/home/hermes/news-paper/daily-draft/$DATE"
FINAL_NEWS="/home/hermes/news-paper/news/$DATE.md"
echo "# Pollo AI News $DATE" > "$FINAL_NEWS"
echo "" >> "$FINAL_NEWS"
if [ -d "$DRAFT_DIR" ]; then
cat "$DRAFT_DIR"/*.md >> "$FINAL_NEWS"
fi
|
- /home/hermes/news-paper/scripts/send_mail.sh
1
2
3
4
5
6
7
8
9
|
#!/bin/bash
DATE=$(date +%Y-%m-%d)
FINAL_NEWS="/home/hermes/news-paper/news/$DATE.md"
if [ -f "$FINAL_NEWS" ]; then
pollo-mail-cli send -t [email protected] -s "Pollo AI News $DATE" -b "$(cat $FINAL_NEWS)"
else
echo "錯誤: $FINAL_NEWS 不存在,無法寄送。"
fi
|