Claude 說會在生成文字裡加入浮水印,但文字裡顯然沒有多加東西,到底怎麼做到? 從模型本來就會依機率選下一個 token 這件事開始,其實很好理解。
先看 LLM 平常怎麼選下一個 token
LLM 不是先想好整篇文章再打出來。它每次只做一件事:根據目前文字, 替「下一個 token」列出一組機率,抽一個接上去,再重複同樣流程。
例如目前寫到:
這個方法很 ___
有效 31%實用 28%有用 24%強大 10%其他 7%這些數字代表候選的相對可能性。31% 的「有效」不是必選; 「實用」與「有用」也都可能被抽到。模型抽完一個 token, 就把它接回句子,重新計算下一輪機率。
模型內部會先替候選打分,再把分數換成機率。理解浮水印不需要知道換算公式; 只要記得分數稍微改變,抽到各 token 的機率也會跟著變。
常見問題先回答
先處理幾個最容易誤會的地方
浮水印是偷偷在文字裡加字元嗎?
不是。模型本來就會依機率抽選下一個 token;一種典型做法是用 hash 規則決定這一輪要稍微提高哪些 token 的機率。 單次看不出來,整段文字累積後就可能出現明顯差距。Claude 是否採用這個做法尚未公開。
為什麼現在外界還驗不了?
Anthropic 還沒公開實作細節與驗證工具。如果採用本文這類做法,驗證時需要重建每一步偏好的 token, 再看整段文字的命中比例是不是高得不像巧合。
手動改幾個字,不就把 hash 全打亂了?
實作細節還沒公開。不過一種常見做法只看最近 個 token, 局部修改只會影響附近幾步;要洗掉整段累積的訊號,通常需要更大幅度地改寫。
為什麼短文不容易驗?
單一 token 幾乎沒有證據。樣本累積得夠多,許多很小的偏差才看得出異常。
調整選字機率不會傷品質嗎?
會,所以比較適合在模型本來就有多個合理選項的位置微調。 幾乎只有一個正確答案時,就不適合硬改機率。
幾個會用到的詞
先知道這四個就夠了。
Token
LLM 取樣的單位,不一定等於一個中文字或一個英文單字。
選字機率
模型會替下一個 token 的每個候選分配機率,再從中抽選。
Secret / hash 規則
Secret 是未公開的值;知道它才能重建每一輪哪些 token 會被稍微加分。
命中率
實際選到偏好 token 的比例。明顯高過正常比例,才算有浮水印訊號。
Anthropic 公開了什麼、沒公開什麼
Anthropic 公開的是功能與限制,沒有公開演算法。先把能確定的事情縮成三點:
- 文字標記做在模型層,所以不同 Claude 產品與 API 產生的內容都能帶上浮水印。
- 複製貼上會保留訊號,也可能撐過部分編輯;太短、大幅改寫或翻譯後則可能驗不到。
- 驗到只代表內容可能被 Claude 處理過,不代表 Claude 是作者。 截至 2026-08-13,公開驗證工具與演算法細節都還沒釋出。
怎麼偷偷把選字機率調高
一個最簡單的做法,是在每一輪把候選 token 偷偷分成兩組。為了方便畫圖,先叫它們 green 和 red:
- Green 組:多拿一點分數,機率稍微提高。
- Red 組:分數不變,仍然可以被抽到。
假設這一輪「有效」與「有用」被分到 green,其餘在 red。原本 31%、28%、24%、10% 的分布,可能變成 33%、26%、25%、9%。沒有 token 被禁止,也沒有硬指定答案; 只是 green 被抽到的機會合計高了一點。
哪些 token 被分到 green,由 secret 和最近幾個 token 經過 hash 決定。 每寫出一個 token,分組就重新計算,因此不是某幾個詞永遠比較常出現。
把它壓成一行,就是:green 候選的分數 += 一點點。
產生端的概念大概只有四步:
候選機率 = 模型計算目前文字green 組 = hash(secret, 最近 k 個 token)候選機率 = 把 green 組稍微調高,再整理回總和 100%下一個 token = 依調整後的機率抽選實際多出的工作只有決定分組、替 green 加分,之後照常抽選。 這些步驟可以直接放在模型產生文字的那一層。
驗證工具在看什麼
假設正常情況下,每個 token 落進 green 組的機率是 50%。 浮水印沒有讓它變成 100%,可能只推到 55%。
只看 20 個 token,正常大約命中 10 次,浮水印大約 11 次,根本分不出來。 換成 1000 個 token,正常約 500 次,浮水印約 550 次,差距就比較難用運氣解釋。
驗證工具知道 secret,可以把每一步的 green / red 分組重建出來,然後一路數: 實際 token 落在 green 的比例,是否高得不正常?
實作上常把差距換成統計分數,也就是「離正常值有幾個標準差」。 文章越長,這個統計判斷通常越穩;短句幾乎沒有辨識力。
改幾個字為什麼不會整篇失效
一開始卡在這裡:中間改掉一個 token,後面的 hash 輸入不是會全部改變嗎?
如果每一步都拿前面整段文字去 hash,這個擔心完全正確:
Hash 的雪崩效應讓輸入稍有變化,輸出就完全不同。改掉第 3 個 token, 第 4 個之後每一步重算出來的 green 分組都跟當初生成時不一樣,命中率會掉回正常比例。
典型改法是只看最近 k 個 token:
拿 走一遍。原本是 A B C D E F G H I, 把 C 改成 X:
- 位置 D 看到最近三個 token
{A, B, X}→ 含 X,分組和原文不同。 - E 看到
{B, X, D}、F 看到{X, D, E}→ 一樣受影響。 - G 看到
{D, E, F}→ X 已經滑出去了, 跟生成時完全一致,命中判斷恢復正常。
修改影響接下來約 個位置;舊 token 滑出去後,驗證規則就重新對齊。
真實方法還可以疊加多組 window 或加入冗餘,讓局部修改更難一次破壞全部訊號; 這裡不再往下展開。
調機率會不會傷品質
機率完全不變,驗證工具就沒有東西可驗。因此浮水印一定會動到選字機率, 問題是怎麼把影響壓小。
挑模型本來就在猶豫的位置
例如下一個 token 有幾個相近的候選:
「這是一個非常 ___ 的方法」 有效 27% 實用 25% 有趣 21% 強大 18% ...四個詞都通順。這種位置挪動幾個百分點,通常不會改變句意。
但有些位置只有一個答案:
「1 + 1 =」 2 99.99% 其他 0.01%這種位置幾乎沒有操作空間,合理做法是跳過,不調整也不計分。
程式碼、算式、JSON、URL 與逐字引用都有大量固定答案,可介入的位置通常比自然語言少。 這也是為什麼不是每個 token 都適合留下浮水印。
為什麼文字要夠長
原因就是前面的 50% 與 55%:短句裡只差一兩次命中,很容易只是運氣; 長文裡多出幾十次命中,才會逐漸離開正常波動範圍。
- 門檻設低:短文比較容易驗出,但也更容易把正常文字誤判成浮水印。
- 門檻設高:誤判較少,但需要更長文字,編輯後也更容易掉到門檻以下。
驗證工具最後仍然只是在做統計判斷。它可以說「這段文字的 green 命中率高得不太像巧合」, 不能證明作者是誰。
改多少會洗掉訊號
複製貼上
Token 序列沒有變,計分結果原則上也不變。Anthropic 已明確確認這點。
局部修改
若規則只看最近 個 token,每次替換會直接影響附近約 個位置。刪除、插入和移動句子的影響則更難估。
只要大部分原文保留,剩下的位置仍可提供證據;最後驗不驗得到,還要看原文長度、修改位置與驗證規則。
整篇改寫、翻譯、丟給另一個模型重寫
這類操作會重新抽選大量 token。新文字沒有遵循原本的 hash 偏好, 留下的訊號主要來自未被改寫的片段。
官方將大幅編輯、改寫、翻譯與混合列為可能驗不到的情況,沒有提供修改比例或成功率。
最後就是三個取捨
浮水印的強度最後都在調整三件事:
- 好不好驗:多短的文章就能看出訊號。
- 耐不耐修改:文字改過之後還剩多少訊號。
- 生成品質:為了浮水印,選字機率被改動多少。
Green 組的加分越大,訊號越容易累積,修改後也比較可能留得住; 但模型選字受到的影響也越大。加分越小,品質影響越低,就需要更長的文字才能驗。
目前的理解
目前把文字浮水印理解成一套帶 secret 的抽樣規則。模型遇到幾個都合理的 token 時, 對其中一部分稍微加分;驗證工具用同一個 secret 重建規則,再看整段文字命中了多少次。
單次選擇看不出異常,累積到長文才有判斷力。局部編輯會損失部分命中,整篇重寫則可能讓訊號消失。 即使驗到,也只能說文字可能經過該系統,不能證明作者身分。
參考
- How Claude marks AI-generated content — Anthropic 官方說明,本文功能與限制的事實來源。
- A Watermark for Large Language Models (Kirchenbauer et al., ICML 2023) — green / red 分組與統計驗證的原始論文。
- Scalable watermarking for identifying large language model outputs (Dathathri et al., Nature 2024) — SynthID-Text 的論文與實際部署經驗。
- google-deepmind/synthid-text — 上面那篇的參考實作,想直接讀 code 的話從這裡開始。
- A Survey of Text Watermarking in the Era of Large Language Models — 想繼續看其他做法時,這篇整理得很完整。