Content-Signal no robots.txt não chega aos crawlers de IA: o erro foi nosso

Content-Signal no robots.txt não chega aos crawlers de IA: o erro foi nosso

Última verificação: 18 de setembro de 2026
13 min de leitura
Guia
500+ projetos WP
SEO técnico

A nossa reserva de direitos sobre treino de IA estava escrita para ninguém. A linha Content-Signal: search=yes, ai-input=yes, ai-train=no aparecia no robots.txt de wppoland.com exatamente uma vez, no grupo User-agent: *, e por baixo dela estavam vinte grupos de crawlers nomeados.

Segundo o RFC 9309, nenhum desses vinte grupos herda o que quer que seja do grupo do asterisco. O GPTBot, o ClaudeBot, o PerplexityBot, o Google-Extended e o resto da lista liam apenas as suas próprias secções, onde essa linha não existia.

Cada crawler que tivemos o cuidado de nomear à mão era precisamente o crawler que não conseguia ver aquilo que escrevêramos para ele.

Escrevemos sobre isto porque o ficheiro é nosso e o erro também. Verificávamos o robots.txt para perceber se não estaria a bloquear alguma coisa por engano, e nunca para perceber se a declaração chegava sequer ao destinatário.

#O que estava exatamente no ficheiro

A estrutura era a que se vê na maioria dos ficheiros que já abrimos: um grupo geral no topo e, por baixo, uma lista de bots nomeados com regras Allow alargadas para endpoints destinados a máquinas.

User-agent: *
Content-Signal: search=yes, ai-input=yes, ai-train=no
Allow: /
Disallow: /cdn-cgi/

Sitemap: https://wppoland.com/sitemap-index.xml
Agentmap: https://wppoland.com/.well-known/ai-catalog.json

User-agent: GPTBot
Allow: /
Allow: /llms.txt
Allow: /facts.json

User-agent: ClaudeBot
Allow: /

User-agent: PerplexityBot
Allow: /

Parece arrumado. O sinal está lá, os grupos nomeados estão lá, os endpoints para agentes estão listados à parte. O problema é que estas duas coisas não têm contacto uma com a outra. Quem lê o ficheiro como documento vê uma política no topo e um conjunto de permissões por baixo, e acrescenta mentalmente uma relação entre as duas que o parser desconhece: o parser não lê documentos, compara um token com uma lista de nomes, fica com o bloco vencedor e deita fora o resto do ficheiro antes de ler uma única diretiva.

#Porque é que uma linha não cobre o ficheiro inteiro

O cliente compara o seu product token com os nomes nas linhas User-agent, sem distinguir maiúsculas de minúsculas, e aplica um grupo: aquele que o nomeia. O asterisco não é o padrão menos específico, é o recurso alternativo, e o RFC 9309 só o usa quando nenhum grupo nomeia o cliente. Quando existe grupo nomeado, o cliente aplica apenas as diretivas desse grupo e o grupo do asterisco deixa de lhe dizer respeito na totalidade. A última frase é o erro inteiro: lê-se como óbvia na especificação e deixa de ser óbvia no momento em que a confrontamos com um ficheiro escrito por nós, porque um ficheiro escrito por nós transporta a nossa intenção, e a intenção é invisível para o único leitor que conta.

Isto não é uma exceção criada para os Content Signals. A mesma regra sempre valeu para Allow e Disallow, e é exatamente por isso que um ficheiro onde alguém acrescentou Disallow: /wp-admin/ só no grupo do asterisco não protege nada contra um bot que tem a sua secção mais abaixo. A diferença está no que vem a seguir.

Com Disallow, a consequência vê-se: a página aparece no índice ou não aparece, e uma semana de dados de indexação diz qual dos dois aconteceu. Com Content-Signal não se vê nada, em nenhuma direção, porque uma declaração de direitos não tem retorno, e uma declaração errada produz exatamente o mesmo histórico observável que uma correta durante todo o tempo que lhe quisermos dedicar.

Content Signals é uma proposta da Cloudflare e não faz parte do RFC 9309, e a Cloudflare ativa esta política por omissão no seu ficheiro robots.txt gerido. O mecanismo de grupos onde essa linha vive, esse, é inteiramente o mecanismo do RFC 9309, por isso a regra do grupo único aplica-se-lhe como a tudo o resto no ficheiro. Uma diretiva nova dentro de um contentor antigo herda as regras do contentor, incluindo aquelas que ninguém foi confirmar antes de a acrescentar.

#Três sinais e aquilo que não prometem

A especificação define três sinais, cada um com valor yes ou no:

SinalA que se aplica
searchconstrução de um índice de pesquisa e devolução de resultados, ou seja, ligações e excertos curtos
ai-inputentrega do conteúdo à entrada de um modelo de IA no momento da resposta, ou seja, RAG e fundamentação de respostas
ai-traintreino e afinação de modelos

O nosso conjunto search=yes, ai-input=yes, ai-train=no é uma escolha consciente, e o compromisso que existe dentro dela merece ser dito sem rodeios. Queremos ser citados em respostas generativas, porque hoje esse é um dos canais por onde alguém nos encontra, e não queremos entregar o corpus para treino, porque um modelo treinado leva o texto consigo sem deixar caminho de volta ao sítio de onde ele veio. Dizer sim ao primeiro e não ao segundo é aceitar que o mesmo crawler pode estar a fazer os dois trabalhos em dias diferentes, e confiar que ele distingue os dias. A ausência de sinal significa uma terceira coisa, diferente de no: o operador do site não dá consentimento nem o recusa por esta via, e é por isso que o silêncio aqui não equivale a recusa.

Nenhum destes sinais bloqueia o que quer que seja. É uma linha de texto num ficheiro que o cliente pode descarregar ou não, ler ou não e respeitar ou não. O servidor responde ao pedido independentemente do que lá esteja escrito. O bloqueio é uma camada separada, avaliada antes da aplicação, e faz-se com regras de WAF, limites de pedidos ou verificação da identidade do bot, e essa camada custa: corre em cada pedido, pode enganar-se a respeito de uma pessoa e precisa de manutenção à medida que os sinais de identidade mudam.

Uma declaração não custa nada e não impõe nada, o que é uma troca razoável desde que se saiba qual das duas acabámos de publicar. O sinal vale exatamente aquilo que vale uma mensagem inequívoca enviada para a morada certa. A nossa era inequívoca e ia para a morada errada.

#Verifique o seu ficheiro com um comando

Demora poucos segundos e funciona em qualquer domínio:

curl -s https://oseudominio.pt/robots.txt \
  | awk 'tolower($0) ~ /^user-agent:/ {ua++} tolower($0) ~ /^content-signal:/ {cs++} END {print "grupos User-agent: " ua "\nlinhas Content-Signal: " cs}'

Uma ressalva antes de agir sobre o resultado: o que é contado são linhas User-agent e não grupos, e a ABNF do RFC 9309 permite várias linhas User-agent a abrir um único grupo, pelo que um ficheiro que empilhe nomes dessa forma vai acusar uma falha que não tem.

Nesse caso, guie-se pela lista do segundo comando e não pela aritmética do primeiro.

Se o número de grupos for maior do que o número de sinais, a diferença diz quantos grupos não veem a sua reserva. No nosso caso o resultado foi vinte e um para um.

A variante mais detalhada escreve os nomes dos grupos onde falta o sinal:

curl -s https://oseudominio.pt/robots.txt \
  | awk '/^[Uu]ser-agent:/ {if (name != "" && !sig) print "sem sinal: " name; name=$2; sig=0} /^[Cc]ontent-[Ss]ignal:/ {sig=1} END {if (name != "" && !sig) print "sem sinal: " name}'

O segundo comando é o que vale a pena ligar a uma pipeline, porque a saída dele é uma lista de coisas a corrigir e não um número para interpretar.

#Como corrigir

A correção é aborrecida: repetir a linha Content-Signal em cada grupo a que deva aplicar-se. Não há atalho, forma abreviada nem herança que se possa ativar.

User-agent: *
Content-Signal: search=yes, ai-input=yes, ai-train=no
Allow: /
Disallow: /cdn-cgi/

User-agent: GPTBot
Content-Signal: search=yes, ai-input=yes, ai-train=no
Allow: /
Allow: /llms.txt
Allow: /facts.json

User-agent: ClaudeBot
Content-Signal: search=yes, ai-input=yes, ai-train=no
Allow: /

User-agent: PerplexityBot
Content-Signal: search=yes, ai-input=yes, ai-train=no
Allow: /

Implementámos esta alteração a 18 de setembro de 2026, no dia em que este artigo saiu. O sinal está agora em 18 grupos de 23, e os cinco que ficaram de fora são scrapers que já têm Disallow do nosso lado, onde uma autorização só tornaria a mensagem menos clara.

A correção obriga a decidir uma coisa que o ficheiro com a linha repetida não decide sozinho: se o mesmo conjunto de sinais serve todos os grupos. Para um crawler de indexação e para um crawler que recolhe corpus de treino a resposta é diferente, e um ficheiro com vinte linhas idênticas sugere que ninguém pensou no assunto. Um grupo em que search=yes não faz sentido, porque o cliente não constrói índice nenhum, devia ter a sua própria redação, e é ao escrever essa redação que o ficheiro deixa de ser uma cópia e passa a ser uma política.

#O segundo buraco: grupos para cada papel

Na mesma leitura do ficheiro percebemos que tínhamos apenas o grupo ClaudeBot e não tínhamos os outros dois: Claude-User, que trata das transferências iniciadas pelo utilizador, e Claude-SearchBot, que trata da fundamentação de pesquisa.

São três papéis distintos e intenções distintas do lado do cliente. Um bot que descarrega a página porque uma pessoa acabou de colar o endereço numa conversa está a fazer algo diferente de um bot que constrói corpus, e faz sentido responder-lhe de outra maneira.

O efeito da ausência desses grupos é exatamente o mesmo que atrás, só que pelo lado oposto: um cliente sem secção própria cai no grupo do asterisco. No nosso caso isso significava que o Claude-User via o sinal correto, porque no asterisco ele estava. Ou seja, num ficheiro em que o sinal não chegava a vinte bots nomeados, chegava aos que não estavam nomeados, exatamente o contrário do que pretendíamos, e produzido pela mesma regra a funcionar tal como está escrita.

#Porque é que este erro sobrevive a uma revisão

Três razões, todas estruturais, nenhuma delas distração.

O robots.txt lê-se de cima para baixo e a secção geral parece hierarquicamente superior. Escrever qualquer coisa lá dentro aciona a intuição que trazemos do CSS ou da configuração de servidores, onde a definição geral é o valor por omissão e a específica sobrepõe-se. No RFC 9309 não há sobreposição. Há escolha de um grupo e rejeição do resto do ficheiro.

Segunda razão: não existe ferramenta que assinale isto. Os testadores de robots.txt verificam se um dado endereço é permitido para um dado bot e não sabem nada sobre Content-Signal, porque não é uma diretiva do RFC. A linha passa como comentário aos olhos do validador e como política aos olhos da pessoa, e cada uma das leituras é coerente consigo mesma.

Terceira, e a mais importante: uma declaração de direitos não produz sinal de retorno. Se colocar mal um Disallow, ao fim de uma semana vê isso no relatório de indexação.

Se colocar mal um Content-Signal, não acontece nada observável, e a ausência de acontecimento tem o mesmo aspeto nos dois casos. Esta classe de defeitos encontra-se a ler o ficheiro, não a olhar para os efeitos, o que é incómodo de agendar, porque ler não tem gatilho.

#As linhas fora dos grupos enganam, porque essas valem mesmo para tudo

Há neste ficheiro uma coisa que induz diretamente a intuição errada. Além dos grupos User-agent, o robots.txt conhece registos independentes de grupo, e o Sitemap é um desses registos. No nosso ficheiro ele fica logo a seguir ao grupo do asterisco:

Sitemap: https://wppoland.com/sitemap-index.xml
Agentmap: https://wppoland.com/.well-known/ai-catalog.json

O Sitemap vale para o ficheiro inteiro, independentemente de onde o colocar e de quantos grupos existam por baixo. Ninguém o repete vinte vezes e ninguém precisa. Quem sabe como o Sitemap se comporta e vê o Content-Signal colocado na mesma zona do ficheiro, duas linhas acima, tem todo o direito de assumir que a linha se comporta da mesma forma.

Não se comporta: uma é um registo global, a outra é uma diretiva dentro de um grupo, nada na sintaxe sinaliza a diferença, e ambas são uma linha de dois membros com dois pontos, uma ao lado da outra.

A conclusão prática, quando se lê o ficheiro de outra pessoa: a indentação e a ordem não querem dizer nada, o que conta é se a diretiva está definida como diretiva de grupo. Allow, Disallow e Content-Signal são de grupo. Sitemap não é.

#O que este artigo não resolve

Deixamos duas coisas de fora de propósito, porque não são nossas.

A primeira é o efeito jurídico da reserva. Os Content Signals invocam uma reserva de direitos expressa no direito de autor, e um texto nesse sentido está mesmo no comentário no topo do nosso ficheiro. Se e quando essa reserva é eficaz, decide um advogado e não quem edita o robots.txt. O nosso contributo é apenas técnico: se a declaração há de ter algum peso, tem pelo menos de chegar ao cliente a quem é dirigida, e a nossa não chegava.

A segunda é o comportamento de cada operador em concreto. Não medimos que crawler lê o Content-Signal, qual o respeita e o que faz com sinais incoerentes em grupos diferentes. Sem medição própria não temos nada a dizer aqui e não vamos repetir números alheios. A correção que descrevemos vale a pena independentemente desse conhecimento, porque arruma um ficheiro que dizia outra coisa do que o autor pretendia, e isso é um defeito por si só.

#O que fazer ao processo

Verificar o alcance do sinal é trabalho de poucos minutos, feito uma vez, mas a manutenção não é de uma vez só. Cada grupo novo acrescentado ao ficheiro, e acrescentam-se com regularidade, porque a lista de crawlers de IA cresce de mês para mês, é um grupo sem sinal enquanto ninguém se lembrar dele.

Por isso o segundo comando acima pertence aos testes e não a uma nota. Uma regra que se verifica sozinha sobrevive; uma regra escrita num documento sobrevive até à edição seguinte feita por alguém que não leu o documento.

Vale também a pena lembrar de que fatia de tráfego estamos a falar. Na nossa medição de agosto de 2026, descrita no artigo sobre tráfego de bots num site pequeno, 72% dos pedidos não vinham de um navegador. O robots.txt é o único sítio onde falamos com essa maioria e a única coisa que essa maioria sabe sobre as nossas condições. Se a frase lá escrita está dirigida ao grupo errado, não é um erro suave, é silêncio.

Fica de pé um limite técnico que convém não disfarçar: o ficheiro apenas afirma, nunca fica a saber se alguém o leu. Quem precisar de mais do que uma afirmação acaba, por força, na camada anterior à aplicação, com todos os custos que essa camada traz.

#Lista de verificação curta

  • Conte os grupos User-agent e as linhas Content-Signal no seu ficheiro. Se os números não baterem certo, a diferença são grupos sem reserva.
  • Repita a linha em cada grupo a que deva aplicar-se. A repetição é aqui a forma correta, não um duplicado.
  • Decida conscientemente se cada grupo recebe o mesmo conjunto de sinais. Vinte linhas idênticas costumam ser sinal de que ninguém decidiu.
  • Confirme se tem grupos separados para papéis distintos do mesmo fornecedor, por exemplo transferências iniciadas pelo utilizador e recolha de corpus.
  • Ligue a verificação à pipeline. A lista de crawlers cresce e cada grupo acrescentado começa sem sinal.
  • Não conte a si próprio a história de que o sinal bloqueia alguma coisa. O bloqueio é a camada anterior à aplicação, isto é uma declaração.
Próximo passo

Transforme o artigo numa implementação real

Este bloco reforça a ligação interna e conduz o leitor para o passo seguinte mais útil dentro da arquitetura do site.

Quer implementar isto no seu site?

Se a visibilidade no Google e em sistemas de IA importa, posso estruturar conteúdo, FAQ, schema e linkagem interna para SEO, GEO e AEO.

Cluster relacionado

Explorar outros serviços WordPress e base de conhecimento

Reforce o seu negócio com suporte técnico profissional em áreas-chave do ecossistema WordPress.

Um crawler lê o grupo do asterisco se tiver um grupo próprio no robots.txt?#
Não. O RFC 9309 diz que o cliente aplica um único grupo, aquele que nomeia o seu product token, e trata o grupo do asterisco como recurso alternativo, usado só quando nenhum grupo o nomeia. Não existe herança a partir do grupo User-agent do asterisco. Se o GPTBot tem secção própria, o grupo do asterisco deixa de lhe dizer respeito por completo.
Onde colocar a linha Content-Signal para que funcione mesmo?#
Em cada grupo a que deva aplicar-se, separadamente. Uma linha no grupo do asterisco abrange apenas os robôs que não têm secção própria. A repetição é aqui a forma correta de escrita, não uma duplicação a eliminar.
O Content-Signal faz parte da norma robots.txt?#
Não. Content Signals é uma proposta da Cloudflare, uma linha adicional no ficheiro robots.txt. Herda, no entanto, a semântica de grupos do RFC 9309, pelo que fica sujeito à mesma regra de grupo único que o Allow e o Disallow.
O ai-train=no impede o treino de um modelo com o conteúdo?#
Não. É uma declaração, não um mecanismo de imposição. O servidor continua a responder ao pedido e um ficheiro de texto não tem como obrigar seja o que for do lado do cliente. O valor do sinal está em ser inequívoco e em chegar ao destinatário certo.
Como verificar o meu ficheiro com um comando só?#
Descarregar o robots.txt e contar as ocorrências da linha Content-Signal e das linhas User-agent. Se houver vinte grupos e um sinal, dezanove grupos não veem a reserva. O comando pronto a usar está no corpo do artigo.

Precisa de FAQ adaptado ao setor e mercado? Criamos uma versão alinhada com os seus objetivos de negócio.

Fale connosco

Artigos Relacionados

Googlebot e JSON-LD: uma só passagem de unescape

A Google mudou a extração de JSON-LD e aplica agora uma só passagem de unescaping de HTML. As entidades com duplo escape deixaram de ser desdobradas, o bloco deixa de fazer parse e os dados estruturados desaparecem. Como medir o seu corpus e como codificar bem.