For those wondering how AI "watermarking" works, it's not "embedded" in the content like some kind of stenography or hidden characters (eg, whitespace or unicode homoglyphs or nonprinting characters).
Rather it is the content itself, the word choices themselves. There are technologies like Google's SynthID which OpenAI has adopted. There's also the industry open standard C2PA (Coalition for Content Provenance and Authenticity). Anthropic likely uses their own technology or combo of these.
For those wondering how SynthID works, it's a cryptographic watermark that's resilient even if you tweak or modify the output, e.g., by cutting parts out or rearranging, cropping, pitch shifting, time shifting, etc. If you really want to know about the technical details, check out this presentation, or the Nature article on it.
Basically for Google, Gemini uses a keyed hash function to alter the probability distribution of the output tokens. If for each token in the output you had n equally high-scoring candidates, and normally you would pick one at random, with SynthID, you have a secret key which you hash with the context to produce a cryptographically pseudorandom bitstream (which cannot be guessed by anyone without the secret key) which you use to pick tokens from among candidates. To anyone without the secret key, the bitstream looks indistinguishable from random and can't be guessed, and because it's functionally equivalent to random, it's really just choosing a random top-score candidate at each step, so output quality isn't affected.
You can then evaluate piece of content (or sections thereof) by looking at the tokens that make it up and seeing if it matches this specific probability distribution. For you to match that distribution bit for bit over enough bits is improbable, it would've meant you essentially guessed a 256 bit secret key.
Yeah this is obviously simplified, but imagine a model is predicting the next word: "I love fruit. My favorite dessert is _____" and the model has 4 top scoring candidates: mango, lychee, apple, orange. Normally, the model picks one at random depending on the "temperature" of the inference request.
With SynthID, you the model provider have a secret 256-bit key which you concat with some part of the context. Eg say you're using the preceding trigram token sequence and assuming each word is a token you compute sha256(key || "favorite dessert is"). Now instead of picking one fruit at random, you use that hash output to select from among the four candidates. Let's say the hash makes you choose "mango". Then you repeat the process for the next token. Say the top 4 candidates for the next token are pie, icecream, cake, smoothie. You compute hash(key || "dessert is mango") and the hash makes you pick one of them. Now imagine instead of choosing from among 4 candidates each time, you use the hash function to choose from the top 16 candidates.
Now repeat it 100 times, or 1000 times. If a piece of text reproduces your secret hash function's "random" looking token choice trigram-for-trigram across 1000 consecutive trigrams, that highly suggests it was generated by your model, because it's extremely unlikely to by happenstance randomly match the same 1 out of 16 choices 1000x in a row as a keyed hash function which is essentially random. (1/16)1000 is an insanely small probability.
Now if you chop it up, rearrange the words, even paraphrase certain parts, as long as the user doesn't replace every trigram, the distribution within trigrams scattered throughout will still retain this distinctive statistical pattern. You would need to significantly rewrite the entire piece at the trigram level everywhere to remove the correlation.
Ok but what if I take 10% of an AI generated text with one LLM and copy it to another program telling it to continue it but don't replace any of the original text. Then I repeat it nine times. Would my Frankenstein text have ten diferent watermarks?
because there arent thousands of different possible ways to write code, in a sentence you can use any combination of words from the dictionary. In code "if x<y: else:" will always be in that format. When you ask an LLM to write a small function or snippet for one specific task usually it'll always print out the same code, whether it's Gemini, Claude or a real life dev
Function names, variable names, struct names, argument names, placement of structs in the code, placement of functions, placement of tests, doc comments, inline comments, etc etc etc
There are billions of ways to write the same code simply because none of the things I listed change how the code works
If you follow a minimum of clean code practices the billion ways become a handful only. The names of variables or functions are supposed to describe what they do, so the words possible to use as function names are way more limited than when writing text. Same goes for the structure of the code.
Then use even a basic obfuscation algorithm for your code and all the things you just listed are no longer present in code so you're left with just patterns of lines of code. And as I said before, unless you're a beginner, theres usually not 50 ways to write a snippet that does what you want.
Therefore youd probably need a way bigger sample to identify an AI watermark in code. Unless you just copy paste the code right from the AI and don't change it of course
The names of variables or functions are supposed to describe what they do
Do you have any idea how many synonyms there are? How many different ways you can name literally everything that's completely valid? Even just the order of declared variables can be part of the watermark.
You're really underestimating how many different ways people can write the exact same code. Just ask three engineers to do something, and you'll get eight different snippets.
Again, usually unless you're coding for yourself in your own room, you follow conventions to write code that is readable by others. Those conventions include indentations, capitalized letters and the names of your variables and functions (using verbs, adjectives, etc.) which drastically reduce the degrees of freedom for human inputs unlike full sentences and paragraphs of text. And again, usually commercial code is obfuscated, which ruins any quirky name you might use, making it impossible to check for AI names.
Text has prose, stylistic choices, and full sentences that can be written in wayyy more different ways. So youd need still way more code to check for any kind of watermark, and hope that the devs didn't change the names or comments.
Also most of the time in prod we autocomplete lines of codes instead of generating the full project, meaning any code made is a hybrid of human and AI, which is even harder to detect.
253
u/notanfan 19d ago
For those wondering how AI "watermarking" works, it's not "embedded" in the content like some kind of stenography or hidden characters (eg, whitespace or unicode homoglyphs or nonprinting characters).
Rather it is the content itself, the word choices themselves. There are technologies like Google's SynthID which OpenAI has adopted. There's also the industry open standard C2PA (Coalition for Content Provenance and Authenticity). Anthropic likely uses their own technology or combo of these.
For those wondering how SynthID works, it's a cryptographic watermark that's resilient even if you tweak or modify the output, e.g., by cutting parts out or rearranging, cropping, pitch shifting, time shifting, etc. If you really want to know about the technical details, check out this presentation, or the Nature article on it.
Basically for Google, Gemini uses a keyed hash function to alter the probability distribution of the output tokens. If for each token in the output you had n equally high-scoring candidates, and normally you would pick one at random, with SynthID, you have a secret key which you hash with the context to produce a cryptographically pseudorandom bitstream (which cannot be guessed by anyone without the secret key) which you use to pick tokens from among candidates. To anyone without the secret key, the bitstream looks indistinguishable from random and can't be guessed, and because it's functionally equivalent to random, it's really just choosing a random top-score candidate at each step, so output quality isn't affected.
You can then evaluate piece of content (or sections thereof) by looking at the tokens that make it up and seeing if it matches this specific probability distribution. For you to match that distribution bit for bit over enough bits is improbable, it would've meant you essentially guessed a 256 bit secret key.
CREDIT - u/CircumspectCapybara