7. Del lenguaje natural al código fuente

Entre una frase como “creá una lista de tareas” y una aplicación funcional existen requisitos, decisiones, archivos, instrucciones y pruebas. La IA acelera esa traducción, pero no elimina sus etapas.

7.1 Introducción

El lenguaje natural expresa objetivos con flexibilidad. El código fuente, en cambio, debe indicar operaciones precisas y compatibles con un entorno técnico concreto.

Cuando pedimos una aplicación mediante Vibe Coding, la inteligencia artificial construye un puente entre esos dos niveles. Interpreta la intención, infiere requisitos, elige una implementación y genera instrucciones que una computadora pueda ejecutar.

Intención → requisitos → decisiones técnicas → estructura → código → ejecución → verificación

Cada flecha representa una oportunidad para acertar, suponer o cometer un error.

7.2 Dos lenguajes con propiedades diferentes

Lenguaje natural Código fuente
Puede depender del contexto compartido. Debe respetar reglas sintácticas explícitas.
Tolera expresiones aproximadas. Necesita operaciones y datos definidos.
Puede contener ambigüedades. Ejecuta una interpretación concreta.
Describe objetivos y experiencias. Implementa comportamientos dentro de una plataforma.
Una frase admite varias soluciones. Cada solución produce consecuencias específicas.

La IA debe convertir flexibilidad en decisiones. Si la solicitud no define esas decisiones, tendrá que inferirlas o pedir una aclaración.

7.3 Primera etapa: identificar la intención

La intención explica para qué existe el cambio. Consideremos esta solicitud:

Creá una lista de tareas para que una persona organice sus actividades diarias.

La intención general es organizar actividades. Todavía no sabemos qué operaciones necesita la aplicación, cómo debe verse ni dónde almacenará la información.

Separar la intención evita comenzar por detalles técnicos prematuros. También permite evaluar después si el código realmente resuelve el problema original.

7.4 Segunda etapa: extraer requisitos

Podemos ampliar la solicitud:

La persona debe poder agregar una tarea, marcarla como completada y eliminarla. No se aceptarán tareas vacías. Las tareas deben conservarse al actualizar la página.

Ahora aparecen comportamientos verificables:

  • Agregar tareas.
  • Cambiar su estado a completada.
  • Eliminar tareas.
  • Rechazar entradas vacías.
  • Conservar la información entre recargas.

Cada verbo suele convertirse en una operación del programa. Cada condición suele convertirse en una validación o una prueba.

7.5 Tercera etapa: resolver decisiones pendientes

Los requisitos funcionales todavía dejan preguntas técnicas y de experiencia de uso:

  • ¿Será una página web, una aplicación móvil o de escritorio?
  • ¿Las tareas pertenecen a un único usuario?
  • ¿Se guardarán localmente o en un servidor?
  • ¿Una tarea completada puede volver a quedar pendiente?
  • ¿Eliminar requiere confirmación?
  • ¿Cómo se mostrará un intento de agregar texto vacío?

Para un primer proyecto podemos decidir: página web, un solo usuario, almacenamiento local, estado reversible y mensaje visible para entradas inválidas.

7.6 Cuarta etapa: elegir la representación de los datos

La frase “una tarea” debe convertirse en datos que el programa pueda manipular. Una representación sencilla podría incluir:

{
  id: 1,
  texto: "Estudiar Vibe Coding",
  completada: false
}

Cada propiedad responde a una necesidad:

  • id permite identificar la tarea que se modificará o eliminará.
  • texto conserva la descripción escrita por la persona.
  • completada representa los dos estados posibles.

Si más adelante aparecen fechas, prioridades o usuarios, la estructura deberá evolucionar.

7.7 Quinta etapa: dividir la aplicación en partes

Una implementación web básica puede distribuirse en tres archivos:

Archivo Responsabilidad Relación con la solicitud
index.html Estructura del formulario y la lista. Permite ingresar y observar tareas.
styles.css Presentación y adaptación visual. Hace comprensibles los estados y controles.
app.js Datos, eventos, validación y almacenamiento. Implementa agregar, completar, eliminar y conservar.

La estructura no es la única posible. Es una decisión adecuada para el tamaño y el objetivo de este ejemplo.

7.8 Sexta etapa: transformar requisitos en funciones

Requisito Operación posible Comprobación
Agregar una tarea agregarTarea(texto) La nueva tarea aparece en la lista.
Impedir texto vacío validarTexto(texto) La lista no cambia y aparece un mensaje.
Cambiar el estado alternarTarea(id) La tarea cambia entre pendiente y completada.
Eliminar eliminarTarea(id) Desaparece únicamente la tarea elegida.
Conservar información guardarTareas() Las tareas permanecen después de recargar.

Esta correspondencia mejora la trazabilidad: podemos señalar qué parte del código intenta satisfacer cada requisito.

7.9 Séptima etapa: generar instrucciones ejecutables

Una de las funciones podría expresarse así:

function agregarTarea(texto) {
  const descripcion = texto.trim();

  if (descripcion === "") {
    mostrarError("Escribí una tarea antes de agregarla.");
    return;
  }

  tareas.push({
    id: Date.now(),
    texto: descripcion,
    completada: false
  });

  guardarTareas();
  mostrarTareas();
}

La función concreta varias decisiones:

  • Elimina espacios al principio y al final.
  • Interrumpe la operación si el texto queda vacío.
  • Crea un objeto con identificador y estado inicial.
  • Actualiza el almacenamiento.
  • Vuelve a dibujar la lista.

Algunas decisiones estaban en la solicitud; otras fueron elegidas durante la implementación. Debemos distinguirlas para saber qué revisar.

7.10 Código sintácticamente válido y código correcto

El navegador puede aceptar la sintaxis de una función y aun así obtener un comportamiento equivocado.

Nivel Pregunta Ejemplo de problema
Sintaxis ¿El lenguaje puede interpretar el código? Falta una llave o un paréntesis.
Ejecución ¿Puede realizarse sin lanzar errores? Se llama a una función inexistente.
Funcionalidad ¿Cumple el requisito? Agrega la tarea, pero no la guarda.
Experiencia ¿La persona entiende y puede usar el resultado? El error existe, pero no es visible.
Calidad ¿Puede mantenerse de forma segura? La lógica está duplicada en varios eventos.

7.11 El papel de las convenciones

Cuando la IA genera código dentro de un proyecto existente, no debería elegir libremente cada detalle. Debe reconocer y respetar convenciones como:

  • Nombres y organización de carpetas.
  • Formato del código.
  • Bibliotecas y componentes disponibles.
  • Manejo de errores.
  • Acceso a datos.
  • Estilo de las pruebas.

Dos soluciones pueden cumplir el mismo requisito, pero una puede integrarse naturalmente y la otra introducir una segunda forma de hacer lo mismo.

7.12 Trazabilidad: conectar frases y cambios

La trazabilidad permite responder por qué existe cada cambio. Una instrucción clara facilita revisar el resultado.

Frase solicitada Cambio esperado Evidencia
“No aceptar tareas vacías” Validación antes de insertar. Prueba con texto vacío y solo espacios.
“Marcar como completada” Estado y control visible. Prueba de ida y vuelta entre estados.
“Conservar al actualizar” Guardado y carga inicial. Recargar la página y comparar la lista.

Si encontramos código que no se relaciona con ningún requisito, debemos preguntar por qué fue agregado.

7.13 Iterar en lugar de pedir todo de una vez

Una solicitud demasiado grande obliga a resolver simultáneamente producto, diseño, arquitectura, almacenamiento, seguridad y publicación. Los errores quedan mezclados y es difícil saber qué decisión produjo cada problema.

Para nuestro ejemplo, una secuencia controlable sería:

  1. Crear la estructura visual con datos simulados.
  2. Permitir agregar tareas y validar el texto.
  3. Incorporar cambio de estado y eliminación.
  4. Agregar almacenamiento local.
  5. Probar casos normales y límites.
  6. Mejorar diseño y accesibilidad sin cambiar la lógica.

Cada etapa produce una versión que puede ejecutarse y evaluarse.

7.14 Qué revisar en el código generado

  • Qué archivos fueron creados, modificados o eliminados.
  • Qué requisitos aparecen implementados.
  • Qué supuestos agregó la IA.
  • Qué dependencias nuevas introdujo.
  • Cómo trata entradas vacías, incorrectas o inesperadas.
  • Si conserva el comportamiento anterior.
  • Qué pruebas existen y qué casos no cubren.
  • Si puede explicarse la relación entre solicitud y solución.
La generación termina cuando aparece código. El desarrollo termina cuando el comportamiento fue comprendido, integrado y comprobado.

7.15 Errores frecuentes en la traducción

  • Implementar una suposición como requisito: la IA elige una opción que nunca fue acordada.
  • Resolver solo el caso ideal: no contempla entradas vacías, duplicadas o inválidas.
  • Elegir demasiada arquitectura: crea capas innecesarias para una aplicación pequeña.
  • Ignorar el proyecto existente: introduce bibliotecas o convenciones diferentes.
  • Confundir interfaz con comportamiento: la página se ve terminada, pero sus controles no funcionan.
  • No conservar datos: el estado visible desaparece al recargar.
  • Modificar más de lo solicitado: mezcla una función nueva con refactorizaciones no requeridas.

7.16 Actividad de comprensión

Partí de esta solicitud:

Creá un contador de gastos mensuales.

Realizá los siguientes pasos antes de pedir código:

  1. Definí quién utilizará la aplicación y con qué objetivo.
  2. Escribí al menos cuatro operaciones necesarias.
  3. Indicá qué datos representa un gasto.
  4. Decidí dónde se almacenará la información.
  5. Agregá dos validaciones.
  6. Redactá tres criterios que permitan probar el resultado.
  7. Dividí la implementación en etapas pequeñas.

El ejercicio muestra que transformar lenguaje natural en software implica tomar decisiones incluso antes de generar la primera línea.