Привет!
Эпоха дикой генерации слопотекста, кажется, заканчивается. Недавно от Anthropic вышла статья How Claude's Text Watermark Works, которая посвящена текстовому водяному знаку и его детекции. Один из главных научпоп-исследователей LLM — Себастьян Рашка — подготовил детальный разбор того, как вообще в LLM может быть устроен такой вотермаркинг: разбор понятный, глубокий, с картиночками — все как мы любим.
Я сделал частичный перевод этого разбора — Себастьян очень крутой, но часто долго разгоняется, слишком много извиняется за свои предположения, порой чрезмерно рекламит книгу, а иногда просто нудит или тяжело пишет.
Поэтому публикую чистенькую, сильно переписанную и адаптированную под русский язык версию. Тема очень крутая и горячая, приятного чтения!

В оригинале в статье идет долгое вступление о том, как LLM вообще генерит токены. Я убрал эту часть: если вы это знаете (а в 2026 надо бы!), то будет скучно, если нет, то приглашаю к оригиналу. Здесь это вступление заменено одним абзацем, а дальше только суть про водяной знак (который я иногда буду называть вотермарком, потому что англицизм вполне настоялся сам по себе).
Модель генерирует ответ по одному токену за раз и на каждом шаге она выдает оценки (скоры) по всему словарю токенайзера, softmax превращает их в вероятности — и дальше наступает сэмплирование, то есть непосредственно выбор следующего токена. Вариантов у него два: жадное декодирование берет самый вероятный токен, всегда и без исключений, а вероятностное сэмплирование бросает нечестный кубик: шансы токена пропорциональны его вероятности, потому чаще всего выбор все равно падает на один из верхних по скорам токенов.

Жадный вариант выглядит логичнее, но на длинных текстах вырождается: модель скатывается в повторы и зацикливания. Дальше всё зависит от того, насколько модель уверена на конкретном шаге: при остром распределении выбор предрешён и кубик ничего не решает. Но при равноценности двух-трех кандидатов, например,— «холодно и пасмурно» (overcast) против «холодно и серо» (gray), — решает именно случайность, и потому один и тот же промпт даёт в итоге слегка разные тексты.
Этот момент запоминаем: водяной знак Claude встроен ровно сюда — не в модель и не в готовый текст, а в источник случайности внутри сэмплирования.
Оба варианта («пасмурно» и «серо») — разумные следующие токены для задачи генерации продолжения текста и выбор между ними равноценен: нельзя объективно сказать, что один из них хуже другого. Поэтому при случайном сэмплировании — поскольку у обоих токенов относительно высокие и притом близкие по величине оценки — мы можем получить как один, так и другой.
Так что при многократном повторении сэмплирования почти в половине случаев мы получили бы «overcast», и почти в половине — «gray». Именно поэтому LLM часто выдают разные ответы на один и тот же промпт.
А выбранный токен затем влияет на все последующие токены, и так далее.
Сиды (random seeds) и детерминированное сэмплирование
Теперь я хотел бы кратко поговорить о генерации случайных чисел: если мы используем генератор случайных чисел вот так, он выдаст случайную последовательность чисел. Если запустить его ещё раз — последовательность будет уже другой и каждый раз при новом запуске мы будем получать разную последовательность.

Но если я задам сид, например 123, и запущу код несколько раз, мы по-прежнему получим случайные числа, но каждый запуск будет приводить к одной и той же последовательности.

То есть они всё ещё случайны: с фиксированным сидом мы по-прежнему получаем случайные числа, отличающиеся друг от друга внутри последовательности, — но теперь они воспроизводимы. Иными словами, с сидом или без него мы в любом случае получаем случайные числа, но с сидом — воспроизводимую последовательность. Запоминаем: эта небольшая вводная поможет лучше понять, как оно устроено.

Например, я уже говорил, что при случайном сэмплировании мы можем получить либо «gray», либо «overcast». Но если мы используем конкретный сид, скажем 42, то будем всегда выбирать, например, «overcast». То есть выбор по-прежнему случайный, но мы делаем его детерминированным. В этом случае для данного промпта модель всегда будет выбирать «overcast».

Если использовать другой сид, модель может выбрать «gray» — и при каждом сэмплировании она будет неизменно выбирать «gray» в качестве следующего токена. То есть это по-прежнему случайное сэмплирование, но мы делаем его детерминированным за счёт сида.
Как работает ключ вотермаркинга

Так вот, в вотермаркинге Claude идея примерно та же: задаётся сид. Но этот сид — не просто число, которое кто-то взял и зафиксировал. Вместо этого используется секретный ключ — по сути, что-то вроде API-ключа, — и из этого ключа вместе с четырьмя предыдущими словами, собственно, и выводится сид.
Суть в том, что как и в генерации чисел, здесь есть фиксированный сид, и этот сид всегда выбирает один и тот же следующий токен. То есть, вместо простого статичного сида у них есть секретный ключ, и вдобавок для вывода сида используется информация о предыдущих токенах. Но об этом позже.

Идея в том, что вотермаркинг делает генерацию текста более детерминированной на определённых позициях. Рассмотрим, например, вот эти правдоподобные тексты слева. Пусть у нас есть текст:
The weather today is cold and ..... (Погода сегодня холодная и...)
Я могу выбрать либо «overcast», либо «gray». Дальше в предложении будет развилка: «light» или «gentle».
Оба варианта взаимозаменяемы.
А затем еще развилки:
the breeze is moving / blowing through the trees (бриз движется / дует в кронах деревьев)
the streets feel quiet / still («улицы кажутся тихими / замершими»)
Это, по сути, означает, что я мог бы сказать как «moving», так и «blowing», как «quiet», так и «still». То есть в тексте есть много ситуаций, где варианты токенов почти равновероятны — как мы уже видели ранее. А значит, прогоняя промпт через LLM мы получаем то один вариант, то другой. Вотермаркинга здесь пока еще нет.
В зависимости от числа таких позиций возможных ответов здесь может быть, например, 128. Разумеется, чем длиннее текст, тем больше в нём позиций со взаимозаменяемыми словами — и тем больше комбинаций, то есть возможных выходных текстов.
Итак, ещё раз: одним из возможных выходных текстов мог бы быть...
The weather today is cold and overcast. A light breeze is moving through the trees, and the streets seem quiet. I think I'll stay home and read a book with a cup of tea
(Погода сегодня холодная и пасмурная. Лёгкий бриз движется сквозь деревья, и улицы кажутся тихими. Думаю, я останусь дома и почитаю книгу за чашкой чая.)
Это один из возможных текстов. Другой возможный текст:
The weather today is cold and gray. A gentle breeze is blowing through the trees, and the streets seem still. I think I'll stay inside and read a novel with a mug of tea
(Погода сегодня холодная и серая. Мягкий бриз дует сквозь деревья, и улицы кажутся безмолвными. Думаю, я побуду дома и почитаю роман за кружкой чая.)
Как видите, сгенерированы два вполне разумных текста, а их комбинаций существует и больше. И все они разумны — нет такого, который был бы объективно лучше другого. Они просто равнозначны, а какой вариант конкретно мы получим — чистая случайность.

Теперь, если зафиксировать сид — например, взять сид 99, — мы можем всегда получать вот этот текст. То есть с помощью сида мы фиксируем, какой ответ получим: случайное сэмплирование остаётся случайным, но становится детерминированным в том смысле, что оно воспроизводимо — результат всегда будет одним и тем же. И это всё ещё генерация без вотермаркинга, теперь просто с сидом.

И вотермаркинг делает по сути то же самое. Только вместо простого сида у них есть так называемый случайный ключ, и этот ключ, собственно, участвует в выборе текста. Но кое-что мы уже можем сказать: в блог-посте про Claude утверждается, что вотермаркинг не должен ухудшать текст. И если посмотреть на этот механизм — да, понятно, почему он не должен его ухудшать.
«К слову, я здесь не защищаю водяные знаки — я просто пытаюсь объяснить, как они работают. Так что, пожалуйста, не убивайте гонца. Я лишь хочу сказать: с точки зрения конечного пользователя вотермаркинг — это не что иное, как фиксация сида, которая делает сэмплирование в некотором смысле детерминированным» (цитата из оригинала).
Строго говоря, «фиксация сида» — объясняющая метафора: настоящая случайность из сэмплирования никуда не девается, ключ лишь подкручивает шансы. Поэтому на практике вотермарк проявляется не как одинаковые ответы на один промпт, а как чуть менее разнообразные.
Где применяется водяной знак

Промежуточный итог: без вотермаркинга мы, как правило, сэмплируем без сида — думаю, большинство людей его вообще не используют и не факт, что его в принципе можно задать у вашего провайдера.
Так или иначе: без вотермаркинга у нас случайное сэмплирование. С вотермаркингом — справа на слайде — сэмплирование тоже случайное. Но вдобавок к чисто случайному сэмплированию появляется ключ вотермаркинга.
Этот ключ вотермаркинга передаётся генератору случайных чисел для установки конкретного сида — этот сид не фиксируется один раз на всю генерацию — иначе это была бы просто воспроизводимость, а не метка. Он работает на каждом шаге: ключ плюс несколько предыдущих токенов дают псевдослучайное число для этого конкретного выбора. Логиты модели при этом не меняются — подменяется только способ бросить кубик.
Поэтому водяной знак живет на этапе сэмплирования, а не внутри LLM. А значит, не нужно обучать или переобучать модели — нужно надстроить логику поверх декодера.
Как работает детекция водяного знака

Но мы ещё не закончили. Хочется также поговорить о том, как понять или проверить, есть ли у текста водяной знак. Детекция водяного знака возможна только при наличии доступа к ключу.
Поэтому если у нас есть несколько текстов, то узнать про водяной знак просто так невозможно — потому что для этого нужен ключ вотермаркинга. Нужна скоринговая функция, которой вы, по сути, оцениваете текст. И идея такая: если оценка выше определённого порога, значит, текст промаркирован; иначе — нет. Но мы как конечные пользователи сделать этого не можем, поскольку ключа у нас нет и никто его не даст.
Ключ будет только у Anthropic, хотя в блог-посте упоминается, что они, конечно, предоставят доступ — точнее, собираются разработать для этого API. Деталей нет, но, возможно, они дадут такой доступ по API для компаний, которым необходимо помечать сгенерированный контент, например, для X или Substack.
А может, такой доступ откроют и для конечных пользователей. Но суть в следующем: детекция водяного знака возможна только при наличии ключа вотермаркинга — ну или того самого API, который они собираются разработать.
Как удалить водяной знак

А вот удаление водяного знака — это интересно. Теперь, когда мы знаем, как работает вотермаркинг, мы понимаем и его слабые места: всё критически зависит от конкретных токенов на определённых позициях. Например, если в тексте ниже выделенные цветом слова (токены) — это позиции вотермаркинга, то мы знаем, что могли бы удалить водяной знак, отредактировав их, верно? Заменив все слова на этих позициях, мы бы со стопроцентной гарантией сломали водяной знак.
Но проблема в том, что мы этих позиций не знаем.

Мы не знаем, где находятся эти слова, потому что не мы генерировали водяной знак — а значит, не знаем, на какие позиции смотреть. Практический сценарий здесь такой: просто редактировать текст наугад. Мы случайным образом меняем несколько слов и надеемся, что затронули достаточно позиций, чтобы повредить водяной знак и фактически его удалить. И поскольку мы также не знаем, какие токены имеют наивысшие оценки — для этого понадобился бы доступ к той самой LLM, чтобы заново прогнать через неё промпт и выяснить это, — нам остаётся только гадать.
Например, мы можем заменить «overcast» на «cloudy» («облачная») — ведь мы не знаем, что высокую оценку имело именно «gray». В данном случае вариант «gray» может показаться интуитивно очевидным, но бывают случаи, где всё далеко не так очевидно. Главная идея: это просто обычное редактирование текста, при котором мы меняем какие-то позиции, но это по-прежнему лишь гадание, где находятся позиции вотермаркинга.
Поскольку мы их не знаем, мы просто должны заменить несколько слов тут и там. И если этих измененных слов достаточно много, это тоже сломает водяной знак.
Как работает скоринговая функция водяного знака
Это был вотермаркинг в двух словах. Выше упоминалась скоринговая функция, позволяющая выяснить, есть ли в тексте водяной знак, — давайте посмотрим на нее детальнее. Она немного сложнее, и для общей картины понимать её устройство не обязательно.
Причина, по которой она устроена именно так, — удешевление детекции. Потому что иначе пришлось бы для каждой проверки снова прогонять весь промпт, получать оценки, затем применять сид вотермаркинга и сравнивать еще раз. Это дорого.
К тому же нужно знать, какая именно LLM использовалась, — а это делает всю затею практически нереализуемой, ведь зачастую мы даже не знаем промпта. Так что у них есть трюк: они, скажем так, модифицируют сэмплирование таким образом, чтобы на этапе скоринга LLM была уже не нужна. В блог-посте упоминается, что метод они позаимствовали из научной статьи в Nature от DeepMind.
Метод называется SynthID-Text, и Anthropic прямо говорит: их вотермаркинг — версия SynthID-Text, но под капотом все детали настройки ожидаемо неизвестны.
SynthID-Text и турнирное сэмплирование

Всё предыдущее про генерацию по-прежнему верно, но появляются новые нюансы в том, как сэмплируется токен.
Они используют не просто, условно, random.choice из NumPy — здесь применяется кое-что более изощрённое.

Итак, снова предположим, что наш контекст — «the weather today is cold», и мы хотим сгенерировать следующий токен. Возьмём, например, варианты: «gray», «overcast», «gloomy» («мрачная»), «cloudy». Вероятность «gray» — 50%, «overcast» — 30%, «gloomy» — 15%. Пусть «cloudy» — 5%, а всё остальное — условно 0. На рисунке всё выглядит немного иначе — переиспользуется старая иллюстрация. Но представьте, что это самые вероятные токены — «gray» и «overcast», — а всё остальное пренебрежимо мало, кроме разве что «gloomy» и «cloudy».
Для понимания примера лучше всего представить маленький словарь из четырёх токенов вместо всех возможных. И мы могли бы использовать random.choice из NumPy с этими вероятностями, чтобы сэмплировать следующий токен.

И мы могли бы использовать ключ вотермаркинга с генератором случайных чисел, чтобы сделать сэмплирование детерминированным и получить нужный нам водяной знак. Но это было бы дорого — не само сэмплирование — с ним всё в порядке, оно довольно дешёвое. Дорогой была бы последующая детекция, если мы захотим проверять случайные тексты из интернета.

Вместо этого у них есть механизм, который применяется прямо при сэмплировании, то есть во время генерации, — так, чтобы его можно было повторно использовать потом, при детекции. Этот механизм называется турнирным сэмплированием. То есть вместо чего-то вроде random.choice они используют концепцию турнирного сэмплирования.
Как это работает? На первый взгляд может показаться сложным, но, честно говоря, выглядит это куда сложнее, чем есть на самом деле — стоит один раз уловить суть — и дальше всё довольно прямолинейно.
У нас по-прежнему есть контекст, а к нему — вероятные (правдоподобные) следующие токены с их вероятностями. Теперь — у них есть то, что называется случайными функциями вотермаркинга.
Случайные функции вотермаркинга

У нас три функции вотермаркинга: G1, G2 и G3. В реальности их может быть 30, 50 и даже больше — здесь три просто потому, что так нагляднее на слайде: компактнее и лучше помещается. Теперь посмотрим на слово «gray» — оно может дать нам сигнатуру 101. Что я имею в виду: мы используем ключ вотермаркинга для генерации сида, и у нас есть три функции — G1, G2, G3.
Я подаю на вход слово «gray». Здесь опускается одна деталь: обычно на вход подаётся не одно слово, а вместе с тремя-четырьмя предыдущими словами контекста — то есть «cold» и «gray». Так вот, если подать это в G1 вместе с ключом вотермаркинга, получим значение 1. Почему? Просто так работает эта функция — она случайная. Случайная функция возвращает либо 0, либо 1. В данном случае, с этим ключом и этим токеном, она возвращает 1.
С тем же ключом, но другой функцией, получаем 0. А вот здесь — снова 1. И если функций больше — скажем, все 30, — сигнатура превратится в очень длинную строку из нулей и единиц.

По сути, это битовая строка — набор битов из нулей и единиц, и для «gray» через функции вотермаркинга получилась сигнатура 101. Теперь то же самое можно проделать и для всех остальных токенов: для «gray» уже сделали, дальше — «overcast», «gloomy» и «cloudy». У каждого получается своя сигнатура.
Например, у «overcast» — 010, у «gloomy» — 001, у «cloudy» — 100. Следующий шаг — собственно турнирное сэмплирование, где мы просто разбиваем токены на пары.
Одно важное упрощение: на самом деле в турнире играют не «все кандидаты по разу», а пул токенов, насэмплированных из распределения модели — частые токены попадают туда по несколько раз. Так вероятности модели продолжают управлять результатом, и текст не портится.
Турнирное сэмплирование

Это как футбольный турнир на стадии плей-офф (на вылет): всегда играют две команды друг против друга. Здесь та же идея: у нас пара токенов, и они, по сути, соревнуются между собой. А очки берутся из тех самых функций. В первом раунде начинаем с первой функции.
Итак, пара «cloudy» и «gray».
Смотрим в таблицу: у «gray» — 1, у «cloudy» — 1, получается счёт 1:1. Пара «overcast» и «gray»: у «overcast» — 0, у «gray» — 1. Получаем 0:1. Пара «gloomy» и «overcast»: у «gloomy» — 0, у «overcast» — 0. Счёт 0:0. И затем «gray» против «gray» — дубликаты тут норма: частые токены попадают в пул по несколько раз.
Пары формируются случайно. Итак, здесь у нас 1:1 — ничья. При ничьей победитель тоже выбирается случайно — вот тут ключ уже ни при чём. Здесь выживает «cloudy». А в этой паре, согласно G1, побеждает «gray» — у него единица. «Gray» проходит дальше. Дальше у «gloomy» и «overcast» ничья — победитель выбран случайно [«overcast»], и последний «gray» тоже выбран случайно.
Теперь у нас «cloudy» и «gray», «overcast» и «gray» — играем следующий раунд турнира. В этом раунде используется G2. Согласно G2, у «cloudy» — 0, у «gray» — тоже 0. У «overcast» — 1, и у «gray» — тоже 0. И далее — следующая стадия турнира.

Итак, ничья — случайно выбираем «gray». А здесь победителем выходит «overcast». В финале — «gray» против «overcast». Снова смотрим на очки: у «gray» — 1, у «overcast» — 0. Побеждает «gray». Вот так и сэмплируется токен «gray». А что здесь делает ключ вотермаркинга? Если вернуться на несколько картинок назад: ключ участвует в генерации этих оценок через случайные функции вотермаркинга.
То есть ключ вотермаркинга, по сути, определяет, какие значения мы получаем на всех этих стадиях. Так что ключ по-прежнему критически важен — с другим ключом все сигнатуры выглядели бы иначе.
Детекция водяных знаков без повторного запуска LLM

Мы сэмплировали следующий токен — именно так и работает эта модифицированная процедура сэмплирования. Мы могли бы обойтись random.choice из NumPy, но у этого подхода есть недостаток: если мы захотим заскорить случайный текст из интернета, придётся заново запускать LLM.
С этой же техникой — не придётся. Да, техника звучит очень странно и громоздко, но её преимущество в том, что теперь мы можем гораздо проще скорить случайные тексты без повторного дорогого запуска языковой модели.
По сути, всё это сделано лишь для того, чтобы детекция была проще и дешевле. Честности ради: без прогона LLM детектируются и другие схемы вотермаркинга, но фича именно турнира в другом — каждый слой добавляет сигнала, и знак ловится надёжнее при том же качестве текста.

Давайте представим, что наш пример «the weather today is cold and gray» — это новый текст, найденный в интернете. Для этого у нас — точнее, у Claude/Anthropic — есть ключ вотермаркинга и те самые функции G1, G2 и G3.
Текст прогоняется через эти функции. Для одной позиции — для «gray» — мы получим 101, так же, как получали в процессе генерации. То есть всё как раньше. И если сложить эти биты, получится два бита: единица и единица. Скажем для простоты, что в этой позиции два бита информации. Это, конечно, очень упрощённая иллюстрация.
Предположим, что для «gray» в этой позиции мы получаем оценку 2. Если бы на этой позиции стояло другое слово — «overcast», — мы получили бы 1; для «gloomy» — тоже 1, и для «cloudy» — 1. То есть я просто суммирую значения по каждой строке. Это и есть оценка, которую мы получаем на каждой позиции.
Если проделать то же самое на других позициях, оценки на них будут другими. Например, предположим, что на первой позиции я получаю 2. Здесь — 2. Для «today» — 3. Для «is» — 2. «Cold» — 2. И «gray» — 3. То есть я применяю функции вотермаркинга так, как показал на предыдущем слайде.

И я просто складываю эти числа по трём функциям. Функции вотермаркинга очень дешёвые — их можно быстро прогнать по всему тексту и получить все оценки. А затем на их основе вычислить среднее число бит. Усреднив все эти значения, я получу, скажем, 2.23.

Теперь возьмём немного другой текст: я заменил «today» на «now» и «gray» на «overcast». Эти позиции теперь получают оценки 1 и 1. И если усреднить по всей строке, выходит 1.71. И для всего этого мне не нужна LLM. Всё, что нужно, — ключ вотермаркинга, генератор случайных чисел и функции G1, G2, G3. И всё.
LLM не нужна — а оценку получить можно, остается только подобрать порог.

Условно, если оценка больше 2, текст вотермаркирован; если меньше 2 — нет.
Вот так и можно детектировать, есть ли водяной знак в случайном тексте из интернета. По сути, это просто применение функций вотермаркинга, усреднение оценок и сравнение с порогом.
Итоги и ограничения вотермаркинга

Разница между генерацией без вотермаркинга и с ним в том, что мы управляем сэмплированием с помощью ключа вотермаркинга. А внутри этого процесса работает турнирное сэмплирование. И для этой детекции водяных знаков нужны секретный ключ и функции вотермаркинга G1…Gn.

И снова про удаление водяного знака — как самую интересную часть. В идеале нужно было бы отредактировать все позиции вотермаркинга для его гарантированной поломки, но мы не знаем, какие именно позиции вотермаркированы. Внутри же позиции выбираются так, чтобы на них были почти равновероятные токены — а есть позиции, где это условие не выполняется. Например, для «trees» может вообще не найтись альтернативного слова с высокой оценкой — поэтому такую позицию они не вотермаркируют.
То есть вотермаркинг применяется, по сути, только на определённых позициях. А поскольку мы не знаем, какие позиции нужно «атаковать», чтобы сломать или удалить водяной знак, нам пришлось бы редактировать текст сразу в нескольких местах.

Что это значит для сгенерированного текста
Для нашего прекрасного будущего вотермаркинг может привести к ухудшению качества сгенерированных ИИ текстов. Потому что генеративный слоп заполонил весь интернет, где-то на нем даже зарабатывают деньги, и потому вотермаркинг такие фабрики не остановит.
Поэтому они просто возьмут еще одну модель.

Они просто будут использовать вторую модель для редактирования текста и получать, так сказать, отредактированный сгенерированный ИИ текст. То есть пайплайн усложняется: вместо того чтобы брать текст напрямую из Claude, теперь Claude генерирует текст, этот текст прогоняется через локальную модель — и на выходе получается отредактированный сгенерированный текст, в котором водяного знака, скорее всего, уже нет.
Почему вероятна именно локальная модель? Потому что Google ведь написали ту статью, верно? Поэтому с огромной вероятностью Gemini тоже вотермаркирует контент. И OpenAI, вероятно, уже делает это или будет делать, как и все остальные ведущие лабы мира. Летом 2026 года около 190 компаний подписали кодекс прозрачности (приложение к европейскому AI Act), поэтому вотермарки так или иначе будут у всех.
А если коррекцию будет делать локальная модель, то с огромной вероятностью она будет меньше фронтирной. Технически, конечно, можно было бы генерировать текст сразу локальной моделью, но фронтирные модели гораздо точнее работают с поиском, делают фактчекинг и производят контент на порядок лучше. Поэтому первая генерация будет фронтирной моделью и затем финальное доведение моделью локальной.
И это доведение будет нацелено на обход вотермарка, а, как уже знаем, это лишь попытка угадать провотермаченные позиции, что в случае с локальными моделями и грозит ухудшением текста. То есть, у нас по-прежнему генеративный слоп, но к тому же неуклюже отредактированный, чтобы обходить слоп-фильтры.
Заключительные мысли
Целью этой статьи было познакомить с тем, что слоп-маркировка на текстовый контент это не идеи поехавших, а наша реальность и у задачи есть вполне красивое инженерное решение. Оно под капотом не такое сложное, но и совсем тривиальным его не назовешь.
Надеюсь, вам было полезно и интересно!
Мой канал про агентов, LLM, продукты и людей: Agentic World и другие статьи:
Комментарии (24)

Recursicorn
31.08.2026 09:25Спасиьо за разбор!
Минусы, у внедрения, конечно же есть, что бы ни говорили Антропики.
Во-первых, у нас забрали температуру и другие параметры сэмплинга. Когда забирали - писали что "современным моделям это не надо" и "они тренируются под определенную температуру", но теперь стало ясно почему на самом деле убрали.
Во-вторых, судя по всему пострадает разнообразие генерации на одинаковом входе. Хочу я 50 раз запустить одну и ту же задачу на разных сидах чтобы проверить консистентность ответа, а сиды теперь не разные. Наверное, секретных сидов все же не один, но уже и не миллион.
Иноеречно, кто-то пробовал генерировать ответ и смотреть через сколько циклов он начнет повторяться?

WhiteBehemoth
31.08.2026 09:25Знать, какой текст сгенерирован иишкой - в общем-то полезно. Не понимаю, что некоторые авторы так возбудились на это? В идеале вообще было бы здорово, чтоб после каждого сгенерированного текста стояла подпись, которую при желании, можно было бы дешифровать в "<модель LLM>, <agent> [Skills used], <user prompt summary>"

grvelvet
31.08.2026 09:25Возбудились нейрослоперы пачками шлепаюшие тексты, в коде это значения не имеет.

akakoychenko
31.08.2026 09:25А история то про кругу ходит. В лохматые года сеошники заменяли слова синонимами, чтобы засрать интернет. Потом поисковики стали умнее. Теперь эти древние говнометы снова расчехлят, но уже под другую цель

rrrrex
31.08.2026 09:25И что в будущем помешает держать на компьютере модель без всяких ключей, которая будет переписывать готовый текст. Ватермарки должны быть глобальные в таком случае, привязаны к целым абзацам, причем не точно, а вероятностно. К примеру, статья о бутерброде с сыром, 10 абзацев с последовательностью: введение, выбор хлеба, выбор сыра, виды сыра, нарезка хлеба и т.д. то есть сама структура статьи должна выдавать ИИ.

Barnaby
31.08.2026 09:25Если я правильно понял логику - очень элегантное решение. Причем чем креативнее текст, тем больше туда можно встроить паттернов и шанс детекта будет только выше, даже если для человеков текст будет выглядеть как полностью авторский.
Правда, все равно будут false-positive, так что люди смогут спорить что они это сами написали просто попав в тот самый процент. Или что они написали все сами, а иишкой только ошибки и неточности исправили.

MxMaks
31.08.2026 09:25Но эти тексты потом читаются людьми и люди со временем перенимают манеру подачи информации ИИ и потом сами пишут тексты. Получается что такой ватермарк окажет влияние на культуру речи человека и со временем, чтобы снова научиться детектить ИИ тексты этот ватермарк для ИИ генерации текстов придется убрать)

Barnaby
31.08.2026 09:25Не должны. Люди ищут закономерности, а там их не будет - смысл токенов никак не участвует в выборе, по сути он будет случайный - как цифры числа Пи. И люди воспринимают слова, а там вообще будут токены.

LimTroev
31.08.2026 09:25Да и сколько будет промахов при детекте. Вспомните про правильные длинные дефисы и прочее, по которым "дектектили".

grigr
31.08.2026 09:25Идея с синонимами хороша. Но обычно только для английского текста, где токены это отдельные слова. В русском тексте все сложнее будет... Но тоже может работать
Тут наверно только пересказ текста поможет любой другой моделью

Ioanna
31.08.2026 09:25То есть эта технология работает только там, где генеративная модель выбирала случайный токен из нескольких равнозначных вариантов? Но они же не всегда равнозначны?

wmlab
31.08.2026 09:25У меня вопрос - а разве для определителя водяного знака, кроме текста и секретного ключа не нужен еще контекст этого текста плюс системный промпт? Ведь привести LLM в исходное состояние без стартового seed не получится?

0xC0CAC01A
31.08.2026 09:25Т.е. перевести гугл-транслейтом туда-сюда и всё, нет больше водяного знака?

adsumushero
31.08.2026 09:25Думаю да, но есть вероятность что Гугл пометит перевод своей маркой, там же Gemini под капотом.

adsumushero
31.08.2026 09:25Особых слов на самом деле нет. На каждом токене модель кидает свой подкрученный кубик. И далее всё зависит от того, был ли у неё выбор. Например: "Погода была холодная и ___" - вариантов много (серая, облачная, дождливая). Кубик реально влияет на выбор и выбранное слово с большей вероятностью окажется согласованным с ключом. При проверке такое слово даёт условно, +1 очко. Или "свет проходит сквозь ___ деревьев" тут только кроны. Кубик кидается, но выбора нет, слово одно. При проверке оно даёт очки как случайное.
Никто заранее не решает здесь метим, здесь нет. Метка размазана по всем словам, просто где-то она прям густая, где-то около нулевая.

powerman
31.08.2026 09:25Мы могли бы обойтись
random.choiceиз NumPy, но у этого подхода есть недостаток: если мы захотим заскорить случайный текст из интернета, придётся заново запускать LLM.С этой же техникой — не придётся.
Это ключевой момент, и именно он неясен. Оба подхода базируются на том, что известны 4 варианта следующего слова с их вероятностями - откуда возьмётся эта информация при проверке текста без запуска LLM, причём именно той, которая использовалась при создании текста?
alivedsn
Возможно, я ничего не понял - но: для слома вотермарка, возможно - надо не менять некоторые слова, а просто переставлять их (особенно если используются ещё несколько предыдущих). Одна такая перестановка в начале текста (не cold and overcast, а overcast and cold) - и вся остальная вотермарка - насмарку. Конечно, надо ещё угадать, что переставлять - но, скорее всего, если перефразировать самую первую фразу в тексте - вуаля. Вообще анализ вотремарка (по идее) должен был бы происходить, например, не от начала к концу текста, а от конца к началу - это бы исключало всякий осмысленный контекст и вмешательство ИИ, делало бы проверку строгой и независимой. Однако никакой возможности для этого я лично не вижу.
Кроме того, каждый следующий текст (на основе того же промпта) может отличаться от предыдущего уже хотя бы потому, что модели развиваются и дообучаются. И учесть "версию модели" не удастся (слишком они громоздкие, чтобы их все хранить).
Гораздо проще тупо запоминать все тексты, которые когда-либо выдала данная модель. Хотя бы на уровне хэшей. И тупо проверять по базе хэшей. Знаю - это тоже приличный идиотизм. Но по ощущению - идиотизм не хуже данных вотермарков...
evgenstf
Там не совсем так работает. Тест проходит скользящим окном (а не всем префиксом) по тексту и для каждого окна высчитывает сигнал "следующий токен был сгенерирован", поэтому перестановка слов ломает знак только в паре соседних позиций, а не во всём тексте. Плюс тест вероятностный, а не точный - он суммирует сигналы по всем окнам и на выходе выдает "насколько вероятно, что в тексте есть ватермарка". Более того, поскольку нам не известен ключ, мы не можем обнаружить все маркирующие места и поменять их. Кажется более-менее рабочий способ только попросить переформулировать текст другую llm, про которую известно, что она ватермарку не проставляет.
Gardeffer
А что если удалять некоторые предложения? Скажем нейронке сгенерировать тест на 100 вопросов, а возьмём каждый десятый. Как счёт поведет себя в этом случае?
evgenstf
Пока что трудно сказать наверняка, насколько этот тест устойчив к манипуляциям с текстом -- антропик еще не открыл апи, и без конкретных экспериментов этого не понять.
Но я бы предположил, что "маркерные" места равномерно распределены, и если взять достаточно большие куски вроде абзацев, ватермарка статистически сможет себя проявить.
freeExec
В статье примерно было видно, что в одном предложении 2+ сигнала. Поэтому оперировать предложениями бесполезно.