「要防止 LLM 在金融分析中產生 Hallucination 或輸出不方便讀的龐大數字,最佳實踐是在 Prompt 中注入硬性執行規則,並在送入模型前先進行程式碼層級的 Pre-processing。」
在 Day 15 中,我們成功將盤後分析重構為「Stage 1-3 Pipeline」。然而,光有管道方向約束還不夠,在實際運作中,還面臨了兩大分析品質問題:
1. 原始數字不可讀:TWSE API 回傳的成交金額往往是長達 12 位數的原始字串(如 123456789012),LLM 經常直接輸出給使用者,極度不友善。
2. 語意幻覺與無效廢話:LLM 偶爾會提及「根據知識庫...」、「因為沒有新聞...」等系統語言,或者在週末休市時模擬當日盤態。
今天我們將深入 daily_analysis.py,解析我們如何透過 _fmt 前處理函式、7 條 Core Execution Rules 與週末模式 解決這些痛點!
TWSE API 輸出的月成交資訊或三大法人數據包含許多 多位數數字。若直接將原始字串餵給 LLM,模型不僅容易算錯小數位數,還會直接把「123456789012」印在報告中。
因此,我們在 generate_report() 中設計了 _fmt() 前處理正則函式,在文字組裝階段就強制將 9 位數以上的數字轉換為直覺的「兆元」或「億元」:
Python
# PRE-PROCESS: Format large numbers in market data BEFORE sending to Gemini
import re as _re
def _fmt(val):
"""Convert raw number strings to readable format."""
if not isinstance(val, str):
return val
clean = val.replace(',', '').strip()
try:
num = float(clean)
if num >= 1_000_000_000_000:
return f"約 {num/1_000_000_000_000:.2f} 兆元"
elif num >= 100_000_000:
return f"約 {num/100_000_000:.1f} 億元"
except (ValueError, TypeError):
pass
return val
# 使用正則自動匹配 9 位數以上的數字進行替換
tw_summary_parts = [
_re.sub(r'[\d,]{9,}', lambda m: _fmt(m.group(0)), p)
for p in tw_summary_parts
]
透過這道預先處理工序,送入 Gemini 的 Prompt 數據本身就已經被標準化,徹底避免了 LLM 在處理多位數時的計算誤差與不可讀問題。
為了確保 Agent 輸出的金融報告風格一致、沒有系統廢話且具備明確的操作指引,我們在 daily_analysis.py 的 Stage 3 與 Fallback Prompt 中,明確寫入了 7 條 Core Execution Rules:
# Role & Tone
你是一位專業、客觀且具備實戰經驗的台灣股市首席分析師。報告應兼具數據精準度、高可讀性與實用操作指引。
# Core Execution Rules
1. 報告長度:總輸出字數嚴格控制在 800-1000 字。說話直奔主題、精簡贅字,確保完整產出到操作建議與免責聲明。
2. 盤態與中長期語氣調和:當日大漲時先肯定多方動能,再以「逢高順勢調節/注意高檔風險」帶出中長期警示。嚴禁在大漲日宣告市場極度悲觀。
3. 數據格式化:金額大於億一律四捨五入換算為億元或兆元(保留小數點後1-2位)。絕對禁止輸出原始多位數數字。
4. 防幻覺:指數點位與前一交易日維持連續性,絕對禁止捏造偏離現況超過10%的數字。
5. 隱藏系統語言:絕對禁止提及「知識庫」「投資框架」「新聞列表為選單」「無具體新聞」等。新聞不足時直接以「從量價結構與籌碼動向觀察」帶過。
6. 技術面白話化:MA5=5日均線/極短線成本, MA20=20日均線/月線。
7. 報告末尾必須包含:倉位控制建議與具體停損/觀察點位。
在週末台股休市時,若強制跑當日盤態分析,模型容易因為沒有今日數據而產生「模擬交易」的幻覺。
在 generate_report() 中加入 is_weekend 判斷分支:當週末執行時,跳過 Stage 1 與 Stage 2 的當日盤態判定,直接切換為《台股週報與下週展望》專用 Prompt:
Python
# Weekend mode: skip Stage 1/2, go directly to Stage 3
if is_weekend:
weekend_prompt = (
"❗ 今天是週末,台股休市。\n"
"報告標題必須為《台股週報與下週展望》。\n"
"內容架構:上週盤態總結 -> 美股與全球宏觀 -> 下週觀盤重點 -> 操作建議。\n"
"嚴禁出現「今日無交易數據」或模擬當日盤態。\n\n"
# 帶入 Role & 7 條 Core Execution Rules...
f"# 市場數據\n{tw_section}\n\n{us_section}\n\n{news_section}\n\n"
f"# 投資知識參考\n{knowledge_section}\n\n"
"# 輸出格式\n"
"請依序產出:1.上週回顧 2.美股狀況 3.下週展望 4.操作建議(含倉位與停損位) 5.免責聲明\n"
"❗ 總字數不得超過1000字。必須完整產出到免責聲明。"
)
# 直接呼叫 Gemini API 生成週報...
透過程式碼前處理 (_fmt) 與 7 條 Core Execution Rules 的配合,達成了:
明天(Day 17)我們將深入探討 Post-processing 程式碼強制規則:包含 9 組系統禁止詞自動替換與 Regex 後處理正規化!
明日預告:【Day 17】後處理防線:Post-processing 程式碼強制規則與 9 組禁止詞自動替換