Implementa avisos del AI Act en un chatbot y contenido web

Implementa avisos del AI Act en un chatbot y contenido web

Un aviso de «usamos IA» en el pie de página no basta para informar a quien abre un chatbot. El artículo 50 exige tratar por separado la interacción con sistemas de IA, ciertas publicaciones generadas o manipuladas y las marcas técnicas del contenido. En la web, eso se traduce en decisiones concretas de interfaz y de gestión de archivos.

La Comisión Europea indica que las obligaciones del artículo 50 se aplican desde el 2 de agosto de 2026. Sus directrices sobre transparencia, adoptadas el 5 de noviembre de 2026, son orientación práctica; el Código de buenas prácticas es voluntario, pero las obligaciones legales no lo son. No basta con una insignia genérica.

Vamos a implementar un chatbot que informa antes de que la persona escriba y una imagen que puede llevar una etiqueta visible cuando corresponda. El flujo será: identificar el tipo de contenido, mostrar el aviso adecuado y, en el caso del chatbot, hacerlo antes del primer mensaje.

flowchart TD
    A["Identificar contenido"] --> B{"¿Interacción con IA?"}
    B -->|"Sí"| C["Aviso junto al chat"]
    B -->|"No"| D{"¿Deepfake o texto cubierto?"}
    D -->|"Sí"| E["Etiqueta visible"]
    D -->|"No"| F["Sin etiqueta automática"]
    C --> G["Conservar marcas técnicas aparte"]
    E --> G
    F --> G

1. Crear la página de prueba

El ejemplo usa HTML, CSS y JavaScript nativos: un lanzador de chat, un panel inicialmente cerrado y una figura con su pie. La etiqueta visible de la imagen aparece activada en el ejemplo para mostrar el resultado; en una aplicación real, el sistema editorial debe decidirla para cada publicación cubierta, no encenderla para cualquier archivo con metadatos de IA.

Guarda esto como index.html y ábrelo en un navegador. El contenido de la imagen es una ruta local de ejemplo; reemplázala por un recurso de tu aplicación.

<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Avisos de transparencia</title>
  <style>
    body { font: 1rem/1.5 system-ui, sans-serif; margin: 2rem auto; max-width: 48rem; padding: 0 1rem; }
    button, textarea { font: inherit; }
    .chat-panel { border: 1px solid #777; margin-top: 1rem; padding: 1rem; }
    .notice, figcaption { background: #f0f0f0; padding: .5rem; }
    figure { margin: 2rem 0; }
    img { height: auto; max-width: 100%; }
  </style>
</head>
<body>
  <main>
    <h1>Ayuda y contenidos</h1>
    <button id="chat-launcher" type="button" aria-expanded="false" aria-controls="chat-panel">
      Hablar con el asistente <span>IA</span>
    </button>
    <section id="chat-panel" class="chat-panel" hidden aria-labelledby="chat-title">
      <h2 id="chat-title">Asistente</h2>
      <p class="notice" role="status">Estás hablando con un sistema de IA, no con una persona.</p>
      <form id="chat-form">
        <label for="message">Mensaje</label>
        <textarea id="message" name="message" required></textarea>
        <button type="submit">Enviar</button>
      </form>
      <p id="chat-result" role="status"></p>
    </section>
    <figure>
      <img src="imagen-ejemplo.jpg" alt="Imagen generada por IA de una taza sobre una mesa">
      <figcaption>Imagen generada por IA</figcaption>
    </figure>
  </main>
  <script src="app.js" defer></script>
</body>
</html>

2. Abrir el chat sin retrasar el aviso

El lanzador ya muestra «IA» como texto real y el panel contiene una explicación completa. Al abrirlo, el mensaje está presente antes de que la persona pueda enviar nada. El artículo 50(1) se refiere a informar de la interacción con IA; las directrices consideran que un aviso destacado antes de la primera interacción probablemente basta en muchos casos. Una mención escondida en condiciones o documentación no sustituye el aviso en contexto.

Este JavaScript completa la interacción básica. No simula una respuesta de IA: presenta el texto introducido como confirmación local, para que el ejemplo sea ejecutable sin un servicio externo. En producción, conecta el formulario al servicio de conversación y conserva el aviso antes del envío.

const launcher = document.querySelector("#chat-launcher");
const panel = document.querySelector("#chat-panel");
const form = document.querySelector("#chat-form");
const message = document.querySelector("#message");
const result = document.querySelector("#chat-result");

launcher.addEventListener("click", () => {
  const opening = panel.hidden;
  panel.hidden = !opening;
  launcher.setAttribute("aria-expanded", String(opening));

  if (opening) {
    message.focus();
  }
});

form.addEventListener("submit", (event) => {
  event.preventDefault();
  result.textContent = `Mensaje preparado: ${message.value.trim()}`;
});

El control actualiza aria-expanded y mueve el foco al campo al abrirse. El aviso, sin embargo, no depende de ese atributo ni de un nombre accesible invisible: quienes ven la página también pueden leerlo. El aviso aparece antes de escribir.

3. Decidir cuándo etiquetar una imagen

La etiqueta visible no corresponde automáticamente a todo contenido generado por IA. La Comisión distingue los deepfakes y, por separado, ciertos textos sobre asuntos de interés público publicados sin revisión humana ni responsabilidad editorial. Para los deepfakes, la definición descrita en las directrices combina parecido con una persona, objeto, lugar, entidad o acontecimiento existente y una apariencia falsa de autenticidad o veracidad. El realismo fotográfico por sí solo no resuelve el criterio.

Por eso, registra la decisión editorial como un campo explícito. Este fragmento completo de JavaScript recibe datos de contenido y construye una figura: cuando requiresVisibleLabel es verdadero, inserta un pie visible y antepone la misma idea al texto alternativo. No infiere que la imagen sea un deepfake a partir de sus metadatos.

function createImageFigure({ src, alt, label, requiresVisibleLabel }) {
  const figure = document.createElement("figure");
  const image = document.createElement("img");
  image.src = src;
  image.alt = requiresVisibleLabel ? `${label}: ${alt}` : alt;
  figure.append(image);

  if (requiresVisibleLabel) {
    const caption = document.createElement("figcaption");
    caption.textContent = label;
    figure.append(caption);
  }

  return figure;
}

const generatedFigure = createImageFigure({
  src: "imagen-ejemplo.jpg",
  alt: "una taza sobre una mesa",
  label: "Imagen generada por IA",
  requiresVisibleLabel: true
});

document.querySelector("main").append(generatedFigure);

Para probarlo sin duplicar la imagen estática del primer bloque, elimina del HTML la figura de ejemplo. Después, guarda la función en app.js y ábrela desde el documento. En una aplicación real, el valor booleano debe salir de la revisión editorial y de la clasificación del contenido, no de una regla como «si el archivo es generado, mostrar etiqueta».

La etiqueta debe poder percibirse sin una herramienta especial ni una acción dedicada. Un texto alternativo ayuda a tecnologías de asistencia, pero no reemplaza un pie visible; una etiqueta que solo aparece al pasar el cursor tampoco es visible para todo el mundo.

4. Mantener separadas la etiqueta y la procedencia

El artículo 50(2) trata de marcas legibles por máquina en las salidas de sistemas generativos. Es una obligación que recae sobre el proveedor del sistema; si una empresa solo utiliza una API ajena, normalmente la responsabilidad de esa marca corresponde al proveedor. Para una web, el problema práctico es no perder la marca al redimensionar, recodificar o generar derivados mediante el CMS o la CDN.

La marca técnica y el pie visible son dos controles distintos. Una manifestación firmada de procedencia, como una credencial de contenido, no se ve en la imagen y no sustituye el etiquetado perceptible que pueda exigir el artículo 50(4). En el flujo de publicación, registra ambos estados por separado:

function validatePublication(asset) {
  const errors = [];

  if (asset.requiresVisibleLabel && !asset.visibleLabel) {
    errors.push("Falta la etiqueta visible requerida.");
  }

  if (asset.providerMarkExpected && !asset.machineReadableMarkPreserved) {
    errors.push("No se ha confirmado la conservación de la marca técnica.");
  }

  return errors;
}

const asset = {
  requiresVisibleLabel: true,
  visibleLabel: "Imagen generada por IA",
  providerMarkExpected: true,
  machineReadableMarkPreserved: true
};

const publicationErrors = validatePublication(asset);
if (publicationErrors.length > 0) {
  console.error(publicationErrors.join(" "));
} else {
  console.log("La publicación supera las comprobaciones configuradas.");
}

Este control no inspecciona ni crea metadatos: obliga a que el proceso de publicación registre el resultado de la comprobación de la cadena de imágenes. La marca debe seguirse a través de la carga, las transformaciones y los derivados; no des por hecho que una optimización la conserva.

5. Revisar el resultado como visitante

Prueba la página con el chat cerrado: el lanzador debe comunicar que es IA sin abrirlo. Luego abre el panel y verifica que el aviso aparece antes del campo de mensaje. En las imágenes, comprueba que el pie se lee sin hover y que coincide con la decisión editorial. Si ofreces una interfaz de voz, el aviso también debe estar en el audio; un tono aislado no basta, y una interfaz de voz que además se muestra en pantalla debe conservar una línea visible.

La etiqueta humana y la marca técnica son controles distintos. Las obligaciones de transparencia del artículo 50 están vigentes desde el 2 de agosto de 2026; la Comisión describe una transición más acotada para ciertas marcas de proveedores, hasta el 2 de diciembre de 2026, en sistemas generativos que ya estaban en el mercado antes de la fecha de aplicación. El aviso del chatbot no recibió ese plazo adicional.

Si un equipo decide no seguir el Código de buenas prácticas, la Comisión señala que debe demostrar por otros medios equivalentes la adecuación de sus medidas de marcado y etiquetado. La interfaz puede resolver dónde aparece el aviso; la publicación aún debe preservar las marcas técnicas que correspondan.

Fuentes: DEV Community, Shaping Europe’s digital future, Shaping Europe’s digital future, Shaping Europe’s digital future