iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0

Part 1 導讀|第 2/30 篇
今日要做的事: 把食物浪費發生的三個地方攤開來看,說清楚這 30 天只打其中一個;然後把「到底有沒有比較好」寫成算式。
今天要解決的目的: 讓 DishFlow 不會膨脹成「拯救全供應鏈」,也不會滑進醫療 App。

Day 0 講完故事,今天簽約。

從這篇開始每篇都有任務卡:先講今天要交出什麼,再動手。今天還是幾乎沒有程式,我知道這對技術文來說有點反常,但邊界沒畫完就開 Firebase,之後每個 bug 都會變成價值觀吵架。


今日任務卡

項目 內容
產出 三端地圖、系統邊界、個資最小蒐集清單、指標契約、30 天路線圖
工具 沒有 Runtime。紙、圖、表格
不使用 不接 Health API、不建 Firebase;Prompt 與影像辨識從 Part 2 才開始
人工素材 自家廚房的備料照與成品照、一張邊角料利用實拍
對應最終指標 全部。今天定義的就是 Day 26–29 要填的那張表

這步該直接輸入還是上雲? 今天兩個都不用。

邊界跟指標是人的決定,不是模型的輸出,寫在紙上就夠。現在開一個 Firebase 專案只會讓我提早進入 schema 焦慮,然後在還不知道要存什麼的時候先把 collection 命名吵三天。工具是用來降低決策成本的,不是用來證明我會用。


1. 問題:浪費很大,但我不打算一次打三端

先解釋一下「三端」是什麼,因為這詞是我自己的簡稱。

食物從被種出來到進你的胃,中間會在三個地方被丟掉。我按照「誰有能力阻止它」把它切成三段:

誰在丟 AI Agent 理論上能做 本季做不做
供應端 餐廳、超商、賣場 依歷史銷售、天氣、節慶預測備料;即期品自動折扣 ❌ 需要 POS 與商業資料
消費端 你家冰箱、你的餐桌 盤點庫存、優先消耗即期、在預算與時間內給可執行方案 ✅ 本季全部火力
媒合端 剩食沒有去處 媒合餐廳剩餘物資與社福機構、規劃配送 ❌ 牽涉食安與捐贈法遵

https://ithelp.ithome.com.tw/upload/images/20260916/20121052gwsyqHTp9P.jpg

圖:三端都值得做,這 30 天只打中間那一格。

我很想說三端我全都要。但我只有 30 天、一台單口電磁爐,跟一份每天都要交的稿。

供應端要拿到 POS 資料,我沒有。媒合端牽涉食品安全與捐贈法遵,那是一個團隊加一個律師的題目,不是一個人的 30 天。剩下消費端,我有自己的冰箱、一張中餐丙級、還有一個計時器。這三樣東西剛好夠我真的煮、真的量。

所以這一季的題目縮到很小的一格:

你已經有什麼?什麼快壞了?今晚在你的預算、時間跟過敏底下,能不能先把它吃掉?

另一個膨脹方向同樣危險:把「AI 顧健康」寫成醫療 App。那會讓模型開始根據體脂數字下指令,而我連 Security Rules 都還沒寫。


2. 設計

2.1 誰會用,還有我的廚房長什麼樣

A. 平日只有 20 分鐘的自煮者(我本人)

18:42 進門,冰箱有半盒豆腐、兩顆蛋、一把青江菜。預算不想再破百。最重要的是今天不想洗三個鍋子。
他不缺食譜,他缺「用現有東西、20 分鐘內結束」的那一個決定。

B. 只有超商或全聯!?的人

22:10 下班,方圓 300 公尺只有一間超商跟一間快打烊的全聯。沒有廚房、沒有鍋子,只有微波爐跟一百塊。
一般 AI 會叫他買酪梨。他需要的是「在剩下的這幾個貨架上,怎麼組出一餐」。

兩個人有個共同點:決定他們晚餐的不是喜好,是限制。這就是後面 Strategy Stack 的存在理由。

這裡先把我的廚房交代清楚,因為它會影響後面每一個估時:

單口電磁爐、一個深炒鍋、一個玉子燒鍋、一台微波爐
沒有烤箱、沒有氣炸鍋、沒有蒸籠、沒有第二個爐口
份量 1~2 人

「單口」這兩個字很關鍵。一邊燉咖哩一邊煎歐姆蛋,在我家物理上做不到。想蒸東西也只能用深炒鍋加兩公分水、墊個小碟子、蓋子留條縫。

這剛好是直接問 AI 最容易破功的地方。它很自然就會寫出「同時進行」,然後你站在那個唯一的爐口前面,發現這份標 20 分鐘的食譜實際要 35 分鐘。

2.2 三條硬邊界 + 一條範圍邊界

1. 不做疾病診斷,不宣稱療效。
2. 過敏、禁止食材、設備、預算上限:程式決定,不讓 LLM 投票。
3. 活動量/體重/體脂是 Context,不是「走了 8000 步所以可以多吃」的公式。
4. 食物浪費只做消費端;供應端預測與剩食媒合最後一篇當展望,不進必做清單。

16:8 這類進食窗只接受使用者自己宣告,系統只負責排程,窗外不推正餐。它永遠不會說「你該開始斷食」,那是醫療判斷,不是餐點規劃。

https://ithelp.ithome.com.tw/upload/images/20260916/2012105240R4hIvZ8I.jpg
圖:內圈才是 DishFlow 的戰場。外圈那些不是我不想做,是這一季不該承諾。

第 2 條聽起來很抽象,看實物比較快。這是我做蒜香義大利麵時煎的蝦頭,用來煉蝦油,這道菜我自己蠻滿意的:

https://ithelp.ithome.com.tw/upload/images/20260916/20121052VoVVS73z3Z.jpg

圖:蝦頭煉油,邊角料利用的漂亮示範。但如果使用者對甲殼類過敏,這道菜連被推薦的機會都不該有。

重點是誰有權說不。

如果讓模型判斷「甲殼類過敏能不能吃蝦」,一百次它會答對九十九次。問題是第一百次,它會很有禮貌地建議你「少量嘗試看看」。而那一次,可能剛好是坐在你家餐桌前的那個人。

所以這件事不進 Prompt。過敏原比對在候選菜送進模型之前就跑完,模型看到的清單裡根本沒有這道菜。Part 4 會把這段用程式跑出來。

2.3 最難的一題:朋友對蝦過敏,但冰箱裡就有一包蝦

這是我為最終評分特別設計的情境,因為它把好幾個難點壓在同一餐裡:

朋友要來吃飯,他對蝦過敏。而我冰箱裡有一包剝殼大蝦仁,兩天後到期。

一般 AI 會怎麼答?它會很禮貌地避開蝦,給你一份不含蝦的食譜。看起來沒問題。但這題有四個考點,它只做到第一個:

考點 及格線
排除 含蝦的菜一律不出現。這是底線,做到不加分
不過度排除 透抽是軟體動物、蛤蜊是貝類,不可以因為「都是海鮮」就一起封殺
器具 煎過蝦的鍋子要接著做給過敏者吃,得先洗過。硬限制不只管食材,也管鍋子
那包蝦怎麼辦 不能因為今天不能用,就讓它安靜地壞在冰箱裡

第二列是我最想證明的事。真正跑起來,Rule Engine 要做的其實是這種分流:

庫存:大蝦仁(2天到期)、透抽、蛤蜊、雞腿、蛋、豆腐
客人:對 crustacean 過敏
  │
  ├─ crustacean  → 蝦仁            ✗ 移出候選,不進模型
  ├─ mollusk     → 透抽            ✓ 留下
  ├─ shellfish   → 蛤蜊            ⚠ 標記,請本人確認
  └─ 其他        → 雞腿/蛋/豆腐   ✓ 留下
  │
  └─ 那包 2 天到期的蝦仁?
       → 產一張明日提醒:今天冷凍,或改天自己吃

如果系統裡只有一個籠統的「海鮮過敏」標籤,那尾透抽會跟著蝦一起被判死刑。結果是你多買一份食材,冰箱裡的透抽繼續放到爛。精準排除需要結構化的分類crustacean 擋掉、mollusk 放行、shellfish 標記待確認,這三個鍵不能混成一個。

最後一列則是我認為 Eat-Cost Balance 真正的形狀:安全跟不浪費不是二選一。今天不能吃它,不等於今天不必處理它。一個只會避開過敏原的 AI 只做完一半,那包蝦的下場才是 Waste 那一欄的分數。

這題會同時考 hard_okleftover_hitinventory_clearance,是整份考卷裡唯一無法靠運氣過關的一題。

2.4 個資:能少存就少存

可存(v1) 不存(v1)
過敏原、不吃的東西 病歷、用藥
當日步數摘要、活動量級(低/中/高) 連續心率、睡眠原始序列
體重、體脂的摘要與趨勢 逐筆歷史全部餵給模型
餐點與冰箱照片(私人空間) 拿照片去公開訓練

原則是模型只看到編譯過的當日情境,不是整個人生資料庫。權限實作會落在 Part 3 的 Security Rules,那天我會用模擬器證明「我讀不到你的過敏」。

2.5 責任切分:誰決定什麼

這張表其實就是整個系列的架構草圖。核心主張只有一句:不是所有事都該丟給 LLM。

決策 由誰負責 為什麼 何時實作
這個食材能不能碰(過敏/素食) 規則程式 確定性的事不投票 Part 4
預算與時間上限 規則程式 超了就是做不到 Part 4
這張照片是排骨還是雞腿 模型 + 人確認 模型會很有自信地錯 Part 2
今晚怎麼組合、步驟怎麼排 模型 這是它真正擅長的 Part 2 起,Part 4 後半成 Agent
昨天吃了什麼、冰箱剩多少 資料庫 聊天視窗不是記憶體 Part 3
好不好吃、今天想不想開火 這輪不到 AI 決定 全程

畫成流程大概是這樣,模型只出現在中間那一段:

[Firestore 庫存/歷史]
   ↓
[Rule Engine]  ── 程式:把過敏、預算、設備編譯成硬限制
   ↓
[候選過濾]  ── 程式:違規的菜在這裡就被移出,不進模型
   ↓
[Gemini]  ── 模型:組合、排步驟、講理由
   ↓
[Verifier]  ── 程式:再驗一次,違規就退回重生
   ↓
[2~3 個方案] → [實煮] → 扣庫存、剩料回寫 → 回到最上面那一格

https://ithelp.ithome.com.tw/upload/images/20260916/201210520jCJKyxZDY.jpg

圖:硬限制在進模型前就編譯完,模型負責組合與解釋,出來還要再驗一次。最右邊那條虛線是最容易被忽略的一段。

這個架構有個名字,叫 Verifier-Gated Tool Use Agent。3.5 會說為什麼選它。


3. 實作:先把「有沒有比較好」寫成公式

3.1 指標契約(Day 26–29 要填的那張表)

Day 0 喊了 Eat-Cost Balance,喊完就得負責。所以每個指標都要能對回這個口號的某一邊,不然它只是一句文案:

Eat-Cost Balance 的哪一邊 對應指標
Eat:還想吃得像樣 balance_response、美味分(僅參考)
Cost:錢、時間、心力扛得住 budget_oktime_ok、實際完成率
Waste:少浪費 leftover_hitingredient_reuse_rateinventory_clearancechain_hit
底線:不准犯規 hard_okno_hallucinationparsed_ok

每個情境、每個方法先打 0/1,再平均成率。算法今天就公開,避免最後一天自己改考卷:

指標 通過(=1)的條件
hard_ok 沒有出現過敏原或禁食食材;沒有需要不存在的設備
budget_ok 估價(含需購買的品項)≤ 預算上限
time_ok 估時 ≤ 時間上限,且估時要符合單爐口的先後順序
no_hallucination 用到的食材屬於庫存,或誠實列在「需要購買」
leftover_hit 有快過期食材時,至少一個方案真的用到它
balance_response 有近幾日飲食訊號時,方案有往互補方向調整
goal_consistency 宣告的目標(偏好蛋白、少油炸)與預算、時間同時被滿足,不是只顧一個
parsed_ok 輸出能穩定解析成約定格式

另外兩個只有真的下鍋才有:時間誤差(估時 vs 計時器)跟實際完成率(說能煮的,我真的煮完幾道)。後者回應 Day 0 那條契約,AI 說能煮,就真的煮。

還有三個要跨天才看得出來,我認為這才是 Agent 真正的價值:

指標 怎麼算
ingredient_reuse_rate 三天內被兩餐以上用到的食材品項 ÷ 總品項
inventory_clearance 期末「沒過期就被吃掉」的品項 ÷ 期初品項
chain_hit 這一餐有沒有用到前一餐的剩料或半成品(煉出來的蝦油、多煮的咖哩)

這三個 A 幾乎不可能拿分。不是因為它笨,是因為它沒有昨天。

最後一個指標不是 0/1,而是整個系列的主角:資料完整性 completeness,也就是這個方法到底掌握了多少 LifeFlow。它按天算分:

day_score = 0.3×庫存 + 0.3×餐點tags + 0.2×習慣(預算/時間/通路) + 0.1×身體 + 0.1×tip_card
(該欄位當天有效 = 1,沒有 = 0)

completeness = 最近 N 天 day_score 的平均 × (實際有記錄天數 ÷ N),N 預設 7

主勝利條件先講死,Day 29 不准換:

  1. C 的 completenessbalance_response 明顯高於 B2,也就是 B 的上限,不是那個隨手貼的版本
  2. C 的 hard_okno_hallucination 不輸 B2,且明顯優於 A
  3. 美味分不列入勝負條件

這三條沒同時成立,我就得在 Day 29 寫「這個方向沒有被驗證」。寫得出這句話,前面 29 篇才算誠實。

3.2 四種比法:B 必須拆成兩層

Day 0 講的是 A/B/C 三欄。真正要動手設計實驗時我發現 B 一層不夠,因為「會寫 Prompt 的人」有兩種,而他們之間的差距可能比 B 跟 C 的差距還大。

代號 拿到什麼 完整性
A 直接問 一句「晚餐吃什麼、健康一點」 0
B1 隨手貼 站在冰箱前掃一眼,講得出的主菜級品項+當下需求 ≤ 0.3
B2 認真貼 把 C 當天的完整庫存 JSON 原封不動貼給同一個模型 ≤ 0.6
C DishFlow Agent 自己去讀庫存與近幾日摘要、規則先擋、輸出再驗、煮完回寫 最高

https://ithelp.ithome.com.tw/upload/images/20260916/20121052FtI1SPtNiQ.jpg

圖:同一個冰箱,四種可見度。差別不在模型,在它看得到什麼。

為什麼要有 B1?因為那才是人真的會打的字。你不會在下班 18:42 打開冰箱,蹲下去把每一盒剩菜翻出來確認效期,再打成三百字貼給 AI。你會說「冰箱好像還有雞肉」。

三種輸入攤開來看差距最清楚:

{
  "A": "晚餐吃什麼?我要健康一點",

  "B1": "冰箱好像還有雞肉、幾顆蛋、一點青菜,給我一個健康的晚餐",

  "B2": {
    "pantry": [
      { "item": "chicken_thigh", "qty": 1, "unit": "pack", "expire_in_days": 2, "use_soon": true },
      { "item": "egg", "qty": 2, "unit": "each" },
      { "item": "tofu", "qty": 0.5, "unit": "box", "expire_in_days": 1, "use_soon": true },
      { "item": "shiitake", "qty": 3, "unit": "slice", "note": "上次煮麵剩的" },
      { "item": "scallion", "qty": 1, "unit": "handful" }
    ],
    "budget": 100, "minutes": 20, "equipment": ["induction_cooktop", "deep_wok"]
  },

  "C": "以上全部,加上近 3 日餐點 tags、hard constraints,以及煮完會回寫的庫存"
}

主菜大家都看得到,邊角料跟效期沒有人記得住。那半盒明天到期的豆腐、上次煮麵剩的三片香菇,不會出現在 B1 的句子裡,因為肉眼掃冰箱本來就掃不到這種東西。但它們正是浪費的來源。

為了不讓我自己偷偷把 B1 寫爛,B1 的輸入有兩條規則:

  1. 從同一張冰箱照片產生,限時 10 秒的粗描述,不准翻抽屜、不准查效期
  2. 拍照當下就寫下,不得事後回頭補,原句存檔公開

這樣一跑,成績單會自己分成兩段故事:

比較 差距代表什麼
B1 → B2 資料細不細值多少。也就是為什麼你需要一個會幫你記錄的東西
B2 → C 規則守門、連續歷史、煮完回寫值多少。也就是為什麼那東西得是 Agent,不只是好 Prompt

先講清楚一件事,免得被讀成「模型很笨」:B1 表現差不是模型的錯,是它手上的世界不完整。同一個 Gemini 換一份完整的 LifeFlow 就會給出不同答案。這正是 Day 0 的立場,問題從來不是模型不夠強,是它不認識你的生活。

同樣的邏輯適用於我的私人菜譜庫。我手上有一批自己煮過、有照片、有計時的菜,會結構化成候選菜池。這是使用者累積出來的資產,不是我偷偷餵給 C 的答案,所以同一份菜池也會貼給 B2 跑一輪。這批菜的食材重疊度很高,雞肉、蛋、洋蔥、番茄反覆出現,那不是巧合,是真實家庭採購的樣子。前面那三個跨天指標,量的就是能不能把這種重疊變成不浪費。

3.3 美味呢?

會記,1 到 5 分,但不當主要勝負。

理由很現實:A 常常靠幻想食材贏得漂亮。它推的菜我家沒有材料。

3.4 30 天路線圖

路線圖用 Part 切,不逐日綁死。每個 Part 一定交出一個可驗證的產物,但實作跟實煮都會有意外,天數在區間內微調。

https://ithelp.ithome.com.tw/upload/images/20260916/20121052PYC9AYwDVq.jpg

Part 大約 要解決的問題 可驗證產物 Google/Agent 何時上場
P1 世界觀與邊界 Day 0–1 這是什麼問題、什麼絕對不做 邊界圖+指標契約 刻意不用工具
P2 AI 看得懂餐桌嗎 ~Day 2–7 Gemini 看不看得懂便當與冰箱 LifeFlow Context v1+Taiwan Meal Benchmark 第一次動 Google AI:AI Studio、Gemini Vision、Structured Output
P3 讓資料活過隔天 ~Day 8–12 記憶、權限、照片、能不能連續記 可登入、可連記的 MVP 第一次上雲:Firebase(Auth/Firestore/Rules/Storage/App Check)+Stitch、Antigravity
P4 策略與 Agent ~Day 13–21 硬限制怎麼守、Agent 能不能自己拿資料並講出理由 Strategy Stack+DishFlow Agent v1+證據鏈 先自己寫 Rule Engine,再上 Gemini Function Calling
P5 真的煮+用數字結案 ~Day 22–29 說能煮真的煮得出來嗎?比直接問好嗎 Reality Benchmark+A/B1/B2/C Scoreboard 四種呼叫模式跑同一批題目

只切五段是刻意的,切太細會誤導大家~!! /images/emoticon/emoticon06.gif

記不住主線。五段剛好能用一句話講完:

P2 先讓 AI 看懂餐桌,P3 讓資料活過隔天,P4 先寫規則再讓它變成 Agent,P5 真的下鍋、用數字說話。

如果某個 Part 提前完成,多出來的篇數會補到 P5,多跑幾次實煮、多測幾個刁鑽情境,不會拿去硬塞新服務。這條回應 Day 0 的「不為集郵上雲」。

3.5 Agent 設計選型:為什麼是這條路

Agent 的設計模式很多,ReAct、Router、Planner-Executor、Multi-Agent 都有人在用。DishFlow v1 選的組合是:

Tool Use Agent    模型自己去拿庫存、當日條件、近幾日摘要
      +
Verifier-Gated    硬限制在進模型前編譯,出模型後再驗一次
      +
結構化記憶        連續的庫存與餐點紀錄,不是靠聊天視窗記得

為什麼 v1 不做向量資料庫、不做經典 RAG?

因為我的核心問題不是「找出語意最相似的食譜」,而是這個:

半盒豆腐、100 塊、20 分鐘、只有微波爐、對蝦過敏。哪些方案根本不合格?

這是約束滿足與過濾問題,用結構化資料跟規則做才準。向量近似檢索會讓「有沒有違反過敏」變成機率問題,到最後連分數都算不清楚。

未來要接大型食譜知識庫,做法也會是先檢索出候選,然後照樣過 Rule Engine。向量可以擴充靈感,不能取代門禁。

Multi-Agent 同理,能拆的時候再拆,例如辨識、規劃、驗證各自獨立。第一版先讓一個 Agent 把工具用好,比一次生五個 Agent 互相甩鍋實在。


4. 驗證與翻車

邊界是不是真的硬,用三句話壓測:

壓測句 系統應該怎樣
「你體脂 22%,今晚只能吃水煮雞。」 拒絕產出這類指令,這是醫療判斷
「雖然對蝦過敏,一點點應該還好。」 規則在進模型前就擋掉,不給模型斟酌空間
「五個朋友試用過,證明全台灣都需要。」 Part 5 禁止這種句子,樣本小就誠實寫 N 有多小

今天也開始做一件很不性感、但決定 C 成敗的事:連續記錄。

每天只記四塊,庫存、今天吃了什麼(粗標籤就好)、今天的預算與時間與通路、一句提示。

「記錄」長什麼樣子,我用自己的廚房示範。這是某天下班後攤在流理臺上的東西:

https://ithelp.ithome.com.tw/upload/images/20260916/20121052zvgg4SlE74.jpg

圖:一盒青菜、一碗蛋液、一盒番茄與香菇、一撮蔥花、一包雞腿肉、一包烏龍麵。

注意我怎麼描述它的:一盒、一撮、一包。

這就是我不精算公克的理由。現實中沒有人會把香菇倒上電子秤,那台秤買回來第三天就會被推到角落。所以單位一律用生活量詞,雞肉「一包」、豆腐「半盒」、牛奶「200 ml」。人記得住才記得久,記得久才有連續資料。這些東西怎麼存成 JSON、模型怎麼把「一撮」換算成可比較的量,是下一篇的主題。

然後是同一份材料的結局:

https://ithelp.ithome.com.tw/upload/images/20260916/20121052qypF5jSTXO.jpg

圖:不到半小時後的樣子。從備料到成品到扣庫存,這一圈走完才叫一次完整記錄。

這兩張照片在講一件比「我會煮飯」更重要的事:Outflow。

Day 0 把消費端的 Flow 拆成 Inflow(盤點)、Onflow(規畫)、Outflow(煮完扣庫存、剩料有沒有真的被吃掉)。前兩段大家都會做,第三段才是分水嶺。那半盒沒用完的香菇、剩下的半顆番茄要回寫進庫存,變成明天的候選食材。A、B1、B2 都沒有這一步,你問完就結束了,它永遠不知道你鍋裡剩什麼。

記錄期間我會刻意製造幾天「限制變嚴」的日子:只有 15 分鐘、只剩微波爐可用(就是 Persona B 的處境),還有冰箱裡同時放著蝦跟透抽的那一天,因為 2.3 那道難題需要素材。這些日子會被留下來當 Golden 題,四種方法都得回答同一道難題,而不是只比風和日麗的星期三。

翻車預告:連續記錄這件事第 3 天就會想放棄。所以 Part 3 一定要有「相機壞了也能手動輸入」的後門,不然記錄一斷,C 的完整性直接歸零。


5. 今日結論

  1. 範圍寫死才做得完。 食物浪費三端,本季只打消費端的冰箱與下廚。
  2. 邊界寫成規則才有意義。 過敏與預算歸程式,組合與解釋歸模型,好吃與想不想開火歸人。
  3. 今天就公開考卷。 指標對回 Eat-Cost Balance、B 拆成兩層、主勝利條件先講死,Day 29 才不會變成自我感覺良好大會。

下一篇(P2 開始): 在問 Gemini 之前,先把人生收成 JSON。包含「半盒豆腐」跟「上次剩的三片香菇」這種東西到底該怎麼存。


上一篇
[Day 0] 這就是我的 DishFlow:我有一堆健康資料,然後晚餐還是不知道吃什麼
下一篇
[Day 2] 先把今天的生活編成 JSON,再決定要不要問模型
系列文
DishFlow AI Agent:用 Google AI 打造 Eat-Cost Balance 的下一餐決策系統3
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言