系列:30 天用 Google AI 打造臺灣防災速報 App(Day 11/30)
「地震時人在浴室怎麼辦?」這類問題不能讓模型憑印象回答,要根據官方的防災指引。做法叫 RAG(Retrieval-Augmented Generation,檢索增強生成):先從一份自己準備的資料裡找出相關段落,再請模型只根據這些段落回答。這份資料就是知識庫。
RAG 分兩天做。今天做第一步:把知識庫的內容整理出來。
| 來源 | 內容 | 塊數 |
|---|---|---|
| 內政部消防署「消防防災館」 | 地震當下,人在各種地方該怎麼做(客廳、床上、浴室、廚房、開車中……) | 13 |
| 中央氣象署(數位科普網、地震百問) | 保命三步驟與行動不便者的做法、規模與震度、餘震、地震能不能預測、地震速報與強震即時警報、海嘯 | 10 |
| 衛生福利部(新聞稿、心理健康司「災難心理重建 Q&A」) | 1925 安心專線、災後常見的身心反應、怎麼照顧自己、什麼時候該找專業協助、怎麼陪伴親友 | 6 |
災後心理這一類是刻意放進來的。地震過後睡不著、一直害怕,也是防災的一部分,知識庫不能只教身體怎麼躲。
授權先確認。 這三個網站的頁尾都有「政府網站資料開放宣告」,內容大致相同:網站上的資料可以無償重製、改作、編輯、公開傳輸,也可以拿來開發產品或服務,不必另外申請,條件是註明出處;機關標誌、商標,以及特別聲明需經同意的影音圖像不在開放範圍內。所以知識庫的每一塊都要帶著來源名稱和原始網址,App 回答時一起顯示。
我沒有把官方頁面的文字整段複製進來。做法是請 AI 讀過每一頁之後,依照頁面的內容整理成重點,步驟和數字都不能改,頁面沒寫的不能加,再由我逐塊核對。原因有三個:網頁原文夾雜導覽列和排版用的文字;同一個情境的內容有時分散在頁面各處;整理過的段落長度比較接近(都在兩百多字以內),檢索的效果比較穩定。
每一塊的樣子:
{
"id": "kb06",
"text": "地震時人在浴室或正在洗澡:浴室地面濕滑,不要急著離開,慌亂衝出去容易滑倒。正在泡澡時不要急著跳出浴缸,把頭壓到低於浴缸邊緣,用雙手或臉盆護住頭頸。留意鏡子,以及櫃子、置物架上的物品掉落。",
"source": "內政部消防署消防防災館",
"url": "https://www.tfdp.com.tw/cht/index.php?code=list&flag=detail&ids=52&article_id=118",
"topic": "地震",
"scenario": "浴室、洗澡中",
"region": "TW",
"fetched": "2026-09-21"
}
text 以外的欄位稱為中繼資料(metadata,也就是描述這筆內容的資料)。source 和 url 用來顯示出處;topic 和 scenario 在後續把文字轉成一串數字(稱為向量,用來比較兩段文字的意思有多接近)時會一起用上;fetched 是整理的日期,官方頁面改版時可以知道哪些要重新核對。region 目前全部是 TW,這個欄位先留著,之後如果加入其他國家的資料,可以用來區分。
這 29 塊寫在一支 Python 程式裡,執行之後存成 chunks.json,之後的檢索程式直接讀這個檔案。整理完的結果:
29 塊;每塊 68–234 字,平均 125 字
來源:消防防災館 13、中央氣象署 10、衛生福利部 6
主題:地震 21、海嘯 2、災後心理 6
把長文件切成小段,稱為切塊(chunking)。常見的切法是每隔固定字數切一刀,但防災指引不適合這樣切。
檢索找到哪幾塊,模型就根據那幾塊回答,所以每一塊要保留一個完整的主題,必要時再合併幾塊來回答。防災問題幾乎都是「〔災害〕發生時,人在〔某個地方〕怎麼辦」,官方指引也是照情境寫的。讓切塊的位置配合情境,找到的那一塊剛好就是完整的做法。如果按字數切,可能「趴下、掩護」在這一塊、「穩住」在下一塊,模型只拿到半個答案。
這份知識庫只涵蓋地震、海嘯和災後心理,共 29 塊。颱風、豪雨、土石流、火災都還沒有。原本規劃要放的日本防災資料,這次也沒有收錄,先把臺灣官方的資料做好。之後擴充颱風、豪雨、土石流、火災這幾類時,再一併評估要收錄哪些日本資料,用來補臺灣指引沒有寫到的細節(例如居家防災儲備清單),收錄的每一塊都會標示是日本資料。
範圍小在這個階段是好事:進入檢索階段時,可以直接測試「問了知識庫沒有的問題,系統會怎麼回答」。
明天 Day 12 把這 29 塊變成可以搜尋的向量,並測試它回答問題的表現。