所有文章

文字浮水印怎麼藏進 AI 回答?

發布於

Claude 說會在生成文字裡加入浮水印,但文字裡顯然沒有多加東西,到底怎麼做到? 從模型本來就會依機率選下一個 token 這件事開始,其實很好理解。

先看 LLM 平常怎麼選下一個 token

LLM 不是先想好整篇文章再打出來。它每次只做一件事:根據目前文字, 替「下一個 token」列出一組機率,抽一個接上去,再重複同樣流程。

例如目前寫到:

text
這個方法很 ___
有效 31%
實用 28%
有用 24%
強大 10%
其他 7%

這些數字代表候選的相對可能性。31% 的「有效」不是必選; 「實用」與「有用」也都可能被抽到。模型抽完一個 token, 就把它接回句子,重新計算下一輪機率。

LLM 不是先寫好整句,而是每次選一個 token目前的文字「這個方法很 ___」下一個 token 的機率有效31%實用28%有用24%強大10%其餘 token 合計 7%抽到有效接回文字,繼續下一輪31% 不是必選;只是抽到「有效」的機會最高
圖 1:LLM 每次根據目前文字算出下一個 token 的機率,抽一個接上,再繼續下一輪。數字只是示意。

模型內部會先替候選打分,再把分數換成機率。理解浮水印不需要知道換算公式; 只要記得分數稍微改變,抽到各 token 的機率也會跟著變。

常見問題先回答

先處理幾個最容易誤會的地方

Q1

浮水印是偷偷在文字裡加字元嗎?

不是。模型本來就會依機率抽選下一個 token;一種典型做法是用 hash 規則決定這一輪要稍微提高哪些 token 的機率。 單次看不出來,整段文字累積後就可能出現明顯差距。Claude 是否採用這個做法尚未公開。

Q2

為什麼現在外界還驗不了?

Anthropic 還沒公開實作細節與驗證工具。如果採用本文這類做法,驗證時需要重建每一步偏好的 token, 再看整段文字的命中比例是不是高得不像巧合。

Q3

手動改幾個字,不就把 hash 全打亂了?

實作細節還沒公開。不過一種常見做法只看最近 kk 個 token, 局部修改只會影響附近幾步;要洗掉整段累積的訊號,通常需要更大幅度地改寫。

Q4

為什麼短文不容易驗?

單一 token 幾乎沒有證據。樣本累積得夠多,許多很小的偏差才看得出異常。

Q5

調整選字機率不會傷品質嗎?

會,所以比較適合在模型本來就有多個合理選項的位置微調。 幾乎只有一個正確答案時,就不適合硬改機率。

幾個會用到的詞

先知道這四個就夠了。

Token

LLM 取樣的單位,不一定等於一個中文字或一個英文單字。

選字機率

模型會替下一個 token 的每個候選分配機率,再從中抽選。

Secret / hash 規則

Secret 是未公開的值;知道它才能重建每一輪哪些 token 會被稍微加分。

命中率

實際選到偏好 token 的比例。明顯高過正常比例,才算有浮水印訊號。

段落目錄

Anthropic 公開了什麼、沒公開什麼

Anthropic 公開的是功能與限制,沒有公開演算法。先把能確定的事情縮成三點:

已公開
  • 文字標記做在模型層,所以不同 Claude 產品與 API 產生的內容都能帶上浮水印。
  • 複製貼上會保留訊號,也可能撐過部分編輯;太短、大幅改寫或翻譯後則可能驗不到。
  • 驗到只代表內容可能被 Claude 處理過,不代表 Claude 是作者。 截至 2026-08-13,公開驗證工具與演算法細節都還沒釋出。
推測下面的 green / red 分組與「只看最近幾個 token」來自既有研究,是理解用的模型,不是 Claude 的實作說明。

怎麼偷偷把選字機率調高

推測這裡用論文常見的 green / red 分組解釋。Claude 是否採用同一套做法仍未公開。

一個最簡單的做法,是在每一輪把候選 token 偷偷分成兩組。為了方便畫圖,先叫它們 green 和 red:

  • Green 組:多拿一點分數,機率稍微提高。
  • Red 組:分數不變,仍然可以被抽到。

假設這一輪「有效」與「有用」被分到 green,其餘在 red。原本 31%、28%、24%、10% 的分布,可能變成 33%、26%、25%、9%。沒有 token 被禁止,也沒有硬指定答案; 只是 green 被抽到的機會合計高了一點。

原始機率分布有效31%實用28%有用24%強大10%加入一點選字偏好有效33%實用26%有用25%強大9%secret K最近 k 個 tokenhash 規則這輪要加分的候選+ 一點綠色候選只多拿一點分數;其他候選仍然可以被抽到
圖 2:secret 與最近幾個 token 決定這一輪哪些候選會被加分,再重新換算機率。數字只是示意。

哪些 token 被分到 green,由 secret 和最近幾個 token 經過 hash 決定。 每寫出一個 token,分組就重新計算,因此不是某幾個詞永遠比較常出現。

把它壓成一行,就是:green 候選的分數 += 一點點。

產生端的概念大概只有四步:

text
候選機率 = 模型計算目前文字
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 的比例,是否高得不正常?

驗證工具用同一把 secret,逐位置重建「當時偏好哪些 token」單一位置只是一次擲硬幣;重點是整段命中比例是否異常A命中B未中C命中D命中E未中F命中G命中H未中I命中J命中正常情況正常預期:5 / 10正常命中率 = 50%實際結果實際命中:7 / 10多出的命中 = 浮水印訊號換成統計分數離隨機預期有幾個標準差?10 個 token 只是畫法示意;真實偵測需要更長文字才能建立可靠統計訊號
圖 3:驗證工具用同一把 secret 重建每一輪的分組,再把 green 命中率和正常預期比較。10 個 token 只是流程示意。

實作上常把差距換成統計分數,也就是「離正常值有幾個標準差」。 文章越長,這個統計判斷通常越穩;短句幾乎沒有辨識力。

推測50% 與 55% 都是為了說明而設的數字。Claude 實際怎麼分組、偏多少、門檻多高,都沒有公開。

改幾個字為什麼不會整篇失效

一開始卡在這裡:中間改掉一個 token,後面的 hash 輸入不是會全部改變嗎?

如果每一步都拿前面整段文字去 hash,這個擔心完全正確:

st=H(K,x1,x2,…,xt−1)s_t = H(K, x_1, x_2, \ldots, x_{t-1})

Hash 的雪崩效應讓輸入稍有變化,輸出就完全不同。改掉第 3 個 token, 第 4 個之後每一步重算出來的 green 分組都跟當初生成時不一樣,命中率會掉回正常比例。

典型改法是只看最近 k 個 token:

st=H(K,xt−k,…,xt−1)s_t = H(K, x_{t-k}, \ldots, x_{t-1})
(a) 每一步都 hash 整個前綴state_t = H(K, x_1 … x_t-1)ABXDEFGHI···✗✗✗✗✗✗X 之後每一步的 hash 輸入都不一樣了 → 後面整段對不上(b) 只看最近 3 個 tokenstate_t = H(K, x_t-3 … x_t-1)ABXDEFGHI···✗✗✗✓✓✓X 還在 window 內X 滑出 window → 重新同步· 沒有完整 window,不計分
圖 4:每次 hash 整段前文時,改一個字會讓後面全亂;只看最近 3 個 token 時,影響會在三步後結束。

拿 k=3k = 3 走一遍。原本是 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 已經滑出去了, 跟生成時完全一致,命中判斷恢復正常。

修改影響接下來約 kk 個位置;舊 token 滑出去後,驗證規則就重新對齊。

真實方法還可以疊加多組 window 或加入冗餘,讓局部修改更難一次破壞全部訊號; 這裡不再往下展開。

推測只看最近幾個 token 是一種典型可行設計,不是 Anthropic 已確認的實作。

調機率會不會傷品質

機率完全不變,驗證工具就沒有東西可驗。因此浮水印一定會動到選字機率, 問題是怎麼把影響壓小。

挑模型本來就在猶豫的位置

例如下一個 token 有幾個相近的候選:

text
「這是一個非常 ___ 的方法」
有效 27%
實用 25%
有趣 21%
強大 18%
...

四個詞都通順。這種位置挪動幾個百分點,通常不會改變句意。

但有些位置只有一個答案:

text
「1 + 1 =」
2 99.99%
其他 0.01%

這種位置幾乎沒有操作空間,合理做法是跳過,不調整也不計分。

多個選項:模型本來就在猶豫「這是一個非常 ___ 的方法」有效27%+一點實用25%有趣21%+一點強大18%多個近似答案 → 適合微調固定答案:幾乎沒有選擇空間「1 + 1 = ___」299.9%30.05%其他0.01%跳過,不調整機率硬偏只會把正確答案弄壞浮水印的空間來自「多個答案本來就差不多合理」
圖 5:有多個合理選項時可以微調;幾乎只有一個答案時就跳過。機率只是示意。

程式碼、算式、JSON、URL 與逐字引用都有大量固定答案,可介入的位置通常比自然語言少。 這也是為什麼不是每個 token 都適合留下浮水印。

為什麼文字要夠長

推測Anthropic 只說太短的文字沒有可靠訊號,沒有公布最低 token 數。

原因就是前面的 50% 與 55%:短句裡只差一兩次命中,很容易只是運氣; 長文裡多出幾十次命中,才會逐漸離開正常波動範圍。

  • 門檻設低:短文比較容易驗出,但也更容易把正常文字誤判成浮水印。
  • 門檻設高:誤判較少,但需要更長文字,編輯後也更容易掉到門檻以下。

驗證工具最後仍然只是在做統計判斷。它可以說「這段文字的 green 命中率高得不太像巧合」, 不能證明作者是誰。

改多少會洗掉訊號

原文複製命中率幾乎不變局部修改命中率下降,訊號還在整篇改寫命中率接近隨機命中的位置被改動破壞重新抽過,等同隨機
圖 6:複製不改變 token;局部編輯只破壞部分位置;整篇改寫會重新抽選大量 token。

複製貼上

Token 序列沒有變,計分結果原則上也不變。Anthropic 已明確確認這點。

局部修改

若規則只看最近 kk 個 token,每次替換會直接影響附近約 kk 個位置。刪除、插入和移動句子的影響則更難估。

只要大部分原文保留,剩下的位置仍可提供證據;最後驗不驗得到,還要看原文長度、修改位置與驗證規則。

整篇改寫、翻譯、丟給另一個模型重寫

這類操作會重新抽選大量 token。新文字沒有遵循原本的 hash 偏好, 留下的訊號主要來自未被改寫的片段。

官方將大幅編輯、改寫、翻譯與混合列為可能驗不到的情況,沒有提供修改比例或成功率。

最後就是三個取捨

浮水印的強度最後都在調整三件事:

好不好驗短文也驗得出來嗎耐不耐修改被改過還剩多少訊號生成品質用詞被拉走多少加分較多加分較少調整加分強度,就是在三者之間移動
圖 7:偏得越強通常越好驗、越耐修改,但生成品質也越可能受到影響。
  • 好不好驗:多短的文章就能看出訊號。
  • 耐不耐修改:文字改過之後還剩多少訊號。
  • 生成品質:為了浮水印,選字機率被改動多少。

Green 組的加分越大,訊號越容易累積,修改後也比較可能留得住; 但模型選字受到的影響也越大。加分越小,品質影響越低,就需要更長的文字才能驗。

目前的理解

目前把文字浮水印理解成一套帶 secret 的抽樣規則。模型遇到幾個都合理的 token 時, 對其中一部分稍微加分;驗證工具用同一個 secret 重建規則,再看整段文字命中了多少次。

單次選擇看不出異常,累積到長文才有判斷力。局部編輯會損失部分命中,整篇重寫則可能讓訊號消失。 即使驗到,也只能說文字可能經過該系統,不能證明作者身分。

推測Green / red 分組、最近幾個 token 的 hash 規則與本文數字都只是理解用的模型,不是 Claude 實作的逆向結果。 Anthropic 公開技術文件後再回來核對。

參考

AI文字浮水印Hash機率統計Anthropic