
「我們必須想像西西弗斯是……成人娛樂主管?!」
如果你是 ChatGPT 的高頻用戶,想必從今年 8 月開始,就碰上過一種神秘現象:ChatGPT 偶爾會在自動生成的會話標題最後,加上一些意義不明的外語單詞,或是來自賭博、色情小廣告的片段。

給中文會話起個英文標題倒是見怪不怪,但在標題里夾帶小廣告確實是全新版本。在國慶假期,我們用一晚上深挖背後可能的技術原理,得出了一些初步判斷:
這不是 ChatGPT 在測試什麼廣告功能,也不存在隱私泄露風險,所以不必擔心哪天標題里出現「瘋狂水世界」;但壞消息是,它的根源可以一直追溯到 2024 年,並且最近焦頭爛額的 OpenAI,似乎無心解決這個影響用戶體驗的技術問題。
註:後文將對部分廣告關鍵詞作隱藏處理。
一場蔓延的「傳染病」
異常字符串泛濫的「傳染病」,最早出現在今年年初的 Codex CLI
。
1 月底,有開發者注意到,當使用 GPT-5.3
模型且上下文很長時,Codex 給出的消息或代碼開始夾雜著中文博彩小廣告,形式上和今天出現在標題末尾的字符別無二致。

2 月份,「傳染病」開始蔓延到 API 端。有人用 GPT5.2-chat-latest 做工具調用時,模型沒執行調用,反而輸出了一串中文和少量泰文的賭博網站廣告詞,且系統提示詞幹淨、沒開聯網搜索。

到 4 月,這一現象在開發者眼中已經司空見慣。有人在開發者社區 LINUX DO
發帖求助稱,GPT 中轉站疑似被掛馬,時不時輸出彩票廣告,回復卻紛紛恭喜他用上了正版 GPT——小廣告就是純血 GPT「在線發牌」的證據。
雖然類似求助帖充斥了 OpenAI 官方支持社區,受害者遍布全球,但在長達半年的時間裡,官方唯一做的事情就是鼓勵「合併討論」、不斷關閉新帖。直至 7 月 25 日,OpenAI 官方支持才第一次正面回應,說「已經了解這一問題」,並表示「預計這一問題會在未來的模型更新中得到解決」。

解決了嗎?答案顯然是:沒有。
如果說 Codex 和 API 的輸出異常還只是局限在小圈子裡流傳,那麼到 8 月中旬,當博彩廣告開始闖入普通用戶的會話標題時,恐怕再也沒有人能夠假裝問題不存在了——除了 OpenAI 自己。

可以說,最近幾個月 OpenAI 確實非常忙碌。GPT-5.6 系列、Astra 模型
、GPT-6 系列
相繼問世,還有 DevDay
發布會和最近 Tibo
喊出的「28 天連更」宣言……但在產品節奏的掩護下,OpenAI 也順利當上了鴕鳥,再未回復過官方社區裡的疑問。
當然,我相信 OpenAI 有在嘗試進行內部優化。至少,隨著模型更新,正文和思維鏈
中的小廣告近乎絕跡;進入到 9 月,標題中出現廣告的頻率總的來說也明顯減少了。
但作為一家匯集了全世界最頂尖研究者的公司,大半年時間過去依然沒能徹底消除小廣告,這一事實似乎暗示著:問題的根源,發生在更深層的地方。
一個標題的誕生歷程
OpenAI 沒有公開說明會話標題的生成機制。不過,技術人員早年發布在 GitHub 上的抓包記錄,留下了一些線索:
在你發起第一輪對話後,網頁端會單獨向 /backend-api/conversation/gen_title/ 發送一個請求,請求中包含了會話 ID 和用於生成標題的模型名稱。隨後,服務端根據會話內容,用指定模型生成標題,並將標題作為對話元數據儲存。
也就是說,在設計上,標題就是獨立於主對話的一次模型調用過程。

不過,這份網頁抓包記錄已經是 2023 年的「文物」,我們無法得知今天的接口名稱和具體調用的標題生成模型。但考慮到標題生成往往快於正文回答,而且存在「正文乾淨、標題被污染」的現象,可以推斷出標題生成使用的或許是一個不同於會話正文的、更輕量化的模型。
這個標題模型有什麼特徵?很幸運,在我日常使用過程中碰到的一個異常標題可以提供一些線索——當時我讓 ChatGPT 生成一組漫畫,但標題模型最終輸出了一整串文字:
創建漫畫 ಚಿತ್ರ展 Adversarial? Wait must Chinese 1-4 words. 「創建線條漫畫」 4 words.
這個標題可以說明幾件事:首先,中間省略主語的「自問自答」環節是 OpenAI 推理模型
思維鏈的典型文風,這表明標題生成模型是一個「想一想再回答」的推理模型;其次,「must Chinese 1-4 words」一定程度上可以倒推出系統輸入標題生成模型的提示詞;最後,本該留在內部思維鏈中的內容也被一併輸出,說明這個模型不能很好地區分「思考」和「回答」的邊界。
還有其他資訊可以佐證最後一點。
在我的另一個會話中,系統最終輸出的異常標題是「讀取文章批註#+#+#+#+」;而此前,有一個日語用戶在官方支持論壇里貼出了他的 Codex 異常回復「このテスト方針で問題ないですか? +#+#+#+#+#+assistant……」。

在這兩個相近案例里,「讀取文章批註」和「このテスト方針で問題ないですか?」(這個測試方案沒問題吧?)已經是完整的標題/句子,按理說,模型此時應該輸出一個特殊的「控制符」來結束回復。但出於未知的原因,模型最終輸出的不是控制符,而是「#+#+#+#+」這個可能被誤認為是控制符的符號詞元
。
換句話說,這個模型經常不知道怎麼合理地結束一項任務。
另一方面,在收集到的異常標題案例中,我還注意到有部分標題的「前半截正常部分」和「後半截異常輸出」之間,存在某種隱秘的語義聯繫。
比如,「解釋西西弗斯幸福 娛樂主管」這個標題里,「幸福」和後面的「娛樂」存在語義關聯;「填寫學歷 մակարդ」後半部分是亞美尼亞語中代表「水平、層級」的詞幹,顯然學歷和層級也有相關性;而在剛剛提到的「創建漫畫 ಚಿತ್ರ展……」中,「ಚಿತ್ರ」是卡納達語的「圖畫」,能銜接上前面的「漫畫」。

綜合以上資訊,我們可以大膽推斷:標題由一個推理模型生成,並且這個推理模型在寫完標題、應該結束生成的那一步上存在問題,經常會導致收尾失敗。
未能成功結束生成的模型,隨後會根據概率繼續輸出「下一個詞」。它可能是和原標題語義相近的外語詞元、詞表里的色情賭博小廣告詞元、被誤認為是控制符的符號詞元,甚至是模型的思維鏈本身,最後形成了我們看見的各種異常標題。
當「弱模型」遇上「髒詞表」
以上猜想,可以解釋為什麼模型生成會出錯,但無法解釋為什麼大多數時候,出錯的結果是輸出「色情賭博小廣告」。
好在,去年一篇入選自然語言處理領域頂會 EMNLP 的論文《Speculating LLMs』 Chinese Training Data Pollution from Their Tokens》(從大語言模型的詞元推測其中文訓練數據污染),系統解答了各種小廣告關鍵詞在 GPT 系列模型中泛濫的原因。

在進一步「診斷」之前,有必要先了解一下常見的大模型工作原理——
我們輸入的提示詞,首先經過「分詞器」(Tokenizer),由它將句子分解成一個個詞元;每個分詞器內部都有一個詞表,它相當於「詞元字典」,會給每個可能出現的詞元都分配一個數字 ID,最終傳入模型的,就是這些數字 ID 構成的數組。

換句話說,核心的語言模型部分,從一開始看到的就是已經被分詞器「消化」過的數組,而不會知道最原始的文字。隨後,語言模型會基於訓練習得的知識,理解這些數組在「語義空間」中的相互聯繫,並組織出新的回答,重新「翻譯」為文字後交給用戶。
問題恰好出在分詞器的「詞表」部分。
從 2024 年 5 月發布的 GPT-4o 開始,OpenAI 將分詞器編碼方案從 `cl100k_base` 換成了新版 `o200k_base`,後者將很多常見的中文詞語和短句加入詞表,讓它們擁有獨立的數字 ID,而不必像以前一樣被切成支離破碎的單字。
但訓練分詞器的團隊似乎沒有意識到,他們用的中文語料里包含了大量從外網抓取的色情、賭博和盜版影視網站數據。
分詞器的訓練方式很簡單:將語料中最經常重複出現的字串合併,定義為一個詞元,並為其分配 ID。偏偏「小廣告」最擅長的事情,就是在多個網站中重複同樣的固定廣告詞組,因此極易被分詞器識別出來。

就這樣,最終做好的 `o200k_base` 詞表中,充斥著海量的小廣告。進一步說,越長的詞元,越是重災區(因為正常語料中很少有重複出現的長詞組)。

論文作者發現,詞表中的 4 字詞元里, 68% 是小廣告;而 6 字以上的詞元,更有 98% 來自廣告。最長的 100 個中文詞元,96 個與賭博、色情或盜版影視相關。未經清洗的數據,最終導致 `o200k_base` 在某種程度上成了「負優化」。

另一方面,不同於分詞器訓練的「粗放」,正式訓練語言模型之前,團隊通常要重新清洗一遍訓練數據,去掉裡面的重複內容和低質量廣告。結果就是,小廣告在詞表里有獨立的詞元身份和數字 ID,但語言模型幾乎從未見過代表這個詞元的數組,找遍上下文都不能理解出這個數組的具體含義。
對模型而言,這只是一個「意義不明」的詞語,和我們看見一個斯瓦西里語詞語沒什麼兩樣——你知道它是詞語,卻不明白它的含義。

關於這一點,你可以親手做一個簡單的實驗來驗證:讓 ChatGPT 重複或解釋「給主人留下些什麼吧」「␣大發快三是不是」這些存在於詞表、卻在模型正式訓練之前被洗掉的詞元,你會發現它開始「已讀亂回」。因為對 GPT 來說,你只是給它發了一個幾近亂碼的詞語。

隨著兩條線索交匯,我們大概可以揭示 ChatGPT 生成小廣告標題的原理了——
首先,是 ChatGPT 用了一個糟糕的標題生成模型,它有時會在標題結束之後停不下來,繼續插入各種語言碎片和亂碼;另外,因為模型本身在清洗過的數據基礎上訓練,它從未見過也解讀不了各種小廣告詞元,於是會將這些詞元統統掃入收納亂碼的「垃圾房」。
而當它出錯,準備在標題最後插入「亂碼」時,會選擇在「垃圾房」里隨手拎出一個詞元;考慮到小廣告詞元在數量上的統治性地位,最終混入標題的,就很可能是小廣告了。
要想解決這個問題,說難也不難,說簡單也不簡單。
最簡便的方法,莫過於制定「事後檢查規則」,多加一道步驟檢查模型生成的標題是否合規,並將不合規的標題打回重新生成。有可能,這正是當前的解決方案,它也恰好能解釋小廣告減少但仍有漏網之魚的現狀。
至於真正「治本」的途徑,還是要重製一個乾淨的詞表——別家詞表乾淨的模型,就從未遭遇此類問題。
但難點在於,詞表和基模是綁定在一起的。更新詞表,意味著整個模型都要重新訓練,而現在的 OpenAI 顯然沒有為了中文用戶體驗而將整個基模推翻重做的動機。
看來,未來一段時間裡,我們都要被迫和小廣告共存了。






