AI 確實可以幫我們排序,但 AI 回傳的結果不能完全相信。
所以今天來檢查 AI 回來的資料到底是不是我們想要的格式。
現在的 /ai/rank-db 有:
result = json.loads(response.text)
return result
我們先改成:
try:
result = json.loads(response.text)
except json.JSONDecodeError:
return {
"error": "AI 回傳的格式不是有效的 JSON"
}, 500
return result
所以完整來說,這一段:
response = client.models.generate_content(
model="gemini-3.5-flash-lite",
contents=prompt
)
result = json.loads(response.text)
return result
改成:
response = client.models.generate_content(
model="gemini-3.5-flash-lite",
contents=prompt
)
try:
result = json.loads(response.text)
except json.JSONDecodeError:
return {
"error": "AI 回傳的格式不是有效的 JSON"
}, 500
return result
這就是我們今天第一個「防呆」。
重新測試http://127.0.0.1:5000/ai/rank-db ,回傳成功就代表能夠驗證成功。
在 /ai/rank-db 裡面,找到:
tasks = cursor.fetchall()
下面接著加:
valid_task_ids = []
for task in tasks:
valid_task_ids.append(task["task_id"])
所以會變成:
tasks = cursor.fetchall()
valid_task_ids = []
for task in tasks:
valid_task_ids.append(task["task_id"])
假設你的資料庫目前有:
1
3
4
5
7
8
9
10
11
13
14
那valid_task_ids就會是:
[1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14]
找到我們剛剛寫好的:
try:
result = json.loads(response.text)
except json.JSONDecodeError:
return {
"error": "AI 回傳的格式不是有效的 JSON"
}, 500
在它下面加:
for item in result:
if item["task_id"] not in valid_task_ids:
return {
"error": "AI 回傳了不存在的 task_id",
"task_id": item["task_id"]
}, 500
因此目前這一段會變成:
try:
result = json.loads(response.text)
except json.JSONDecodeError:
return {
"error": "AI 回傳的格式不是有效的 JSON"
}, 500
for item in result:
if item["task_id"] not in valid_task_ids:
return {
"error": "AI 回傳了不存在的 task_id",
"task_id": item["task_id"]
}, 500
return result
這段就是在拿 AI 的答案一個一個檢查。
例如資料庫裡:[1, 3, 4, 5, 7]
AI 回:
task_id = 4
task_id = 7
task_id = 999
就會發現999不存在,因此會回傳錯誤。
重新測試http://127.0.0.1:5000/ai/rank-db ,回傳成功就代表能夠驗證成功。
假設現在資料庫裡有11個任務,那如果 AI 少回一個,這種情況如果我們沒有檢查,前端可能會以為:「AI 已經幫我排完了。」,但其實它少排了一個任務。
在 task_id 驗證下面繼續加
for item in result:
if item["task_id"] not in valid_task_ids:
return {
"error": "AI 回傳了不存在的 task_id",
"task_id": item["task_id"]
}, 500
在這段下面加入:
# AI 實際回傳了哪些任務
result_task_ids = []
for item in result:
result_task_ids.append(item["task_id"])
# 「資料庫的任務」和「AI 回傳的任務」是不是完全一樣。
# valid_task_ids:資料庫裡應該有哪些任務
if set(result_task_ids) != set(valid_task_ids):
return {
"error": "AI 回傳的任務不完整"
}, 500
重新測試http://127.0.0.1:5000/ai/rank-db ,回傳成功就代表能夠驗證成功。
理想情況下,如果有 11 個任務,應該是:1、2、3、4、5、6、7、8、9、10、11
但 AI 有可能回:1、2、3、3、5、6...
這代表兩個任務都拿到 Priority 3。
在前面的驗證程式下面,繼續加上:
priorities = []
for item in result:
priorities.append(item["priority"])
if len(set(priorities)) != len(priorities):
return {
"error": "AI 回傳的 priority 有重複"
}, 500
重新測試http://127.0.0.1:5000/ai/rank-db ,回傳成功就代表能夠驗證成功。
DAY19 我們沒有去改 AI 的排序邏輯,而是先在 Flask 這邊加一道「檢查關卡」。
Day 19 完成的 4 個驗證
| 驗證 | 檢查什麼 |
|---|---|
| JSON 驗證 | AI 回傳的是不是合法 JSON |
task_id 驗證 |
AI 有沒有產生不存在的任務 |
| 任務完整性 | AI 有沒有漏掉資料庫中的任務 |
priority 驗證 |
AI 有沒有給兩個任務相同的優先順序 |
下一篇我們要:讓 AI 不只是告訴我「誰第一名」,還要告訴我「為什麼」。
這個「理由」變成系統的一部分,讓使用者看得懂 AI 為什麼推薦某個任務,不是只是 reason。