從 Day 03 用 Terraform 建好環境開始,這個系列一路做了合成資料、星狀綱要、多觸點歸因、在 SQL 裡請 Gemini 診斷成效異常、讓 AI 看廣告圖、根據成效打素材草稿、會自己查資料庫的聊天助理、護欄、評測與成本儀表板,最後把助理部署上線,做到可以排程每天早上自己寫好日報再推進 Slack,整套系統呼叫模型與 BigQuery ML 建模型的費用,有逐次紀錄的部分加起來約新台幣 34 元。
今天回頭整理這 28 天踩過的坑,也照昨天的預告交代哪些設計後來證明是對的、哪些當初想得太簡單,整理完發現大部分的坑都是同一個樣子,結果看起來對數字也像真的,只有拿標準答案或後台資料去對才知道哪裡錯,會直接報錯的坑反而好處理。
先講一件會影響讀者的事,Google Cloud 已經公告 gemini-3.6-flash 在 2026 年 11 月 19 日停用,之後的請求會回 HTTP 404,這個系列從 Day 09 起有 12 個程式檔直接呼叫這個模型,11 月 19 日之後照著文章重做的讀者會在這些地方卡住,第 5 章整理怎麼一次找出來、該換成哪個模型、換的時候要注意什麼。
今日核心目標:
gemini-3.6-flash 停用的影響範圍與換模型時要注意的地方整套系統由下往上是四層,坑也照這四層分布。
| 層 | 包含的篇章 | 代表性的坑 |
|---|---|---|
| 資料串接層 | Day 04 到 Day 07 | 金流自訂欄位放中文會驗章失敗、手機開頭的 0 不見、GA4 金額存在整數欄位、UTM 只記在少數事件上 |
| 分析層 | Day 08 到 Day 17 | 歸因規則一換功勞就換人、答案就放在分析資料旁邊、不分受眾直接比結論方向相反、K-means 每次分得不一樣 |
| AI 與助理層 | Day 18 到 Day 24 | 沒有工具就自己編數字、放手寫文案就冒出誇大用語、把個資交出去的是工具 |
| 雲端與成本層 | Day 03、Day 10、Day 20、Day 26 | 預算警報在試用額度期間不會寄、只寫模型名稱就貴一成、模型不一定在當初以為的區域、助理被收掉就忘了前面的對話 |
回頭看這張表有一個共通點,這些坑幾乎都不會報錯,SQL 寫錯查詢當下就失敗,很快就會被修好,真正花時間的是查詢成功、結果也感覺很合理的那一種,越往上層越明顯,到了助理那一層模型回的是一段通順的中文,錯的時候也一樣通順,所以這個系列的檢查也一層一層往上加,從載入時的對帳到事先寫死的判準,一直到程式碼裡的護欄。
Day 04 串綠界金流時,原本想把「加大 80x160 cm」這種尺寸文字放進自訂欄位,後來發現自訂欄位會被算進驗章,只要金流端對中文或半形空白做過任何轉換,整筆付款在感謝頁就會被判定失敗,而且極不容易被發現,最後改成只放尺寸的索引數字。
Day 06 把合成資料載入 BigQuery 時先用自動偵測綱要當對照,0949247891 這種手機號碼被猜成整數,開頭的 0 直接消失,照 GA4 格式產生的訪客 ID 被猜成浮點數,尾數被捨去,這些欄位看起來都有值,要到拿去比對顧客或串接時才會發現對不上,所以五張表最後都寫了明確的綱要。
Day 07 接 GA4 每日匯出時,Live Demo 站兩天 99 個事件就遇到四個沒預期到的狀況,金額 10 筆全部存在整數欄位、浮點數欄位是 0 筆,只讀浮點數欄位的話營收會悄悄歸零,沒有交易的事件 transaction_id 填的是字串 (not set) 而不是空值,99 個事件只有 2 個帶 UTM,要在同一個工作階段裡補齊來源,每日表也不是隔天一早就有,兩天都晚了一天以上才出現。
追蹤數字和後台對不上這件事,Day 05 刻意藏進合成資料當成考題,8 月 27 日網站追蹤到的購買掉到 0 筆,前七天平均是 43.9 筆,後台訂單卻照常有 37 筆,Day 09 請 Gemini 判讀時兩個模型都抓到這是追蹤碼失效而不是沒有生意,關鍵就是同時拿到了網站追蹤和後台訂單兩邊的數字,只看 GA4 的話這一天會被當成業績崩盤。
Day 08 用三種規則分配同一批訂單的功勞,google / cpc 用第一次接觸算分到 295 筆,用最後接觸算分到 670 筆,meta / paid_social 剛好反過來,第一次接觸 610 筆、最後接觸 385 筆,很多後台報表預設看最後點擊,看到搜尋廣告的成交多就把 Meta 的預算挪過去,在這份資料裡 Meta 是第一次接觸分到最多訂單的通路,歸因規則沒講清楚之前,任何一張通路報表都會帶著一個預設立場。
從 Day 11 起我一直對讀者說答案放在獨立的資料集 martech_gt,分析只讀 martech_dw,只要 SQL 裡沒有出現 martech_gt 就代表沒有偷看答案,期中回頭檢查時才發現 Day 07 建素材維度表時,把有沒有人物、按鈕位置、主色、文字多寡四個設計規格欄位一起帶進了 martech_dw,那正是 Day 16 要考 Gemini 的答案,等於考卷旁邊就放著解答,而檢查只認 martech_gt 這幾個字,所以完全沒有發現,Day 15 把這四欄搬進答案資料集,也在文章裡交代了這件事。
Day 17 把 AI 看圖讀出的特徵和轉換率放在一起比,不分受眾直接算時,按鈕放右下的轉換率倍數是 0.907,看起來放右下比較差,改成同通路、同受眾分層之後變成 1.133,方向整個相反,原因是按鈕放右下那一組的工作階段有七成七來自開發新客,沒有右下按鈕的那組只有五成八,開發新客的轉換率本來就比較低,分層後的 1.133 信賴區間是 0.94 到 1.37,也包含 1,兩個數字都不代表按鈕會影響轉換率,這裡要記住的是分不分層連方向都會不一樣,行銷人天天在比素材,混在一起比很可能做出完全相反的決定。
Day 11 的 K-means 分群每重跑一次分法就不一樣,發文前重跑時分法已經和前一天文章用的那一次不同,而那一次的模型已經被覆蓋找不回來,最後用 BigQuery 的時光回溯把當時的結果另存成一張正式表,從此多了一條規矩,會覆蓋共用物件的重建之前先另存副本,文章裡也老實寫了讀者重跑的結果可能和文章不同。
合成資料停在 2026 年 9 月 16 日,Day 22 示範「上週哪支廣告最貴」時真正的上週根本沒有資料,所以助理把資料最後一天的隔天 9 月 17 日當成今天,Day 27 的日報因此每天內容都一樣,Day 28 的流程再加上基準日參數 as_of,要示範某一天的狀況就重播那一天,才能拿 8 月 27 日追蹤碼失效的那一天來測警報。
Day 21 做了一個對照實驗,同一批六個問題分別在給工具與不給工具兩種情況下問 gemini-3.6-flash,不給工具時有幾題模型沒有說查不到,而是直接給出新台幣 125,000 元和 ROAS 3.5,另一題給了 1,250 與 980 筆這種看起來很具體的數字,資料庫裡根本沒有這些數字,更諷刺的是沒有工具的那一組用掉的思考 Token 反而比較多,3,364 對 907,等於多花錢編故事。
Day 18 讓 Gemini 根據成效打素材草稿時也是一樣,題目只寫盡量發揮創意、多強調機能的那一版,6 份草稿有 5 份用了極致、強效、黃金這類誇大用語,同一份題目加上四條規則之後是 0 份,模型照字面把多強調做到最好,規則寫進題目之後這些用語就沒有再出現。
Day 23 的實測裡模型本身比我想像中耐打,藏在活動備註裡的兩則注入指令模型自己都沒有照做,真正把五位顧客的姓名、email 和手機整份交出來的是沒有護欄的查詢工具,模型只是照著工具給的資料回答,所以個資的防線要放在程式碼裡,在進到模型之前就先遮掉,另外測不當內容的那一題 Safety Settings 四個類別一次都沒有擋下,它管的是另一種風險,也擋不住個資外洩。
替 AI 打分數也一樣,Day 24 用規則、兩個評分模型和人分別替 16 則回答打分數,有一則回答把錯的日期講得很肯定,規則和兩個評分模型都給了 1 分,我把它改成 0 分,因為講錯又講得很肯定比老實說查不到更糟,這種判斷要由人來下,再寫回評分標準讓評分模型照著做,這也是我認為最後一關一定要有人的原因。
Day 26 把助理部署到 Cloud Run 之後用瀏覽器實測,第一句答完 4 秒閒置的執行個體就被收掉,第二句由新的執行個體接手,前面的對話全部不見,另一次則是閒置 15 分鐘才被收掉,什麼時候收是個未知,用程式連續發問測試時沒有遇到,換成人打字的速度才遇到,後來改成記憶體只當暫存,找不到就從 BigQuery 的問答紀錄表接回同一個帳號 30 分鐘內的對話。
第二個常見的坑是模型不一定在以為的地方,gemini-3.5-flash-lite 沒有 us-central1 的版本,所以 Day 10 的快取只能建在 global,Day 20 的 gemini-3.1-pro-preview 在 us 位置叫不動,要改寫 global 端點的完整網址,Day 24 的評分服務也要走 global 端點才找得到模型,而 BigQuery 只寫模型名稱時會送到非 global 端點,單價比 global 貴一成,Day 10 發現之後 Day 14 起統一用非 global 單價,同一個系列因此出現兩套單價,Day 09 與 Day 13 的費用後來都更正過。
第三個坑藏在 Day 03,Terraform 建的預算警報原本設成扣掉抵免之後才計算金額,依官方文件的說法,用免費試用額度的讀者在抵免用完之前三段警報都不會寄,這是 10 月 3 日回頭檢查 Day 02、03 時找到的,沒有實際等到警報驗證,當天改成不扣抵免直接計算,也更新了文章。
run.sh 呼叫模型之前先印出最壞情況的金額,輸入 yes 才開始呼叫ops_llm_usage,Day 25 的儀表板直接接這張表gemini-3.5-flash-lite、分類題用 thinking_budget 0 關掉思考、呼叫前先印估價、跑過的不重跑、助理服務每天有花費上限| 階段 | 篇章 | 有紀錄的費用(新台幣) | 花得最多的一篇 |
|---|---|---|---|
| 在 SQL 裡叫 AI | Day 09 到 Day 15 | 約 8.7 元 | Day 10 快取實測約 4.5 元 |
| 看圖與素材 | Day 16 到 Day 20 | 約 16.9 元 | Day 20 三個等級的模型評測 7.60 元 |
| 助理 | Day 21 到 Day 24 | 約 5.8 元 | Day 23 護欄測試 2.54 元 |
| 上線與自動化 | Day 25 到 Day 28 | 約 3.0 元 | Day 26 部署後實測 2.13 元 |
| 合計 | 約 34.4 元 |
Day 16 到 Day 24 用的是 Day 25 儀表板算出來的數字,和當天文章有 0.01 元的四捨五入差,另外有兩筆沒有逐次紀錄,Day 18 的一支 Veo 影片按秒計費,當天估 4 到 6 元,Day 24 的評分服務不回報 Token,估價上限 2.77 元,兩筆加上去約 38 到 43 元,實際金額以帳單為準。
回頭看這張表,費用高低和呼叫次數的關係不大,差別在給模型什麼和用哪個模型,Day 19 同一批比對給截圖花 3.56 元、給文字只要 1.96 元,Day 25 的報表裡 24 次 gemini-3.1-pro-preview 花的錢和走 global 端點的 85 次 gemini-3.6-flash 差不多,另一個要留意的是單價會變,gemini-3.6-flash 和替代它的 gemini-3.8-flash 現在都是到 2026 年底的導入期價格,2027 年起每百萬 Token 輸入與輸出都變成兩倍。
~/ai-driven-martech-pipeline 執行 git pull
gemini-3.6-flash 2026-07-21 發布、2026-11-19 停用,替代模型 gemini-3.8-flash,2026-09-02 發布、已經是正式版、還沒有公布停用日,官方頁列的支援區域有 global 與 us、eu 多區域,Google 的通知信另外也建議了 Gemini 3.5 Flashgemini-3.5-flash-lite 則在「發布後至少可用 12 個月」的那張表,停用日最早是 2027-07-21cd ~/ai-driven-martech-pipeline && grep -rnE "(ENDPOINT|endpoint) *(=|=>) *'gemini-3\.6-flash'|MODEL *= *\"gemini-3\.6-flash\"|JUDGES\", \"gemini-3\.6-flash" --include=*.sql --include=*.py .
這行只找真的會呼叫模型的寫法,預期印出 14 行,分在 12 個檔案。
| 檔案 | 篇章 | 行數 |
|---|---|---|
diagnosis/diagnose.sql |
Day 09 | 1 |
acceptance/blind.sql |
Day 13 | 1 |
multimodal/describe.sql |
Day 14 | 1 |
structured/extract.sql |
Day 15 | 1 |
drafts/generate.sql |
Day 18 | 1 |
consistency/compare.sql |
Day 19 | 2 |
benchmark/bench.sql |
Day 20 | 2 |
agent/ask.py |
Day 21 | 1 |
agent/chat.py |
Day 22 | 1 |
agent/guard_test.py |
Day 23 | 1 |
evaluation/eval_run.py |
Day 24 | 1 |
agent/serve.py |
Day 26 起的助理服務,Day 27、28 的流程透過它呼叫 | 1 |
直接搜尋 gemini-3.6-flash 會找到更多行,它們分成四種,處理方式不一樣。
| 種類 | 例子 | 停用後會怎樣 | 換模型時要做什麼 |
|---|---|---|---|
| 呼叫模型 | 5.2 找到的 14 行 | 回 HTTP 404,那一天的程式跑不下去 | 改成新模型 |
| 讀存好的結果 | agent/tools.py 與 workflows/setup.sql 用 d.model = 'gemini-3.6-flash' 挑 Day 09 那一輪的判讀 |
判讀已經存在表裡,不受影響 | 用新模型重跑 Day 09 時才一起改 |
| 單價與估價 | monitoring/price.sql、各篇的 cost.sql 與 report.sql、eval_run.py 的評分模型單價 |
不影響執行 | 加上新模型的單價 |
| 檢查與評分 | benchmark/check.sql、benchmark/score.sql 寫死要比較的模型名稱 |
不影響執行 | 換模型重跑 Day 20 時一起改,否則檢查會對不上 |
看起來只要把 14 行換掉就好,仔細檢查換模型的流程之後又找到幾個會讓人卡住的地方,所以這一篇不叫讀者自己改,全系列完成之後我會在儲存庫一次換好、實跑確認再推上 GitHub。
run.sh 為了確保實驗的題目與判準沒有在看完結果之後被改過,會檢查幾個檔案有沒有未 commit 的修改,有就直接停下,但模型名稱與端點也寫在這些檔案裡,讀者只是換個模型就會被擋下,.env.example 其實已經留了 GEMINI_MODEL_FLASH 卻沒有程式讀它,完賽後會改成從環境變數讀模型名稱,檢查也改成只提醒,並把當下的版本記進結果表monitoring/run.sh 每次執行都會重建單價表,手動加進去的單價會被洗掉,而助理服務在執行個體第一次處理請求時讀單價,找不到剛好一列就不回答blind.sql 用 CREATE MODEL IF NOT EXISTS,Day 09 已經用 3.6 Flash 建過同名的遠端模型,只改 endpoint 不會生效bq query --use_legacy_sql=false "SELECT model, COUNT(*) AS calls, MAX(DATE(logged_at, 'Asia/Taipei')) AS last_day FROM martech_dw.ops_llm_usage GROUP BY model ORDER BY calls DESC"
這張表從 Day 16 起記錄每一次拿得到 Token 用量的呼叫,查詢在 BigQuery 每月免費額度內,看到 gemini-3.6-flash 的最後一天還在 11 月 19 日之後就代表還有地方沒有換到,沒有出現也不代表都換好了,Day 09 到 Day 15 不寫這張表,Day 21 到 Day 24 的程式只記成功的呼叫,所以還是要搭配 5.2 的指令一起看,5.2 的指令我在儲存庫上實際跑過,結果是 14 行、12 個檔案。
git status,自己改過的檔案用 git stash 收起來或用 git checkout -- 檔案名稱 還原,再執行 git pull,否則 git 會因為本機的修改會被覆蓋而拒絕更新bash monitoring/run.sh 重建單價表,讓新模型的單價進到表裡,再執行 bash scripts/deploy_assistant.sh 重新部署助理服務,Day 27 的日報流程與 Day 28 的 Slack 通知都是透過助理服務呼叫模型,不用另外改如果要重新開始,以下這些項目會在事前就做好:
(not set),載入與攤平時都不要假設型別這 28 天最大的收穫不是哪一個服務的用法,而是學會不相信看起來對的結果,行銷資料一接進來就可能少了開頭的 0、營收悄悄歸零,歸因規則一換功勞就換人,混在一起比的素材結論會整個相反,AI 會編出很具體的數字會照字面把誇大做到最好,雲端服務會照自己的規則收掉執行個體、把請求送到比較貴的端點,這些坑都不會報錯,能抓到它們靠的是和後台的對帳、事先藏好的標準答案還有先寫死的判準與程式碼裡的護欄。
也再提醒一次,gemini-3.6-flash 在 2026 年 11 月 19 日停用,照著這個系列重做的讀者可以先用第 5 章的指令找出自己環境裡用到的地方,換成 gemini-3.8-flash 的程式我會在全系列完成後一次更新到儲存庫並實跑確認。
明日預告:Day 30《整套系統開源交付之後,MarTech 還能怎麼走?》,最後一天交代整個儲存庫怎麼用、當初規劃的樣子和最後完成的樣子差在哪裡,以及這套系統接上真實資料之後還能往哪裡走。