iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0

Part 2|第 4/30 篇
今日要做的事: 用 AI Studio 測 Vision;把外食與自煮拆成兩條資料流。
今天要解決的目的: Day 2 定好庫存那 0.3 的資料形狀;今天補上外食餐點的紀錄,讓沒開火的日子也能進入 completenessbalance_response

真實流程不是每天打開冰箱才決定吃什麼。沒時間、沒體力就外食;有餘裕,才會打開冰箱讓 DishFlow 幫我組下一餐。


今日任務卡

項目 內容
產出 餐點/冰箱兩支 Prompt、兩條資料流、三輪實測
工具 AI Studio(Gemini 3.1 Pro Preview);便當照 SO 關、冰箱照 SO 開
不使用 Firebase、Storage、Functions、前端
素材 便當 1+冰箱 4;今天實測 3 輪,另 2 張留給 Day 7
指標 completeness 的餐點 tags(外食日也算)、balance_responseno_hallucination

直接輸入,不上雲。 先在零基礎設施下量 Vision,才分得出錯在模型還是之後的 App。


1. 問題:缺的是外食那一格

https://ithelp.ithome.com.tw/upload/images/20260918/20121052GoA0AG2SNq.jpg

圖:Day 2 已定好庫存 0.3 的資料形狀;餐點 tags 0.3 若外食不進系統就是空的。評分仍要算外食日的 tags,不然 balance_response 沒有輸入。

前兩天我一直從「冰箱裡有什麼」出發,但正常人不是每天都有時間和體力煮飯。真實流程更像這樣:

今天有時間、有體力 ──▶ 打開冰箱 ──▶ DishFlow 用庫存規劃自煮
今天沒時間、沒體力 ──▶ 外食/超商 ──▶ 記下吃了什麼,不扣家中庫存

所以外食不是例外模式,也不是「今天沒有使用 DishFlow」。它仍然要留下餐點 tags,算進當天的完整性;之後有空自煮時,系統才知道前幾餐吃了什麼,能往互補方向推薦。差別只在於:外食寫入飲食紀錄,自煮還會動到庫存。

這也表示產品不能要求「每天先拍冰箱」。冰箱照是進貨、清點或定期校正庫存時才需要;外食日只記餐點即可。少一步,才比較像真的生活。

另外,台灣餐桌對英文訓練資料也不友善(隔層便當、滷味、三角飯糰)。拿 salad bowl 的 Prompt 來問,模型會很有禮貌地裝懂。


2. 設計

2.1 兩條資料流

https://ithelp.ithome.com.tw/upload/images/20260918/20121052a3O77abUsF.jpg)

圖:外食只寫 tags、不碰 pantry;自煮還要扣庫存。分錯會誤扣或庫存永遠不清。

所以 food_source 必須是欄位:home | convenience_store | supermarket | eat_out

這張圖畫的是「吃完之後資料往哪裡走」,不是要求使用者每餐都先拍冰箱。使用者先依時間、體力決定外食或自煮;照片辨識負責把結果送進正確的資料流。

2.2 今天要測的五題

  1. 主食/主菜/配菜有沒有分開
  2. 醬色會不會被說成炸
  3. 看不清會不會承認
  4. 認不認得出外食 vs 自煮(該不該扣庫存)
  5. 沒入鏡的格子會不會硬掰

https://ithelp.ithome.com.tw/upload/images/20260918/2012105289ly3D0Tt9.jpg

圖:餐盒+塑膠袋 vs 自家碗盤,視覺線索夠清楚。


3. 實作

3.1 面板與餐點 Prompt

兩種照片、兩套設定:

設定 便當照(餐點) 冰箱照(庫存)
Structured outputs (沿用 Day 2 pantry schema)
Temperature 0 0
Thinking Medium Medium
Tools 全關 全關

便當照要關:今天要看它會不會把醬色講成炸、會不會幫沒入鏡的格子補完。一開 schema,這些裝懂容易被「填滿欄位」蓋掉。
冰箱照要開:Day 2 已經定好 unit enum 與 pantry 欄位,今天直接沿用。Structured outputs 只能固定形狀,不能保證辨識正確;醬料層把味霖、醬油寫成 drink,就是「格式正確、內容錯誤」的例子。

你在看一張台灣餐點照片。

列出:主食、主菜、配菜、烹調方式。
判斷 food_source:外食(一次性餐盒、店家包裝)還是自煮(自家碗盤、鍋具)。
只描述看得到的東西,沒看到的格子不要推測。
不確定的放到 uncertain_items。
不要給營養建議。用繁體中文。

3.2 便當照:過關

https://ithelp.ithome.com.tw/upload/images/20260918/20121052BPEF1cfaMC.jpg

https://ithelp.ithome.com.tw/upload/images/20260918/20121052YwHWxxicUq.png

欄位 輸出
主食 白飯(主菜下方部分露出)
主菜 帶皮禽肉(深褐油亮)
配菜 炒高麗菜、四季豆、豆干
烹調 烤或滷/炒
food_source 外食
uncertain_items 燒鴨或油雞,無法百分百確認

三個重點:沒把醬色當炸;沒幫白飯那格補完;禽肉停在 uncertain。收成:

{
  "slot": "lunch",
  "label": "鴨腿便當",
  "food_source": "eat_out",
  "tags": ["braised", "poultry", "vegetable_present", "sauce_heavy"],
  "uncertain_items": ["烹調:烤或滷", "禽肉:燒鴨或油雞"],
  "needs_confirmation": true
}

braised 就夠:對 balance_response 重要的是「不是炸」。sauce_heavy 不是「鈉高」,只標看得到的。

3.3 冰箱是另一支題,不是每餐流程

https://ithelp.ithome.com.tw/upload/images/20260918/20121052nMuEQYttde.jpg

圖:餐點照=消費紀錄;冰箱照=庫存快照。產品上冰箱是進貨/每週掃,不是每餐全層辨識。今天只做壓力測試。

kind(食材/調味/飲料/非食物)由模型看;priority: staple 由 Rule Engine 對。完整冰箱 Prompt 見文末附錄。

一張一張丟。 一次四張會混層,Day 7 題庫就無法歸因。

截圖常常裁掉回答本體,所以模型輸出也要貼進文章。下面兩段都保留 Structured outputs 實際產生的 JSON,不人工改格式。

3.4 三輪實測

目前結果是便當過、醬料翻車;冷凍海鮮的主要食材辨識過關,但漏掉粉紅色封口夾。

醬料層(翻車)

https://ithelp.ithome.com.tw/upload/images/20260918/20121052LS2ZHwBnOr.jpg

https://ithelp.ithome.com.tw/upload/images/20260918/20121052e9My1Vlbfm.jpg

模型的 Structured outputs 原始 JSON:

{
  "items": [
    {
      "name": "紅蓋罐裝醬料",
      "qty": 1,
      "unit": "each",
      "qty_text": "畫面中清楚可見一個完整的玻璃罐",
      "approx": true,
      "kind": "seasoning",
      "location": "fridge"
    },
    {
      "name": "星巴克蜜桃蘋果優格",
      "qty": 1,
      "unit": "each",
      "qty_text": "畫面中清楚可見一個帶有紙套的杯裝優格",
      "approx": true,
      "kind": "ingredient",
      "location": "fridge"
    },
    {
      "name": "NIPPON PREMIUM 富良野哈密瓜沙瓦",
      "qty": 1,
      "unit": "each",
      "qty_text": "畫面中清楚可見一個易開罐",
      "approx": true,
      "kind": "drink",
      "location": "fridge"
    },
    {
      "name": "紙盒裝飲品",
      "qty": 1,
      "unit": "box",
      "qty_text": "畫面中可見一個帶有圓形瓶蓋的紙盒包裝",
      "approx": true,
      "kind": "drink",
      "location": "fridge"
    },
    {
      "name": "紅蓋寶特瓶飲品",
      "qty": 1,
      "unit": "each",
      "qty_text": "畫面中可見一個完整的寶特瓶",
      "approx": true,
      "kind": "drink",
      "location": "fridge"
    },
    {
      "name": "金黃蓋寶特瓶飲品",
      "qty": 1,
      "unit": "each",
      "qty_text": "畫面中可見一個被部分遮擋的寶特瓶",
      "approx": true,
      "kind": "drink",
      "location": "fridge"
    }
  ],
  "uncertain_items": []
}
實際 模型 判定
香蔥鵝油 紅蓋罐裝醬料/seasoning 半過
優格/沙瓦 品牌正確
牛奶 紙盒裝飲品/drink 半過
味霖、日式醬油 寶特瓶飲品/drink 翻車
uncertain [] 裝懂

味霖/醬油變 drink → 調味料從可用清單消失,leftover_hit 失真。JSON 形狀再漂亮,kind 錯了後面規則也救不回來。

冷凍海鮮(主要食材過關,漏掉一項)

https://ithelp.ithome.com.tw/upload/images/20260918/20121052mcl3nKQN2V.jpg

重新開啟 Structured outputs 後,模型的原始 JSON:

{
  "items": [
    {
      "name": "Kirkland 冷凍生蝦",
      "qty": 1,
      "unit": "bag",
      "qty_text": "畫面左側看到一包藍色包裝的冷凍蝦",
      "approx": true,
      "kind": "ingredient",
      "location": "freezer"
    },
    {
      "name": "生凍花枝排",
      "qty": 1,
      "unit": "bag",
      "qty_text": "畫面右側看到一包透明夾鏈袋裝,標籤寫著生凍花枝排",
      "approx": true,
      "kind": "ingredient",
      "location": "freezer"
    }
  ],
  "uncertain_items": [
    "被蝦子和花枝排擋住的後方物品,因被包裝遮擋無法辨識具體品種。"
  ]
}

蝦(crustacean)與花枝排(mollusk)分開、freezer 正確,後方遮擋物也進了 uncertain。Golden 題最重要的一步成立:過敏只擋蝦、放行花枝排。

但它漏掉畫面中的粉紅色封口夾。這不會污染 pantry,因為夾子本來就不該入庫;仍要記成 Vision 的漏偵測。數量也只到 1 bag,看不出剩餘比例,粗單位仍要人確認。

附帶修正 Day 1:冷凍蝦不會兩天到期;解凍進冷藏才是壓力來源。

3.5 拍照條件會直接打到辨識

今天兩張冰箱照其實已經在考「真實拍攝」,不是棚拍:

條件 這批照片裡長什麼樣 後果
光線 冰箱內燈偏黃/不均,冷凍層更暗 標籤對比差,文字難讀
遮擋 手、封口夾、前後疊放、結霜 品名讀不全,只好猜或裝懂
隨意構圖 紙盒被裁切、瓶子只露蓋子 牛奶變「紙盒裝飲品」、醬油變「金黃蓋飲品」

以後拍給 Vision 的庫存照要更清楚: 單層、正面、標籤朝鏡頭、少用手擋、能開燈就開。壓力測試可以故意拍壞(Day 5/Day 7 題庫需要),但當「正式入庫」的照片,清楚度就是資料品質。隨意拍不是生活感,是在把錯誤寫進 pantry

另兩張題庫(Day 7 再測)
袋裝青菜(硬猜品種?)/花椰菜米(portionMICROWAVE)。原圖:day3-05day3-06

3.6 Day 7 題庫列

day3-02  便當     food_source=eat_out,禽肉 uncertain     沒裝懂
day3-03  醬料層   味霖/醬油→drink,uncertain=[]         裝懂
day3-04  冷凍海鮮 蝦/花枝排分開,漏掉封口夾           沒裝懂
day3-05  袋裝菜   (待測)
day3-06  花椰菜米 (待測)

每列加記:光源、距離、有沒有遮擋標籤。


4. 驗證與翻車

翻車 今天 後果
醬色當炸 晚餐一路往清淡偏
禽肉硬猜 污染 today_meals
調味料→drink leftover_hit 失真
用不確定名裝確定 uncertain 失效
外食認成自煮 誤扣庫存
沒入鏡硬掰 發明白飯比例
看得到的非食物漏列 (粉紅封口夾) 不污染庫存,但代表偵測不完整
光線差/遮擋/裁切 (醬料層尤明顯) 文字讀不到 → 泛稱+kind 猜錯

先改 Prompt,不要 Fine-tune。 下一刀大概是:寶特瓶褐色/淡色液體,優先當調味料。還裝懂就交給 Day 5 的 needs_confirmation。拍照規範跟 Prompt 一樣重要:輸入糊,輸出再漂亮也只是漂亮的錯。

錯一次會污染後面 3~7 天的 balance_summary。照片先放本地 meals/raw/,Cloud Storage 是 Day 10 的事。


5. 今日結論

  1. 外食要進評分。 餐點 tags 佔 0.3;不記外食,balance_response 沒輸入。
  2. 兩條流:外食不扣庫存,自煮要扣。
  3. Structured outputs 只保證形狀,不保證內容;拍照清楚度=資料品質。 醬油仍可能被標成 drink。壓力測試可以拍壞,正式入庫不行。

下一篇: 今天只替冰箱庫存套用 Day 2 的欄位;Day 4 要正式替餐點照設計 Meal JSON,讓 food_source、tags 與 uncertain 都能穩定寫入。


附錄:冰箱 Prompt(完整)

冰箱照請 打開 Structured outputs,欄位對齊下方列表(與 Day 2 unit enum 一致)。Prompt 本文:

你在看一張我家冰箱的照片。

列出畫面中看得到的每一項,每項給我:
- name:品項名稱
- qty + unit:unit 只能用 each / piece / slice / box / pack / bag /
  bunch / handful / fist / palm / cup / tbsp / tsp / ml / portion
- qty_text:你怎麼判斷這個量(例如「拆封剩約一半」)
- approx:一律 true
- kind:ingredient 食材 / seasoning 調味料 / drink 飲料 / non_food 非食物
- location:fridge 或 freezer,從結霜與抽屜位置判斷

規則:
1. 被袋子、包裝或手遮住而認不出來的,不要猜具體品種,放到 uncertain_items。
2. 數量只看得到一部分時,就用看得到的數字,不要推測後面還有幾個。
3. 沒有看到日期就不要編到期日。
4. 不要推薦菜色,也不要給營養建議。

用繁體中文。

上一篇
[Day 2] 先把今天的生活編成 JSON,再決定要不要問模型
下一篇
[Day 4] 餐點照終於進了 JSON,但模型突然不會說「不確定」
系列文
DishFlow AI Agent:用 Google AI 打造 Eat-Cost Balance 的下一餐決策系統6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言