版本更新摘要: - 文件版本升級至 1.3 (2024-12-04) - 技術架構現代化更新 - 套件版本更新以支援 Python 3.13 - 新增詳細的版本更新記錄 主要變更: - 前端:改為輕量化實作(HTML + Vanilla JS) - 後端:支援 Python 3.13,SQLAlchemy 2.0+ - 爬蟲:httpx + BeautifulSoup4 取代 Scrapy - 排程:APScheduler 取代 Celery - 安全:更新認證與加密套件版本 - PDF:WeasyPrint 67.0+ 支援繁中字型 - 新增:Gitea 版本控制系統資訊 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
436 lines
17 KiB
Markdown
436 lines
17 KiB
Markdown
每日報導 APP
|
||
功能規格書 (Functional Specification)
|
||
文件版本 1.3
|
||
建立日期 2024-11-24
|
||
最後更新 2024-12-04
|
||
專案名稱 每日報導 APP
|
||
專案類型 內部工具
|
||
|
||
1. 專案概述
|
||
1.1 專案目標
|
||
建立一套企業內部新聞彙整與分析系統,協助市場分析專員有效率地蒐集、篩選並彙整產業新聞,透過 AI 自動摘要功能產出綜合分析報告,供內部讀者訂閱閱讀。
|
||
1.2 用戶故事
|
||
用戶故事 A:市場分析專員
|
||
身為市場分析專員,我需要一個方法來縮短每天用關鍵字查找各大網站新聞的過程,因為目前耗用太多時間。
|
||
用戶故事 B:讀者
|
||
身為讀者,我需要一個方法來針對市場分析專員所提供的資料進行分析,因為目前耗用太多時間。
|
||
1.3 預估使用者規模
|
||
角色 人數 說明
|
||
系統管理員 1-2 位 負責系統設定與維護
|
||
市場分析專員 1 位 負責新聞篩選與發布
|
||
讀者 40 位 訂閱並閱讀報告
|
||
|
||
2. 系統架構
|
||
2.1 部署環境
|
||
• 部署方式:地端部署(1Panel 管理介面)
|
||
• 前端平台:Web 優先,支援行動裝置響應式設計
|
||
• 系統語言:繁體中文 / 英文雙語介面
|
||
• 語言切換:用戶手動選擇(右上角切換)+ 系統自動偵測瀏覽器語言
|
||
• 內容翻譯:摘要內容支援自動翻譯(新聞內容不翻譯)
|
||
2.2 技術架構
|
||
• 前端框架:HTML + Vanilla JavaScript(輕量化實作)
|
||
• 前端通訊:RESTful API
|
||
• 後端框架:FastAPI (Python 3.11+,已支援 Python 3.13)
|
||
• 資料庫:MySQL 8.0 / SQLite(開發環境)
|
||
• 資料庫 ORM:SQLAlchemy 2.0+(連線池管理)
|
||
• 快取系統:Redis(選用)
|
||
• 任務佇列:APScheduler(輕量化排程)
|
||
• LLM 整合:支援 Google Gemini API / OpenAI API / Ollama 地端模型
|
||
• 認證整合:JWT + AD/LDAP 驗證 + 本地帳號
|
||
• 版本控制:Git + Gitea(https://gitea.theaken.com)
|
||
|
||
3. 角色與權限
|
||
角色 權限範圍
|
||
系統管理員 LLM 設定、AD 整合、群組管理、用戶管理、系統設定
|
||
市場分析專員 新聞抓取管理、篩選編輯、報告發布、群組內容設定
|
||
讀者 訂閱群組、閱讀報告、留言討論、個人收藏、匯出 PDF
|
||
|
||
4. 功能需求
|
||
4.1 新聞抓取模組
|
||
4.1.1 新聞來源
|
||
來源 登入方式 抓取內容
|
||
Digitimes 帳號密碼登入(付費訂閱) 全文擷取
|
||
經濟日報 公開網頁爬取 全文擷取
|
||
工商時報 公開網頁爬取 全文擷取
|
||
|
||
4.1.2 抓取技術
|
||
• 爬蟲框架:httpx + BeautifulSoup4(輕量化爬蟲)
|
||
• HTML 解析:lxml 6.0+(Python 3.13 相容)
|
||
• 登入狀態管理:維持 session,定期檢查有效性,使用 Cookie 持久化
|
||
• 去重機制:比對標題 + 發布時間,避免重複抓取
|
||
• 新聞欄位提取:標題(必填)、正文內容(必填)、發布時間(必填)
|
||
• 錯誤重試:使用 tenacity 實作自動重試機制
|
||
|
||
4.1.3 抓取排程
|
||
• 定時抓取:每日 08:00 執行
|
||
• 抓取範圍:即時累積至當日的新聞
|
||
• 資料存儲:建立新聞資料庫供日後查詢
|
||
• 處理方式:使用 APScheduler 進行背景任務排程
|
||
• 並發控制:使用 asyncio 提升抓取效率
|
||
|
||
4.1.4 異常處理
|
||
1. 系統自動重試(最多 3 次,間隔 5 分鐘)
|
||
2. 部分成功的新聞先處理,失敗的稍後重試
|
||
3. 重試失敗後通知系統管理員
|
||
4. 專員可透過介面手動觸發重新抓取
|
||
|
||
4.2 關鍵字群組管理
|
||
4.2.1 群組分類方式
|
||
• 依產業別分群:半導體、面板、車用電子...等
|
||
• 依議題分群:政策法規、市場趨勢...等
|
||
4.2.2 群組設定項目
|
||
• 群組名稱與描述
|
||
• 關鍵字清單(可新增、編輯、刪除)
|
||
• AI 摘要背景資訊設定
|
||
• AI 摘要方向設定(每個群組獨立設定)
|
||
4.2.3 群組與報告關係
|
||
一份報告 = 一個群組的彙整內容
|
||
|
||
4.3 AI 摘要模組
|
||
本系統整合多種大型語言模型 (LLM) 服務,提供靈活的 AI 摘要能力,系統管理員可依據需求切換不同的 LLM 提供者。
|
||
4.3.1 支援的 LLM 提供者
|
||
提供者 類型 建議模型 適用場景
|
||
Google Gemini 雲端 API gemini-1.5-pro 長文本分析、多語言
|
||
OpenAI 雲端 API gpt-4o / gpt-4o-mini 通用摘要、高品質輸出
|
||
Ollama 地端部署 llama3 / qwen2 / gemma2 資料不外流、離線使用
|
||
|
||
4.3.2 Google Gemini API 整合規格
|
||
API 端點
|
||
• Base URL: https://generativelanguage.googleapis.com/v1beta
|
||
• 認證方式: API Key (透過 URL 參數或 Header)
|
||
支援模型
|
||
• gemini-1.5-pro: 最高品質,支援 100 萬 tokens 上下文
|
||
• gemini-1.5-flash: 快速回應,適合即時摘要
|
||
• gemini-1.0-pro: 穩定版本,成本較低
|
||
請求格式
|
||
POST /v1beta/models/{model}:generateContent
|
||
Content-Type: application/json
|
||
設定參數
|
||
參數 預設值 說明
|
||
temperature 0.7 控制輸出隨機性 (0-1)
|
||
maxOutputTokens 2048 最大輸出 token 數
|
||
topP 0.95 nucleus sampling 參數
|
||
topK 40 top-k sampling 參數
|
||
|
||
4.3.3 OpenAI API 整合規格
|
||
API 端點
|
||
• Base URL: https://api.openai.com/v1
|
||
• 認證方式: Bearer Token (Authorization Header)
|
||
支援模型
|
||
• gpt-4o: 最新多模態模型,高品質輸出
|
||
• gpt-4o-mini: 輕量版本,成本效益高
|
||
• gpt-4-turbo: 128K 上下文,適合長文
|
||
請求格式
|
||
POST /v1/chat/completions
|
||
Content-Type: application/json
|
||
設定參數
|
||
參數 預設值 說明
|
||
temperature 0.7 控制輸出隨機性 (0-2)
|
||
max_tokens 2048 最大輸出 token 數
|
||
top_p 1.0 nucleus sampling 參數
|
||
frequency_penalty 0 重複懲罰 (-2 至 2)
|
||
presence_penalty 0 新話題懲罰 (-2 至 2)
|
||
|
||
4.3.4 Ollama API 整合規格(地端部署)
|
||
API 端點
|
||
• Base URL: http://localhost:11434 (可自訂)
|
||
• 認證方式: 無需認證(建議內網部署)
|
||
支援模型(需預先下載)
|
||
• llama3:8b / llama3:70b: Meta 開源模型,繁中支援佳
|
||
• qwen2:7b / qwen2:72b: 阿里巴巴模型,中文最佳化
|
||
• gemma2:9b / gemma2:27b: Google 開源模型
|
||
• mistral:7b: 歐洲開源模型,效能優異
|
||
請求格式
|
||
POST /api/generate 或 POST /api/chat
|
||
Content-Type: application/json
|
||
設定參數
|
||
參數 預設值 說明
|
||
temperature 0.7 控制輸出隨機性 (0-1)
|
||
num_predict 2048 最大輸出 token 數
|
||
top_p 0.9 nucleus sampling 參數
|
||
top_k 40 top-k sampling 參數
|
||
stream false 是否串流輸出
|
||
硬體需求建議
|
||
模型規模 最低記憶體 建議配置
|
||
7B-8B 參數 8GB RAM 16GB RAM + GPU 8GB
|
||
13B-27B 參數 16GB RAM 32GB RAM + GPU 16GB
|
||
70B+ 參數 64GB RAM 128GB RAM + GPU 48GB+
|
||
|
||
4.3.5 LLM 設定管理介面
|
||
管理員設定功能
|
||
• 選擇 LLM 提供者(下拉選單切換)
|
||
• 設定 API Key(加密儲存於資料庫)
|
||
• 選擇使用的模型版本
|
||
• 設定 Ollama 端點 URL(地端部署時)
|
||
• 調整生成參數(temperature, max_tokens 等)
|
||
• 連線測試功能(顯示回應時間)
|
||
全系統統一設定
|
||
LLM 設定由系統管理員統一配置,所有群組共用相同的模型與參數,確保輸出品質一致性。
|
||
|
||
4.3.6 摘要處理邏輯
|
||
多篇新聞合併策略
|
||
• 全部合併成一段綜合分析(無數量限制)
|
||
• 當新聞內容超過模型 token 限制時,先進行初步摘要再送 LLM
|
||
• 背景資訊與摘要方向放在 user prompt 開頭傳遞給 LLM
|
||
• 處理方式:串行處理(一個接一個群組依序產生摘要)
|
||
|
||
摘要輸出格式
|
||
• 多篇相關新聞合併產出一段綜合分析
|
||
• 純文字格式,適合閱讀與匯出
|
||
• 每個群組可設定專屬的背景資訊與摘要方向
|
||
|
||
4.3.7 錯誤處理與備援
|
||
• API 呼叫失敗時自動重試(最多 3 次)
|
||
• 摘要失敗時通知專員手動處理
|
||
• 記錄錯誤日誌供管理員查看
|
||
• 支援設定備援 LLM 提供者(未來擴充)
|
||
|
||
4.4 報告發布模組(專員端)
|
||
4.4.1 篩選介面功能
|
||
• 勾選/排除特定新聞
|
||
• 可手動編輯 AI 摘要內容
|
||
• 預覽發布前報告呈現
|
||
4.4.2 發布規則
|
||
• 發布時間:工作日 09:00 前必須發出
|
||
• 工作日定義:週一至週五(排除假日),使用台灣行事曆 API 判斷
|
||
• 逾時處理:延遲發布時通知讀者
|
||
• 已發布報告:專員可以撤回(標記為已撤回),但不可修改內容
|
||
|
||
4.4.3 通知機制
|
||
Email 通知規格
|
||
• Email 內容:報告標題、發布日期、AI 摘要內容、線上閱讀連結
|
||
• Email 樣式:響應式 HTML(支援手機閱讀)
|
||
• 發送策略:批次發送(每批 10 封)
|
||
• 失敗處理:記錄失敗日誌、通知系統管理員
|
||
|
||
4.5 讀者端功能
|
||
4.5.1 訂閱管理
|
||
• 讀者可自行訂閱感興趣的群組
|
||
• 一位讀者可訂閱多個群組報告
|
||
4.5.2 閱讀介面
|
||
• 響應式設計,支援手機閱讀
|
||
• 報告瀏覽與歷史查詢
|
||
4.5.3 互動功能
|
||
• 留言功能:同群組讀者皆可見(討論性質)
|
||
• 留言審核:關鍵字過濾後自動審核
|
||
• 收藏功能:個人收藏清單(未來擴充)
|
||
• 標註功能:個人筆記用途(未來擴充)
|
||
|
||
4.5.4 匯出功能
|
||
PDF 匯出規格
|
||
• 生成技術:WeasyPrint 67.0+
|
||
• PDF 內容:公司 Logo、報告標題、發布日期、AI 摘要內容、相關新聞列表(標題 + 連結)、頁首頁尾文字
|
||
• PDF 樣式:固定樣式(不可自訂)
|
||
• 權限:專員與讀者皆有權限匯出
|
||
• 中文字型:支援繁體中文顯示
|
||
|
||
4.6 系統管理模組
|
||
4.6.1 用戶管理
|
||
• AD/LDAP 整合:僅驗證帳密
|
||
• 支援非 AD 帳號(外部顧問、實習生等)
|
||
• 角色指派與權限管理
|
||
4.6.2 LLM 設定
|
||
• 提供者選擇:Google Gemini / OpenAI / Ollama
|
||
• API 金鑰管理:儲存在環境變數(加密儲存)
|
||
• 加密金鑰輪換:每 3 個月定期輪換
|
||
• 模型版本選擇
|
||
• Ollama 端點設定(地端部署)
|
||
• 連線測試與回應時間顯示
|
||
|
||
4.6.3 PDF 模板設定
|
||
• 可上傳公司 Logo
|
||
• 自訂頁首頁尾文字
|
||
• 固定樣式模板(不可自訂)
|
||
|
||
5. 每日工作流程
|
||
時間 執行者 動作
|
||
08:00 系統 自動抓取各新聞來源當日累積新聞
|
||
08:00 系統 依關鍵字群組分類新聞並呼叫 LLM 產生 AI 摘要
|
||
08:30 專員 登入系統審核新聞,勾選/排除、編輯摘要
|
||
09:00 前 專員 確認無誤後發布報告
|
||
09:00 系統 發送 Email 通知給已訂閱該群組的讀者
|
||
全天 讀者 登入閱讀、留言、收藏、匯出 PDF
|
||
|
||
6. 非功能性需求
|
||
6.1 效能需求
|
||
• 新聞抓取完成時間:30 分鐘內(含 AI 摘要)
|
||
• 頁面載入時間:3 秒內
|
||
• 同時在線用戶:至少 50 人
|
||
• LLM 摘要回應時間:單次請求 30 秒內
|
||
• 快取策略:使用 Redis 快取提升查詢效能(選用)
|
||
• 資料庫連線:使用 SQLAlchemy 2.0+ 連線池管理
|
||
• 異步處理:使用 asyncio 提升 I/O 密集型操作效能
|
||
|
||
6.2 資料保留政策
|
||
• 報告與新聞資料保留期限:60 天
|
||
• 操作日誌保留期限:60 天
|
||
• 過期資料自動清理機制
|
||
|
||
6.3 可用性需求
|
||
• 系統可用性:工作日 07:00-22:00 需正常運作
|
||
• 備份策略:每日增量備份
|
||
• 任務處理:使用 APScheduler 進行排程任務處理
|
||
• 郵件發送:使用 aiosmtplib 5.0+ 進行異步郵件發送
|
||
|
||
6.4 安全性需求
|
||
• 身份認證:JWT Token + python-jose 3.5+(支援 cryptography)
|
||
• 密碼加密:使用 passlib + bcrypt 5.0+ 進行密碼雜湊
|
||
• AD/LDAP 整合:使用 ldap3 2.9+ 進行企業帳號驗證
|
||
• HTTPS 加密傳輸
|
||
• API Key 加密儲存(AES-256),儲存在環境變數
|
||
• 加密金鑰輪換:每 3 個月定期輪換
|
||
• 操作日誌記錄:記錄用戶登入/登出、新聞抓取記錄、AI 摘要產生記錄、報告發布記錄、系統錯誤記錄、API 呼叫記錄
|
||
|
||
6.5 監控與告警
|
||
• 系統健康檢查
|
||
• 新聞抓取失敗告警
|
||
• AI 摘要失敗告警
|
||
• 資料庫連線異常告警
|
||
• 系統效能監控
|
||
|
||
7. LLM 成本估算
|
||
以下為各 LLM 提供者的預估成本(以每日 50 篇新聞、每篇 1000 字計算):
|
||
提供者 輸入成本 輸出成本 每月估算
|
||
Google Gemini $0.00025/1K tokens $0.0005/1K tokens 約 $5-15
|
||
OpenAI GPT-4o $0.005/1K tokens $0.015/1K tokens 約 $30-60
|
||
OpenAI GPT-4o-mini $0.00015/1K tokens $0.0006/1K tokens 約 $3-8
|
||
Ollama (地端) 免費 免費 僅硬體成本
|
||
* 實際成本依使用量而異,建議先以小量測試確認
|
||
|
||
8. 資料庫設計
|
||
8.1 主要資料表
|
||
• users(用戶表):儲存用戶基本資訊與角色
|
||
• groups(群組表):儲存關鍵字群組設定
|
||
• keywords(關鍵字表):儲存各群組的關鍵字清單
|
||
• news(新聞表):儲存抓取的新聞內容
|
||
• reports(報告表):儲存每日產出的報告
|
||
• report_news(報告新聞關聯表):多對多關聯表,記錄報告與新聞的對應關係
|
||
• comments(留言表):儲存讀者留言
|
||
• llm_settings(LLM 設定表):儲存 LLM 提供者與參數設定
|
||
• system_logs(系統日誌表):儲存系統操作與錯誤日誌
|
||
• user_group_subscriptions(用戶群組訂閱表):記錄用戶訂閱的群組(多對多關係)
|
||
|
||
8.2 關聯關係
|
||
• 報告與新聞:多對多關係(一篇新聞可出現在多份報告),透過 report_news 關聯表
|
||
• 群組與報告:一對一關係(一份報告對應一個群組)
|
||
• 用戶與群組:多對多關係(用戶可訂閱多個群組),透過 user_group_subscriptions 關聯表
|
||
|
||
8.3 索引策略
|
||
• 新聞標題索引:優化新聞查詢效能
|
||
• 新聞發布時間索引:優化時間範圍查詢
|
||
• 群組關鍵字索引:優化關鍵字匹配效能
|
||
• 用戶訂閱關係索引:優化訂閱查詢效能
|
||
• 報告發布時間索引:優化報告歷史查詢
|
||
|
||
9. 環境變數配置
|
||
所有敏感資訊與連線設定均透過環境變數管理,確保安全性與彈性。
|
||
|
||
9.1 資料庫連線(已確認)
|
||
• DB_HOST:mysql.theaken.com
|
||
• DB_PORT:33306
|
||
• DB_NAME:db_A101
|
||
• DB_USER:A101
|
||
• DB_PASSWORD:Aa123456
|
||
• 連線狀態:✅ 測試連線正常
|
||
|
||
9.2 Redis 連線(必填)
|
||
• REDIS_HOST:Redis 主機位址(預設:localhost)
|
||
• REDIS_PORT:Redis 埠號(預設:6379)
|
||
• REDIS_PASSWORD:Redis 密碼(如有)
|
||
• REDIS_DB:Redis 資料庫編號(預設:0)
|
||
|
||
9.3 Celery 設定(必填)
|
||
• CELERY_BROKER_URL:訊息佇列 URL(格式:redis://[password@]host:port/db 或 amqp://user:password@host:port/vhost)
|
||
• CELERY_RESULT_BACKEND:結果儲存位置(通常與 broker 相同)
|
||
|
||
9.4 SMTP 設定(必填)
|
||
• SMTP_HOST:SMTP 伺服器位址
|
||
• SMTP_PORT:SMTP 埠號(預設:587)
|
||
• SMTP_USERNAME:SMTP 帳號
|
||
• SMTP_PASSWORD:SMTP 密碼
|
||
• SMTP_FROM_EMAIL:寄件者 Email
|
||
• SMTP_FROM_NAME:寄件者名稱(預設:每日報導系統)
|
||
• SMTP_USE_TLS:是否使用 TLS(預設:True)
|
||
|
||
9.5 AD/LDAP 設定(選填)
|
||
• LDAP_SERVER:LDAP 伺服器位址
|
||
• LDAP_PORT:LDAP 埠號(預設:389)
|
||
• LDAP_BASE_DN:LDAP Base DN
|
||
• LDAP_BIND_DN:LDAP 綁定 DN(如有)
|
||
• LDAP_BIND_PASSWORD:LDAP 綁定密碼(如有)
|
||
• LDAP_USER_SEARCH_FILTER:用戶搜尋過濾器(預設:`(sAMAccountName={username})`)
|
||
|
||
9.6 LLM API Keys(選填,依選擇的提供者設定)
|
||
• GEMINI_API_KEY:Google Gemini API Key
|
||
• OPENAI_API_KEY:OpenAI API Key
|
||
• OLLAMA_ENDPOINT:Ollama 端點 URL(預設:http://localhost:11434)
|
||
|
||
9.7 Digitimes 帳號(必填)
|
||
• DIGITIMES_USERNAME:Digitimes 登入帳號
|
||
• DIGITIMES_PASSWORD:Digitimes 登入密碼
|
||
|
||
9.8 應用程式設定(必填)
|
||
• SECRET_KEY:應用程式密鑰(用於加密,建議至少 32 字元)
|
||
• JWT_SECRET_KEY:JWT 簽章密鑰(建議至少 32 字元)
|
||
• APP_ENV:環境(development/staging/production)
|
||
• DEBUG:除錯模式(預設:False,生產環境必須為 False)
|
||
|
||
9.9 環境變數管理方式
|
||
• 開發環境:使用 `.env` 檔案(不納入版本控制)
|
||
• 生產環境:使用 1Panel 環境變數設定介面
|
||
• 敏感資訊:API Keys、密碼等均加密儲存
|
||
• 加密方式:AES-256 加密,加密金鑰儲存在環境變數中
|
||
|
||
10. 附錄
|
||
10.1 名詞定義
|
||
名詞 定義
|
||
群組 依產業別或議題分類的關鍵字集合,作為新聞分類與報告產出的單位
|
||
報告 針對單一群組,彙整相關新聞並產出 AI 綜合摘要的每日產出物
|
||
專員 市場分析專員,負責新聞篩選、編輯與發布工作
|
||
讀者 訂閱並閱讀報告的內部用戶
|
||
LLM Large Language Model,大型語言模型,用於產生 AI 摘要
|
||
Ollama 開源的本地 LLM 執行框架,可在企業內部部署運行
|
||
|
||
10.2 待確認事項
|
||
1. Digitimes 帳號憑證管理方式 → 已確認:管理者設定
|
||
2. 經濟日報、工商時報爬蟲策略 → 已確認:請求間隔 3-5 秒
|
||
3. PDF Logo → 已確認:開放上傳選項
|
||
4. Email 發送服務 → 已確認:SMTP
|
||
5. LLM 提供者 → 已確認:Google Gemini / OpenAI / Ollama 三選一
|
||
|
||
10.3 版本更新記錄
|
||
|
||
版本 1.3 (2024-12-04)
|
||
更新內容:
|
||
• 技術架構更新
|
||
- 前端改為輕量化實作(HTML + Vanilla JavaScript)
|
||
- 後端支援 Python 3.13
|
||
- SQLAlchemy 升級至 2.0+
|
||
- 任務排程改用 APScheduler(輕量化)
|
||
- 新增 Gitea 版本控制系統資訊
|
||
|
||
• 套件版本更新
|
||
- lxml 升級至 6.0+(Python 3.13 相容)
|
||
- WeasyPrint 升級至 67.0+
|
||
- httpx + BeautifulSoup4 取代 Scrapy
|
||
- aiosmtplib 升級至 5.0+
|
||
- python-jose 升級至 3.5+
|
||
- bcrypt 升級至 5.0+
|
||
- ldap3 2.9+
|
||
|
||
• 功能優化
|
||
- 新增 asyncio 並發控制
|
||
- 使用 tenacity 實作錯誤重試機制
|
||
- 改善安全性需求描述
|
||
- 優化 PDF 中文字型支援
|
||
|
||
版本 1.2 (2025-01-27)
|
||
• 初始版本規格定義
|
||
• 完成基本功能需求規劃
|
||
|
||
版本 1.1 (2024-11-24)
|
||
• 專案啟動
|
||
• 初步需求收集
|
||
|
||
— 文件結束 —
|