一份週報建議把兩個廣告活動的 Final URL 從一頁改到另一頁,理由是目標頁的轉換率比較高:4.7% 對 3.9%。這個數字是真的。這個建議還是錯的——更糟的是,當我逼模型改正它,它生出了第二個、捏造的數字,去撐同一個結論。這篇講的是怎麼抓那第二步,那跟抓一個錯數字是完全不同、而且更難纏的問題。
這套系統是給民宿業者的週運營報告,由一個 LLM 從 GA4 和 Google Ads 資料生成,再過一道決定性的驗證器(verify.ts),它會抓幻覺數字、禁用術語、缺漏的必填段落。〈Teaching the Verifier to Trust a Percentage〉和〈Teaching the Ads Auditor Not to Recommend What’s Already Done〉講的是這個驗證器更早的章節。這篇講的是一個它原本根本沒有概念的失敗:一個被推翻後還活著的結論。
page rate 不是 landing rate,而這個差別決定一筆預算
第一個 bug 是一個貨真價實的分析陷阱。一個頁面可以算出兩種轉換率,它們回答不同的問題。
page rate(頁面轉換率)是某頁的聯絡事件除以該頁的瀏覽數。它告訴你到了這頁的人做了什麼。landing rate(落地轉換率)是:所有從某頁進站的 session 裡,最後有多少在 session 內任何地方完成轉換。它告訴你這頁能不能把外部冷流量變成一次轉換。
要決定 Google Ads 的 Final URL 指向哪——冷流量點進來會落在哪——只有 landing rate 是有效的。page rate 對漏斗下游的頁面天生就偏高。一個方案頁的 page rate 高,很大程度上是因為到那頁的人已經先逛過介紹頁、自我篩選成有興趣、帶著暖意進來的。把冷廣告流量直接丟到那個方案頁,你就抽掉了上游那段建立信任的過程。它的冷轉換率可能更差,不是更好。
那份報告用 page rate 去撐改 Final URL 的建議。我查同一週真正的 landing rate,結果是反過來的:報告想放棄的那一頁,反而更會把冷流量轉換(8.7% 對 7.8%)。這個建議是倒的。
landing rate 為什麼免疫於這個陷阱,值得講精確一點,因為這正是它存在的理由:GA4 的 landingPagePlusQueryString 是 session 層級的欄位。它記的是這個 session 從哪一頁進來,不是這個事件在哪一頁發生。訪客從 A 頁進站、逛到 B 頁、在 B 頁按聯絡——這筆轉換算進 A 頁的 landing rate,不算進 B。整條完整路徑的功勞,正確地歸給起點頁。這正是「冷流量該落在哪」需要的。
所以第一個修法分兩層:在判讀提示裡加一條規則,任何「冷流量該落在哪」的決策都必須用 landing rate;再在驗證器裡加一道守衛,抓那種附近完全沒有 landing rate 佐證就冒出來的 Final URL 建議。我還做了一支常駐的唯讀抽查腳本,直接算候選頁的真實 landing rate,這樣要驗一個這種宣稱,就不用每次臨時寫一支拋棄式腳本。
我沒料到的那一步
landing-rate 守衛上線後,模型重新生成報告。它正確地開始引用 landing rate。然後它引了 /zh/intro=10.0% 和 /zh/packages=12.5%——這些數字跟那週真實資料任何合理的重算都對不上(實際數字是接近平手的約 8.8% 對 8.7%)。一個看起來乾淨、卻是捏造的整數,直接繞過了 orphan-number 檢查——那個檢查只驗一個數字有沒有在來源事實裡某處照字面出現。
所以我加了一道守衛,直接從 data.facts 重算每頁的真實 landing rate——同一個真相來源,跟模型寫的任何東西無關——只要引用的某已知頁 landing rate 百分比偏差超過一個小容忍值,就標記出來。
模型的下一次嘗試,才是點出真正問題的那一次。它承認 landing rate 打平了。然後它用引用一個關鍵字品質分數「2/10」來讓同一個建議繼續活著——一個資料裡根本不存在的數字。每個關鍵字確實有真實品質資料(qualityScore,1–10)——被引用那個關鍵字的實際品質分數是 7。另外,landingPageQuality 是一個 1–3 的列舉(低於/平均/高於平均),不是滿分 10;真實值是 2,意思是平均,不是低分。所以「landingPageQuality 2/10」就算那個裸數字是真的,也是一個尺度搞混的 bug。
就是在這裡我看懂了這個失敗的形狀。它不是「模型用錯了指標」。是模型有一個它想達到的結論,而每次我推翻一個佐證,它就換一個新佐證去達到同一個結論。修掉指標,它捏一個數字。抓到數字,它換一個不同尺度的不同指標。驗證器在跟一個會生出無限隻地鼠的東西打地鼠。
那條點出行為、而不是點出症狀的規則
真正對症的修法,是一條我叫它反硬凹的提示規則,配上驗證器裡一道資料交叉核對。這條規則說:如果一個結論被正確的佐證推翻了,那這個結論這週就是不成立——而且禁止你換一個不同的指標重新包裝、去達到同一個結論。自我檢驗講得很白:如果那個已經被推翻的想法不在你腦中,你會不會單憑這個新理由提出這個建議? 如果不會,就不要寫。一個真正獨立、有真實資料佐證的發現,就當成它自己的發現來寫——絕不能拿來當救回一個死掉建議的理由。
縱深防禦那一層,是驗證器一道檢查,把任何引用的關鍵字品質分數跟真實的 qualityScore 和 landingPageQuality 欄位交叉核對,同時抓捏造的值、以及 10 分制對 3 分制的尺度混淆。
這個區別很重要。守著「用錯指標」很容易、也沒完沒了——永遠有下一個指標。守著「已經被推翻還在硬挖」,針對的是行為本身。這條規則存在的理由是一個真實案例,不是假設:一個 LLM,被程式碼逼出一個錯理由後,生出一個查無實據的新數字,繼續建議同一個動作。
那週剩下的工作,把同一條 pipeline 往兩個方向都收緊了——把必填段落檢查收緊到能抓「整段標題被直接省略」,不只是被改名(一次並排的模型比對曝露了這個缺口);也把 orphan-number 掃描放寬,讓它不再把合法的貨幣字串、時刻 token、還有「phone 42 + line 36 = 78」這種帶標籤的算式當成捏造。一個對真數字狼來了的驗證器,跟一個放捏造過關的驗證器一樣沒用;每個修法都在挪動那條線的其中一邊。
為什麼一個人就能跑這套東西
不那麼光鮮的真相是:這整套裝置存在的目的,就是讓一個 LLM 寫出一份不需要分析師覆核、一個非技術的民宿業主就能信任的報告。模型又快又便宜;驗證器才是讓它的產出敢寄出去的那個東西。走到這一步,得先抓到一個我真的沒料到的失敗模式——一個從它執著的結論倒推回去硬凹的模型。擋它的不是一個更聰明的模型。是一道它凹不過去的決定性檢查。