iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0
ChatGPT & Codex

AI 時代的輕量化開發:ChatGPT 打造 LINE 多模態記帳與續訂預警 Agent系列 第 12

[Day 12] AI 不只會聊天:打造 LINE × Gemini × Google Sheets 智慧記帳管線

  • 分享至 

  • xImage
  •  

前言

昨天已經讓 SubWise 能夠透過 Gemini 理解使用者的自然語言,例如輸入「我今天買咖啡花了80元」,Gemini 可以判斷這是一筆消費,並整理成結構化資料:

{
  "type": "expense",
  "category": "Food",
  "amount": 80,
  "item": "咖啡",
  "date": "2026-08-13",
  "note": null
}

但這裡有一個很重要的問題:AI 知道我花了 80 元,那然後呢? 如果每次都只能把結果顯示在 LINE 裡,這還稱不上真正的智慧記帳。

今天的目標,就是把這條資料流真正接起來:
LINE → Gemini AI → Expense JSON → Python 資料驗證 → Google Sheets

讓 SubWise 第一次真正完成「自動記帳」。Day 12 的核心任務有三個:建立 Google Sheets 寫入功能、建立 Expense Service 負責驗證 AI 回傳資料、把整個流程部署到 Render 並透過 LINE 實際測試。


今日實作實錄

一、建立 expense_service,AI 理解與程式驗證分工

為了避免把所有邏輯都塞進 app.py,另外建立 expense_service.py,專門負責「驗證 Gemini 的消費資料 → 呼叫 Google Sheets 寫入」:

def save_expense(data):
    if not data:
        return False
    if data.get("type") != "expense":
        return False

    amount = data.get("amount")
    if amount is None:
        print("❌ 缺少消費金額")
        return False

    if data.get("date") is None:
        print("❌ 缺少消費日期")
        return False

雖然 Gemini 很聰明,但 AI 回傳的資料還是需要 Python 再驗證一次,例如確認金額能轉成數字、且大於 0:

try:
    amount = float(amount)
except (TypeError, ValueError):
    print("❌ 消費金額格式錯誤")
    return False

if amount <= 0:
    print("❌ 消費金額必須大於 0")
    return False

這是今天很重要的架構概念:不要讓 AI 直接決定資料庫裡最後會存什麼——Gemini 負責「理解」→ Python 負責「驗證」→ Google Sheets 負責「儲存」。另外也把 itemnote 整理成單一欄位(例如「咖啡|下午茶」),讓 Google Sheets 的資料更簡潔。

二、本機測試成功

建立 test_save_expense.py,用固定資料測試,執行後成功看到:

🧪 SubWise Expense Service 測試
🚀 開始透過 expense_service 寫入 Google Sheets...
✅ 消費資料已寫入 Google Sheets
📌 測試結果:✅ 測試成功

代表 expense_service → google_sheets → Google Sheets 這條線在本機已經打通。

三、部署到 Render:本機成功 ≠ 雲端成功

把程式部署到 Render 後,一連串問題才真正開始:

問題一:ModuleNotFoundError: No module named 'google'
本機虛擬環境已經安裝 Gemini SDK,但 Render 是重新根據 requirements.txt 建立環境——本機有安裝不代表 Render 有安裝,補上 google-genairequirements.txt 後解決。

問題二:ModuleNotFoundError: No module named 'gspread'
同樣的原因,補上 gspread==6.2.1requirements.txt 後,Render 才正常啟動。

問題三:Render 找不到 credentials.json
因為 credentials.json 被正確地放進 .gitignore(Google Service Account 金鑰不應該上傳到 GitHub),Render 自然也拿不到這個檔案。解決方式是改用 Render 的 Environment Variables,新增 GOOGLE_CREDENTIALS_JSON 存放憑證內容,讓本機繼續用 credentials.json、Render 則透過環境變數取得憑證。這是今天很重要的部署觀念:本機檔案可以存在,但部署環境的機密資料應該透過 Environment Variables 提供。

問題四:Extra data: line 1 column 12 (char 11)
一開始以為是程式邏輯錯誤,後來發現是 Render 裡的 GOOGLE_CREDENTIALS_JSON 貼錯了格式,修正 JSON 內容後解決。

問題五:Gemini 一度回傳 503 UNAVAILABLE
錯誤訊息顯示模型當下處於高流量狀態,這不是程式碼寫錯,重新測試一次後 Gemini 就正常回應了。這也提醒了一件事:第三方 API 發生暫時性錯誤,不一定代表程式有問題,Debug 時要先看清楚錯誤類型。

四、最終測試:LINE → Google Sheets 全流程成功

修正所有問題後,再次透過 LINE 傳送「我今天買咖啡花了80元」,Render Logs 依序顯示收到訊息、交給 Gemini 處理、解析成 JSON、判斷為消費資料、寫入 Google Sheets:

📦 Gemini JSON:{'type': 'expense', 'category': 'Food', 'amount': 80, 'item': '咖啡', 'date': '2026-08-13', 'note': None}
💰 Gemini 已辨識為消費資料
📝 開始寫入 Google Sheets...
✅ 消費資料已寫入 Google Sheets

打開 Google Sheets,真的看到 2026-08-13 | Food | 80 | 咖啡 這筆資料。🎉 成功!


今天遇到的錯誤整理

問題 原因 解決方式
No module named 'google' Render 缺 Gemini SDK 加入 google-genai
No module named 'gspread' Render 缺 Google Sheets 套件 加入 gspread
credentials.json 不存在 金鑰沒有上傳 Render 改用 Environment Variable
Extra data JSON 憑證格式貼錯 修正 GOOGLE_CREDENTIALS_JSON
503 UNAVAILABLE Gemini 暫時高流量 稍後重新測試
本機成功、Render 失敗 本機與部署環境不同 分別處理依賴與機密設定

這也讓我更深刻體會到:部署不是把程式丟上雲端就結束,真正的部署,是要讓程式、依賴、環境變數、外部服務全部一起正常運作。


今日完成

  • 建立 expense_service.py,負責驗證 Gemini 回傳資料
  • 本機測試 expense_service → Google Sheets 寫入流程
  • 修正 Render 缺少 google-genaigspread 套件問題
  • 改用 Environment Variable 提供 Render 端的 Google 憑證
  • 修正 JSON 憑證格式錯誤
  • 完成 LINE → Gemini → expense_service → Google Sheets 全流程實測

今天留下了幾個重要 Commit:19e92ee45d8e2aa6c97f562e52e1333cfcb,完整記錄了今天從「程式跑不起來」到「LINE 真的可以把資料寫進 Google Sheets」的過程。

目前完整的資料管線:
LINE 使用者 → Gemini AI(多模態理解)→ expense service(資料驗證)→ Google Sheets(資料儲存)

這代表 SubWise 已經不只是聊天機器人,開始具備「感知 → 理解 → 判斷 → 執行 → 儲存」的 Agent 雛形。

在 LINE 輸入「我今天買咖啡花了80元」,SubWise 自動完成消費辨識,並將資料寫入 Google Sheets:
https://ithelp.ithome.com.tw/upload/images/20260813/20178527jet0qT9tSz.png


明日預告

明天 Day 13,將把 Day 11 完成的查詢功能也一起接上 LINE Bot,讓「我這個月花多少?」「我有哪些訂閱?」不只是本機測試成功,而是真的能在 LINE 對話中直接使用。我們明天見!


上一篇
[Day 11] 不用翻記帳 App!我讓 AI 幫我一秒查出「這個月花多少」與「Netflix 何時扣款」
下一篇
[Day 13] 讓查帳功能真正上線:把 Query Service 接進 LINE Bot 即時對話
系列文
AI 時代的輕量化開發:ChatGPT 打造 LINE 多模態記帳與續訂預警 Agent16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言