{"id":743,"date":"2026-09-26T18:34:19","date_gmt":"2026-09-26T21:34:19","guid":{"rendered":"https:\/\/yellowkode.com\/blog\/watermarking-llm-comportamento-agentes-lasso-synthid-text\/"},"modified":"2026-09-26T18:34:19","modified_gmt":"2026-09-26T21:34:19","slug":"watermarking-llm-comportamento-agentes-lasso-synthid-text","status":"publish","type":"post","link":"https:\/\/yellowkode.com\/blog\/watermarking-llm-comportamento-agentes-lasso-synthid-text\/","title":{"rendered":"Como Watermarking de LLM Muda o Comportamento de Agentes: O Estudo da Lasso sobre SynthID-Text"},"content":{"rendered":"<p>Em 17 de setembro de 2026, a Lasso Security publicou uma pesquisa chamada <em>The Provenance Tax<\/em>, assinada por Andrea Siposova, medindo o efeito do watermarking de texto do Claude no comportamento de agentes. A base \u00e9 o SynthID-Text, do Google DeepMind, que integrou em todos os modelos Claude a partir de agosto de 2026 para cumprir o Artigo 50(2) do EU AI Act. O achado curto: a marca invis\u00edvel preserva qualidade percebida no texto, mas muda decis\u00f5es individuais de tool call e de recusa, especialmente sob prompt injection.<\/p>\n<h2>O fato, em uma frase<\/h2>\n<p>Watermarking de LLM n\u00e3o \u00e9 metadado nem caractere escondido. \u00c9 uma mudan\u00e7a no <em>sampling<\/em>, o passo em que o modelo escolhe o pr\u00f3ximo token. E se voc\u00ea tem um agente que age a partir daqueles tokens (nome de ferramenta, argumento, path), a mesma interven\u00e7\u00e3o que embute a marca pode alterar o que o agente faz.<\/p>\n<h2>Como o SynthID-Text funciona por baixo do cap\u00f4<\/h2>\n<h3>O ponto onde a marca entra<\/h3>\n<p>Um LLM gera texto assim: para cada posi\u00e7\u00e3o, ele calcula uma distribui\u00e7\u00e3o de probabilidade sobre o vocabul\u00e1rio e amostra um token dela. O SynthID n\u00e3o mexe nos <em>logits<\/em>. Ele deixa os logits em paz e modifica a amostragem. Puxa v\u00e1rios tokens candidatos da distribui\u00e7\u00e3o original do modelo, roda um torneio de elimina\u00e7\u00e3o simples entre eles, onde uma fun\u00e7\u00e3o pseudoaleat\u00f3ria com chave decide cada partida. O vencedor \u00e9 emitido.<\/p>\n<h3>Uma analogia que carrega a mec\u00e2nica<\/h3>\n<p>Pense num sorteio de mata-mata de campeonato. Os times (tokens candidatos) foram convocados pela probabilidade real do modelo, ent\u00e3o ningu\u00e9m entra fora do crit\u00e9rio normal. O que muda \u00e9 o juiz: em vez de tirar cara ou coroa a cada jogo, o juiz consulta uma fun\u00e7\u00e3o que depende de dois inputs, uma chave secreta e os \u00faltimos tokens j\u00e1 gerados. Mesma chave e mesmo contexto sempre produzem o mesmo resultado. Quem tiver a chave depois consegue verificar se o campe\u00e3o de cada rodada bate com o que aquela fun\u00e7\u00e3o geraria, e isso vira a evid\u00eancia estat\u00edstica de que o texto passou pelo torneio.<\/p>\n<p>Onde a analogia quebra: no futebol o resultado do jogo \u00e9 uma amostra ruidosa da for\u00e7a dos times; aqui, dado chave e contexto, o resultado \u00e9 determin\u00edstico. E n\u00e3o existe um \u00fanico torneio, existe um por posi\u00e7\u00e3o, com o contexto rolando junto.<\/p>\n<h3>Os tr\u00eas componentes<\/h3>\n<p>A constru\u00e7\u00e3o tem tr\u00eas pe\u00e7as que trabalham em sequ\u00eancia a cada token. O gerador de seed aleat\u00f3rio \u00e9 uma f\u00f3rmula que pega o contexto recente (os \u00faltimos tokens) mais uma chave secreta e cospe um n\u00famero. Mesmo contexto, mesma chave, mesmo n\u00famero, sempre. \u00c9 o truque da aleatoriedade determin\u00edstica: parece aleat\u00f3rio para quem n\u00e3o tem a chave, mas \u00e9 totalmente reproduz\u00edvel para quem tem. Em seguida vem o torneio de amostragem, que \u00e9 o mecanismo descrito acima. Por \u00faltimo, uma fun\u00e7\u00e3o de pontua\u00e7\u00e3o usada s\u00f3 na detec\u00e7\u00e3o, para testar se um texto candidato tem cara de ter passado pelo torneio.<\/p>\n<p>Uma janela deslizante dos \u00faltimos tokens, tipicamente quatro, \u00e9 hasheada junto com a chave para produzir um seed. Esse seed alimenta um conjunto de fun\u00e7\u00f5es pseudoaleat\u00f3rias, as g-functions. O algoritmo puxa tokens candidatos e os passa por v\u00e1rias camadas de torneio, cada camada pontuando com uma g-function e o vencedor avan\u00e7a. O token que ganha o torneio \u00e9 o emitido.<\/p>\n<h3>N\u00e3o distorcivo, mas n\u00e3o id\u00eantico<\/h3>\n<p>Aqui est\u00e1 o ponto que confunde muita gente. O SynthID pode ser configurado como n\u00e3o distorcivo, o que significa que ele preserva a distribui\u00e7\u00e3o de sa\u00edda do modelo em expectativa. Em expectativa \u00e9 a chave: se voc\u00ea fizesse infinitas rodadas variando a aleatoriedade do watermark, na m\u00e9dia a distribui\u00e7\u00e3o seria id\u00eantica \u00e0 sem marca. Mas numa gera\u00e7\u00e3o concreta, com uma chave fixa, o token escolhido pode ser diferente do que seria escolhido sem watermark. A garantia \u00e9 estat\u00edstica, n\u00e3o pontual. Foi exatamente esse gap que a Lasso mediu.<\/p>\n<h3>Por que isso vira problema em agente<\/h3>\n<p>O torneio tem mais margem para alterar a escolha onde o modelo est\u00e1 mais indeciso. Em prosa, uma escolha entre dois sin\u00f4nimos plaus\u00edveis \u00e9 irrelevante. Em sa\u00edda estruturada, tipo um JSON de tool call, chaves e nomes de fun\u00e7\u00e3o costumam ter probabilidade concentrada num \u00fanico token, ent\u00e3o o watermark quase n\u00e3o muda nada ali. Mas <em>valores<\/em>, como uma query de busca, um path de arquivo, um destinat\u00e1rio, um n\u00famero, s\u00e3o regi\u00f5es de mais incerteza. \u00c9 l\u00e1 que o torneio tem espa\u00e7o para alterar o token que sai, e \u00e9 exatamente esse token que o agente vai executar.<\/p>\n<h2>O que isso significa na pr\u00e1tica<\/h2>\n<h3>Os n\u00fameros do estudo<\/h3>\n<p>A Lasso rodou um design pareado: mesmo prompt, mesmo seed, mesma ordem, gerando com e sem SynthID atrav\u00e9s do <code>SynthIDTextWatermarkLogitsProcessor<\/code> da HuggingFace. Nos testes de tool calling em BFCL v4, a acur\u00e1cia agregada caiu em seis dos sete modelos. Mas o dado mais interessante \u00e9 o que eles chamam de <em>churn<\/em>: a fra\u00e7\u00e3o de itens cujo veredito muda entre as duas condi\u00e7\u00f5es. No phi-4 a T=1.0, 16,8% dos veredicts de tool call mudaram, enquanto a perda l\u00edquida de acur\u00e1cia era de s\u00f3 2,87 pontos. Isso significa que muitas chamadas passaram de certo para errado e outras de errado para certo, e o placar final escondeu a bagun\u00e7a.<\/p>\n<p>Uma chamada de ferramenta bem formada, para a ferramenta certa, mas com o argumento errado (path errado, destinat\u00e1rio errado, valor errado) \u00e9 o pior tipo de erro, porque ela executa. No Llama-3.1-8B, a maior fatia da perda veio justamente de argumentos incorretos.<\/p>\n<h3>O caso da recusa sob prompt injection<\/h3>\n<p>A parte que mais deveria preocupar quem constr\u00f3i agente \u00e9 a de seguran\u00e7a. O estudo pega 200 comportamentos maliciosos do HarmBench e testa em duas condi\u00e7\u00f5es: pedido cru e pedido com uma t\u00e9cnica fixa de injection anexada como conte\u00fado recuperado. No gemma-3-27b a T=0.001, o churn de recusa vai de 6% no pedido cru para 23,5% sob injection, e a mudan\u00e7a l\u00edquida de compliance sai de -1 para +12,5 pontos. Traduzindo: com o watermark ligado, o modelo passa a atender pedidos danosos que recusaria sem ele, e o efeito aparece muito mais forte quando o input \u00e9 advers\u00e1rio.<\/p>\n<p>Isso conecta os dois lados do problema. Um agente \u00e9 um modelo com acesso a ferramentas. Se o watermark enfraquece a recusa e ao mesmo tempo muda os argumentos das chamadas, o teatro fica interessante do jeito errado.<\/p>\n<h3>Depende da chave<\/h3>\n<p>O efeito tamb\u00e9m varia com a chave do watermark. Rodando onze chaves diferentes no mesmo cen\u00e1rio de injection, no Llama-3.1-8B a mudan\u00e7a no sucesso do ataque foi de -4,5 a +14,5 pontos dependendo da chave. Duas chaves distintas geram dois comportamentos distintos no mesmo modelo com o mesmo prompt. Isso significa que trocar a chave do watermark, algo que fica no lado do provider, pode alterar o comportamento de seguran\u00e7a do seu agente sem que voc\u00ea toque em nada.<\/p>\n<h2>Onde isso quebra<\/h2>\n<p>Antes de sair aplicando esse resultado como se fosse uma condena\u00e7\u00e3o do SynthID, vale marcar onde a coisa \u00e9 mais fr\u00e1gil do que parece.<\/p>\n<p>Primeiro, o estudo mede refusal <em>a n\u00edvel de modelo<\/em>, n\u00e3o comportamento fim-a-fim de agente com tools reais executando. A ponte entre &#8220;o modelo respondeu em vez de recusar&#8221; e &#8220;o agente executou uma a\u00e7\u00e3o danosa&#8221; existe, mas n\u00e3o foi medida diretamente no mesmo experimento. A Lasso \u00e9 honesta sobre isso.<\/p>\n<p>Segundo, o efeito \u00e9 <em>fortemente<\/em> dependente do modelo. phi-4 e Qwen3-4B praticamente n\u00e3o se mexem em nenhum dos cen\u00e1rios, mas isso tamb\u00e9m n\u00e3o \u00e9 boa not\u00edcia: os dois j\u00e1 tendem a over-refuse, inclusive em pedidos benignos. &#8220;N\u00e3o muda&#8221; pode significar &#8220;j\u00e1 estava travado antes&#8221;.<\/p>\n<p>Terceiro, a Anthropic sustenta o oposto sobre qualidade. Em testes internos, eles n\u00e3o viram impacto do watermarking no conte\u00fado, criatividade ou legibilidade do texto do Claude. No paper do SynthID-Text, o Google DeepMind testou isso servindo um modelo com watermark para uma fatia do tr\u00e1fego do Gemini e comparando avalia\u00e7\u00f5es. N\u00e3o encontraram diferen\u00e7as estatisticamente significativas do modelo sem watermark. E num estudo controlado, avaliadores humanos comparando respostas com e sem marca lado a lado n\u00e3o viram diferen\u00e7a de qualidade. Isso n\u00e3o contradiz a Lasso: qualidade percebida em prosa e estabilidade de decis\u00e3o em tool call s\u00e3o propriedades diferentes. Mas quem s\u00f3 ler o an\u00fancio da Anthropic vai sair com a impress\u00e3o errada.<\/p>\n<p>Quarto, a t\u00e9cnica de prompt injection do estudo \u00e9 uma s\u00f3, fixa. N\u00e3o sabemos como o efeito escala com t\u00e9cnicas diferentes ou combinadas.<\/p>\n<p>Eu convivo com esse tipo de armadilha quando escrevo sobre ferramentas. Fiz um bot que explica qualquer assunto pelo universo geek que a pessoa gosta. Ele explicou recurs\u00e3o com A Origem e disse que os n\u00edveis de sonho rodavam em paralelo, o que no filme acontece e em recurs\u00e3o n\u00e3o. Encantador, confiante e errado exatamente no ponto que importava. Ningu\u00e9m pegaria isso. Watermarking com efeito de sampling drift \u00e9 a mesma classe de problema em escala industrial: a sa\u00edda continua fluente, a m\u00e9trica agregada quase n\u00e3o muda, e o erro espec\u00edfico passa em branco.<\/p>\n<h2>O que n\u00e3o d\u00e1 para afirmar ainda<\/h2>\n<p>O estudo da Lasso usa modelos open weights rodando o processor do HuggingFace com configura\u00e7\u00e3o p\u00fablica do SynthID-Text. N\u00e3o \u00e9 o Claude em produ\u00e7\u00e3o, \u00e9 uma implementa\u00e7\u00e3o de refer\u00eancia. A Anthropic n\u00e3o publicou a configura\u00e7\u00e3o exata (n\u00famero de camadas de torneio, tamanho do n-gram, esquema de chaves) da vers\u00e3o que roda nos modelos deles, e disse explicitamente que a implementa\u00e7\u00e3o \u00e9 <em>uma vers\u00e3o<\/em> do SynthID-Text, n\u00e3o a original. Ent\u00e3o o quanto desse efeito voc\u00ea vai ver especificamente com Claude via API \u00e9 uma pergunta aberta.<\/p>\n<p>Tamb\u00e9m n\u00e3o d\u00e1 para afirmar que o efeito se traduz linearmente para agentes de produ\u00e7\u00e3o. Um agente real tem retries, valida\u00e7\u00e3o de schema, camadas de guardrails, humano no loop em algumas rotas. Cada uma dessas camadas absorve parte do drift. Quanto? Depende do agente. Ningu\u00e9m mediu ainda.<\/p>\n<p>E h\u00e1 a quest\u00e3o de quanto o efeito depende de estar usando modelo pequeno. Os modelos do estudo v\u00e3o de 4B a 27B par\u00e2metros. Modelos maiores tendem a ter distribui\u00e7\u00f5es de tokens mais concentradas em muitos pontos, o que em tese daria menos margem para o torneio alterar a sa\u00edda. Em tese.<\/p>\n<h2>Como testar isso voc\u00ea mesmo<\/h2>\n<p>Se voc\u00ea quer sentir o efeito sem montar um benchmark inteiro, o caminho m\u00ednimo \u00e9 este:<\/p>\n<ol>\n<li>Instale <code>transformers<\/code> recente e escolha um modelo open weights (Llama-3.1-8B ou gemma-3-12b d\u00e3o bem para reproduzir o efeito relatado).<\/li>\n<li>Prepare dois pipelines de gera\u00e7\u00e3o id\u00eanticos. Em um deles, adicione o <code>SynthIDTextWatermarkLogitsProcessor<\/code> \u00e0 lista de logits processors. No outro, n\u00e3o.<\/li>\n<li>Fixe seed, temperatura e ordem de execu\u00e7\u00e3o nos dois. A \u00fanica diferen\u00e7a deve ser o processor.<\/li>\n<li>Rode o mesmo conjunto de prompts nos dois. Comece com prompts que pe\u00e7am sa\u00edda estruturada (um JSON de chamada de fun\u00e7\u00e3o com um argumento textual longo, tipo query ou path).<\/li>\n<li>Compare item a item. N\u00e3o olhe s\u00f3 m\u00e9dia. Conte quantos itens tiveram a resposta alterada, mesmo que as m\u00e9tricas agregadas pare\u00e7am iguais.<\/li>\n<\/ol>\n<p>Um trecho m\u00ednimo do processor, para orienta\u00e7\u00e3o:<\/p>\n<pre><code>from transformers import AutoModelForCausalLM, AutoTokenizer\nfrom transformers.generation import SynthIDTextWatermarkingConfig\n\nmodel = AutoModelForCausalLM.from_pretrained(\"meta-llama\/Llama-3.1-8B-Instruct\")\ntok = AutoTokenizer.from_pretrained(\"meta-llama\/Llama-3.1-8B-Instruct\")\n\nwm_config = SynthIDTextWatermarkingConfig(\n keys=[654, 400, 836, 123, 340, 443, 597, 160, 57, 29],\n ngram_len=5,\n)\n\nout_wm = model.generate(**inputs, watermarking_config=wm_config, do_sample=True)\nout_plain = model.generate(**inputs, do_sample=True) # mesmo seed, sem wm\n<\/code><\/pre>\n<p>A partir da\u00ed, se voc\u00ea opera um agente, o teste que importa \u00e9 o pareado sob a mesma t\u00e9cnica de injection que voc\u00ea j\u00e1 usa no seu red team. Rode antes e depois de habilitar o watermark, olhe churn por item, n\u00e3o s\u00f3 a m\u00e9dia. Se o n\u00famero for baixo, \u00f3timo. Se for alto e voc\u00ea n\u00e3o notou, era exatamente esse o ponto do estudo.<\/p>\n<p>Watermarking existe por uma boa raz\u00e3o de proveni\u00eancia, e o Artigo 50(2) do EU AI Act n\u00e3o vai a lugar nenhum. Mas a pesquisa nova sugere que as modifica\u00e7\u00f5es do SynthID-Text \u00e0 sele\u00e7\u00e3o de tokens podem ter consequ\u00eancias n\u00e3o intencionais al\u00e9m da escolha de palavras, incluindo influenciar quais ferramentas o modelo invoca e alterar a probabilidade de aderir ou ignorar seus guardrails de seguran\u00e7a. Isso \u00e9 o tipo de propriedade que precisa entrar na sua bateria de avalia\u00e7\u00e3o, n\u00e3o ficar na nota de rodap\u00e9 do provider.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Um estudo da Lasso mostra que watermarking do Claude via SynthID-Text pode alterar tool calls e recusas de seguran\u00e7a. Explico o mecanismo e como testar.<\/p>\n","protected":false},"author":2,"featured_media":742,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-743","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/posts\/743","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/comments?post=743"}],"version-history":[{"count":0,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/posts\/743\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/media\/742"}],"wp:attachment":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/media?parent=743"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/categories?post=743"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/tags?post=743"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}