Auditoría S-CTS: riesgo de contenido escalado y huella semántica repetitiva
Una afirmación llamativa fue el punto de partida: Google estaría utilizando S-BERT y un sistema llamado S-CTS para detectar contenido generado con IA a gran escala.
La lectura rápida invitaba a construir un detector. La lectura del paper obligaba a hacer algo más prudente —y bastante más útil—: separar lo que la investigación demuestra de lo que solo podemos trasladar como hipótesis a una auditoría de contenidos web.
El resultado no es una herramienta que identifica contenido de IA, ni una puntuación que predice penalizaciones. Es un proceso que convierte un rastreo de Screaming Frog en una auditoría trazable: valida la extracción, analiza cada página, compara todo el corpus, prioriza mejoras, redacta cambios concretos y los aplica en WordPress mediante Claude y MCP, siempre con aprobación humana y verificación posterior.
Si no te quieres leer todo, te lo resumo
Partimos de una investigación de Google sobre abuso sintético coordinado y, en lugar de fingir que la reproducíamos, la usamos como patrón de ingeniería para auditar mejor un dominio. Distinguimos siempre tres capas: lo que el paper demuestra, lo que Sentence-BERT permite de verdad y lo que nosotros adaptamos con límites explícitos.
El caso completo trabajó con 36 URLs, 3.505 bloques de contenido estructurado y 630 comparaciones entre páginas. Terminó con una primera oleada de 7 URLs modificadas y verificadas, sin añadir hechos, cifras ni fuentes inventadas.
La parte valiosa no fue obtener un número. Fue poder responder, para cada decisión, qué observamos, dónde estaba la evidencia, qué era hipótesis, qué propusimos, quién lo aprobó y qué se cambió realmente. Cuando el contenido se produce a escala, esa trazabilidad vale más que cualquier detector.
El punto de partida: una interpretación demasiado atractiva
El paper de Google se titula Scalable Detection of Adversarial Synthetic Slop and Coordinated Media Abuse. Describe S-CTS, siglas de Scalable Cluster Termination System, como un sistema para identificar y actuar sobre clústeres coordinados de cuentas en plataformas de vídeo.
La diferencia de contexto es decisiva. La investigación no estudia artículos de una web ni presenta un componente de Google Search. Trabaja con cuentas, relaciones entre ellas, patrones de publicación, señales de infraestructura y contenido multimodal. Entre las señales citadas aparecen patrones de uso de API, series temporales, metadatos de generación, embeddings de texto, información visual, audio y transcripciones.
Además, una parte importante del sistema depende de algoritmos internos y señales propietarias. No existe en el paper una receta pública que podamos trasladar a un sitemap y ejecutar desde fuera.
El trabajo sí menciona que, para el contenido textual, pueden utilizarse embeddings generados por modelos como Sentence-BERT. Pero de ahí no se deduce que S-BERT sea un detector universal de textos creados con IA.
El paper original de Sentence-BERT presenta un método para obtener representaciones semánticas de frases que pueden compararse mediante similitud coseno. Eso permite encontrar textos próximos o formar clústeres con mucha más eficiencia que comparando cada pareja directamente con BERT. No determina quién escribió un texto, si es correcto, si aporta valor o si incumple una política.
La conclusión del informe inicial fue, por tanto, incómoda pero necesaria:
No podemos reproducir S-CTS ni convertir S-BERT en un detector fiable de autoría. Sí podemos aprovechar algunos patrones de ingeniería para construir una auditoría mejor.
Qué demuestra la investigación y qué adaptamos nosotros
Para no mezclar evidencia con interpretación, el proyecto separó ambas capas desde el principio.
| Investigación demostrada | Adaptación práctica de la auditoría |
|---|---|
| S-CTS analiza clústeres coordinados, no solo piezas aisladas. | Revisamos el corpus completo, sus pares y sus clústeres, no únicamente cada URL por separado. |
| Combina señales de cuenta, infraestructura, comportamiento y contenido. | Combinamos estructura, repetición, metadatos, evidencia y relaciones semánticas observables públicamente. |
| Utiliza ventanas temporales y procesamiento por lotes. | Versionamos rastreos y dejamos preparada la comparación entre ejecuciones. |
| Los casos ambiguos pueden pasar a revisión humana. | Ninguna similitud decide por sí sola una fusión, redirección o reescritura. |
| Sentence-BERT puede representar proximidad semántica. | Usamos embeddings —o un fallback identificado— para seleccionar pares candidatos a revisión. |
| El sistema real usa señales y modelos propietarios. | No llamamos S-CTS a nuestras métricas ni afirmamos reproducir el sistema de Google. |
Esta separación también encaja con la política pública de Google Search. El abuso de contenido a escala no se define simplemente por utilizar IA. Se refiere a generar muchas páginas con el propósito principal de manipular rankings y sin ayudar al usuario, normalmente mediante contenido poco original y con poco o ningún valor, con independencia de cómo se haya creado.
Por eso una auditoría útil no debería preguntar solo si una página se parece a otros textos. Debe preguntar también:
- ¿Qué necesidad resuelve esta página?
- ¿Qué aporta que no aporten las demás?
- ¿Qué afirmaciones puede respaldar?
- ¿Qué parte es plantilla legítima y qué parte es repetición editorial?
- ¿Qué función ocupa dentro del conjunto?
- ¿Qué riesgo tendría fusionarla, moverla o eliminarla?
Del informe a un método operativo
El informe técnico descartó construir un único índice agregado tipo S-CTS. Una sola cifra habría ocultado diferencias importantes y transmitido una precisión inexistente.
En su lugar, el proceso separó tres dimensiones:
- Repetición y escala: fórmulas recurrentes, oraciones repetidas, n-gramas, encabezados, estructuras y patrones transversales.
- Valor diferencial: cobertura propia, ejemplos, datos, fuentes, límites, claridad de intención y contribución exclusiva de cada página.
- Prioridad: impacto comercial, tráfico, conversiones, enlaces, actualidad y coste de la intervención.
Las dos primeras dimensiones podían estudiarse parcialmente a partir del contenido. La tercera necesitaba Search Console, analítica, enlaces y datos de negocio. Cuando esos datos no estaban disponibles, la limitación quedaba registrada: no se rellenaba con una valoración inventada.
Cada etapa generó un archivo nuevo. Ninguna sobrescribió la anterior. Esto hizo posible reconstruir el camino desde una frase original hasta el cambio publicado.
Screaming Frog como capa de adquisición
Screaming Frog fue la herramienta adecuada para recorrer el dominio, renderizar las páginas y ejecutar lógica personalizada sobre cada URL.
Su documentación permite configurar fragmentos en Configuration > Custom > Custom JavaScript. Los fragmentos de tipo Extraction devuelven uno o varios valores mediante seoSpider.data(...), y cada valor se distribuye en una columna del informe. Creamos dos JavaScript.
SCTS Page Features: señales locales por página
El primer script devolvía 24 campos, entre ellos: título, autor y fechas detectadas; tipo de schema editorial; palabras, oraciones, párrafos y encabezados; longitud media y porcentaje de oraciones largas; diversidad léxica; repetición de oraciones y 5-gramas; encabezados duplicados; enlaces internos y externos; tablas, figuras y citas; proporción del contenido principal frente al cuerpo completo; hash del contenido y firma de encabezados; y flags locales para seleccionar páginas que merecían revisión.
Los umbrales eran hipótesis operativas. Por ejemplo, menos de 300 palabras activaba THIN_CONTENT, una diversidad léxica inferior a 0,28 activaba LOW_LEXICAL_DIVERSITY y una proporción de cuerpo principal inferior a 0,20 activaba LOW_MAIN_BODY_RATIO.
Esos flags no eran factores de ranking, probabilidades de spam ni resultados de S-CTS. Servían para formular preguntas y localizar casos que revisar.
SCTS Clean Content: contenido estructurado por bloques
El segundo script resolvía un problema más importante: no bastaba con exportar una gran celda de texto si después queríamos señalar una evidencia exacta o proponer un cambio verificable.
Utilizamos Mozilla Readability sobre un clon del documento renderizado. Readability modifica el DOM durante su análisis, por lo que trabajar con document.cloneNode(true) evita alterar la página que está procesando el rastreador.
El contenido principal se transformó en JSON_BLOCKS_V1, con esta estructura:
{
"version": 1,
"language": "es",
"title": "Titulo de la pagina",
"blocks": [
{
"position": 1,
"type": "heading",
"level": 1,
"section": "Titulo de la pagina",
"text": "Titulo de la pagina",
"words": 4
}
]
}
El extractor preservaba encabezados, párrafos, elementos de lista, citas, código, tablas y pies de figura. Cada bloque conservaba posición, tipo, nivel, sección, texto y palabras.
Para evitar perder artículos largos, el JSON se dividía en hasta 12 columnas de 28.000 caracteres. La capacidad total era de 336.000 caracteres, y el informe indicaba expresamente si el payload había sido truncado.
Esta decisión fue clave. La trazabilidad posterior no dependía de que un modelo recordase dónde había leído algo: cada evidencia seguía vinculada a una URL y a posiciones concretas.
Qué podían hacer los JavaScript y qué quedaba fuera
Los scripts se ejecutaban URL por URL. Podían extraer y calcular señales locales, pero no comparar todo el dominio. No generaban por sí solos:
- embeddings del corpus completo;
- similitudes entre las 630 parejas;
- clústeres de páginas;
- intención de búsqueda;
- prioridades comerciales;
- propuestas de edición;
- cambios en WordPress.
Esa separación evitó convertir Screaming Frog en una caja negra. Su función era obtener datos consistentes. El análisis de corpus se realizaría después, en un entorno que pudiera reconstruir bloques, ejecutar modelos y conservar tablas de control.
La primera prueba: demostrar que los datos eran fiables
El rastreo produjo un CSV con las columnas normales de Screaming Frog, 24 columnas de SCTS Page Features y 21 columnas de SCTS Clean Content.
Antes de auditar nada, el Prompt 1 tuvo una única misión: reconstruir y validar. Sobre 36 URLs obtuvo:
| Control | Resultado |
|---|---|
| URLs originales y únicas | 36 / 36 |
| JSON válidos | 36 |
| URLs truncadas | 0 |
| Bloques totales | 3.505 |
| Bloques de contenido | 2.396 |
| Encabezados | 1.078 |
| Incidencias de extracción | 0 |
El archivo de salida desglosó cada bloque en una fila. Los encabezados se marcaron como contexto, los bloques editoriales como contenido y 31 separadores o elementos sin palabras léxicas como excluidos. Nada se eliminó silenciosamente y el texto original no se reescribió.
Solo entonces el corpus recibió el veredicto APTO PARA AUDITORÍA.
Este orden puede parecer conservador, pero evita un error común: dedicar horas a interpretar métricas generadas sobre contenido incompleto, truncado o mal extraído.
Un pipeline de prompts con una responsabilidad por fase
La auditoría no se resolvió con un único megaprompt. Utilizamos siete prompts encadenados, cada uno con entradas, salidas y prohibiciones propias.

| Prompt | Función | Entregable |
|---|---|---|
| 1 | Reconstruir, validar y normalizar el CSV | Datos preparados por URL y bloque |
| 2 | Auditar cada contenido sin compararlo todavía con otros | Incidencias, fortalezas y diagnóstico por sección |
| 3 | Analizar relaciones, solapamientos y clústeres | Todos los pares, candidatos y relaciones confirmadas |
| 4 | Integrar hallazgos y ordenar el trabajo | Plan priorizado y validaciones pendientes |
| 5 | Redactar una primera oleada de cambios exactos | Sustituciones, inserciones y movimientos |
| 6 | Convertir los cambios en prompts autónomos para Claude | Instrucciones autocontenidas para WordPress |
| 7 | Comprobar el estado real después de publicar | Verificación global y observaciones fuera de alcance |
La separación cambió la calidad de los resultados. El Prompt 2 no podía comparar URLs ni afirmar que había ejecutado S-CTS o S-BERT. Su trabajo era leer 640 secciones y localizar incidencias con texto y posiciones válidas. Encontró 61 incidencias —24 altas, 24 medias y 13 bajas—, registró 86 fortalezas y señaló 17 URLs para revisión prioritaria.
El Prompt 3 no podía aceptar automáticamente una similitud como canibalización. El Prompt 4 no podía inventar datos de rendimiento. El Prompt 5 no podía introducir fuentes plausibles para completar una afirmación. El Prompt 6 no podía modificar WordPress. Y el Prompt 7 no podía aprovechar la verificación para corregir observaciones nuevas sin una autorización diferente.
Las prohibiciones no eran un apéndice: eran parte del diseño.
El momento crítico: S-BERT no estaba disponible
El Prompt 3 debía intentar cargar sentence-transformers/paraphrase-multilingual-mpnet-base-v2, generar embeddings normalizados y registrar modelo, biblioteca, dimensión y dispositivo.
El entorno no disponía de sentence-transformers, PyTorch ni el modelo. La respuesta correcta no era fingir que se había ejecutado S-BERT ni detener todo el proyecto. Aplicamos el fallback previsto:
TFIDF_WORD_CHAR_ENSEMBLE_V1
65 % palabras, n-gramas (1,2)
35 % caracteres char_wb, n-gramas (3,5)
sublinear_tf = true
strip_accents = unicode
normalizacion L2
Los resultados quedaron etiquetados como COMPLETO_CON_METODO_ALTERNATIVO y nunca se denominaron embeddings S-BERT.
Para comparar el corpus se crearon 1.188 segmentos trazables. Los segmentos tenían como objetivo entre 50 y 80 palabras, no cruzaban H2 o H3, no se solapaban y conservaban sus posiciones originales. El título se representaba por separado para no aumentar artificialmente la similitud entre todos los segmentos de una misma página.
Con 36 URLs había exactamente 630 pares únicos. Se calcularon todos. Los percentiles del propio corpus, los vecinos mutuos, la similitud de títulos, las firmas y la cobertura asimétrica seleccionaron 137 candidatos. Después llegó la parte irrenunciable: leerlos y clasificar la relación real.
El resultado fue:
- 52 pares distintos dentro de los candidatos;
- 85 relaciones semánticas confirmadas;
- 7 clústeres prácticos;
- 2 URLs aisladas;
- 3 conflictos potenciales de intención;
- 0 candidatos a consolidación.

La etiqueta conflicto potencial fue deliberada. Sin datos de consultas y rendimiento no podíamos confirmar canibalización. Del mismo modo, una similitud alta no justificaba una redirección.
De 61 incidencias a un plan que se pudiera ejecutar
El Prompt 4 integró la auditoría individual, las relaciones entre páginas y las fortalezas que debían conservarse. Generó 69 tareas: 18 de prioridad P1, 27 de prioridad P2 y 24 de prioridad P3; 27 listas para trabajar, 21 pendientes de validación y 21 para planificar.
También registró 31 validaciones pendientes: siete relacionadas con fuentes o hechos, catorce con actualización temporal, tres con Search Console y siete con decisiones editoriales humanas.
Esto evitó confundir lo importante con lo ejecutable. Una tarea puede ser prioritaria y, al mismo tiempo, estar bloqueada por una fuente, una decisión de arquitectura o la falta de un contenido de destino.
La primera oleada se limitó a 7 URLs y once incidencias. El Prompt 5 trabajó sobre 794 bloques y 22.513 palabras. Documentó 53 registros de cambio; entre ellos, 35 bloques reescritos, 9 inserciones y 8 movimientos. El entregable también recogía decisiones sobre títulos y promesas.
Hubo una restricción especialmente útil: 96 bloques permanecieron en su ubicación hasta que existieran los destinos necesarios para moverlos. Preparar una arquitectura futura no autorizaba a retirar contenido presente.
Tampoco se añadió ningún hecho, cifra o fuente. Cuando una afirmación pedía referencias reales o verosímiles, se corrigió el criterio: las referencias debían existir y poder verificarse; si no había una fuente suficiente, el vacío se declaraba.
Por qué el primer diseño del Prompt 6 no servía
La primera versión del Prompt 6 producía instrucciones como:
task_id: TASK-023
issue_ids: INC-027
Eso tenía sentido dentro de los Excel, pero no para Claude conectado a WordPress. Obligaba al agente ejecutor a volver a abrir y entender todos los archivos de análisis. También mezclaba la trazabilidad interna con el contexto necesario para editar una página.
La solución fue generar prompts directos y autocontenidos. Cada prompt incluía:
- URL, slug y títulos conocidos;
- campo exacto que se podía tocar;
- texto actual y texto nuevo completos;
- anclas para cada inserción;
- enlaces, HTML y énfasis que debían preservarse;
- lista de campos que debían permanecer intactos;
- comprobaciones posteriores;
- frase literal de aprobación.
El Prompt 6 final generó siete prompts inmediatos, cinco condicionados y uno de verificación. Claude no necesitaba los Excel para ejecutar ninguno de ellos.
Claude y WordPress: leer, presentar, aprobar, escribir y releer
La conexión MCP con WordPress hizo posible trabajar sobre el contenido real, pero el acceso técnico no debía convertirse en permiso editorial. Cada prompt operaba en dos fases.
Fase 1: solo lectura
Claude localizaba la entrada y recuperaba ID, tipo, estado, slug, títulos y fecha de modificación. Después buscaba los textos y anclas, comprobaba que fueran únicos y mostraba una tabla:
| Nº | Elemento | Acción | Texto actual | Texto nuevo | Estado |
|---|---|---|---|---|---|
| 1 | Contenido editable | Sustituir | Texto literal | Texto propuesto | LISTO |
Los estados posibles eran LISTO (el cambio era inequívoco), YA APLICADO (el nuevo valor ya estaba presente) y BLOQUEADO (faltaba una decisión o no podía garantizarse la operación). Si había una fila bloqueada, Claude no solicitaba autorización de escritura.
Este mecanismo detectó problemas que un prompt genérico habría pasado por alto:
- el texto esperado coincidía con el title SEO, pero no con el título nativo ni con el H1;
- dos cambios afectaban al mismo H4;
- una sustitución podía eliminar un enlace interno;
- una inserción admitía varias ubicaciones editoriales;
- un H1 contenía un
<em>que debía conservarse; - un lead tenía un
<strong>aplicado solo a una parte de la frase; - una entrada de TOC manual no se actualizaba al cambiar el H2.
Fase 2: escritura autorizada
Cuando no quedaban bloqueos, Claude pedía una frase específica, por ejemplo APROBAR CAMBIOS EN PIPELINE GEO. La aprobación cubría únicamente la tabla inmediatamente anterior. Después Claude aplicaba los cambios, volvía a leer la entrada y comprobaba que aparecía el texto nuevo, que había desaparecido el antiguo cuando correspondía, que no se había duplicado ningún H1, que los enlaces, IDs y énfasis seguían presentes, que las cifras, fuentes, tablas y bloques no autorizados permanecían intactos, y que no se habían introducido artefactos de wpautop o serialización.
Las siete páginas de la primera oleada terminaron con estado COMPLETADO Y VERIFICADO.
La verificación global encontró lo que quedaba fuera
El Prompt 7 revisó 60 elementos de cambio sobre el estado actual de WordPress. También confirmó que 65 bloques sectoriales que debían conservarse seguían íntegros.
La verificación no se limitó a comprobar frases. Revisó solapes, títulos, enlaces, H1, <em>, <strong>, ubicaciones y campos preservados. Encontró dos observaciones que no violaban lo aprobado:
- un H2 estaba actualizado, pero la entrada manual de su TOC conservaba el texto anterior;
- una página mostraba correctamente la firma de Fernando Ferreiro, pero su autor nativo de WordPress seguía asignado a Agencia, lo que afectaba al autor del schema generado por Rank Math.
Como ambas cuestiones estaban fuera del alcance de los 60 cambios, Claude no las corrigió. Se creó una operación independiente, se verificó en solo lectura, se pidió otra frase de aprobación y se comprobó el resultado después de escribir. Ese detalle resume bien el método: detectar algo no equivale a estar autorizado para cambiarlo.
Qué funcionó y qué no debemos exagerar
El proceso funcionó porque mantuvo separadas adquisición, análisis, decisión y ejecución. Funcionó especialmente bien para:
- convertir un dominio en bloques auditables;
- localizar evidencias sin depender de una lectura manual dispersa;
- reducir todas las parejas a candidatos revisables;
- distinguir páginas complementarias de posibles conflictos;
- conservar fortalezas y contenido que no debía moverse;
- convertir recomendaciones en cambios exactos;
- detectar ambigüedades antes de tocar una página publicada;
- demostrar después qué cambió y qué permaneció intacto.
Pero hay límites claros:
- no ejecutamos el sistema S-CTS de Google;
- S-BERT no llegó a ejecutarse en este entorno;
- TF-IDF seleccionó candidatos, no detectó autoría ni calidad;
- sin Search Console no confirmamos canibalización;
- sin datos de negocio, la prioridad es editorial, no económica;
- Readability puede equivocarse al identificar el contenido principal;
- una verificación por API no sustituye siempre la revisión visual;
- los umbrales deben recalibrarse para cada dominio, plantilla e idioma.
Cómo convertirlo en un proceso reutilizable
La documentación final se organizó como un pequeño proyecto versionado:
auditoria-scts/
├── docs/
├── screaming-frog/
├── prompts/
├── schemas/
├── examples/
├── CHECKSUMS.sha256
├── CHANGELOG.md
└── README.md
Para cada ejecución conviene guardar un manifiesto con el dominio y alcance, la fecha y zona horaria, la versión de Screaming Frog, los hashes de los JavaScript, la versión de Readability, el modelo semántico realmente utilizado, los parámetros del fallback, los archivos de entrada y salida, los recuentos de control y la persona o agente responsable.
También conviene mantener un pequeño conjunto de pares ya revisados —distintos, complementarios, hub-spoke, solapamiento parcial y conflicto potencial— para comparar modelos y calibrar umbrales en futuras ejecuciones.
El siguiente paso técnico no consiste en añadir más flags. Consiste en repetir la auditoría con S-BERT real, comparar la estabilidad de candidatos y clústeres frente a TF-IDF, incorporar Search Console y analítica como capas separadas, y medir qué cambios producen mejoras observables.
La conclusión: la auditabilidad es más valiosa que un detector
La promesa inicial era construir algo parecido a un detector de contenido de IA. El resultado terminó siendo más útil.
S-CTS aportó un patrón: no mirar piezas aisladas, combinar señales, estudiar relaciones, trabajar con ventanas y reservar los casos ambiguos para revisión. S-BERT aportó una técnica para representar proximidad semántica. Screaming Frog aportó una capa reproducible de adquisición. Los prompts separaron responsabilidades. Claude y MCP permitieron ejecutar cambios sobre WordPress sin renunciar al control humano.
La parte importante no fue obtener una puntuación. Fue poder responder, para cada decisión, qué observamos, dónde estaba la evidencia, qué parte era una hipótesis, qué propusimos cambiar, quién lo aprobó, qué se modificó realmente y qué comprobamos después.
Cuando el contenido se produce y mantiene a escala, esa trazabilidad es una defensa práctica contra dos riesgos distintos: publicar material repetitivo sin valor y corregirlo mediante automatizaciones que nadie puede explicar. Una buena auditoría no debería decir únicamente que algo parece problemático. Debería permitir demostrar por qué, intervenir con precisión y verificar el resultado.
En Indexando Marketing y Agencia GEO trabajamos así las auditorías de contenido a escala: con métodos reproducibles, criterio editorial y cambios que se pueden explicar y verificar uno a uno.
Fuentes primarias
- Google Research: Scalable Detection of Adversarial Synthetic Slop and Coordinated Media Abuse.
- Reimers y Gurevych: Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks.
- Google Search Central: Spam policies for Google web search.
- Screaming Frog: SEO Spider Configuration — Custom JavaScript.
- Mozilla: Readability.
