Un agente de código puede explorar un repositorio, modificar varios módulos, ejecutar comandos y preparar una pull request en una sola sesión. Esa capacidad reduce mucho el coste de implementar una solución. No reduce en la misma medida el coste de decidir qué solución necesitamos ni el de comprobar que el resultado es correcto.
Cuando una tarea llega como una petición ambigua, el modelo completa los huecos. Decide qué significan los términos, qué casos parecen importantes y cómo debe encajar la solución en el sistema. Muchas de esas decisiones serán razonables. Algunas contradecirán reglas que el equipo nunca llegó a escribir.
Por eso el desarrollo asistido por IA necesita algo más que mejores prompts. Necesita una cadena de referencias y comprobaciones que conecte la intención con el código:
Problema → especificación → implementación → tests → integración continua → revisión
Cada pieza responde a una pregunta distinta. La especificación explica qué queremos y qué límites existen. Los tests comprueban comportamientos concretos. La integración continua garantiza que esas comprobaciones se ejecuten antes de aceptar un cambio.
La especificación reduce las decisiones improvisadas
Spec-Driven Development, o desarrollo dirigido por especificaciones, utiliza una especificación explícita como referencia para planificar, implementar y validar un cambio.
Esto no significa que todo el código deba generarse automáticamente desde un documento formal. Tampoco obliga a preparar decenas de páginas antes de modificar una línea. En el trabajo con agentes, una especificación resulta valiosa cuando evita que una conversación temporal sea la única fuente de la intención.
Una buena especificación debería aclarar, al menos:
- Qué problema experimenta el usuario o el negocio.
- Qué comportamiento debe ofrecer el sistema.
- Qué casos y restricciones conocemos.
- Qué decisiones ya están tomadas.
- Qué queda fuera del cambio.
- Cómo comprobaremos el resultado.
El nivel de detalle depende del trabajo. Una corrección pequeña puede caber en una descripción breve con un caso reproducible. Una funcionalidad que afecta a varias partes del sistema necesita conservar más decisiones y sobrevivir a varias sesiones o personas.
¿Qué es Spec-Driven Development? Es una forma de desarrollar en la que una especificación guía la planificación, la implementación y la validación. Para un agente, actúa como una fuente estable de intención y reduce las decisiones que debe improvisar.
No todos los cambios necesitan el mismo proceso
El exceso de especificación también tiene un coste. Un documento largo puede quedarse obsoleto, introducir decisiones que nadie tomó o exigir más tiempo de lectura que el cambio que pretende explicar.
Antes de escribir una especificación completa conviene preguntar:
- ¿El trabajo cabe en una sola sesión y puede validarse fácilmente?
- ¿Afecta a varios módulos o equipos?
- ¿Contiene decisiones funcionales que pueden interpretarse de varias maneras?
- ¿Necesitamos que otra persona o agente retome el trabajo más adelante?
- ¿Una equivocación tendría consecuencias importantes?
Cuanto mayor sea la duración, el número de participantes o el coste del error, más valor aporta conservar la especificación fuera de la conversación.
Un spike funciona de otro modo. Su objetivo es reducir una incertidumbre y puede utilizar código desechable para conseguirlo. Cuando la investigación termina, lo aprendido debe incorporarse a la decisión o especificación posterior; el prototipo no se convierte por ello en producto.
Quién debe escribir y revisar una especificación
Una especificación funcional no debería ser una descripción técnica disfrazada. Su primera obligación es explicar el comportamiento que necesita el usuario.
La persona que conoce el negocio aporta el problema, las reglas y las excepciones. Producto delimita el alcance y ordena los casos de uso. La persona que mejor conoce la arquitectura comprueba que la propuesta utiliza el lenguaje del sistema, respeta sus límites y no crea una segunda solución para algo que ya existe.
Esta revisión arquitectónica debe ocurrir antes de delegar la implementación. Los agentes son muy eficaces completando huecos: cuando una convención no está documentada, aplican otra razonable; cuando desconocen una invariante, pueden construir alrededor de ella. El resultado puede funcionar y, aun así, aumentar la incoherencia del sistema.
Conviene separar dos preguntas:
- ¿Qué debe poder hacer el usuario? La especificación funcional responde desde fuera del sistema.
- ¿Qué debe respetar la implementación? Las decisiones arquitectónicas fijan límites, invariantes e interfaces.
Ambas perspectivas tienen que encontrarse antes de que el agente escriba código.
Skills pequeñas frente a procesos cerrados
Algunas propuestas de SDD intentan gobernar el ciclo completo mediante una cadena obligatoria de documentos y pasos. Puede funcionar en determinados contextos, pero también puede hacer que una tarea sencilla pague el coste de un proceso pensado para cambios mucho mayores.
El repositorio Skills for Real Engineers, de Matt Pocock, muestra un enfoque más componible. Sus Skills abordan fallos concretos: aclarar el problema, conservar decisiones en una especificación, dividir trabajos grandes, construir un prototipo, implementar con TDD, diagnosticar errores o revisar el código.
Una de sus decisiones más interesantes es que la especificación no se utiliza siempre. Si el trabajo ya está decidido y cabe en una sesión, puede implementarse directamente. Si debe sobrevivir a varias sesiones, se convierte la conversación y el contexto del repositorio en una referencia que otro agente pueda retomar.
La idea útil no es copiar todas las Skills. Es construir un proceso modular: añadir disciplina donde el equipo tiene un fallo observable y evitar ceremonias que no cambian el resultado.
Los tests son una garantía ejecutable limitada
La especificación utiliza lenguaje para expresar la intención. Un test toma una parte de esa intención y la convierte en una comprobación que el sistema puede ejecutar.
Esa garantía tiene límites. Una prueba solo protege el comportamiento que hemos sabido expresar. Puede pasar toda la batería y seguir existiendo un error en un caso que nadie contempló. Aun así, proporciona al agente algo que el razonamiento por sí solo no ofrece: una señal externa y repetible.
Sin tests, el agente inspecciona el código y estima si su cambio es correcto. Con tests puede avanzar en pasos pequeños, comprobar el resultado y detectar si ha roto comportamientos anteriores.
Los tests útiles para agentes comparten varias características:
- Comprueban comportamiento observable, no detalles internos accidentales.
- Producen errores comprensibles cuando fallan.
- Pueden ejecutarse de manera aislada y repetible.
- Utilizan resultados esperados independientes de la implementación.
- Se encuentran cerca del nivel donde se toma la decisión que protegen.
Una prueba que deja de funcionar por renombrar una función privada dificulta el cambio sin proteger al usuario. Una prueba que verifica una compra, una autorización o un cálculo protege una capacidad real del sistema.
TDD como ciclo de feedback
Test-Driven Development propone un ciclo sencillo: escribir una prueba que falla, implementar lo necesario para hacerla pasar y mejorar el código manteniendo la batería en verde.
Con agentes, este ciclo reduce el tamaño de cada apuesta. El modelo no genera una gran cantidad de código para descubrir al final si la dirección era correcta. Trabaja sobre un comportamiento, recibe feedback y utiliza lo aprendido en el siguiente.
TDD no debe convertirse en una obligación mecánica. Hay investigaciones, cambios visuales y refactorizaciones cuyo primer paso puede ser distinto. Lo importante es conservar el principio: el agente necesita ciclos de feedback frecuentes y debe poder demostrar el comportamiento que está construyendo.
También hay que evitar una trampa habitual: pedir al agente que escriba de una vez todos los tests imaginados y después toda la implementación. Esa separación puede producir pruebas que validan una estructura supuesta en lugar del comportamiento real. Los cortes verticales —un comportamiento comprobado de principio a fin— proporcionan feedback antes.
¿Qué es TDD? Test-Driven Development es un ciclo en el que se escribe una prueba que falla, se implementa el código necesario para hacerla pasar y después se mejora la solución sin romperla.
BDD y Gherkin como puente con negocio
Behavior-Driven Development resulta útil cuando varias áreas necesitan discutir el comportamiento con el mismo lenguaje. En lugar de comenzar por clases, funciones o endpoints, parte de ejemplos reconocibles.
Gherkin permite escribir esos ejemplos con una estructura sencilla:
Dado que un cliente tiene una suscripción activa
Cuando solicita cancelar la renovación
Entonces conserva el acceso hasta el final del periodo contratado
Negocio puede reconocer la regla. Producto puede preguntar por excepciones. Arquitectura puede decidir dónde debe cumplirse. El agente puede utilizar el escenario como criterio de implementación y, si el equipo lo automatiza, como prueba ejecutable.
Gherkin aporta menos cuando describe detalles internos o se utiliza únicamente para traducir tests que ya eran comprensibles. Su valor aparece cuando conecta una conversación funcional con una comprobación del sistema.
¿Qué son BDD y Gherkin? BDD describe el comportamiento esperado mediante ejemplos que negocio y tecnología pueden discutir. Gherkin es una sintaxis frecuente para expresarlos con estructuras como «Dado», «Cuando» y «Entonces».
La integración continua convierte los tests en una regla
Una batería de pruebas no protege el producto si ejecutarla depende de la memoria o la disciplina individual. El equipo necesita que la validación forme parte del camino normal de cada cambio.
La integración continua ejecuta automáticamente los tests y otros controles cuando alguien abre o actualiza una pull request. Con GitHub Actions podemos preparar un flujo que instale el proyecto en un entorno limpio, ejecute las comprobaciones y comunique el resultado a GitHub.
Los required status checks permiten impedir la integración mientras una comprobación obligatoria no haya terminado correctamente. Así, los tests dejan de ser una recomendación y se convierten en una condición compartida.
Esto es especialmente importante con agentes. Aunque el agente afirme haber ejecutado los tests, el sistema vuelve a comprobar el cambio fuera de su sesión. La integración continua reduce diferencias entre entornos y deja un resultado visible para quien revisa la propuesta.
El conjunto mínimo suele incluir:
- Tests automatizados.
- Comprobación de tipos, si el lenguaje la permite.
- Formato y reglas estáticas.
- Compilación o empaquetado.
- Validaciones de migraciones cuando afectan a datos.
- Controles de seguridad relevantes para el proyecto.
No todas las comprobaciones tienen que bloquear cualquier cambio. El equipo debe distinguir entre una advertencia informativa y una condición sin la cual el código no puede aceptarse.
¿Qué es la integración continua? Es la ejecución automática de pruebas y otros controles cuando se propone un cambio. Garantiza que las comprobaciones configuradas se realizan; no que esas comprobaciones cubran todos los errores posibles.
Una cadena práctica para trabajar con agentes
Un flujo razonable para un cambio de producto puede ser:
- Aclarar el problema con la persona que conoce la necesidad.
- Explorar el repositorio y las decisiones existentes.
- Redactar la especificación funcional y los casos relevantes.
- Revisar el encaje arquitectónico y los límites.
- Acordar en qué nivel se comprobará el comportamiento.
- Implementar en pasos pequeños, ejecutando los tests durante el trabajo.
- Revisar el cambio contra la especificación y las normas del proyecto.
- Abrir una pull request y ejecutar la integración continua.
- Exigir que los controles obligatorios pasen antes de integrar.
- Convertir cualquier regresión posterior en una nueva prueba.
Este flujo no tiene que aplicarse con la misma intensidad a todos los cambios. La disciplina debe crecer con el riesgo, la duración y el número de decisiones implicadas.
Errores frecuentes
Confundir una conversación con una especificación. Una conversación contiene dudas, alternativas y decisiones descartadas. Antes de implementar hay que sintetizar qué quedó acordado.
Permitir que el agente defina el comportamiento y lo valide con tests escritos por él mismo sin revisión. La misma interpretación equivocada puede aparecer en el código y en la prueba.
Probar detalles internos. Produce una batería frágil que dificulta mejorar la implementación.
Conservar especificaciones obsoletas como documentación permanente. Algunas son registros temporales de una entrega. Las decisiones duraderas deben trasladarse a la documentación adecuada.
Ejecutar los tests solo al final. Los ciclos largos retrasan la información y aumentan el coste de corregir la dirección.
Configurar CI sin convertir los controles importantes en obligatorios. El resultado aparece en la pull request, pero puede ignorarse.
Confundir una batería verde con software correcto. Los tests confirman lo comprobado, no todo lo posible.
Los agentes necesitan libertad dentro de un sistema
La respuesta a los errores de los agentes no puede ser revisar manualmente cada línea que generan ni limitar su uso a escribir funciones pequeñas. Eso desperdiciaría gran parte de su capacidad.
Podemos conceder más autonomía cuando el sistema conserva la intención, proporciona feedback y detiene los cambios que incumplen condiciones conocidas. Las especificaciones, los tests y la integración continua forman parte de ese sistema.
La especificación reduce ambigüedad. Los tests dan al agente una referencia ejecutable. La integración continua aplica la regla fuera de su sesión. La revisión humana se concentra entonces en aquello que no puede automatizarse fácilmente: si hemos resuelto el problema adecuado, si la arquitectura sigue siendo coherente y si el riesgo asumido tiene sentido.
Esta disciplina no frena el desarrollo asistido por IA. Permite utilizarlo en trabajos más importantes sin depender únicamente de la confianza en el modelo.
Si quieres implantar este enfoque en tu equipo, puedes leer la página de servicio Estandariza cómo programa tu equipo con IA.
Glosario
BDD Behavior-Driven Development. Enfoque que utiliza ejemplos comprensibles para concretar y comprobar el comportamiento esperado.
CI o integración continua Ejecución automática de pruebas y otros controles cada vez que se propone o incorpora un cambio.
Gherkin Sintaxis para describir comportamientos mediante escenarios con estructuras como «Dado», «Cuando» y «Entonces».
Pull request Propuesta para incorporar cambios al código compartido. Permite revisarlos y ejecutar comprobaciones antes de aceptarlos.
Skill Conjunto reutilizable de instrucciones que enseña a un agente cómo realizar una tarea siguiendo un método.
Spec-Driven Development Forma de desarrollo en la que una especificación explícita guía la planificación, la implementación y la validación.
TDD Test-Driven Development. Ciclo basado en escribir una prueba que falla, implementar el comportamiento y mejorar después la solución.
Referencias