Claude 生成下一個字的時候,本來就要在幾個語意相近的候選詞之間選一個——浮水印沒有讓候選詞變少,也沒有換掉哪個字會出現,它換的是「選哪一個」這一步用的骰子。
浮水印沒有改字,改的是抽樣的骰子
看完這篇你會知道一件事:Anthropic 幫 Claude 文字輸出加上浮水印,用的不是換詞、也不是調字頻,而是把生成過程裡「挑下一個字」這一步用的隨機來源,換成一個由密鑰與前文算出的偽隨機分數——這套技術是 Google DeepMind 在 2024 年 Nature 論文發表的 SynthID-Text 的一個版本。文章會從多數人對「文字浮水印」的錯誤直覺講起,講到分數怎麼被塞進取樣這一步,再具體看它在哪些情況會失靈:事實性句子、短樣本、被大幅改寫的文字。
「換詞」以外的浮水印,長什麼樣子
多數人聽到「文字浮水印」,腦中浮現的畫面通常是換詞——把某些字換成比較少見的同義詞,或者調整某些字出現的頻率,讓統計上抓得到痕跡。這套直覺不是憑空來的,圖片浮水印、音訊浮水印確實常常走「改一點點內容,換取可偵測的痕跡」這條路線。但 Anthropic 說明 Claude 文字浮水印時,講的是另一件事:「Watermarking does not impact the quality of Claude's output. To a reader, a watermarked response is indistinguishable from an unwatermarked one.」——浮水印前後的輸出,讀者肉眼分不出差別。Anthropic 自己內部測試的結論也是同一個方向:「no impact of watermarking on the content, level of creativity, or readability of Claude's text」。這句話的源頭其實在上游——Claude 的文字浮水印是 SynthID-Text 的一個下游版本,而 SynthID-Text 本身講的也是同一件事:「without compromising the quality, accuracy, creativity or speed of the text generation」,下游沿用的正是上游這條技術路線一路傳下來的同一個性質,不是另外一個獨立來源給出的佐證。
Support 頁面用另一種措辭講同一件事:「it weaves an imperceptible watermark directly into the text itself. You won't see it, and it doesn't change the meaning, quality, or readability」——浮水印是織進文字本身的,不是外掛在檔案上的東西。這裡要先岔開一句:Anthropic 另外還有一層完全不同的機制,遵循的是「the Coalition for Content Provenance and Authenticity (C2PA) open standard」,掛在檔案格式上簽章,格式轉換、重新存檔、截圖都會把它洗掉。這篇要講的文字浮水印是另一回事,它嵌在文字的統計特徵裡,跟檔案格式無關——後面會看到它真正會失效的條件,跟 C2PA 那層完全不一樣。
C2PA 中繼資料會在什麼情況下不見,support 頁面說得具體:「format conversion, re-saving, screenshots, or other means」——任何動到檔案容器格式的操作都可能把它洗掉。文字浮水印完全不靠檔案容器,它嵌在文字本身的統計特徵裡,只要文字內容原封不動地存在,浮水印訊號就還在。這也是後面要講的「失效條件」,跟 C2PA 的失效條件完全不是同一組。
為什麼「換詞」這套直覺撐不住
如果浮水印真的是換詞或調頻率,馬上會撞上兩個問題。第一,換詞這件事本身容易被讀出來——換詞的規則越系統化,人多讀幾段就會覺得選字怪怪的,「肉眼分不出差別」這句話立刻站不住。第二,換詞或調頻率這條路線得靠犧牲品質換偵測強度:換成比較少見的同義詞,句子自然度會下降;調整字頻,長文一定會露出某種人工痕跡。Anthropic 的說法剛好是反過來——「Watermarking doesn't require extra tokens, and will not be more expensive」,另外「Watermarking carries no identifying information and can't be traced to a specific person, organization, or chat」——不多花 token、不多花錢、也不帶任何可以追人的資訊。這三句放在一起在說一件事:真正的機制完全不碰「選了哪個詞」這個結果,它動的是選詞之前的那一步。
這兩件事背後其實是同一種工程直覺:任何要靠「多做一件事」才能運作的浮水印方案,都會在某個地方留下代價——多算一輪要多花運算時間,多吐幾個字要多花頻寬,事後補簽章要多存一份中繼資料。Anthropic 選的路線刻意避開這整類代價,因為它動的不是生成完之後的加工,是生成當下那一次隨機數呼叫本身。這也代表想繞過浮水印,靠的不是找出並刪掉某個標記字元——沒有單一字元可以刪。要讓浮水印訊號變弱,主要的路是換掉夠多原本由 Claude 選出的字,這正是後面要展開的「大幅改寫會讓訊號變弱」的原因。
骰子換了,牌沒換
LLM 生成一個字,本來的流程是:模型先給出一份候選詞分佈,接著用一個隨機數決定要從這份分佈裡抽出哪一個。這一步的隨機數平常是任意來源——系統熵、PRNG 種子,跟這個字本身、跟這段對話都無關。Anthropic 說明機制的原句是:「Instead of using an arbitrary random number generator to pick the next word, watermarking uses the key and a few words that come before to settle what word the model should pick.」翻成白話:拿掉那個任意亂數源,換成用一把密鑰加上前文脈絡算出來的偽隨機值來決定選哪個字。緊接著那句話講得更精準:「choices are still made at random, but the source of the randomness is different」——選字這個動作看起來還是隨機的,變的只是隨機性從哪裡來。
合理的推測是,金鑰之外還要拉進前文,是為了不讓浮水印變成一張可以對照破解的密碼表——如果只靠金鑰決定,同一個位置永遠會選中同一個字,等於是一份固定對照表;把前文脈絡也算進去之後,同一把金鑰在不同上下文裡選出的字會不一樣,想反推出金鑰,得先掌握完整的生成脈絡。
點一下或滑鼠停留看用語解釋 · 3 個詞
每一步生成,模型都先給出一份候選詞分佈模型對「下一個字該選誰」給出的機率排序,例如「雨」0.80、「雷雨」0.15、「陣雨」0.05。浮水印完全不動這份分佈本身。,接著把前文脈絡目前為止已經生成的最後幾個字。同一把金鑰配上不同的前文,會算出不同的雜湊值。跟金鑰一起丟進雜湊函式,替每個候選詞算出一個分數介於 0 到 1 之間、由金鑰與前文決定的偽隨機值,純粹是偵測時「這個字算不算數」的權重,不代表任何語意。,分數高的候選詞被選中的機率就被拉高——這正是骰子被換掉的那一步。
這也是為什麼浮水印不會佔用文字裡一個額外的欄位或記號——它不藏在某個特定位置,而是藏在每一步「為什麼選這個字、不選那個字」的統計傾向裡。單獨看一個字看不出任何端倪,需要把一整段文字的分數加總起來看,這條線才會現形。
這套「在取樣端動手腳」的技術路線不是 Anthropic 自己發明的。Anthropic 直接寫明:「Claude's text watermark is a version of the SynthID-Text approach published by Google DeepMind in a Nature paper in 2024」,往前追,這條技術系譜還可以接到「a family of approaches that go back to a proposal by Scott Aaronson in 2022」。DeepMind 自己對機制的描述用詞更精確一層:「SynthID is designed to embed imperceptible watermarks directly into the text generation process. It does this by introducing additional information in the token distribution at the point of generation by modulating the likelihood of tokens being generated.」——不是換掉候選詞,是在生成當下調整候選詞被選中的機率。偵測端要做的事,DeepMind 講得也很直接:「This pattern of scores is compared with the expected pattern of scores for watermarked and unwatermarked text, helping SynthID detect if an AI tool generated the text.」拿一整段文字算出來的分數模式,去跟「有浮水印」和「沒浮水印」兩種預期模式比對——不是從文字裡解碼出一串隱藏訊息,是看這段文字的選字習慣統計上偏不偏。
取樣端跟偵測端是兩個獨立的系統:生成的時候,模型只需要知道金鑰跟前文;偵測的時候,偵測端需要同一把金鑰,把整段文字重新跑一次分數計算再比對,這代表偵測必須掌握生成時用的那把金鑰。沒有金鑰,光看文字本身猜不出浮水印藏在哪裡——這正是為什麼偵測機制的細節,現在還沒有辦法只靠讀這篇文章就自己兜出來。
同一份候選詞表,兩種骰子怎麼分道揚鑣
把上面這段話拆成可以動手看的東西,會更清楚。下面這個模擬用同一句話的六個生成步驟——每一步都給出三個候選詞、各自的機率——分別跑一般取樣跟浮水印取樣兩條路徑。兩條路徑用的候選詞表完全一樣,差別只在「選哪一個」用的骰子不同:一般取樣的骰子是真隨機,每次重跑結果都不同;浮水印取樣的骰子由固定金鑰加上前文算出來,同一段前文,每次都落在同一個字上。
按播放看六步生成過程 · 兩條取樣路徑並排
同一份候選詞表跑兩條取樣路徑:上排一般取樣(真隨機,每次重跑不同),下排浮水印取樣(金鑰加前文決定,同一句話每次落在同…
兩種取樣單獨看一步都像丟骰子,肉眼分不出差別。浮水印那顆骰子把隨機源換成金鑰加前文的雜湊值,分數穩定往上堆;一般取樣的分數只是隨機遊走,兩條線因此越走越開。
曲線的意思是:偵測端拿同一把金鑰,對這段文字裡每個實際出現的字重新算一次分數,累加起來。照這套機制推下去:如果文字是一般取樣生出來的,累加出來的分數會在期望值附近隨機游走——因為選字這件事根本沒管過這把金鑰算出來的分數。如果文字是浮水印取樣生出來的,累加出來的分數會穩定往上堆——因為每一步選字的時候,這把金鑰算出來的分數本來就是選字條件的一部分。這是把 DeepMind 說的分數模式比對具體化:偵測端不需要知道文字裡哪個字被動過手腳,只需要看整段文字的分數走勢像不像浮水印該有的樣子。
把這個邏輯放大到真實場景更好懂:一篇幾百字的短文,能拿來累加分數的字不多,兩條線的差距還沒拉開就結束了;一篇幾千字的長文,就算每一步的偏移很小,加總幾千次之後,浮水印路徑會穩定甩開一般路徑的隨機游走範圍。這正是下一段要展開的「長度」變數。
寫成虛擬碼,浮水印取樣那一步大概長這樣(示意,非原始實作):
// 示意:浮水印取樣的核心步驟(簡化版)
candidates = model.next_token_distribution(context)
// 例如 candidates = [("雨", 0.80), ("雷雨", 0.15), ("陣雨", 0.05)]
for (word, prob) in candidates:
score = hash(secret_key, context, word) // 0.0 ~ 1.0,只由金鑰與前文決定
biased = log(prob) + WEIGHT * score
chosen = argmax(biased)
// 分數高的候選詞,被選中的機率被系統性拉高
// 但挑出來的仍然是 candidates 裡本來就存在的詞
這整套機制從頭到尾都不是簽章式的是非題。Anthropic 自己講得直接:「There are limitations to the effectiveness of watermarking」,而且可偵測性同時取決於兩個變數——「Depending on the length of the text and how heavily Claude has edited it, those changes might not be enough to make Claude's involvement detectable」。文字長度決定訊號量夠不夠,改動幅度決定還剩多少 Claude 自己選的字,這兩個變數分別在下面兩段展開:一段用滑桿具體看「長度」怎麼決定訊號夠不夠,一段用改寫前後的對照看「改動幅度」怎麼決定還剩多少訊號可以測。
score 這條線要走出穩定的斜率,前提是有夠多步驟可以累積。下面這個控制項把生成步數換成粗略的字數,滑到不同長度,看「偵測端看得出偏移」這件事在什麼長度區間才成立——這是示意用的分類,不是 Anthropic 公佈的精確門檻,用意是呈現「長度」這個變數怎麼直接決定訊號夠不夠。
拖動滑桿看樣本長度怎麼決定訊號夠不夠 · 示意分類,非精確門檻
這對應到 Anthropic 原句的另一半:「Detecting a watermark also doesn't work well on small samples, where there are fewer word choices and thus less information to go on」——樣本太短,浮水印訊號來不及累積,不是機制失靈,是統計量不夠。
什麼情況下,這顆骰子露不出馬腳
浮水印會弱、甚至測不出來,情況比想像中集中——幾乎都能歸回同一個根因:能挑的候選詞不夠多,或者文字不夠長。這件事對工程師的意義很直接:判斷一段文字能不能被浮水印抓到,不是看內容像不像 AI 寫的,是看這段文字落在哪一種候選詞密度、多長、被動過多少手腳。
| 失效情境 | 根因 | 來源怎麼說(節錄) |
|---|---|---|
| 事實性內容/程式碼 | 可替換的等價寫法本來就少 | 「fewer choices that can be made without decreasing the accuracy」 |
| 過短的樣本 | 出現次數不夠,統計量不足 | 「fewer word choices and thus less information to go on」 |
| Claude 校對人類原稿 | 多數字不是 Claude 選的 | 「there's very little (if anything) for the watermark to attach to」 |
| 被大幅改寫或翻譯 | 原本的選字模式被打散 | 「can be greatly reduced when an AI-generated text is thoroughly rewritten or translated to another language」 |
事實性內容跟程式碼是同一件事的極端版本。Anthropic 講事實性段落的原因是:「Watermarking is sparser on factual passages where there are fewer choices that can be made without decreasing the accuracy of the text」——選項變少不是隨便選的,是因為亂選會讓內容變得不準確。程式碼多數時候要求精確、可替換的等價寫法本來就少,Anthropic 說程式碼「has generally less watermarking than some other forms of text」。DeepMind 對同一件事的措辭是:「SynthID text watermarking is less effective on responses to factual prompts because there are fewer opportunities to adjust the token distribution without affecting the factual accuracy」——同一條限制,下游的 Anthropic 頁面跟上游的 DeepMind 說法各自用自己的話講了一次,不是同一句話被轉述兩次。程式碼是這條規律最乾脆的例子——變數名稱、函式簽名、標準函式庫的呼叫方式,能替換的空間本來就窄,換一個看起來語意相同的寫法,很可能直接編譯不過或行為不同。候選詞集合窄到這種程度,浮水印能塞進去的訊號自然也窄。
這篇文章刻意把 Anthropic 自家頁面的說法跟 DeepMind 的說明文章並排放,不是因為兩邊在互相抄——是因為浮水印的限制不是 Anthropic 實作沒做好,是整條「在取樣端調機率」技術路線共同的性質。換一家公司做同樣的取捨,一樣會撞上事實性內容浮水印變弱、短樣本測不準這兩個限制。
另一個容易被忽略的情境方向剛好相反:Claude 校對人類寫好的原稿。Anthropic 講得很白:「When Claude proofreads text written by a person, what it gives back has generally only been lightly edited; because nearly all the words are the person's, there's very little (if anything) for the watermark to attach to」。這句話背後的機制邊界寫在另一句更短的話裡:「The watermark only applies to words Claude chooses」——浮水印套用的對象是 Claude 自己選出來的字,不是整段輸出文字。人類寫的字,從一開始就不在這個機制的作用範圍裡。
改寫方向也一樣:一段 Claude 原始輸出被大幅改寫或翻譯之後,剩下的字有多少還是 Claude 自己選的,決定了浮水印還剩多少。拖動下面這條分隔線,看同一句話在「原始輸出」跟「大改後」兩種狀態下,字詞留存的樣子怎麼變。
拖動分隔線比較改寫前後 · 6 個詞格
Support 頁面把這類情境列成一組:「heavily edited, paraphrased, translated, or mixed into other writing」,跟過短的樣本「very short」放在一起,一併說成偵測不可靠的常見原因。DeepMind 的上游研究把這個現象講得更具體:改寫或翻譯之後,偵測信心「can be greatly reduced when an AI-generated text is thoroughly rewritten or translated to another language」——不是完全歸零,是明顯下降。
工程師如果想拿浮水印做自己的偵測工具,目前還做不到。Support 頁面承諾之後會「enable users and other third parties to detect Claude's embedded watermarks and provenance metadata」,但偵測演算法、門檻怎麼設都還沒公開——「We'll share details on detection mechanisms in forthcoming technical documentation」。這代表現在能驗證的只有取樣端這一半的機制,偵測端的細節要等技術文件補齊之後才拿得到。
最後一點容易被忽略:偵測結果從頭到尾都是機率性的,不是簽章式的是非題。Support 頁面把這句話講得很清楚:「Detecting a Claude mark tells you that the content may have been processed by Claude」,並且直接承認「is not fully conclusive」。反過來也一樣——「Lack of a detected mark doesn't mean the content wasn't AI-generated or processed」,沒測到浮水印,不能反推內容不是 AI 生成或處理過的。
這也是為什麼把浮水印偵測結果直接當成「這篇文章是不是抄的」或「這份作業是不是用 AI 寫的」唯一依據,會踩到 Anthropic 自己都提醒過的陷阱——高信心的正向結果值得參考,但低信心或沒測到,既不能證明也不能否證,中間永遠留著一段機率性的灰色地帶。工程上比較保守的用法,是把浮水印偵測結果當成眾多訊號之一,跟其他線索一起看,而不是單獨拿來做非黑即白的判定。
把這幾件事收在一起看:浮水印不會讓 Claude 的輸出變慢、變貴,也不會讓輸出洩漏使用者身份;但它同時也不是一把能百分之百驗證內容出處的萬能鎖,短文、被大幅改寫的文字、程式碼,都可能測不出來。要在自己的產品邏輯裡用這個訊號,得先接受它是機率性的線索,不是判決。把這篇文章從頭到尾走一遍,其實只有一件事在變:隨機性從哪裡來。候選詞分佈沒變,模型的能力沒變,唯一被動過手腳的,是那顆決定「這一次要選誰」的骰子。
Take-away:浮水印沒有換掉 Claude 會選的字,換掉的是選字那一步用的骰子——骰子的種子從任意亂數換成金鑰加前文,訊號能不能被偵測到,看的是候選詞夠不夠多、文字夠不夠長,不是有沒有被動過手腳。