[CODE]

那個把你最想要的訂單擋在門外的否定字

否定字的傷害天生看不見——它擋掉的查詢從不出現在任何報表裡。這篇講一個兄弟帳號怎麼變成揭穿它的對照組,以及為什麼「東西存在」不等於「東西在生效」。

1 min read AI 生成
google-ads automation typescript bnb ai

有一個帳號把「20人」「30人」設成廣泛比對的否定字。設的那天邏輯是對的:A 館最多住十五人,一團二十人服務不了,把查詢擋掉、省下點擊。

問題是兩棟可以合訂——十五加十八是三十三——而兩棟合訂正是業主最想接的訂單類型。同一時間,隔壁那個從沒設這兩個否定字的兄弟帳號,每個月在同樣的查詢上帶進 5.5 次轉換。同一個市場、同一個業主、相反的結果。一棟住不下,兩棟住得下。否定字不知道這個差別。

沒有人看得見這個損失。這就是整件事的核心,也是這將近兩週工作貫穿始終的那條線。

否定字的傷害是天生看不見的

廣告帳號裡其他每一種錯誤都會留下痕跡。某個爛關鍵字花太多錢,花費欄會告訴你。廣告指到錯的頁面,跳出率會告訴你。但否定字是在查詢還沒產生任何曝光之前就把它擋掉——所以它讓你損失的東西從不出現在任何報表裡,因為從報表的角度看,那個需求根本不存在。

這不是什麼罕見的邊角案例。這是這道防護的預設行為,而它讓錯的否定字和對的否定字看起來永遠一模一樣。加一個對的,你的垃圾流量下降。加一個錯的,你的垃圾流量下降而且一筆你本來會接到的訂單默默消失。從帳號內部看,這兩者完全無法分辨。

找出這個傷害的唯一辦法,是去看一個這個否定字沒有生效的地方。這種地方剛好只有兩個。

第一個是另一個帳號。如果 A 帳號有一個 B 帳號沒有的否定字,那 B 帳號那些會轉換的搜尋字,就是 A 正在丟掉什麼的即時畫面。B 是 A 沒辦法為自己當的對照組。「20人/30人」的損失能被發現,靠的根本不是分析那個出問題的帳號,而是拿它跟沒出問題的那個比對。

第二個是同一個帳號裡的漏接。否定字只擋它字面上比對到的查詢。如果「恆春泳池民宿」這個查詢因為觸發了另一個關鍵字而仍然有轉換,那你就有證據證明需求是真的——即使你正打算把「泳池」整個設成否定字。停掉一個零轉換的關鍵字,跟封死一整類查詢,是兩回事:前者是放棄一注,後者是把整條路堵死。

我把這兩個交叉比對做成了一支唯讀的稽核工具。對每個帳號裡的每一個否定字,它去兄弟帳號裡找那些會轉換、而這個否定字本來會擋掉的搜尋字;也在同一帳號裡找漏出來的轉換。它只回答一個問題:如果這個否定字不在,我們會看到什麼?

AI 一直拿上個月的數據,去否決今天早上才定的策略

同樣的盲點還有第二張臉,出現在文案產生器上。一天之內連續三次,寫廣告文案的 LLM 想砍掉某個關鍵字,理由是它「沒有轉換數據」——但那個字是同一天早上、幾小時前才買進來的,就是為了搶一個競品帳號正在贏的字。零數據不是對這個字價值的判決,是對這個字年紀的判決。

這是個會自己閉合的陷阱:新字沒有文案 → 永遠跑不出曝光 → 永遠沒有數據 → 被判沒價值刪掉 → 永遠沒有文案。這個自我實現的預言兩個方向都跑得通——被擋掉的查詢看起來像不存在的需求,剛買進的新字看起來像失敗的需求。兩個是同一種錯覺:沒有訊號被讀成沒有價值

修法是把「已經上線、但還沒有歷史」的字單獨、明確地列給模型,並禁止它把這種沉默當成判決。我還得寫一個每站專屬的文案紅線檔——一份產生器每次跑之前必讀的硬約束——因為那個模型一旦有了「要避讓兄弟帳號主力關鍵字」的規則,就把它誤用到了產品事實上。它不敢寫「五房包棟可住15人」,理由是「15人」是兄弟帳號的主力字。但避讓適用於你出價去搶的東西,不適用於你是什麼。一個住得下十五人的民宿,不能因為另一個帳號也買了那個字,就不敢說自己住得下十五人。

規則疊到第三層,模型就開始從自己的推導再往下推導,每一步都離地面更遠。所以我現在畫的界線是:LLM 適合拿真實數據去優化既有文案,不適合執行一個今天才決定、數據還不存在的新策略。後者用手寫定稿,從檔案讀進來,不用產生。

「東西存在」不等於「東西在生效」——這個我一天之內錯了三次

這個原則最深的版本根本跟關鍵字無關。它講的是:你以為你查過某件事,其實只查了它的其中一層。

一天之內我犯了同一類錯誤三次,每一次都差點導致錯誤的操作:

我宣稱有一條孤兒 sitelink 正在把付費點擊送去別家民宿的網站。並沒有——那條素材存在於素材庫,但沒掛在任何一個放送層上,所以它一毛錢都花不了。我看了素材,沒看那三張決定素材有沒有被連結的表——活動層、帳戶層、廣告群組層。

我宣稱全艦隊的否定字清單都沒生效。並沒有——每一份都掛在帳號層、運作正常。我查了一個連結層,漏掉了它們真正所在的那一層。

然後我在一支工具裡寫下「PMax 不支援共用否定字清單」。它支援——有一個帳號的 PMax 活動就掛著這樣一份清單。我憑對這個 API 行為的印象把它排除掉,根本沒去查。

在 Google Ads API 裡,「資源存在」和「資源在哪一層生效」是不同的表,而且資源生效的地方通常不只一個。素材要查三個連結層。否定字要查四層——帳號、共用清單、活動、廣告群組。受眾訊號要查兩層。只查一層就會誤判;這不是風險,是必然。

最難堪的是:我為了稽核否定字有沒有生效而寫的那支工具,自己就帶著同一個 bug——它只查一層,會把整個艦隊都宣判成失效。一支存在目的就是檢查東西有沒有在運作的工具,因為只看一個地方而失敗了。所以我對人和對機器都寫下同一條規矩:在宣稱任何廣告設定生效或沒生效之前,把它可能掛載的每一層都查過。查不到就說「查不到」,永遠不要說「沒有」。而且不要憑對某個 API 行為的印象下判斷——去查、去實測,不然就老實說這是猜的。

為什麼這件事現在才有

這裡面沒有一樣東西——一個交叉比對六個帳號、找出被隱形擋掉的需求的唯讀稽核;一個知道哪些關鍵字太年輕不能判的文案產生器;一套動手之前先查每一個掛載層的紀律——幾年前會為一群小民宿做。不是沒有人想做,而是這筆帳從來划不來。這種深度的跨帳號廣告清潔,本來是一個全職分析師的工作,沒有哪個民宿的預算請得起。它現在存在,是因為 AI 把建工具、跑工具的成本壓到了一組小客戶真的扛得起的程度。

但讓隱形問題變得更尖銳、而不是更緩和的,也正是同一個 AI——因為一個被叫去「移除沒有轉換的關鍵字」的模型,會很有自信地把那個自我實現的預言大規模執行。必須留在人手上的判斷是這一個:這個零,是一個判決,還是一個我因為沒去看答案所在的地方、自己造出來的空缺?

那個擋掉三十三人合訂訂單的否定字,已經跑了好幾週,讓業主一直損失他們最想要的訂單,而它在任何一個報表看得到的地方,都沒有留下一絲痕跡。