# **單元目標** 這個單元的最終目標是要為我們團隊的防災App做一個AI問答助理的功能,這個功能可以幫忙用戶解決關於天氣的疑難雜症,主要涵蓋範圍有:實時天氣回報、未來天氣預測回報、災害風險評估、以及家人位置的天氣狀況等等,其中有幾項是要配合其他功能進行。 接下來的流程我會秉持"先完成再優化”的原則,先讓程式可以成功解決小問題,再讓可解決的涵蓋範圍擴大,進而完成一整個功能。 # **資料前處理** 由於這個功能會用到非常多關於天氣狀況的資料,所以我選擇用中央氣象局的開放資料API,除了公信力強,還有資料全面的優點。我們可以從這個地方得到很多種類的數據,光是天氣預報的時間區間就有半天、一天和一天半,甚至有一周的選項,同時這些資料中還有包含最高最低溫和濕度等等的數據。 這個階段我想先做簡單的資料前處理,我只擷取了36小時天氣預報資料中的地區和最高溫兩項數據,這份資料會拿來用在接下來的語言模型測試。 首先進行資料前處理: ```python import requests import pandas as pd load_dotenv('/content/.env') CWB_API_KEY = os.getenv("CWB_API_KEY") url = f"https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization={API_KEY}&format=JSON" response=requests.get(url) if response.status_code == 200: data=response.json() print("data get!") else: print("no data.") records=data["records"]["location"] #get the block from .json #transfer the data into a table weather_list=[] for loc in records: locationName = loc["locationName"] for element in loc["weatherElement"]: if element["elementName"]=="MaxT": maxT = element["time"][0]["parameter"]["parameterName"] weather_list.append({ "縣市": locationName, "最大溫度": maxT }) #turn the list into the dataframe df_weather = pd.DataFrame(weather_list) df_weather.head(10) ``` 我們整理出來的資料長這樣: ``` 嘉義縣:最高溫 33°C 新北市:最高溫 33°C 嘉義市:最高溫 34°C 新竹縣:最高溫 35°C 新竹市:最高溫 35°C 臺北市:最高溫 33°C 臺南市:最高溫 32°C 宜蘭縣:最高溫 32°C 苗栗縣:最高溫 35°C 雲林縣:最高溫 33°C 花蓮縣:最高溫 31°C 臺中市:最高溫 33°C 臺東縣:最高溫 32°C 桃園市:最高溫 33°C 南投縣:最高溫 33°C 高雄市:最高溫 32°C 金門縣:最高溫 33°C 屏東縣:最高溫 33°C 基隆市:最高溫 31°C 澎湖縣:最高溫 31°C 彰化縣:最高溫 33°C 連江縣:最高溫 31°C ``` # **語言模型測試** 接下來將處理好的資料當作prompt餵給語言模型,我選擇用Ollama的API,模型是phi3-mini,因為我電腦容量不夠,phi3-mini算是俗擱大碗的語言模型,之後拿到學校資源再來測試openAI的表現如何。 以下是簡單的測試碼,我請phi3-mini依照地區最高溫分析一下台北市的天氣: ```python import requests import json def ask_ollama(prompt): url = "http://localhost:11434/api/generate" payload = { "model": "phi3:mini", "prompt": prompt } try: response = requests.post(url, json=payload, stream=True) response.raise_for_status() print("🤖 Phi-3 Mini 回覆:\n") for line in response.iter_lines(): if line: data = json.loads(line) print(data.get("response", ""), end="", flush=True) print("\n") except requests.exceptions.RequestException as e: print(f"❌ API 錯誤: {e}") if __name__ == "__main__": ask_ollama("嘉義縣:最高溫 33°C 新北市:最高溫 33°C 嘉義市:最高溫 34°C 新竹縣:最高溫 35°C 新竹市:最高溫 35°C 臺北市:最高溫 33°C 臺南市:最高溫 32°C 宜蘭縣:最高溫 32°C 苗栗縣:最高溫 35°C 雲林縣:最高溫 33°C 花蓮縣:最高溫 31°C 臺中市:最高溫 33°C 臺東縣:最高溫 32°C 桃園市:最高溫 33°C 南投縣:最高溫 33°C 高雄市:最高溫 32°C 金門縣:最高溫 33°C 屏東縣:最高溫 33°C 基隆市:最高溫 31°C 澎湖縣:最高溫 31°C 彰化縣:最高溫 33°C 連江縣:最高溫 31°C 請根據氣溫分析一下台北的天氣。") ``` 以下是模型的回覆: ``` 🤖 Phi-3 Mini 回覆: 根據氣溫分析,在台北市的今天,最高溫度預計為33°C,並有可能變動到 32°C到34°C之間。夜間的溫度會下降到27°C到28°C之間。今天是早上時 期,還要注意到寒風可能出現。根據台北品牛裝满的運動場所,最高溫度可 能會有微小的提高,但宜保持中等温度當地選址。在台北市的海上地方,氣 溫可能會有些過分,需要注意紫色和金綠色的空物體辦公室,他們提供了比 較温和的環境。 ``` 可以發現語言模型的回覆內容有非常明顯的瑕疵,到後面甚至還有"42號混凝土"的既視感,最後已經毫無邏輯可言了,所以接下來要想辦法優化語言模型的表現。 # **問題點:prompt的內容** 經過網路爬文和GPT諮詢後,我發現問題出在prompt。我前面處理資料的方法是把每一個地區的天氣特徵抓出來,一次餵給語言模型,原本預期是造一個字典給模型,讓模型可以依照prompt尋找自己需要的數據,沒想到最後卻造成噪音過多,最後導致語言模型已讀亂回,花了一些時間研究我得出一個結論,給一個地區的全面資料,會勝過造一本字典給語言模型。所以接下來要針對prompt進行修改,我在想或許可以反向操作,讓語言模型先理解用戶給的prompt,再去做資料的查找。 接下來的優化方法:語義解析+RAG。