← Volver al blog

La programación con IA trae preocupaciones que las herramientas estándar no resuelven

Ilustración que contrasta los cambios caóticos de código generados por IA con el enfoque estructurado de AITM

La IA actual puede escribir una función, un componente o un endpoint completo en pocos segundos. El problema no aparece donde la gente lo espera: en la sintaxis o en la velocidad. Aparece en el momento en que la IA tiene que tocar un sistema existente: decenas de archivos, un historial de decisiones, reglas de negocio que no están escritas en ningún sitio salvo "en la cabeza" de los desarrolladores. Cómo prevenir este problema de forma sistemática es el tema de toda esta serie, y la herramienta a la que iremos llegando poco a poco se llama AITM.

Antes de llegar ahí, conviene plantear una pregunta que todo equipo que trabaja con agentes de IA acaba respondiendo tarde o temprano, por las buenas o por las caras: ¿cómo se sabe realmente que el resultado que un agente devolvió como "terminado" es de verdad correcto, y no que solo lo parece? La respuesta llegará al final de este artículo, pero antes veamos por qué esta pregunta no es tan obvia como parece.

Cómo se ve esto en la práctica

Un escenario típico: se le pide a un agente de IA que modifique una función. El agente la corrige, pero olvida que esa función se llama desde otros tres lugares con expectativas distintas. O "mejora" la estructura del código porque le pareció lógico, y con ello rompe lógica posterior que ni siquiera llegó a ver.

No son errores aislados: es un problema sistémico. El agente de IA no tiene el contexto de todo el sistema, solo lo que cabe en el prompt y lo que logra leer mediante búsqueda de texto completo. Decide a partir de palabras, no de la lógica de negocio. Si hay documentación disponible, a menudo carga todo el contenido, incluida la parte que no tiene nada que ver con el prompt dado. Y esto es cierto incluso para los modelos más potentes disponibles (Opus, Fable, Astra y similares): no es que el modelo no sea lo bastante inteligente, es que no tiene dónde almacenar de forma sistemática este conocimiento entre intervenciones individuales.

A medida que crece el número de líneas de código fuente, que la lógica de negocio se vuelve más compleja y que los módulos y clases se interconectan más, esta búsqueda empeora. Acaban entrando en la IA datos que no tienen nada que ver con la corrección, y el resultado es código técnicamente bien escrito pero que sigue la lógica de negocio equivocada. La funcionalidad resultante queda rota, o se "corrige" un fragmento de código que nadie quería tocar en primer lugar.

Dónde se atasca exactamente

El obstáculo fundamental es la alucinación, y es muy difícil de eliminar. El segundo problema es la calidad del prompt, sobre la que los usuarios ya podemos influir en parte. Pero sobre ambos se cierne una limitación más dura: el límite de contexto. Incluso con los modelos más grandes disponibles, hablamos de aproximadamente un millón de tokens, para entornos que tienen cientos de miles de líneas de código.

Por experiencia, el umbral práctico a partir del cual lo básico, como una Skill o un hint en un archivo md, deja de ser suficiente ronda las 150.000 líneas de código. Hacia las 300.000 líneas el entorno se vuelve realmente complejo: el estado del día a día empieza a desmoronarse y las cosas se rompen solas. Hablamos de software construido con POO, con condiciones lógicas complicadas y partes conectadas mediante mecanismos de mensajes/eventos y técnicas similares. En un código así, la referencia entre una llamada y su tratamiento no siempre es evidente, y a la IA le cuesta muchísimo esta parte: es bastante probable que no llegue a descubrir todo el código vinculado a un método dado.

A ello se añade otra capa: el propio agente de IA, a partir del prompt, suele lanzar sus propios subagentes, y la creación de esos subagentes está a su vez bajo el control de la IA, lo que introduce otra fuente más de error. Si la IA asigna un peso mayor a una palabra que solo se incluyó en una frase por fluidez gramatical (no como instrucción), puede lanzar a partir de esa palabra un subagente que procese algo que nunca se quiso. Y un subagente puede transmitir sus propios errores a otros agentes más adelante en la cadena, de modo que las alucinaciones individuales pueden propagarse y acumularse a lo largo de ella.

Parecería que un agente de comprobación, cuyo trabajo es verificar que todo se hizo según la especificación, debería resolverlo. Pero ¿qué significa realmente "verificar"? Si otra IA evalúa la Task del mismo modo en que se procesó, solo se obtiene la confirmación del mismo juicio, no una comprobación independiente. Solo cuando se usa un LLM distinto y mejor para la comprobación aumenta de verdad la probabilidad de detectar el error, pero es una decisión que alguien debe tomar deliberadamente, no un resultado automático de "se hizo una comprobación".

Queda todavía otro camino: ejecutar la aplicación o una prueba existente, leer el error del registro y corregirlo para que la prueba pase. Incluso aquí, sin embargo, sigue en pie la cuestión de qué se corrigió realmente: ¿es de verdad un bug, o es un error causado por un cambio en la lógica de negocio que un paso anterior hizo sin querer? La corrección en sí suele ser clara y el error desaparece, pero a menudo rompe de paso otra parte del código. Mucho depende de lo complejo que sea el código y de las dependencias que tenga.

Para cosas más simples, por ejemplo un formulario web con edición, validación tras rellenarlo y guardado de datos mediante lógica de negocio, esto no suele ser exigente y la probabilidad de éxito ronda el 99 %. Para estructuras más complejas, se puede acabar de verdad en un estado en el que la estructura del código empieza a desmoronarse y un bug sigue a otro. Ejecutar pruebas y pruebas e2e repetidamente puede ir corrigiéndolo poco a poco, pero en un sistema realmente complejo pueden hacer falta muchos intentos, y cada uno cuesta algo.

La respuesta que prometimos al principio

Volvamos a la pregunta inicial: ¿cómo se sabe que un resultado es realmente correcto y no solo que parece terminado? Solo a partir del prompt y de la comprobación posterior no se puede saber con fiabilidad. Hemos visto por qué: contexto limitado, alucinaciones que se propagan entre subagentes, una comprobación que en el peor de los casos solo confirma el mismo error, y una corrección guiada por el registro que no puede distinguir un bug real de un efecto secundario.

Estos son los métodos que los programadores usan habitualmente hoy, y para cambios más simples funcionan bien. El siguiente nivel es la orquestación mediante IA: se preparan ciertos datos sobre el sistema y se mantienen actualizados, de modo que se pueda dar a la IA mejor información y así reducir el margen que tiene para hacer algo distinto de lo que se pidió. Esta es exactamente la finalidad para la que se creó AITM — AI Task Manager: antes de que el agente que escribe el código llegue siquiera a la solicitud, el sistema incorpora Contracts (comportamiento documentado), un mapa del DOM y la lógica de negocio del área en cuestión, y solo entonces, con ese conocimiento, ensambla la Task. No depende de un único agente directamente, sino de toda una Pipeline y de otros métodos que AITM utiliza para lograr mejores resultados.

Los días siguientes mostrarán exactamente cómo se ve esto en AITM con prompts, agentes y pasos de Pipeline concretos, y por qué es una forma de trabajar con la IA distinta de la que los programadores conocen de una consola simple.