做到 Day 24 為止,這個任務管理 Web App 已經有:
新增任務
編輯任務
刪除任務
任務狀態
分類
到期日
MySQL 儲存
Git 版本控制
Code Review
但有一件事一直還沒真正開始:
AI。
從 Day 25 開始,我要加入這個專案真正和 AI 有關的部分。
不過今天我不打算直接把 AI 接進 Flask,也不會讓 AI 產生的內容直接寫進 MySQL。
今天只做一件事:
先確認 Python 能不能成功呼叫 AI API,並把一個比較大的目標拆成幾個小任務。
原本我的規劃是使用 Claude API,但真正開始實作前,我把方案改成:
Groq API
+
OpenAI-compatible API
+
openai/gpt-oss-20b
Claude Code 還是我開發這個專案時使用的工具。
只是 Web App 未來負責「任務拆解」的 AI,改成透過 Groq 呼叫 openai/gpt-oss-20b。
一開始我先把 Day 25 的範圍限制得很小。
今天不做:
今天只需要做到:
輸入一個大型目標
↓
Python 呼叫 Groq API
↓
openai/gpt-oss-20b 處理
↓
拆成 5~8 個小任務
↓
印在終端機
先證明 API 可以正常使用,再慢慢把它接回原本的 Web App。
這樣如果出問題,也比較容易知道到底是:
API 問題
Python 套件問題
API Key 問題
Prompt 問題
而不是 Flask、MySQL 和 AI 全部混在一起查。
我的專案目前使用:
Python 3.9.13
電腦上雖然另外有 Python 3.14,但我沒有因為要接 AI API 就直接升級整個專案。
這次仍然使用原本的 venv。
Claude Code 檢查套件相容性後,最後在 requirements.txt 加入:
openai==2.47.0
所以現在這個專案會透過 OpenAI Python SDK,去呼叫 Groq 提供的 OpenAI-compatible API。
安裝完成後,我先確認版本:
venv\Scripts\python.exe -c "import openai; print(openai.__version__)"
結果是:
2.47.0
另外也執行:
pip check
確認目前套件之間沒有相依性衝突。
這一步讓我注意到一件事:
可以 pip install
不一定代表:
真的可以在目前 Python 環境正常執行
所以最後還是要真的 import、真的執行,甚至真的呼叫一次 API 才算完成。
Groq API 需要 API Key。
這種 Key 不能直接寫成:
api_key = "真正的 API Key"
如果之後不小心把程式 commit 到 Git,Key 就可能一起被提交。
所以我繼續使用原本專案已經有的 .env。
先到 Groq Console 建立 API Key,再把真正的 Key 放進:
GROQ_API_KEY=自己的真正_API_Key
而 .env.example 只加入:
GROQ_API_KEY=your_groq_api_key
這樣別人看到專案時,知道需要設定 GROQ_API_KEY,但不會看到真正的 Key。
而 .env 本來就已經放在 .gitignore。
所以真正的 API Key 不應該被 Git 追蹤。
這次我沒有直接去改 app.py。
而是在專案根目錄新增:
groq_api_test.py
這個檔案只負責 Day 25 的 API 測試。
也刻意沒有 import:
Flask
db
models
config
因為今天只是驗證 AI API。
目前概念上變成:
ai-task-manager/
│
├─ app.py
├─ db.py
├─ config.py
├─ models/
├─ templates/
├─ static/
│
├─ groq_api_test.py ← Day 25 新增
│
├─ requirements.txt
├─ .env
└─ .env.example
這樣就算 AI 測試程式有問題,也不會影響原本的 Web App。
這次比較容易搞混的地方是:
雖然我使用的是 Groq API,Python 裡卻是:
from openai import OpenAI
接著建立 client:
client = OpenAI(
api_key=groq_api_key,
base_url="<https://api.groq.com/openai/v1>",
)
整個流程其實是:
OpenAI Python SDK
↓
Groq 的 OpenAI-compatible API
↓
openai/gpt-oss-20b
所以:
使用 OpenAI SDK,不代表請求一定是送到 OpenAI 官方 API。
真正送去哪裡,是由:
base_url
決定。
這次 base_url 指向 Groq,所以實際請求是送到 Groq。
這次使用:
openai/gpt-oss-20b
其中:
20B
代表大約 200 億個參數。
目前我要做的事情只是:
一個大目標
↓
拆成 5~8 個小任務
所以先從 20B 開始就夠了,不需要一開始就用更大的模型。
這次呼叫模型時設定:
model="openai/gpt-oss-20b"
另外還有:
reasoning_effort="low"
因為「把目標拆成幾個任務」目前不需要非常高強度的推理。
輸出上限則設定:
max_completion_tokens=1024
一開始有考慮設成 4096,但今天只需要幾個簡短的小任務,所以先使用 1024。
後面的實際測試也證明,目前這個數量很夠。
這次不是單純把使用者輸入直接丟給模型。
程式裡會先透過 System Prompt 告訴 AI 應該怎麼回答,大致要求是:
使用繁體中文。
把使用者提供的大型目標,
拆成 5~8 個可以實際執行的小任務。
每項任務使用編號,
並附上簡短說明。
不要加入多餘的開場白。
接著 User message 才放真正的目標,例如:
我要準備期末專題
概念就是:
System:
你是一個任務拆解助手……
User:
我要準備期末專題
做到這裡,我才比較明顯感覺到 Prompt 不只是:
問 AI 一句話
而是還能先規定:
AI 的角色
回答語言
回答格式
任務數量
內容限制
Day 27 還會再專門調整 Prompt,所以今天先讓基本版本可以正常工作。
測試程式沒有把:
我要準備期末專題
直接寫死在 Python 裡。
而是從命令列讀取。
執行:
venv\Scripts\python.exe groq_api_test.py "我要準備期末專題"
這串指令可以拆成三部分。
第一段:
venv\Scripts\python.exe
代表:
使用這個專案
venv裡的 Python。
也就是目前專案使用的 Python 3.9.13。
第二段:
groq_api_test.py
代表:
執行 Day 25 新增的 API 測試程式。
最後:
"我要準備期末專題"
就是傳給 Python 程式的大型目標。
所以整個流程其實是:
我要準備期末專題
↓
groq_api_test.py
↓
Groq API
↓
openai/gpt-oss-20b
↓
拆解結果
之後如果想換題目,也不用改 Python。
例如:
venv\Scripts\python.exe groq_api_test.py "我要準備英文檢定"
就可以直接測另一個目標。
第一次真的執行:
venv\Scripts\python.exe groq_api_test.py "我要準備期末專題"
終端機顯示:
目標:我要準備期末專題
呼叫中……
API key 無效或沒有權限,請檢查 .env 裡的 GROQ_API_KEY。
第一眼看到當然是:
失敗了。
但這次失敗其實也剛好驗證了錯誤處理。
程式沒有直接丟出一整頁 traceback,而是顯示比較容易理解的:
API key 無效或沒有權限
而且沒有把真正的 API Key 印出來。
所以錯誤處理本身是有工作的。
修正 .env 裡的 API Key 後,我再重新測一次。
再次執行:
venv\Scripts\python.exe groq_api_test.py "我要準備期末專題"
這次成功了。
終端機回傳:
1. 確定專題題目與研究範圍:選定題目並列出主要研究目標與問題
2. 進行文獻回顧與資料蒐集:查閱相關學術資料,整理重要理論與案例
3. 撰寫研究方法與實驗設計:決定採用的研究方法、資料收集與分析工具
4. 執行實驗或資料分析:按設計收集數據並進行處理與統計分析
5. 撰寫報告與製作簡報:整理研究結果,撰寫專題報告與簡報稿
6. 準備答辯與修訂:模擬答辯並根據評審意見修正報告和簡報
7. 確認格式與引用規範:校對文字、引用格式,確保符合學校要求
8. 最終提交與備份:將所有文件整理、備份並按時提交給評審委員會
下面還有這次 API 呼叫的資訊:
--- 資訊 ---
model: openai/gpt-oss-20b
finish_reason: stop
tokens: prompt=160 completion=256 total=416
看到:
finish_reason: stop
代表模型是正常完成回答。
不是因為輸出長度超過限制被強制中斷。
這次第一次自己串 API,也第一次真的看到 token 使用量。
結果是:
prompt=160
completion=256
total=416
先簡單理解就好。prompt:
160
代表這次送給 AI 的內容用了 160 tokens。
completion:
256
代表 AI 產生回答用了 256 tokens。
最後:
total=416
就是:
160 + 256 = 416
也就是這一次 API 請求總共使用的 token。
這也是 API 和平常直接使用聊天介面很不一樣的地方。
自己串 API 時,可以看到每一次請求到底用了多少 token。
第一次成功之後,我又換了一個完全不同的內容:
venv\Scripts\python.exe groq_api_test.py "告訴我種花小技巧"
結果 AI 真的改成輸出種花相關內容:
1. 選擇適合的花種:根據氣候、土壤與光照選擇耐候性強的品種。
2. 準備肥沃土壤:混入堆肥、腐葉土及適量堆肥堆,調整 pH。
3. 安排合理間距:避免植株過密,確保通風與光照充足。
4. 定期澆水與排水:保持土壤濕潤但不積水,並使用排水良好的花盆。
5. 施用平衡肥料:在生長季節每 4–6 週施用微量元素配方肥。
6. 觀察病蟲害:定期檢查葉面,使用有機農藥或天然防治方法。
7. 進行修剪與整形:去除枯枝、過密枝,促進新芽生長。
8. 追蹤花期與再植:記錄開花時間,根據需要進行換盆或翻土。
這次的資訊是:
model: openai/gpt-oss-20b
finish_reason: stop
tokens: prompt=161 completion=271 total=432
這個測試也證明:
不是把第一次的回答寫死
而是真的有經過:
命令列輸入
↓
Python
↓
Groq API
↓
GPT-OSS
↓
新的回答
原本在規劃時有擔心:
max_completion_tokens=1024
會不會太少。
但這兩次實際測試的 completion 分別是:
第一次:256 tokens
第二次:271 tokens
距離 1024 都還很遠。
所以目前「把目標拆成 5~8 個簡短任務」這種用途:
1024 tokens 已經夠用
暫時沒有必要調高。
如果未來真的看到:
finish_reason: length
或回答被截斷,再來調整就好。
這次 groq_api_test.py 不只有成功的流程。
也另外處理幾種常見狀況:
API Key 無效
Rate Limit
API 狀態錯誤
網路連線失敗
沒有設定 GROQ_API_KEY
例如 .env 裡如果完全沒有:
GROQ_API_KEY
程式會直接顯示找不到 GROQ_API_KEY 的提示並結束。
不會繼續發送 API 請求。
所以目前可以分成:
正常情況
→ 呼叫 API
→ 印任務
沒有 Key
→ 直接停止
錯誤 Key
→ 顯示 API Key 錯誤
其他 API / 網路錯誤
→ 顯示對應訊息
比完全不處理 exception 清楚很多。
API 成功後,最後還有一件很重要的事情:
git status
我要確認真正存 API Key 的:
.env
沒有出現在 Git 裡。
Day 25 這次真正修改的是:
.env.example
requirements.txt
groq_api_test.py
CLAUDE.md
而:
.env
不應該出現。
這代表真正的 GROQ_API_KEY 還是只有留在自己的電腦。
這次執行:
git add .
還看到:
warning: LF will be replaced by CRLF
一開始看到 warning,我還以為是不是 git add . 失敗了。
但其實不是。
這只是 Git 在提醒:
目前檔案使用 LF 換行
Windows 之後可能會使用 CRLF
它是:
warning
不是:
error
所以檔案仍然有正常加入 staging area。
之後只要再用:
git status
確認準備提交哪些檔案就可以了。
Day 25 完成後,我也同步更新了 CLAUDE.md。
因為原本專案規劃寫的是:
未來:Anthropic Claude API
但這已經不符合實際狀況。
現在真正採用的是:
Groq API
+
OpenAI-compatible client
+
openai/gpt-oss-20b
所以 CLAUDE.md 裡也同步記錄:
openai==2.47.0
openai/gpt-oss-20b
另外也保留一條限制:
不要自動把 AI API(Groq)相關程式碼加進 Web App,除非我明確要求;獨立測試腳本
groq_api_test.py除外。
因為目前 AI API 已經能獨立執行,但還不希望 Claude Code 自己提前把它塞進 app.py。
這次 Day 25 包含:
Groq API 串接
GPT-OSS 任務拆解測試
requirements.txt
.env.example
groq_api_test.py
CLAUDE.md 更新
所以最後使用:
git add .
git commit -m "完成 Day 25 Groq API 任務拆解"
這樣之後查看 Git 歷史時,也能很明確知道這個 commit 做了什麼。
今天完成的不是:
AI 已經整合進 Web App
目前 Web App 本身其實還沒有 AI 功能。
真正完成的是:
Python
↓
Groq API
↓
openai/gpt-oss-20b
↓
成功產生任務拆解結果
目前可以整理成:
Python 3.9.13 ✓
openai==2.47.0 ✓
Groq API ✓
GROQ_API_KEY ✓
openai/gpt-oss-20b ✓
繁體中文任務拆解 ✓
不同輸入可以得到不同結果 ✓
錯誤 API Key 有處理 ✓
Token 使用量可以取得 ✓
.env 沒有提交 Git ✓
接進 Flask Web App 尚未開始
寫入 MySQL 尚未開始
轉成 Task 資料 尚未開始
這個界線很重要。
Day 25 做到的是:
AI 已經可以回答。
但還沒做到:
AI 的回答可以被 Web App 真正使用。
以前直接使用 ChatGPT 或 Claude 時,我看到的流程很單純:
輸入問題
↓
AI 回答
但這次第一次自己串 API 之後,才發現程式中間其實還有:
Python 程式
↓
讀取 API Key
↓
建立 API Client
↓
指定 API 位址
↓
指定模型
↓
準備 Prompt
↓
送出 Request
↓
收到 Response
↓
取出需要的內容
↓
處理錯誤
↓
查看 Token
現在 AI 雖然已經可以幫我把一個目標拆開,但它回傳的東西仍然只是:
一大段文字
例如:
1. 確定專題題目
2. 蒐集資料
3. 撰寫研究方法
...
這對人來說很好讀。
但對程式來說,下一個問題馬上就出現了:
我要怎麼把這段文字變成真正的 Task?
這就是 Day 26 要處理的事情。
先確認 API 能呼叫、再決定要不要寫進 MySQL,這個切法我覺得對。我自己的經驗是 LLM 拆任務的輸出格式不穩,之後接 Flask 前可以先固定一組壞輸入來測:空回應、非 JSON、少欄位、任務數量過多、標題超長,確認解析層會直接拒絕而不是勉強寫入。這樣換模型(例如從 gpt-oss-20b 換掉)時,也能用同一組測資看行為有沒有變。