Part 5|第 29/30 篇
今日要做的事: 回頭看 DishFlow 從一個晚餐問題,走到 Rule Engine、Gemini 推薦與 Firestore 紀錄,整理這段時間真正學到的事。
今天要解決的目的: 看看原本想做的 Eat-Cost Balance,哪些已經有證據,哪些留給最後兩篇來接上。
Day 0 我站在冰箱前面,手邊有步數和體脂,晚餐還是不知道吃什麼。
做到今天,冰箱沒有變聰明。但我至少開始知道,哪些菜不該被推薦、模型為什麼選這道,以及按下推薦後究竟留下了什麼。
不過有個問題還沒解決:如果我真的把這道菜煮完,明天的冰箱知道嗎?

左邊四步已經能在本機按出來。右邊三步還沒有按鈕,留給最後兩篇:一篇接採用、取消和完成,一篇用更新後的冰箱再推薦下一餐。

| 項目 | 內容 |
|---|---|
| 產出 | 一份開發心得、已完成的工程成果,以及最後尚未接通的流程 |
| 回顧 | 9 月的實煮照片、五天回放、16 題 Golden Benchmark、Day 27 的三次真實操作 |
| Google 技術 | Gemini Structured Output、Function Calling、Firebase Auth、Firestore |
| 今天不做 | 新的模型實驗、重煮料理、補上不存在的真人採用數據 |
| 下一步 | 採用/取消/完成 → Firestore Outflow → 下一餐 Context |
一開始想得很完整。
時間、錢、心力、飲食需求、少浪費。如果能把這些事情交給一個 AI Agent,星期三晚上應該就能輕鬆一點。
但真的開始做,碰到的問題都比「AI 要怎麼推薦晚餐」更小。
模型說 15 分鐘,到底從洗菜開始算,還是從開火開始?
朋友對蝦過敏,這件事能不能讓 Gemini 自己決定?
冰箱裡有半盒豆腐,模型推薦了另一道菜,這算符合剩料優先嗎?
還有一題我後來一直放不下:推薦已經出來了,但我根本沒煮,明天的冰箱應不應該少一顆蛋?
這些事情拆開看,像是在寫一堆 Rule、Schema、Validator 和測試。
連續幾天跑 node test.js,畫面確實有點無聊。
不過做完才發現,如果前面沒把這些邊界說清楚,後面的分數就很容易變成自己說了算。
Day 20 原本想量食譜估時和真正下鍋的誤差。
但我不想為了文章重新煮一輪九道菜。
9 月那些菜是真的煮過、吃過,照片都還在。只是當時沒有拿碼表從第一個備料動作開始計時。
所以後來只保留回溯時間格。
照片證明做過,回憶提供大概的時間範圍,沒有碼表就不算精確的 MAE。
這讓系列少了一張漂亮的時間誤差成績單。
現在回頭看,我不後悔。
Day 27 是我很想保留的一天。
前面已經跑過 Golden Benchmark,但這次我真的打開自己做的 Alpha,在 localhost:3027 調整冰箱、時間、預算和設備,再按「幫我決定今晚吃什麼」。
三次輸入是分開的。
我把時間設成 30 分鐘。
蛤蜊剩 1 天,但食譜紀錄是回溯的 57 分鐘。
所以這道菜根本進不了合法候選。
Gemini 最後選了蔥花玉子燒,理由裡還提到候選用不到蛤蜊。tip 則提醒我,蛤蜊只剩 1 天。
這個結果不完美,但我覺得很有意思。
模型知道冰箱有那包蛤蜊,時間規則卻不允許它今天推薦那道料理。
提醒快過期,和真的有辦法在時間內煮完,是兩回事。
歐姆蛋咖哩是我 9 月真的煮過的。
但在這次條件裡,採購要 7 點,中預算上限只有 4 點。
所以它在進 Gemini 前就被拿掉。
結果 Gemini 在合法候選中選了蛤蜊番茄蛋,採購剛好 4 點。
沒有超支。
可是明明勾了少買,最後還是去買原本不在冰箱裡的蛤蜊。
超支這關擋住了。
少買有勾,它還是把 4 點花完。
Hard 只負責不讓它超過上限。少買、先用快過期的、今晚想吃什麼,它不會自動排好。
最後我把設備限制成只有微波爐。
15 道食譜最後只剩微波洋蔥雞肉蛋蓋飯合法。
Gemini 選了它。
另外 14 道是規則先拿掉的。它沒有第二道可以挑。
理由可以寫得很順。不能開火的那關,在進模型之前就過完了。
這三次都寫進 Firestore。
隔天還查得到當時的冰箱、被拿掉的菜、它回的那一道,還有驗證結果。
比畫面上只留一張推薦卡,踏實一點。
五天回放裡,有記憶花了 7 點。
沒記憶花了 12 點。
差在第二天。
第一天兩邊看的是同一個冰箱。
第二天起,有記憶的那組用的是前一天扣完的庫存。
沒記憶的,還拿第一天那份在規劃。
昨天用掉的,今天就比較不會再買一次。
兩邊都還是有東西過期。
這是我鎖好的同一格冰箱,跑一次。家裡有沒有少丟菜,這組數字說不了。
腳本還會把那餐直接當成做完。
我自己不一定會。
看完,可能去買便當。
也可能先按採用,煮到一半又不想煮。
Day 17 把這兩件事拆開了。
adopted 不扣庫存。
complete_cook 才 outflow。
那天測的是本機裡的順序。
Day 27 的頁面還沒有這兩個按鈕。
這段是我現在想補上的。
以後如果還要自己用,我就留這套。
AI Studio 用來試呼叫。
Gemini 在名單裡選一道,順便寫理由。
Firebase 把隔天還要查的東西留下。
推薦做出來之後,後面還有一半在我身上。
我不想為了吃晚餐,再貼一次長 prompt。
也不想看完推薦,自己去 Firestore 把那顆蛋扣掉。
下一篇要少的是這些手動。不再加一個新功能。
這 30 天做完,比較像一套做法。
不像一個會自己管家的助理。
條件要先寫下來。
結果要留得下來查。
模型說的,和程式算過的,要分開。
開頭那張圖,右邊三步還沒有按鈕。
採用或取消,是我決定的。
採用的時候,庫存不動。
取消,也不能扣。
真的煮完,才 outflow。
明天打開的冰箱,得是扣完之後的那一份。
Day 17 有這個順序。
Day 22 的腳本會直接把餐當成煮完。
頁面上還沒接起來。
這兩件事分兩篇做。
明天如果還讀到昨天的冰箱,今天的推薦就是對著錯的庫存在說話。
模型不能替沒發生的事改庫存。
推薦只是建議。
採用只是先記下來。
煮完才算吃過。
接下來兩篇:
鍋子還是要洗。
下次打開冰箱,至少不用再跟它解釋,昨天那顆蛋到底吃了沒有。