Writing

用歷史資料改提示詞:Trackly 圖片記帳抽取器的證據帳本

AI,Local AI,Product,Notes · 2026-05-06

這次 Trackly 圖片記帳提示詞優化,不是從抽象原則開始,而是從一批歷史記帳資料裡反覆追問同一件事:這筆失敗到底是 prompt 錯、gold 錯,還是驗收規則錯?

我最後採用的工作方式,是把每個失敗都整理成一條證據鏈:

證據原始觀察結論動作
訂單詳情頁缺少「實付」字樣畫面已有商品價格與必付費用,但模型輸出 pendingprompt 過度依賴 final-paid label修改 completed/pending 規則
美團「隨單購買」主訂單 17.5,另有 隨單購買 神券包 合計 ¥9.9同一訂單應合併記帳保留並強化合併金額規則
另一筆美團訂單主訂單 1.3,隨單購買 22.9,DB gold 只有 1.3gold 漏掉附加購買加入 gold override,不改 prompt
酸辣粉截圖42.7 + 1.5 = 44.2,底部又有裁切紅包 -¥13,但 OCR 未完整給出扣減模型可見證據不足,屬可爭論樣本標成 ambiguous_input_evidence,不拿來強改 prompt
titleEmoji / description 退化候選 prompt 輸出固定 💰、空 description、地址塞 title低 token 化犧牲產品欄位補回欄位語義規則

證據一:完成訂單不一定有「實付」標籤

第一條真正改變 prompt 的證據,是「已完成訂單被判成 pending」。有些訂單頁沒有明確寫出「實付」或「合計」,但畫面已經能看到商品價格、服務費、配送費、打包費,以及哪些項目是免收或折扣。模型當時的錯誤不是算錯,而是拒絕記帳。

這導致 prompt 裡加入更強的 completed 判斷:

已下單/已支付/交易詳情頁能由可見價格與必付費用合計時,必須 completed,不得因缺少實付標籤 pending。

這不是某一筆樣本補丁,而是把「可見金額證據」提升到 task-level decision。改完後,該類 targeted repeat 過了 3/3,再跑相鄰 small sample 也維持 20/20

證據二:同一訂單裡的附加購買要合併

第二條證據來自美團「隨單購買」。其中一筆截圖顯示:

已優惠7.5元 ¥17.5
隨單購買
神券包 合計 ¥9.9

如果只取 17.5,就漏掉同一訂單內的附加購買。正確記帳金額是:

17.5 + 9.9 = 27.4

這條證據支持 prompt 裡的合併規則:

同一訂單內同時有主商品結算小計和隨單購買/附加購買合計,兩者都屬本次支出,需相加。

證據三:有些錯誤應該改 gold,不該改 prompt

第三條證據更重要,因為它沒有改 prompt,而是改 gold。另一筆美團資料顯示三種可能解讀:

main order only: 1.3
with-order purchase only: 22.9
main order + with-order purchase: 1.3 + 22.9 = 24.2

候選 prompt 穩定輸出 24.2。DB gold 是 1.3,legacy prompt rerun 則輸出 22.9。人工回看原始消費紀錄後,確認 Trackly 應該記的是 24.2。所以這不是 prompt failure,而是 gold defect。處理方式是加入 gold-overrides.json,而不是把 prompt 改到迎合錯誤 DB gold。

證據四:強證據必須是模型可見的證據

第四條證據後來反過來修正了我對「強證據」的理解。酸辣粉那筆資料裡,人類回看截圖時可以得到一個合理的真實支付公式:

酸辣粉豪華單人餐 42.7
打包費 1.5
美團紅包 -13
42.7 + 1.5 - 13 = 31.2

但這不是一條足夠強的 prompt 證據。模型實際可用的 OCR 只穩定給到商品價與打包費,底部紅包扣減只是在圖像邊緣露出片段,並不是一條可靠、完整、可讀的輸入證據。

所以這筆不能用來要求模型必須輸出 31.2,也不能推導出「底部裁切、final paid 缺失時仍必須 completed」這種過強規則。更合理的處理,是把它標成 ambiguous_input_evidence:如果模型看不清扣減,pending 合理;如果模型只根據 OCR 可見項計算,completed 44.2 合理;如果模型成功讀到 -13completed 31.2 也合理。

這個修正比單純增加一條 prompt 規則更重要:歷史資料不只用來補 prompt,也用來阻止 prompt 被錯誤證據污染。最後保留的是較保守的通用規則:只有清楚可讀的商品/服務價格、必要費用、免收/贈送項與優惠扣減能閉合成加減公式時,才要求 completed;如果費用或扣減被提示但金額不可可靠讀取,就允許 pending

證據五:低 token 不能犧牲產品欄位

最後一組證據是產品欄位退化。幾個候選版本在金額上沒問題,但輸出品質變差:

titleEmoji: 固定 💰
description: 空字串
title: 混入地址或付款資訊
products: 缺失

這些不是裝飾欄位。Trackly 的記帳結果需要可讀、可掃描、可回顧。因此 prompt 補回這些規則:

title 用交易/商品/服務短標題,不放地址、長編號、帳號或冗長明細;
description 收納地址、口味、規格、店名或備註;
titleEmoji 依 title、products 或消費內容選貼切 emoji;
completed 支出不要用 💰 兜底;
有清楚主品、附帶品或免費品時輸出 products/product。

最後形成的處理規則

這次優化最後留下的,不只是一份 prompt,而是一套判斷規則:

失敗類型處理方式
畫面證據清楚,prompt 拒絕或算錯改 prompt
畫面證據清楚,DB gold 錯改 gold override
模型可見證據不足,或 OCR/圖像互相不完整標記 ambiguous_input_evidence 或 unverifiable,不硬補單一標準答案
歷史分類不可信降級為 diagnostic
產品欄位退化補產品語義規則

所以這次真正的工程結論是:歷史資料不能直接當標準答案,但可以當證據來源。每一筆失敗都必須先分類,只有能被模型實際收到的原始畫面/OCR 支持、能泛化、且能改善產品行為的證據,才有資格改 prompt。

最終成績

最後候選 prompt 通過了 1200 筆 functional gate:

指標結果
驗收筆數1200/1200
正確率100%
XML schema OK1200/1200
titleEmoji present1200/1200
titleEmoji non-default1200/1200
description present1200/1200
description non-empty1199/1200
products present1047/1200

成本也明顯下降:

指標Legacy baselineCandidate變化
System prompt tokens35861533-57.25%
Aligned 260 avg prompt/input tokens6890.394837.39-29.80%
Aligned 260 avg total tokens7173.955028.15-29.91%
Aligned 260 avg elapsed29.55s27.12s-8.22%

這個結果可以比較精確地表述為:功能驗收通過,token 成本顯著下降,wall-clock 有改善但沒有宣稱通過 strict 10% elapsed certification。

真正有價值的不是單一分數,而是這次建立了一套可重複使用的證據帳本:什麼改 prompt,什麼改 gold,什麼改驗收規則,什麼不該動。