Category: Arquitectura de Software

  • Las 4 habilidades que definen al programador en la era de la IA

    Las 4 habilidades que definen al programador en la era de la IA

    Un cliente me llamó a las 11 de la noche. Me dijo que su equipo llevaba tres semanas con Claude Code y que la productividad se había disparado. Más código por sprint. Menos bugs. Entregas más rápidas.

    Pero había un problema.

    "Bezael, el equipo construye muy rápido. El problema es que construye muy rápido la cosa equivocada."

    Tres semanas generando código con IA. Código correcto, bien estructurado, con tests. Y un producto que no resolvía lo que el cliente necesitaba.

    Ese es el nuevo riesgo para el programador en la era de la IA. No que la IA te reemplace escribiendo código. Sino que la velocidad de producción amplifique el coste de tomar decisiones equivocadas. Antes tardabas un mes en construir algo mal. Ahora tardas tres días.

    Lo que separa a los developers que avanzan de los que se atascan no son sus habilidades técnicas. Son cuatro habilidades del programador en la era de la IA que ningún LLM puede suplir.


    Las habilidades del programador en la era de la IA que este post desarrolla son cuatro: entender el problema real antes de escribir una línea, comunicar la solución a stakeholders no técnicos, especificar con precisión lo que el agente debe construir, y negociar trade-offs cuando los requisitos chocan. Son las habilidades que la IA no puede ejecutar por ti — y las que determinan si su velocidad se convierte en ventaja o en ruido.


    Por qué el código ya no es el cuello de botella del programador en la era IA

    Durante veinte años el cuello de botella en el desarrollo de software fue escribir el código. Encontrar developers. Escalar equipos. Mantener la velocidad.

    Eso ha cambiado.

    Hoy un developer con Claude Code puede producir en un día lo que antes llevaba una semana. Los agentes no se cansan, no tienen bloqueos creativos, y no discuten sobre si usar tabs o spaces. El Stack Overflow Developer Survey 2025 documenta que más del 75% de developers ya usa o planea usar herramientas de IA en su flujo de trabajo — el cambio está aquí.

    Pero los agentes hacen exactamente lo que les pides. Ni más, ni menos. Y si lo que les pides es impreciso, ambiguo, o directamente equivocado, producen código impecable que resuelve el problema equivocado.

    El cuello de botella se ha desplazado. Ya no está en escribir. Está en pensar.


    Habilidad 1: Entender el problema real antes de abrir el editor

    Esta es la más subestimada y la que más dinero cuesta cuando falla.

    Un cliente te dice: "Necesitamos un dashboard con métricas en tiempo real." Un developer técnico abre el editor y empieza a pensar en WebSockets, en qué charting library usar, en cómo estructurar el backend.

    Un developer con criterio hace una pregunta primero: "¿Para qué vas a usar ese dashboard? ¿Quién lo mira y qué decisión toma a partir de lo que ve?"

    Esa pregunta cambia todo.

    A veces el dashboard en tiempo real que pedían era en realidad un email diario con tres métricas. A veces era un CSV que se cargaba en Excel. A veces ni siquiera era un problema de visualización — era un problema de que nadie en la empresa sabía qué datos tenía disponibles.

    Con IA esto se vuelve crítico. Porque ahora la velocidad de producción es tan alta que el coste de empezar en la dirección equivocada es enorme. Construyes tres features completas en el tiempo que antes tardabas en escribir media. Si las tres están mal orientadas, has quemado tres veces más tiempo que antes.

    La habilidad de entender el problema real — no el síntoma que te describen, sino la causa raíz que lo genera — es la que protege todo lo demás.

    No se aprende con más cursos de programación. Se aprende haciendo preguntas incómodas antes de escribir una línea.


    Habilidad 2: Comunicar la solución a quien no es técnico

    El código más elegante del mundo no vale nada si nadie en la empresa entiende qué resuelve ni por qué importa.

    Esto ha sido siempre un problema para los developers. Pero con IA se vuelve más urgente, porque ahora eres capaz de construir cosas más complejas, más rápido, con más capas de abstracción. Y cuanto más complejo es lo que construyes, más difícil es explicarlo a quien toma las decisiones de negocio.

    La comunicación técnica a stakeholders no técnicos no es "simplificar para que lo entienda un niño". Es traducir impacto.

    Un stakeholder no necesita entender cómo funciona una cola de mensajes asíncrona. Necesita entender que gracias a esa cola, el sistema puede procesar diez mil pedidos en paralelo sin que ningún usuario espere más de dos segundos. Eso sí lo entiende. Y eso sí cambia cómo percibe el valor de lo que has construido.

    Esta habilidad también protege tu trabajo. Si tu contribución es invisible para quien decide los presupuestos, eres vulnerable. Si puedes hacer visible el impacto técnico en términos de negocio, eres indispensable.

    Practica esto: después de cada feature que entregues, escribe en dos frases qué problema de negocio resuelve y qué habría pasado sin ella. Si no puedes hacerlo, tienes un problema antes de que alguien externo lo detecte.

    Hay un ejercicio que funciona muy bien para esto: antes de la próxima reunión de sprint, prepara una explicación de lo que estás construyendo en menos de 60 segundos, sin usar términos técnicos. Si necesitas más tiempo o tienes que recurrir al jargon, la feature aún no está suficientemente clara en tu cabeza. Esa claridad — la que te permite explicarla en voz alta — es exactamente la que también necesitas para especificarla bien para un agente.

    Esta habilidad se conecta directamente con la siguiente. Un developer que no puede explicar lo que construye a un humano tampoco puede especificarlo con precisión para una máquina.


    Habilidad 3: Especificar con precisión lo que el agente debe construir

    Esta es la habilidad nueva. La que no existía como tal hace tres años y que ahora es central.

    Los agentes de IA son ejecutores extraordinarios de instrucciones precisas. Son ejecutores pésimos de instrucciones vagas.

    "Construye un sistema de autenticación" puede producir cualquier cosa desde un JWT básico hasta un sistema OAuth completo con múltiples proveedores y gestión de sesiones. El agente hará algo. Y lo que haga puede ser técnicamente correcto y completamente inadecuado para tu contexto.

    Especificar bien significa definir:

    1. Qué hace el sistema — comportamiento concreto, no intención abstracta
    2. Qué NO hace — los límites son tan importantes como las funcionalidades
    3. Bajo qué restricciones — tecnología, rendimiento, compatibilidad, seguridad
    4. Cómo se valida que está correcto — criterios de aceptación verificables

    Si quieres entender mejor el perfil completo del developer que trabaja con agentes en producción, el post sobre qué es un Agentic Engineer cubre ese rol con detalle. La especificación es su primer requisito.

    Llevo varios años aplicando una metodología para esto que llamo Spec-Driven Development. La idea es que antes de que el agente escriba una línea, tienes un documento que responde esas cuatro preguntas. No un documento largo ni burocrático — uno preciso. El Libro SDD documenta este proceso completo, desde cómo estructurar la especificación hasta cómo convertirla en tareas que un agente puede ejecutar sin desviarse.

    La diferencia entre un developer que especifica bien y uno que no lo hace no se mide en velocidad. Se mide en cuánto código hay que tirar a la basura al final de cada sprint.


    Habilidad 4: Negociar trade-offs cuando los requisitos chocan

    Los requisitos siempre chocan. Siempre.

    "Quiero que sea seguro, rápido, barato, flexible y que esté listo para el martes." No puedes tener las cinco cosas. Nunca has podido. Pero antes la conversación sobre qué sacrificar era más lenta porque construir era más lento. Ahora, con la velocidad que da la IA, la presión para tomarlo todo aumenta.

    Un developer que sabe negociar trade-offs no es el que cede ante la presión del cliente. Es el que hace explícito el coste de cada decisión y ayuda a quien decide a entender qué están eligiendo realmente.

    "Si priorizamos velocidad de lanzamiento, el sistema no va a escalar bien por encima de diez mil usuarios. Podemos lanzar en dos semanas con esa limitación asumida, o lanzar en seis semanas con una arquitectura que aguante cien mil. ¿Qué es más importante ahora mismo para el negocio?"

    Esa conversación requiere que el developer entienda el negocio suficientemente bien como para hacer la pregunta correcta. Requiere que sepa comunicar la implicación técnica en términos de impacto. Y requiere que tenga la seguridad de plantear la conversación antes de que los problemas aparezcan en producción.

    Con agentes de IA esto se vuelve más delicado porque la velocidad de implementación hace que sea tentador no tener esa conversación. "Lo construimos rápido, si no funciona lo cambiamos." Pero cambiar una decisión arquitectural después de que cuatro features dependen de ella no es barato, aunque la IA escriba el código.

    En el curso Construye con IA dedicamos una parte específica a cómo estructurar estas conversaciones antes de empezar a generar código — porque los errores más costosos no son de sintaxis, son de dirección.


    Las habilidades del programador que la IA no puede reemplazar

    La IA escribe código. Lo depura. Lo refactoriza. Lo documenta. Lo testea.

    No puede entrar a una reunión y detectar que lo que el cliente pide en realidad responde a un miedo que no ha verbalizado. No puede leer el contexto político de una organización para entender por qué un requisito existe. No puede mirar los ojos de un stakeholder y saber que cuando dice "necesitamos esto para el viernes" en realidad está diciendo "si esto no sale el viernes, me cuesta el trabajo".

    Esas lecturas son humanas. Y en un entorno donde el código se genera en segundos, son el verdadero diferencial.

    Los developers que van a crecer en los próximos años no son los que más saben de LLMs. Son los que combinan criterio técnico con las habilidades de comunicación, especificación y negociación que hacen que ese criterio tenga impacto.


    El developer que va a sobrevivir a la IA

    No es el que sabe más frameworks.

    No es el que tiene mejores prompts para Claude.

    Es el que puede entrar en una sala con personas técnicas y no técnicas, entender lo que realmente está en juego, definir con precisión lo que hay que construir, y explicar con claridad por qué ciertas cosas no se pueden tener al mismo tiempo.

    Este cambio de rol — de ejecutar tareas a tomar decisiones con criterio — es lo que ya analizamos en profundidad en el post sobre el programador que se convierte en product builder. Las cuatro habilidades de este post son el motor que hace posible ese salto.

    La IA amplifica la velocidad de ejecución. Las cuatro habilidades de las que hablamos hoy amplifican la calidad de las decisiones. Y en software, las decisiones siempre cuestan más que el código.

    En Dominicode Labs trabajamos estos temas con developers que están construyendo con IA en proyectos reales — no ejercicios de academia, sino productos con usuarios, deadlines, y stakeholders que necesitan respuestas los lunes por la mañana.

    Si quieres empezar hoy, elige la habilidad que sabes que tienes más floja de las cuatro y pasa esta semana ejerciéndola deliberadamente. Una conversación con un stakeholder. Un documento de especificación antes de abrir el editor. Una pregunta incómoda que no has hecho todavía.

    El código lo escribe la IA. El criterio lo pones tú.


    Preguntas frecuentes

    ¿Estas habilidades sustituyen al conocimiento técnico profundo?
    No, lo complementan. Sin base técnica sólida no puedes especificar bien ni negociar trade-offs con conocimiento de causa. Lo que cambia es que el conocimiento técnico ya no es suficiente por sí solo — necesitas combinarlo con estas capacidades para que tenga impacto real. Un developer que solo sabe programar pero no puede comunicar ni especificar ni negociar tiene cada vez menos diferencial frente a un agente de IA.

    ¿Cómo se aprende a especificar para agentes de IA si nunca lo he hecho?
    Empieza por escribir, antes de cualquier tarea, un documento de dos párrafos: uno con lo que el sistema debe hacer y uno con lo que no debe hacer. Con ese ejercicio simple ya estás especificando. A medida que lo practiques, irás añadiendo restricciones, criterios de aceptación y contexto. La metodología Spec-Driven Development es un marco más completo para esto, documentado en el Libro SDD.

    ¿Estas habilidades son más importantes para freelancers que para developers en empresa?
    Son importantes en los dos contextos, pero de formas distintas. El freelance que no sabe comunicar ni negociar pierde clientes. El developer en empresa que no sabe hacer estas cosas se queda estancado en roles de ejecución y ve cómo los que ascienden son los que saben tener las conversaciones difíciles. En ambos casos, la consecuencia de no desarrollarlas es la misma: invisibilidad.

    ¿La velocidad que da la IA no hace que estos trade-offs sean menos importantes porque "se puede cambiar todo fácilmente"?
    Es una trampa común. Sí, la IA acelera la implementación. Pero hay decisiones — de arquitectura, de modelo de datos, de contratos de API — que una vez tomadas son costosas de cambiar aunque el código lo escriba un agente.

    Si tu base de datos está mal modelada, reescribir las queries con IA no resuelve el problema. El coste de las malas decisiones estructurales no ha bajado con la IA.

    Lo que ha bajado es el coste de implementar la decisión, buena o mala. Eso amplifica el impacto de decidir bien tanto como el de decidir mal.

    ¿Existe algún perfil técnico donde estas habilidades no importan?
    Si trabajas en investigación pura, en open source sin usuarios directos, o en roles muy especializados de bajo nivel donde el contacto con stakeholders es mínimo, el peso relativo de estas habilidades es menor. Pero para la mayoría de developers que trabajan en productos, servicios o consultoría — que es la mayoría — estas cuatro capacidades son cada vez más determinantes para el crecimiento profesional.


    Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.

  • Proyecto greenfield con SDD: spec global + slices verticales

    Proyecto greenfield con SDD: spec global + slices verticales

    Hace unas semanas un developer del canal me contó lo que había pasado en su último proyecto.

    Seis horas. Eso tardó en planificar un proyecto greenfield con SDD usando slices verticales. Tenía un spec global, features bien definidas, tareas granulares. Parecía perfecto.

    Ejecutó el primer slice con su agente IA. La app funcionaba. Autenticación, flujo de datos, navegación — todo correcto.

    Y era completamente gris. Sin estilos. Sin diseño. Una interfaz que parecía sacada de 1998.

    No había especificado nada sobre la UI en su spec. Ni colores, ni componentes, ni sistema de diseño. El agente hizo exactamente lo que se le pidió: implementar la lógica. Y lo hizo bien.

    El problema no era el agente. Era el spec.

    El error que nadie te dice sobre SDD en proyectos nuevos

    Spec-Driven Development (SDD) es una metodología en la que cada feature comienza con un documento de especificación estructurado — el spec — antes de escribir código. El spec define qué hace la feature, cómo se ve, y qué criterios debe cumplir para considerarse completa.

    Cuando descubres SDD, la primera intuición es clara: especifica todo antes de escribir una línea de código. Visión, usuarios, funcionalidades, arquitectura, flujos.

    Y esa intuición es correcta… pero incompleta.

    Hay dos errores que se cometen casi siempre en un proyecto greenfield con SDD:

    El primero es intentar especificar el proyecto completo antes de tocar el teclado. Un spec monolítico de 40 páginas que detalla hasta la última feature antes de que exista una sola línea de código. Es atractivo. Se siente seguro. Y casi siempre es un error.

    El segundo es lo que le pasó a ese developer: especificar las features en términos de lógica y flujos, pero olvidar que las features tienen una cara visible. Que los usuarios las ven. Que el diseño no es una capa que se añade al final — es parte de la feature.

    Ambos errores llevan al mismo resultado: rediseño tardío, deuda técnica, y la sensación de que SDD no funciona cuando el problema real es la estrategia, no la metodología.


    La estructura que sí funciona: spec global ligero + slices con UI

    La solución tiene dos capas. Una sesión corta de spec global que define las reglas del juego, y luego un ciclo de feature-por-feature donde cada spec incluye explícitamente la UI.

    Capa 1: El spec global ligero

    Este documento no especifica features. Especifica el contexto en el que todas las features van a vivir. Se hace una sola vez, en una sola sesión, y no debería tomar más de 45 minutos.

    # Spec Global — [Nombre del proyecto]
    _Versión: 1.0 | Fecha: YYYY-MM-DD_
    
    ## Visión
    [Una sola frase que describe qué es el producto y para quién.]
    
    ## Stack técnico
    - Frontend: Angular 22 con Signals
    - Backend: NestJS + Supabase
    - Estilos: Tailwind CSS v4
    - Testing: Jest + Testing Library
    
    ## Sistema de diseño
    - Librería de componentes: Angular Material / PrimeNG / custom
    - Paleta de colores: primario #1A73E8, fondo #F8FAFC, texto #0F172A
    - Tipografía: Inter, base 16px
    - Espaciado: escala de 4px (4, 8, 12, 16, 24, 32, 48...)
    - Breakpoints: sm 640px / md 768px / lg 1024px / xl 1280px
    
    ## Convenciones de arquitectura
    - Estructura: feature-based (cada feature es un módulo independiente)
    - Estado global: NgRx Signal Store
    - Llamadas HTTP: Resource API (Angular 22)
    - Validación: Zod en schemas compartidos
    
    ## Decisiones técnicas ya tomadas
    - Autenticación: Supabase Auth (no reinventar)
    - Despliegue: Vercel (frontend) + Railway (backend)
    - No usar: Redux clásico, Class Components, módulos NgModule legacy
    
    ## Features planificadas (sin detallar)
    1. Autenticación
    2. Dashboard principal
    3. Gestión de proyectos
    4. Reportes
    

    Eso es todo. No más. El spec global no detalla cómo funciona cada feature — solo establece las reglas que todas van a respetar.

    Lo más importante de ese documento son las secciones de sistema de diseño y convenciones de arquitectura. Son el contrato que el agente va a respetar en cada feature. Si no las defines aquí, las decide él — y probablemente no va a coincidir con lo que tienes en la cabeza.

    Capa 2: El spec de cada feature — con sección UI obligatoria

    Aquí está el cambio que lo transforma todo. Cuando vas a implementar una feature, escribes su spec detallado en ese momento, no antes. Y ese spec siempre incluye una sección de UI/UX.

    # Feature 1: Autenticación
    _Contexto: spec global v1.0 | Estado: en implementación_
    
    ## Qué hace
    Permite al usuario crear cuenta, iniciar sesión y recuperar contraseña.
    Usa Supabase Auth. No hay lógica de autenticación propia.
    
    ## Flujos principales
    1. Registro: email + contraseña → verificación por email → redirect a dashboard
    2. Login: email + contraseña → redirect a dashboard (o a la ruta que intentaba visitar)
    3. Recuperación: email → link con token → nueva contraseña → login
    
    ## UI/UX (obligatorio)
    - Layout: columna centrada, max-width 400px, padding 24px
    - Componentes a usar: InputField, Button, Alert — todos del sistema de diseño global
    - Estados visuales a implementar:
      - Loading: botón con spinner, campos desactivados
      - Error: Alert rojo con mensaje específico (no "algo salió mal")
      - Éxito: redirect inmediato, sin pantalla intermedia
    - Mobile first: el form debe funcionar bien en 320px
    - No inventar componentes nuevos — usar los del spec global
    
    ## Criterios de aceptación
    - [ ] El usuario puede registrarse con email válido
    - [ ] El usuario recibe email de verificación
    - [ ] El usuario puede iniciar sesión y llega al dashboard
    - [ ] Los estados de loading y error son visibles
    - [ ] El form es usable en móvil
    
    ## Lo que NO hace esta feature
    - No maneja OAuth (Twitter, Google) — queda para v2
    - No maneja roles de usuario — eso es responsabilidad del dashboard
    

    La sección UI/UX no es opcional. Es donde especificas exactamente qué tiene que ver el usuario cuando interactúa con esta feature. Si la omites, el agente tomará esa decisión por ti, y probablemente tomará la decisión más rápida, no la más correcta.


    Spec total upfront vs spec incremental — la comparativa real

    La tentación de escribir el spec completo del proyecto antes de arrancar tiene sentido desde afuera. La realidad es diferente.

    Spec total upfront Spec incremental (global ligero + features)
    Tiempo inicial 2-3 días o más 45 min (spec global) — hasta 20× más rápido para arrancar
    Riesgo Alto — cambias de opinión cuando ves el código real Bajo — ajustas cada feature antes de implementarla
    UI/UX Probablemente omitida o abstracta Concreta en cada feature, con contexto real
    Consistencia Dependes de que el spec inicial fuera perfecto El spec global garantiza coherencia entre features
    Deuda de redesign Alta — aparece cuando el 80% del código ya existe Baja — se elimina en cada ciclo de validación visual
    Útil con agentes IA Solo si el agente tiene memoria perfecta (no la tiene) Sí — cada prompt incluye contexto concreto y actualizado

    El spec incremental no significa improvisación. Significa que el contexto que tienes cuando implementas la feature 4 es mejor que el que tenías antes de escribir una sola línea de código. Y ese contexto — los componentes que ya existen, las decisiones que ya se tomaron, los problemas que ya aparecieron — enriquece el spec de la siguiente feature.

    Este enfoque es una variación de la Vertical Slice Architecture documentada por Jimmy Bogard, aplicada al contexto de specs con agentes IA.

    El rediseño tardío no ocurre porque el spec sea incremental. Ocurre porque no hay spec en absoluto.


    El ciclo de trabajo en un proyecto greenfield SDD

    El flujo que funciona es simple, y se repite para cada feature:

    1. Escribe el spec de esa feature (con sección UI incluida)
    2. Dáselo al agente como contexto completo
    3. Implementa
    4. Valida visualmente antes de marcar como hecho
    5. Usa lo aprendido para enriquecer el spec de la siguiente feature

    El paso 4 es crítico y muchos lo saltan. Validar visualmente significa abrir el navegador, probar el flujo como lo haría un usuario real, y confirmar que los estados de loading, error y éxito se ven como los especificaste. No basta con que los tests pasen.

    Si en el paso 4 descubres que algo no se ve bien, arréglalo antes de avanzar. El coste de arreglar un componente mal implementado en la feature 1 es mínimo. El coste de arreglar el mismo patrón cuando ya está repetido en las features 1, 3, 5 y 7 es considerable.


    Lo que cambia cuando tienes el spec global

    El spec global tiene un efecto que no es obvio hasta que lo usas en producción.

    Cuando llegas a la feature 4, el agente tiene contexto. Sabe que los inputs van con Tailwind, que el estado global es NgRx Signal Store, que los errores se muestran con el componente Alert del sistema de diseño. Si estás usando Angular 22, también puedes aprovechar la Resource API para centralizar las llamadas HTTP en el spec desde el principio — sin que el agente invente su propio patrón. No lo tienes que repetir en cada prompt.

    Y cuando llega alguien nuevo al proyecto — o cuando tú mismo vuelves al código tres meses después — entiende en 10 minutos las decisiones que se tomaron y por qué.

    Eso no lo da el código. Lo da el spec.

    Si quieres profundizar en la metodología completa, en el libro de Spec-Driven Development tienes el framework completo: cómo estructurar specs, cómo trabajar con agentes IA de forma efectiva, y los patrones que se usan en proyectos reales de producción.


    La UI no es una capa. Es un contrato.

    El error del developer que me escribió no fue usar SDD. Fue asumir que SDD significa especificar todo el proyecto antes de arrancar.

    SDD significa especificar lo suficiente, en el momento correcto, con el nivel de detalle correcto. El spec global define el campo de juego. El spec de cada feature define las reglas de ese momento.

    Y la UI no es una capa que se añade al final. Es parte del contrato de cada feature.

    Si quieres ver este flujo en acción — desde el spec hasta el commit — en el curso Construye con IA: De la Idea al Producto aplicamos exactamente esta metodología: spec global, slices verticales, validación visual antes de avanzar. Con agentes IA reales, en proyectos que no son de juguete.

    Y si prefieres el formato comunidad, en Dominicode Labs compartimos los specs reales de los proyectos que construimos juntos — con las decisiones que se tomaron y las que se descartaron.

    El spec no te quita velocidad. Te quita el coste de arreglar lo que nadie especificó.


    FAQ

    ¿Cuánto tiempo debería tardar el spec global de un proyecto real?

    Entre 30 y 60 minutos. Si tardas más, estás especificando features en el spec global, y eso no es su función. El spec global define el contexto y las reglas. Las features se detallan una a una cuando llega su turno.

    ¿Es obligatoria la sección UI/UX en el spec de cada feature?

    En proyectos con interfaz visible, sí. Si estás construyendo una API sin frontend, la sección UI/UX no aplica, pero deberías incluir una sección de contratos de API: endpoints, tipos de respuesta, códigos de error. El principio es el mismo: especifica todo lo que el agente necesita para no tomar decisiones que tú deberías tomar.

    ¿Cómo manejo las features que dependen de otras que aún no están implementadas?

    En el spec de la feature con dependencia, añades una sección “Asunciones” que documenta qué esperas de las features previas. Si la feature A aún no existe, especificas el contrato que A debería cumplir — y cuando implementes A, ese contrato ya está documentado. Es una forma de diseño by contract que funciona muy bien con agentes.


    Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.

  • Qué es un agent harness: la anatomía del sistema que rodea al LLM

    Qué es un agent harness: la anatomía del sistema que rodea al LLM

    En AI Engineer 2026, Tejas Kumar (IBM) hizo algo incómodo delante de cientos de ingenieros: cogió GPT-3.5 Turbo — un modelo de 2023, una antigualla — y le pidió completar una tarea con herramientas. El agente falló. Y no solo falló: mintió. Dijo “he votado” sin haber votado. La tool call nunca se ejecutó.

    Entonces hizo lo interesante. No tocó el prompt ni una vez. No cambió de modelo. Solo añadió piezas alrededor — lo que hoy llamamos un agent harness: límites de pasos, un paso de verificación determinista, un handler de login que no dependía del LLM. Mismo modelo viejo, misma tarea. El agente la completó.

    Entender qué es un agent harness — qué piezas lo componen y por qué el modelo es la parte más pequeña del sistema — es probablemente la habilidad más rentable que puedes desarrollar como developer este año.

    La charla de Tejas ya pasa de 132.000 visualizaciones. Martin Fowler publicó sobre harness engineering. LangChain publicó “The Anatomy of an Agent Harness”. MongoDB lo resumió en una frase: el LLM es la parte más pequeña de tu sistema de agentes. Esto no es una moda de Twitter. Es la disciplina consolidándose.

    Y como dijo Tejas: 2025 fue el año de los agentes. 2026 es el año de los harnesses.

    Qué es un agent harness, sin humo

    La definición de Tejas es la mejor que he escuchado: el harness es todo lo que rodea al modelo y le da anclaje en la realidad.

    La metáfora es literal. El arnés de un escalador lo ancla a algo estable: si resbala, no cae. El arnés de un perro evita que se desboque detrás de la primera ardilla. El harness de un agente hace las dos cosas: ancla al modelo a tu sistema real y evita que se desboque.

    ¿Por qué importa tanto? Por una asimetría brutal de control. El modelo es una caja negra que alquilas por tokens. No puedes abrirla, no puedes depurarla, no puedes garantizar nada sobre ella. El harness es la parte que tú controlas al cien por cien. Si quieres fiabilidad — y en producción no hay otra opción — la fiabilidad vive en el harness, no en el modelo.

    Ya escribí sobre el harness desde el lado del usuario en Harness Engineering con Codex de OpenAI: cómo configurar AGENTS.md, modos de aprobación, ese terreno. Este post va por el otro lado. Vamos a abrir el capó.

    La anatomía: las 6 piezas de un harness

    Todo harness serio — Claude Code, Codex, Pi, el que construyas tú — tiene estas seis piezas. Cambian los nombres y la sofisticación, no la anatomía.

    1. Tool registry

    El catálogo de herramientas que el modelo puede invocar: leer archivos, ejecutar comandos, llamar APIs. Sin tools, el modelo solo genera texto. Las tools son sus manos.

    2. El modelo

    Sí, es una pieza más. Una de seis. No el sistema entero. Interiorizar esto cambia cómo diseñas.

    3. Gestión de contexto

    La ventana de contexto se llena, y un contexto saturado degrada al modelo mucho antes de reventar el límite de tokens. El harness necesita primitivas de compaction: resumir lo viejo, descartar lo irrelevante, conservar lo esencial. En Hacker News los devs ya lo dicen abiertamente: la gestión de contexto es hoy un cuello de botella mayor que la calidad del modelo.

    4. Guardrails

    Límites duros que el modelo no puede negociar: máximo de pasos, máximo de mensajes, qué comandos requieren aprobación. Son el código determinista que evita que un agente confundido queme tu presupuesto de API en un bucle infinito.

    5. El agent loop

    El corazón: el ciclo que llama al modelo, ejecuta sus tool calls, le devuelve los resultados y repite hasta terminar. Y alrededor, el “loop sobre el loop”: qué pasa cuando el ciclo interno acaba — ¿se verifica? ¿se reintenta? ¿se escala a un humano? Si quieres ver esta pieza llevada a producción, ya escribí sobre cómo implementar un loop de agente efectivo para LLM en producción.

    6. El verify step determinista

    La pieza que casi todo el mundo omite y la que más fiabilidad compra. Cuando el agente dice “he terminado”, no le crees: lo compruebas con código. ¿Existe el archivo? ¿Pasan los tests? ¿Devuelve 200 el endpoint? Verificación sin LLM. Sobre esta pieza volvemos luego, porque es la moraleja de la demo de Tejas.

    Pi: un harness de cristal

    El problema de estudiar harnesses con Claude Code o Codex es que son opacos. Usas el harness, pero no puedes leerlo.

    Por eso el mejor ejemplo pedagógico ahora mismo es Pi (badlogic/pi-mono en GitHub, hoy bajo la org Earendil). Lo creó Mario Zechner y hoy lo desarrolla junto a Armin Ronacher — sí, el creador de Flask y Jinja2 — y lleva más de 61.000 stars. Es un coding agent de terminal con un harness mínimo a propósito: puedes leerlo entero en una tarde y entender cada pieza.

    Recorre la anatomía con Pi en la mano:

    Tool registry: cuatro tools. Read, Write, Edit, Bash. Nada más. Y con eso un coding agent funciona, porque casi todo lo que hace un developer se reduce a leer, escribir, editar y ejecutar.

    Agent loop: un ReAct mínimo. Streamea la respuesta del modelo, comprueba si hay tool calls, las ejecuta, mete los resultados en el contexto y repite. En pseudocódigo (ilustrativo, no el código real de Pi):

    // Ilustrativo: la forma del loop ReAct de un harness mínimo
    while (true) {
      const response = await model.stream(context);
    
      if (response.toolCalls.length === 0) break; // terminó
    
      for (const call of response.toolCalls) {
        const result = await tools.execute(call); // Read | Write | Edit | Bash
        context.push(toolResult(call, result));
      }
    }
    

    Eso es. Esa docena de líneas es el corazón de todo coding agent que has usado. El resto del harness existe para que ese loop no se estrelle contra la realidad.

    Contexto: Pi inyecta una sola línea de descripción por capacidad instalada. Minimalismo deliberado: contexto pequeño, modelo más fino.

    Extensibilidad: aquí está la filosofía de Pi. Lo que otros agentes traen de fábrica, en Pi lo construyes tú — extensiones en TypeScript con acceso a tools, comandos, atajos, eventos y la TUI completa, más skills, prompt templates y themes. El core no engorda. Y esa decisión lo convirtió en plataforma: tanto Flu (del equipo de Astro) como OpenClaude están construidos sobre Pi.

    Si quieres tocarlo: npm install -g @earendil-works/pi-coding-agent y a leer código.

    La lección del verify step

    Vuelve a la demo de Tejas, porque ahí está la tesis del post.

    GPT-3.5 Turbo sin harness: el agente miente. Afirma haber hecho cosas que no hizo. Y ojo — no es maldad, es la naturaleza del modelo: genera el texto más plausible, y “ya he votado” es texto plausible.

    La solución no fue prompt engineering. Fue un guardrail más una verificación determinista:

    // Ilustrativo: guardrail + verify step alrededor del loop
    const MAX_STEPS = 15;
    
    for (let step = 0; step < MAX_STEPS; step++) {
      await agentLoop(task, context);
    
      if (await verify(task)) return "done"; // código, no LLM:
      // ¿existe el registro? ¿pasó el test? ¿respondió 200?
    
      context.push("La verificación falló. La tarea NO está completa. Continúa.");
    }
    throw new Error("Máximo de pasos alcanzado: escalar a humano");
    

    Con eso, el modelo de 2023 deja de mentir. No porque sea más listo: porque el harness no le permite declarar éxito sin pruebas. El verify step convierte "confío en lo que dice el agente" en "compruebo lo que hizo el agente". Esa es toda la diferencia entre demo y producción.

    Qué significa esto para ti

    Que el valor se está moviendo. De saber elegir modelo a saber construir el sistema alrededor del modelo.

    Con un buen harness, un modelo barato u open source — GPT-OSS, Qwen3 — llega muchísimo más lejos de lo que crees. La demo de Tejas lo prueba con un modelo de hace tres años. Inviertes una vez en el harness (código tuyo, determinista, testeable, versionado en git) y cada modelo nuevo que conectes hereda esa fiabilidad gratis.

    Y hay otra consecuencia que me toca de cerca: un harness se especifica, no se improvisa. Decidir guardrails, criterios de verificación y límites del loop antes de escribir código es exactamente el enfoque Spec-Driven que cuento en el libro de SDD. Un agente sin spec es un loop sin guardrails.

    Si quieres practicar este músculo construyendo productos reales con agentes, es la lógica que aplicamos de principio a fin en el curso Construye con IA: de la idea al producto, con el sistema — no la fe en el modelo — sosteniendo el resultado.

    Tu tarea para hoy es concreta: clona Pi, abre el loop y léelo. Es la mejor clase de arquitectura de agentes disponible, y es gratis.

    Lo que viene: Flu

    Este post es la pieza 1 de la serie "El año de los harnesses".

    En la pieza 2 subo de nivel: video en YouTube sobre Flu, el framework harness del equipo de Astro, construido precisamente sobre Pi. Si Pi es el harness mínimo para entender la anatomía, Flu es lo que pasa cuando un equipo serio construye encima de esa base para producción.

    Suscríbete al canal de YouTube de Dominicode para no perdértelo. Y si quieres discutir tu propio harness con otros developers que están construyendo con agentes, en Dominicode Labs es la conversación de cada semana.

    Preguntas frecuentes

    ¿Qué es un agent harness?

    Es todo el sistema que rodea al LLM y le da anclaje en la realidad: el tool registry, el agent loop, la gestión de contexto, los guardrails y la verificación determinista. El modelo genera decisiones; el harness las ejecuta, las limita y las comprueba. Es la parte del sistema de agentes que tú controlas.

    ¿Cuál es la diferencia entre un harness y un framework de agentes?

    Un framework de agentes (LangChain, CrewAI) te da abstracciones para orquestar LLMs: chains, grafos, equipos de agentes. El harness es más fundamental: es la pieza concreta que conecta un modelo con la realidad — loop, tools, guardrails, verificación. Todo framework de agentes contiene un harness dentro; pero puedes escribir un harness completo en cien líneas sin ningún framework, como demuestra Pi.

    Agent harness Framework de agentes
    Qué resuelve Conectar un modelo con la realidad de forma fiable Orquestar uno o varios agentes entre sí
    Nivel de abstracción Bajo: loop, tools, guardrails, verify Alto: chains, grafos, roles, equipos
    Ejemplos Pi, el harness de Claude Code, Flu LangChain, CrewAI, LangGraph
    Cuándo usarlo Siempre — todo agente corre dentro de uno Cuando orquestas flujos multi-agente complejos

    ¿Necesito construir mi propio harness o uso uno existente?

    Para programar día a día, usa uno existente (Claude Code, Codex, Pi). Construye el tuyo cuando el agente sea parte de tu producto: ahí necesitas controlar guardrails, verificación y costes, y un harness propio mínimo suele ganar a un framework genérico. En cualquier caso, lee uno entero al menos una vez — Pi es la opción perfecta — porque te cambia cómo usas todos los demás.

    ¿Qué es Pi (pi coding agent)?

    Pi es un coding agent open source de terminal creado por Mario Zechner y desarrollado hoy junto a Armin Ronacher (creador de Flask), con más de 61.000 stars en GitHub. Su harness es mínimo a propósito: 4 tools (Read, Write, Edit, Bash) y un loop ReAct que cabe en una pantalla. Todo lo demás se añade con extensiones TypeScript, skills y templates. Es la base sobre la que se construyen Flu y OpenClaude, y el mejor harness para estudiar porque puedes leerlo completo.

    ¿Por qué un modelo viejo con harness supera a un modelo nuevo sin harness?

    Porque los fallos típicos de un agente — declarar éxito sin haber hecho el trabajo, entrar en bucles, perder el contexto — no se arreglan con más inteligencia, se arreglan con estructura: guardrails que cortan los bucles y un verify step determinista que no acepta "ya está" sin pruebas. En la demo de Tejas Kumar (AI Engineer 2026), GPT-3.5 Turbo pasó de mentir a completar la tarea solo añadiendo harness, sin tocar el prompt.


    Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.

  • Product builder: el cambio de mentalidad que la IA hace posible

    Product builder: el cambio de mentalidad que la IA hace posible

    Hace tres años me llegó un mensaje de un developer con siete años de experiencia en React. Me decía:

    “Bezael, sé hacer cualquier cosa que me pidan. Pero no tengo nada propio. Ni una app, ni un proyecto, ni un ingreso fuera de mi salario.”

    Lo que describía no era un problema de habilidades técnicas. Era un problema de identidad.

    Se veía a sí mismo como alguien que ejecuta. Alguien que recibe tickets, los cierra, y espera el siguiente. Un programador en el sentido más literal del término.

    Y eso, en 2026, es el camino más directo a la irrelevancia.

    Lo que ese developer necesitaba — lo que muchos developers necesitan — es pasar de ejecutar a construir: convertirse en un product builder.


    El developer que ejecuta vs. el product builder que construye

    Un product builder es un developer que combina criterio técnico con pensamiento de producto: no solo implementa soluciones, sino que decide qué problemas merecen ser resueltos y para quién.

    Hay una diferencia fundamental entre los dos perfiles, y no tiene nada que ver con el nivel técnico.

    Programador tradicional Product builder
    Pregunta: “¿Cómo lo implemento?” Pregunta primero: “¿Debería implementarlo?”
    Espera que alguien le diga qué construir Tiene una tesis propia sobre qué problema merece ser resuelto
    Mide su valor en líneas de código o tecnologías que domina Mide su valor en si algo que construyó funciona para alguien real

    No estoy diciendo que uno sea mejor persona que el otro. Estoy diciendo que el mercado está cambiando a una velocidad que hace que el primer perfil sea cada vez más reemplazable — y el segundo, más valioso que nunca.


    Por qué ahora es el momento exacto para hacer este cambio

    La barrera técnica para construir un producto ha colapsado.

    Antes, si querías lanzar algo solo, necesitabas dominar frontend, backend, base de datos, autenticación, despliegue, y probablemente seis frameworks distintos. Necesitabas un equipo o años de práctica en cada capa.

    Hoy, con herramientas como Claude Code, un developer con criterio puede tener un MVP funcionando en días. No porque la IA programe por ti — sino porque amplifica lo que ya sabes y elimina la fricción entre la idea y el código que la materializa.

    Eso cambia la ecuación por completo. Ya no es técnica la limitante. Es saber qué construir, para quién, y por qué alguien pagaría por ello.

    Eso es exactamente lo que trabajo en el curso Construye con IA: usar la IA no para generar código al azar, sino para ir de una idea real a un producto real con criterio de producto desde el principio.


    Qué comportamientos concretos tiene un product builder

    No voy a darte una lista de buzzwords. Te voy a decir cómo actúa alguien que ya hizo el cambio.

    Empieza por el problema, no por la tecnología. Antes de elegir un stack, un product builder ya sabe a qué usuario le duele qué cosa. La tecnología es una consecuencia de la solución, no el punto de partida.

    Shipea antes de que esté perfecto. El perfeccionismo técnico es el enemigo número uno de construir productos. Un product builder sabe que una versión imperfecta en manos de usuarios reales vale más que una versión perfecta en un repositorio privado.

    Habla con usuarios. No con amigos que te dicen que tu idea es buena. Con personas que tienen el problema que quieres resolver. Y aprende a distinguir entre lo que dicen que quieren y lo que realmente usarían.

    Entiende el negocio. No necesitas un MBA. Necesitas entender por qué alguien pagaría, cuánto pagaría, y cómo llegas a esa persona. Un product builder piensa en distribución desde el día uno.

    Itera con datos. No con opiniones. Lanza, mide, ajusta. El ciclo es corto y deliberado.


    Las cinco habilidades que nadie te enseñó en ningún bootcamp

    1. Pensamiento de producto

    No es saber usar Figma ni saber escribir user stories. Es desarrollar el hábito de preguntarte: “¿Qué problema real resuelve esto? ¿Para quién específicamente?”

    Cuando ves una app que usas cada día, un product builder la desmonta mentalmente: qué decisiones tomaron, qué sacrificaron, por qué funciona.

    2. Velocidad de validación

    La idea de construir durante meses antes de mostrar algo a alguien es una trampa. El objetivo no es construir — es aprender lo antes posible si lo que estás construyendo tiene sentido.

    Eso significa aprender a hacer prototipos rápidos y demos que generan feedback real. Una landing page que vende antes de que exista el producto ya es validación.

    3. Escritura que convierte

    Un product builder sabe explicar su producto en una frase. Sabe escribir una descripción que hace que alguien quiera probarlo. Sabe comunicar valor, no features.

    Esta habilidad — que parece ajena al mundo técnico — es una de las más diferenciadoras.

    4. Distribución y audiencia

    El código más limpio del mundo no vale nada si nadie lo usa. Un product builder piensa desde el principio en cómo va a llegar a sus usuarios: SEO, comunidad, contenido, partnerships, cold outreach.

    No tienes que hacerlo todo. Pero tienes que tener una respuesta a la pregunta: “¿Cómo van a enterarse de que esto existe?”

    5. Tolerancia a la ambigüedad

    Este es el más difícil para muchos developers, porque venimos de entornos donde los requisitos están (supuestamente) definidos. Construir un producto propio significa tomar decisiones con información incompleta, constantemente.

    Aprender a avanzar sin certeza total es una habilidad que se entrena, no que se tiene o no se tiene.


    El rol de la IA en todo esto

    La IA no te convierte en product builder. Eso lo haces tú con las decisiones que tomas.

    Lo que sí hace la IA es eliminar excusas.

    Antes, “no tengo tiempo para construir algo propio porque el backend me llevaría meses” era una razón real. Hoy no lo es. Hoy puedes hacer el backend en días, el frontend en días, el despliegue en horas.

    Lo que la IA no puede hacer por ti es decidir qué problema merece tu atención. No puede hablar con tus usuarios potenciales. No puede construir la audiencia que va a usar lo que hagas.

    Esa es tu parte. Y es la parte que más importa.

    Si quieres ver cómo trabajo este proceso — de la idea al producto con criterio de ingeniería y de negocio — en Dominicode Labs tenemos proyectos reales donde aplicamos exactamente esto: spec, validación, shipping, iteración.


    Cómo empezar el cambio hoy (sin abandonar tu trabajo)

    No te estoy pidiendo que renuncies ni que lances una startup la semana que viene. Te estoy pidiendo algo mucho más concreto.

    Elige un problema que tengas tú mismo — algo que te frustra como developer, como usuario, como persona — y pasa dos semanas construyendo una solución mínima. No perfecta. Mínima.

    Compártela con cinco personas que tengan el mismo problema. Observa qué pasa.

    Eso es un ciclo completo de product builder. Y lo puedes hacer este mes.

    La metodología que uso para estructurar este proceso — desde la especificación hasta el producto funcionando — está documentada en el Libro SDD. No es solo para proyectos grandes: es para cualquier developer que quiera pasar de “tengo una idea” a “tengo algo que funciona y que alguien usa”.


    El cambio no es técnico. Es de identidad.

    Volviendo al developer que me escribió hace tres años.

    Le dije algo simple: deja de pensar en qué tecnologías sabes y empieza a pensar en qué problema puedes resolver para alguien esta semana.

    No le dije que aprendiera product management. No le dije que hiciera un curso de negocios. Le dije que eligiera un problema pequeño y real, y que construyera algo — no para su portfolio, sino para alguien que lo necesita.

    Hoy tiene un producto SaaS que le genera ingresos recurrentes, lo sigue manteniendo como side project, y lleva ocho meses sin depender de que alguien le diga qué ticket hacer.

    Eso es lo que significa ser un product builder. No es un título. Es una forma de relacionarte con lo que construyes.

    Y la IA ha puesto esa posibilidad al alcance de cualquier developer que decida tomarla.


    Preguntas frecuentes

    ¿Un product builder necesita saber de diseño?
    No necesitas ser diseñador. Sí necesitas entender los principios básicos de UX y tener criterio para cuando algo es demasiado confuso para un usuario. Herramientas como Figma o incluso componentes UI prefabricados resuelven la mayor parte del problema visual. Lo que no puede resolver una herramienta es saber si tu producto tiene sentido.

    ¿Se puede ser product builder trabajando para una empresa?
    Sí, y de hecho es uno de los perfiles más buscados en empresas de producto. La diferencia es que aplicas el pensamiento de producto dentro de un equipo: cuestionas los requisitos, propones soluciones, mides el impacto real de lo que construyes. No eres el que ejecuta tickets — eres el que ayuda a decidir qué tickets merece la pena hacer.

    ¿La IA reemplaza al product builder?
    La IA reemplaza al developer que ejecuta tareas sin criterio. Al product builder lo amplifica, porque puede construir más rápido y experimentar más sin necesitar un equipo grande. La IA toma decisiones técnicas; el product builder toma decisiones de producto. Son funciones distintas.

    ¿Por dónde empiezo si nunca he lanzado nada propio?
    Empieza por un problema que conozcas bien — preferiblemente uno que tú mismo tengas. Construye la versión más pequeña posible que lo resuelva. Compártela con gente real antes de que esté “lista”. El error más común es esperar a tenerlo perfecto antes de mostrárselo a alguien. La retroalimentación temprana es lo que convierte una idea en un producto.

    ¿Cuánto tiempo lleva la transición de programador a product builder?
    No es una transición con fecha de fin — es un cambio de mentalidad que se profundiza con cada proyecto. El primer ciclo completo (idea, construcción mínima, usuarios reales, iteración) ya te cambia cómo ves el trabajo. La mayoría de developers que conozco que hicieron el cambio notan la diferencia después del primer proyecto propio que alguien usa de verdad.


    Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.

  • Qué es un Agentic Engineer y cómo convertirte en uno en 2026

    Qué es un Agentic Engineer y cómo convertirte en uno en 2026

    El año pasado hablé con un developer que llevaba tres meses usando Claude como copiloto. Me dijo: “Bezael, soy un 30% más rápido. Pero sigo sin entender lo que ocurre debajo.”

    Tres meses. Treinta por ciento más de velocidad. Y la sensación de que le faltaba algo.

    Le faltaba exactamente esto: pasar de usar agentes de IA a diseñarlos. De consumir herramientas a entender qué las hace funcionar en producción, dónde fallan, cómo orquestarlas para que resuelvan problemas complejos sin supervisión constante.

    Eso es agentic engineering — y en 2026 se está convirtiendo en la disciplina más relevante para cualquier developer que construya con IA.

    Qué es exactamente el agentic engineering

    El agentic engineering es la ingeniería de software especializada en diseñar, construir y operar sistemas de agentes de IA que trabajan de forma autónoma para completar objetivos.

    No es usar ChatGPT para escribir código más rápido. No es añadir un botón de “generar con IA” a tu app. Es una disciplina de arquitectura de sistemas con sus propios patrones, sus propias decisiones de diseño y sus propios problemas de producción.

    La diferencia práctica: un developer que usa IA como copiloto recibe sugerencias y decide qué aceptar. Un agentic engineer diseña el sistema donde la IA toma decisiones, ejecuta acciones y se corrige a sí misma — y lo hace de forma predecible, trazable y fiable.

    Esa es la distancia. No es trivial.

    Por qué importa ahora y no en dos años

    Hasta 2024, los agentes eran demos. Impresionantes en vídeo, rotos en producción. El modelo se confundía, las herramientas fallaban, el contexto se perdía a las diez iteraciones.

    En 2025 cambió algo fundamental: los modelos de frontera dieron un salto cualitativo en razonamiento. Claude Sonnet 4 (Anthropic, 2025), GPT-4o y Gemini 2.5 Pro pueden mantener objetivos complejos durante decenas de ciclos de herramienta sin perder el hilo — algo que sus predecesores de 2023 no podían hacer de forma fiable.

    Eso abrió una ventana que no va a durar indefinidamente: los developers que entiendan cómo orquestar estos sistemas tienen una ventaja real ahora, antes de que esto se empaquete en herramientas de no-code para cualquiera.

    La demanda ya está llegando. Las empresas no buscan developers que sepan usar IA como asistente. Buscan developers que sepan construir sistemas donde la IA hace trabajo autónomo de verdad — revisión de código, análisis de datos, procesamiento de documentos, automatización de pipelines enteros.

    El mercado se está moviendo. La pregunta es si tú te mueves con él o lo observas desde fuera.

    La diferencia real con vibe coding (y por qué importa)

    Hay que nombrarlo porque está en todas partes: el vibe coding — dejar que el modelo genere código mientras tú aceptas todo sin entender qué hace.

    No es necesariamente malo para prototipar. Pero confundir vibe coding con agentic engineering es uno de los errores más caros que puedo ver en un developer que quiere construir cosas serias.

    El vibe coding asume que el modelo siempre sabe lo que hace. El agentic engineering parte de la premisa contraria: el modelo es poderoso pero falible, y tu trabajo como ingeniero es diseñar el sistema que lo hace fiable.

    La diferencia concreta:

    Vibe coding Agentic Engineering
    Acepta la sugerencia del modelo Diseña el sistema que valida la salida del modelo
    Trabaja con prompts sueltos Trabaja con pipelines de contexto, memoria y herramientas
    No entiende por qué funciona Entiende el agentic loop y puede depurarlo
    Falla en producción sin saber por qué Instrumenta observabilidad para ver qué hace el agente
    Escala hasta el primer bug complejo Escala porque el sistema tiene controles de calidad

    El vibe coding te da velocidad al principio. El agentic engineering te da sistemas que funcionan en producción durante meses, sin que tengas que apagar el servidor a las 2 de la mañana porque el agente tomó una decisión que no deberías haberle permitido.

    Qué sabe hacer un Agentic Engineer

    Esto no es una lista de tecnologías. Es un mapa de competencias — cada una representa una decisión de diseño real que separa un sistema de agentes que funciona de uno que falla.

    Habilidades técnicas core

    Habilidad Por qué importa en producción
    Diseño de flujos multi-agente Saber cuándo descomponer en subagentes y cuándo no — la descomposición innecesaria multiplica los puntos de fallo
    Gestión de contexto y memoria El contexto mal diseñado es la causa número uno de degradación en agentes de larga ejecución
    Tool design y herramientas seguras Las herramientas mal diseñadas son el vector de ataque más común en sistemas agénticos
    Orquestación y handoffs Cómo un agente pasa trabajo a otro sin perder información crítica en la transferencia
    Observabilidad y trazabilidad Sin trazas, depurar un agente en producción es imposible — solo ves inputs y outputs, no el razonamiento
    Límites y control humano Definir qué acciones requieren confirmación y cuáles pueden ser autónomas — no todo el tiempo, no nunca
    Evaluación de agentes Cómo medir si el agente está haciendo bien su trabajo, más allá de “parece correcto”

    Habilidades de sistema

    Un agentic engineer también tiene que pensar en capas más amplias:

    • Arquitectura de prompts de sistema — no es escribir un prompt, es diseñar las instrucciones que gobiernan el comportamiento del agente en todos los escenarios posibles
    • Gestión de errores en pipelines asíncronos — los fallos en sistemas multi-agente no se propagan como en código síncrono normal
    • Estrategias de retry y fallback — qué hace el sistema cuando el modelo devuelve una respuesta malformada o una herramienta falla en el ciclo 8 de 15
    • Cost management — los tokens tienen precio; un agente que entra en bucle puede consumir más en una hora que todo un mes de uso normal

    La diferencia con el developer tradicional

    Un developer tradicional escribe código que ejecuta instrucciones exactas. Sabes exactamente lo que hará tu función processPayment() si la lees línea a línea.

    Un agentic engineer trabaja con sistemas donde el comportamiento exacto es no determinista. El mismo input puede producir outputs ligeramente diferentes. El agente puede resolver el problema de tres maneras distintas y todas pueden ser válidas — o puede fallar de formas que no estaban en ningún test.

    Esto no hace el trabajo más fácil. Lo hace diferente. Requiere un cambio de mentalidad: de “verificar que el código es correcto” a “diseñar el sistema para que los errores sean detectables, contenidos y recuperables”.

    También requiere entender el negocio a un nivel más profundo. Cuando un agente tiene autonomía para tomar decisiones, las consecuencias de una decisión incorrecta son mayores que cuando un developer escribe código que hace exactamente lo que le dicen.

    El agentic engineer tiene que entender qué acciones son reversibles, cuáles tienen consecuencias económicas y cuáles requieren supervisión humana.

    Cómo convertirte en un Agentic Engineer: roadmap práctico

    No hay un título. No hay una certificación que lo valide todavía. Lo que hay es experiencia construyendo sistemas reales y la capacidad de razonar sobre ellos.

    Este es el roadmap que yo seguiría si empezara hoy:

    Fase 1 — Entiende el mecanismo antes de las abstracciones (2-3 semanas)

    Implementa un agentic loop desde cero con la API de Anthropic o OpenAI. Sin LangChain. Sin frameworks. Solo el bucle percibir-razonar-actuar con tres herramientas básicas: leer archivos, escribir archivos, ejecutar comandos. Si no has leído el post sobre el agentic loop, empieza por ahí — cubre exactamente esta capa.

    La estructura mínima en TypeScript tiene este aspecto:

    while (objective.isNotComplete()) {
      const observation = await perceive(environment);  // leer contexto
      const decision = await llm.reason(observation);   // razonar con el modelo
      const result = await tools.execute(decision);     // ejecutar herramienta
    
      if (decision.type === "final_answer") break;
      environment.update(result);                       // actualizar estado
    }

    No es código de producción — es el esqueleto. Entender qué entra y qué sale en cada paso es lo que te permite depurar cuando el agente toma una decisión inesperada en el ciclo 12.

    El objetivo no es llegar rápido a producción. Es entender qué ocurre en cada iteración para poder diagnosticar problemas después.

    Fase 2 — Diseña tu primer agente con propósito real (3-4 semanas)

    Coge un problema concreto de tu trabajo diario y construye un agente que lo resuelva. No un agente genérico. Uno que haga una cosa específica bien: revisar PRs, procesar facturas, generar reportes a partir de datos, lo que sea que tenga valor en tu contexto.

    La restricción de “un problema específico” es intencional. Los agentes generalistas fallan más que los especializados. Empieza acotado.

    Fase 3 — Introduce observabilidad desde el principio (paralelo a Fase 2)

    Antes de confiar en que tu agente funciona, instrumenta lo que hace. Registra cada herramienta que llama, cada decisión que toma, cuántos tokens consume por ciclo. Sin esta capa no puedes mejorar el sistema — solo puedes rezar para que funcione.

    Fase 4 — Construye tu primer sistema multi-agente (4-6 semanas)

    Aquí está el salto real. Diseña un sistema donde dos o más agentes colaboran: un orquestador que divide el trabajo y subagentes que lo ejecutan. Implementa los handoffs. Entiende dónde se pierde contexto en la transferencia y cómo evitarlo.

    Este es el nivel donde empieza a tener sentido hablar de agentic engineering como disciplina, no como experimento.

    Fase 5 — Opera en producción (continuo)

    Despliega. Observa los fallos reales. Itera. Los problemas que solo aparecen en producción — usuarios que hacen cosas inesperadas, APIs externas que fallan en el momento equivocado, el modelo que decide hacer algo creativo con un input ambiguo — son los que te convierten en engineer de verdad.

    Dónde aprenderlo hoy

    La teoría ya no es el problema. Lo que falta en casi todo el material disponible es el criterio: cuándo usar qué patrón, cómo depurar cuando el sistema falla, qué decisiones de arquitectura importan en producción y cuáles son optimización prematura.

    En el curso Construye con IA cubrimos exactamente este criterio: desde el agentic loop hasta el diseño de sistemas multi-agente, pasando por las decisiones de arquitectura que hacen que un agente funcione en producción y no solo en demos.

    Y si quieres el marco estructural para diseñar antes de construir — la metodología que evita construir el sistema equivocado — el libro de Spec-Driven Development explica cómo especificar sistemas de agentes antes de escribir una sola línea de código.

    El developer que llegó a tiempo

    Vuelvo al developer del principio. El que era un 30% más rápido pero no entendía lo que ocurría debajo.

    Le dije que esa sensación era buena. No porque ser ignorante sea bueno, sino porque reconocer el gap es el primer paso para cerrarlo.

    La mayoría de los developers que usan IA hoy están en ese punto. Más rápidos. Más productivos. Pero construyendo sobre una caja negra que no controlan.

    El agentic engineering es la disciplina que convierte esa caja negra en un sistema que entiendes, que puedes depurar y que puedes confiar en que funciona cuando no estás mirando.

    Eso no es el futuro. Es lo que los mejores developers están haciendo ahora mismo.

    Si quieres ver cómo aplicamos estos principios en proyectos reales — con análisis de arquitecturas, sesiones de revisión de código y una comunidad de developers que ya construyen sistemas de agentes en producción — pásate por Dominicode Labs.

    FAQ — Preguntas frecuentes sobre Agentic Engineering

    ¿Qué es el agentic engineering exactamente?

    El agentic engineering es la disciplina de ingeniería de software especializada en diseñar, construir y operar sistemas de agentes de IA autónomos. A diferencia del desarrollo de software tradicional, trabaja con sistemas donde el comportamiento es no determinista y los agentes pueden tomar decisiones, ejecutar acciones y corregirse a sí mismos en tiempo real. El foco está en hacer esos sistemas predecibles, trazables y fiables en producción, no solo en demos controladas.

    ¿En qué se diferencia un Agentic Engineer de un developer que usa IA?

    Un developer que usa IA la utiliza como asistente: genera código, sugiere soluciones, responde preguntas. El agentic engineer diseña sistemas donde la IA actúa con autonomía: orquesta tareas, gestiona herramientas, mantiene contexto y opera sin supervisión constante. La diferencia no es de herramientas sino de nivel de abstracción y responsabilidad sobre el sistema.

    ¿Se necesita experiencia con LLMs para convertirse en Agentic Engineer?

    No es imprescindible, pero acelera mucho entender cómo funcionan los LLMs internamente: cómo procesan el contexto, por qué el tamaño del contexto importa, cómo el diseño del prompt afecta al comportamiento. Un developer con experiencia en arquitecturas de backend distribuidas tiene una ventaja real — los problemas de fiabilidad, observabilidad y gestión de errores son conceptualmente similares.

    ¿Cuáles son los frameworks más usados en agentic engineering hoy?

    En 2026 los más extendidos son LangGraph (para flujos con estado y ramificaciones complejas), las primitivas nativas de Anthropic con tool use, y las de OpenAI con function calling. Claude Code es una implementación completa de un agentic loop para desarrollo de software. Para orquestación visual y automatizaciones de negocio, n8n tiene nodos de AI Agent que implementan el loop sin escribir código. La recomendación es aprender el mecanismo antes que el framework — los frameworks cambian, el agentic loop no.

    ¿El agentic engineering reemplaza al desarrollo de software tradicional?

    No lo reemplaza, lo extiende. Los sistemas de agentes necesitan infraestructura, APIs, bases de datos, autenticación — todo el stack de desarrollo tradicional. Lo que cambia es la capa de lógica de negocio: en lugar de escribir código imperativo que ejecuta pasos exactos, el agentic engineer diseña el sistema que permite a la IA razonar sobre esos pasos. Ambas capas son necesarias y complementarias.

    ¿Qué diferencia hay entre agentic engineering y prompt engineering?

    El prompt engineering es una técnica dentro del agentic engineering — diseñar las instrucciones que gobiernan el comportamiento del agente. Pero el agentic engineering es mucho más amplio: incluye arquitectura de sistemas, diseño de herramientas, gestión de memoria y contexto, observabilidad, estrategias de fallback y operaciones en producción. Un buen prompt es necesario pero no suficiente para construir un agente que funcione en producción.


    Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.

    Si este post te ha sido útil, hay más contenido técnico sobre IA aplicada al desarrollo en el canal de YouTube de Dominicode.

  • Clean Architecture en frontend con IA: respeta las capas

    Clean Architecture en frontend con IA: respeta las capas

    Le pedí a un agente que generara la feature de listado de productos para un proyecto frontend.

    Veinte segundos después tenía el código listo. Funcionaba. Los datos aparecían en pantalla.

    Y entonces abrí el componente y vi esto:

    // ProductListComponent.tsx — lo que el agente generó sin contexto
    const ProductListComponent = () => {
      const [products, setProducts] = useState([]);
    
      useEffect(() => {
        fetch("https://api.myapp.com/products")
          .then(res => res.json())
          .then(data => setProducts(data));
      }, []);
    
      return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
    };

    Una llamada HTTP directamente en el componente. Sin interface. Sin use case. Sin repository. Sin manejo de errores. La lógica de negocio mezclada con la presentación, exactamente lo que llevaba seis meses evitando en ese proyecto.

    El agente no hizo lo que yo quería. Hizo lo que era más rápido de generar.

    Ese es el problema real cuando usas IA en un proyecto con clean architecture frontend: la IA optimiza para el camino más corto, no para el más correcto. Y sin guía, el camino más corto siempre es el spaghetti.

    (Los ejemplos de este post usan TypeScript 5.4 con Angular 19 / React 18 como referencia, y Claude Code en su versión de 2026. El CLAUDE.md y los principios aplican igualmente a Cursor y GitHub Copilot.)

    Por qué la IA destroza la arquitectura si la dejas sola

    Clean Architecture en frontend no es difícil de entender. Es difícil de sostener.

    Cualquier developer senior entiende la separación de capas. El problema es que cuando el equipo crece, cuando hay presión de tiempo, cuando alguien nuevo entra al proyecto — las capas se erosionan. Un fetch aquí, una lógica de transformación allá directamente en el componente.

    La IA acelera exactamente este problema.

    Los LLMs aprenden de código real que existe en internet. Y el código real que existe en internet está lleno de llamadas HTTP en componentes, lógica de negocio en controllers, transformaciones de datos sin tipado. Los modelos han visto millones de ejemplos de ese código. Lo reproducen con total confianza porque estadísticamente es el patrón más frecuente.

    Si no le dices al agente qué arquitectura sigue tu proyecto, asumirá que no tienes ninguna.

    Las capas que importan en frontend

    Clean Architecture en frontend es un patrón de organización de código que divide la aplicación en tres capas independientes (Domain, Data, Presentation) con una regla de dependencia estricta: las capas externas dependen de las internas, nunca al revés.

    En frontend, estas tres capas se pueden modelar de forma clara — independientemente de si usas Angular, React o Vue:

    Domain — El núcleo. Aquí viven las entities (los modelos de negocio), los use cases (la lógica que define qué puede hacer el sistema) y los ports (las interfaces que definen contratos sin implementación concreta).

    Data — La capa de acceso a datos. Repositories (implementaciones concretas de los ports), DTOs (los objetos que llegan de la API tal como los devuelve el servidor), y adapters/mappers (la transformación de DTO a entity).

    Presentation — Lo que el usuario ve. Componentes, páginas, ViewModels (la forma específica en que la presentación necesita los datos), y el estado de UI.

    La regla de dependencia es simple: las capas externas dependen de las internas. La Presentation conoce el Domain. El Data implementa los contratos del Domain. El Domain no sabe que existe ninguna de las otras dos.

    Presentation → Domain ← Data

    El componente no habla con la API. Habla con un use case. El use case habla con un repository port. El repository concrete habla con la API y transforma los datos antes de devolverlos.

    Eso es lo que el agente rompió cuando puso el fetch directamente en el componente.

    Dónde la IA puede ayudarte más en Clean Architecture

    La IA es extraordinariamente buena en el trabajo más aburrido de Clean Architecture.

    Crear interfaces de repositorios. Generar mappers entre DTOs y entities. Escribir use cases que siguen un patrón uniforme. Crear tests unitarios de use cases que no tienen dependencias externas. Esas son tareas repetitivas, con patrones claros, donde el agente brilla.

    Y son exactamente las tareas que los developers saltamos “para ir más rápido” y que luego generan deuda técnica durante meses.

    Tarea de Clean Architecture IA sin contexto IA con contexto
    Generar entity con validación Genera clase plana sin contratos Sigue el patrón de entity existente
    Crear repository port (interface) Puede saltárselo e ir a la implementación Crea interface primero, luego implementación
    Escribir adapter/mapper DTO → Entity Transforma inline en el componente Crea mapper en capa Data con tipos explícitos
    Implementar use case Mezcla lógica de UI con lógica de negocio Separa correctamente, inyecta el port
    Manejo de errores en Data layer Try/catch en el componente Manejo en el repository, domain errors tipados
    Test de use case Test de integración con API real Unit test con mock del repository port

    La diferencia entre las dos columnas no es el modelo. Es el contexto que le das.

    Cómo darle contexto al agente para que respete la arquitectura

    Hay tres mecanismos que uso y que funcionan en producción.

    1. Estructura de carpetas que documenta la arquitectura

    Si tu estructura de carpetas refleja las capas, el agente las ve antes de generar código. Cuando lee el proyecto antes de actuar, el patrón es obvio:

    src/
    ├── domain/
    │   ├── entities/
    │   │   └── product.entity.ts
    │   ├── use-cases/
    │   │   └── get-products.use-case.ts
    │   └── ports/
    │       └── product.repository.port.ts
    ├── data/
    │   ├── repositories/
    │   │   └── product.repository.ts
    │   ├── dtos/
    │   │   └── product.dto.ts
    │   └── mappers/
    │       └── product.mapper.ts
    └── presentation/
        ├── components/
        │   └── product-list/
        └── view-models/
            └── product-list.vm.ts

    Un agente que lee esta estructura sabe dónde va cada pieza. La carpeta es la arquitectura documentada.

    2. CLAUDE.md con reglas de arquitectura

    Si usas Claude Code, el archivo CLAUDE.md en la raíz del proyecto es leído automáticamente antes de que el agente actúe. Es tu oportunidad de definir las reglas del juego:

    # Arquitectura del proyecto
    
    Este proyecto sigue Clean Architecture con tres capas:
    
    ## Reglas de dependencia (OBLIGATORIAS)
    - Los componentes en presentation/ NUNCA importan directamente de data/
    - Los componentes solo usan use cases de domain/use-cases/
    - Los use cases solo conocen ports de domain/ports/, nunca implementaciones concretas
    - Todo acceso a API externo va en data/repositories/, nunca en componentes ni use cases
    
    ## Antes de generar código nuevo
    1. Si es lógica de negocio → crea use case en domain/use-cases/
    2. Si es acceso a datos → crea o modifica el repository en data/repositories/
    3. Si es transformación de datos → crea mapper en data/mappers/
    4. Si el port no existe → créalo en domain/ports/ antes de la implementación
    
    ## Naming conventions
    - Entities: *.entity.ts
    - Use cases: get-products.use-case.ts (verbo + sustantivo)
    - Ports: product.repository.port.ts
    - DTOs: product.dto.ts
    - Mappers: product.mapper.ts

    Esto no es opcional. Es la diferencia entre un agente que genera spaghetti y uno que genera código que encaja en tu arquitectura.

    3. Prompt con diagrama de capas

    Cuando pides una feature específica, incluye siempre la capa donde debe vivir:

    Necesito implementar la feature "obtener lista de productos" siguiendo la arquitectura del proyecto.
    
    Genera en este orden:
    1. ProductDTO en data/dtos/ (tal como viene de la API)
    2. ProductEntity en domain/entities/ (modelo de negocio limpio)
    3. ProductMapper en data/mappers/ (transforma DTO → Entity)
    4. IProductRepository port en domain/ports/ (interface del contrato)
    5. ProductRepository en data/repositories/ (implementación concreta que usa fetch)
    6. GetProductsUseCase en domain/use-cases/ (orquesta el repositorio, devuelve entities)
    
    El componente ya existe — no lo modifiques. Solo genera las capas de dominio y datos.

    Ejemplo práctico: de DTO a Use Case con el agente

    Así es como queda el código cuando el agente tiene contexto. Le pedí exactamente las piezas del ejemplo anterior con el CLAUDE.md activo:

    // domain/entities/product.entity.ts
    export interface ProductEntity {
      id: string;
      name: string;
      price: number;
      inStock: boolean;
    }
    
    // data/dtos/product.dto.ts
    export interface ProductDTO {
      id: string;
      nombre: string;         // la API devuelve en español
      precio_eur: number;     // con otro nombre
      stock: number;          // número, no boolean
    }
    
    // data/mappers/product.mapper.ts
    import { ProductDTO } from "../dtos/product.dto";
    import { ProductEntity } from "../../domain/entities/product.entity";
    
    export const toProductEntity = (dto: ProductDTO): ProductEntity => ({
      id: dto.id,
      name: dto.nombre,
      price: dto.precio_eur,
      inStock: dto.stock > 0,
    });
    
    // domain/ports/product.repository.port.ts
    import { ProductEntity } from "../entities/product.entity";
    
    export interface IProductRepository {
      getAll(): Promise<ProductEntity[]>;
      getById(id: string): Promise<ProductEntity | null>;
    }
    
    // data/repositories/product.repository.ts
    import { IProductRepository } from "../../domain/ports/product.repository.port";
    import { ProductEntity } from "../../domain/entities/product.entity";
    import { ProductDTO } from "../dtos/product.dto";
    import { toProductEntity } from "../mappers/product.mapper";
    
    export class ProductRepository implements IProductRepository {
      private readonly baseUrl = "https://api.myapp.com";
    
      async getAll(): Promise<ProductEntity[]> {
        const response = await fetch(`${this.baseUrl}/products`);
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        const dtos: ProductDTO[] = await response.json();
        return dtos.map(toProductEntity);
      }
    
      async getById(id: string): Promise<ProductEntity | null> {
        const response = await fetch(`${this.baseUrl}/products/${id}`);
        if (response.status === 404) return null;
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        const dto: ProductDTO = await response.json();
        return toProductEntity(dto);
      }
    }
    
    // domain/use-cases/get-products.use-case.ts
    import { IProductRepository } from "../ports/product.repository.port";
    import { ProductEntity } from "../entities/product.entity";
    
    export class GetProductsUseCase {
      constructor(private readonly productRepository: IProductRepository) {}
    
      async execute(): Promise<ProductEntity[]> {
        // El use case no tiene try/catch — delega el manejo de errores al repository.
        // Los errores de infraestructura suben como excepciones; la capa de presentación decide cómo mostrarlos.
        return this.productRepository.getAll();
      }
    }

    El componente ahora solo necesita instanciar el use case e invocar execute(). No sabe que existe una API. No sabe el formato de los DTOs. No hace transformaciones. Solo le habla al dominio.

    Eso es Clean Architecture aplicada. Y el agente lo generó todo en un solo turno porque sabía exactamente dónde iba cada pieza.

    Dónde la IA falla aunque tengas contexto

    El CLAUDE.md no es una bala de plata.

    Hay situaciones donde el agente ignora las reglas o las interpreta de forma inesperada. Las más comunes:

    Features cross-capa sin spec previa. Si le pides “añade filtros al listado de productos”, el agente puede añadir el estado del filtro en el use case (lógica de UI en el dominio), en la URL de la API directamente, o en el componente — sin pasar por el use case. La feature es compleja y el agente toma atajos.

    Refactorizaciones de archivos existentes. Al modificar código que ya existe y que no sigue la arquitectura, el agente tiende a preservar el patrón existente en lugar de corregirlo. Si el archivo ya tiene un fetch en el componente y le pides que añada una funcionalidad, lo más probable es que añada otro fetch.

    Código sin tests previos. Sin tests que fallen cuando se rompe la arquitectura, el agente no recibe feedback negativo cuando viola las capas. El código compila, parece correcto, y el problema solo aparece cuando otro developer intenta extender la feature meses después.

    La solución a los tres casos es la misma: spec primero, código después.

    La hoja de ruta correcta: SDD + IA

    Lo que marca la diferencia no es qué agente usas. Es si empiezas con una especificación o si vas directo al código.

    Cuando escribes la spec primero — qué entities existen, qué use cases necesita la feature, qué contratos definen los ports — el agente tiene un mapa. No adivina la arquitectura. La sigue porque está documentada antes de que genere la primera línea.

    Spec-Driven Development (SDD) es exactamente esta metodología: especificar antes de implementar, usar la spec como contrato entre el developer y el agente. He documentado todo el proceso — con plantillas, ejemplos y el flujo completo — en el Libro SDD. Si tu proyecto tiene problemas de arquitectura cuando usas IA, el libro es el punto de partida más directo que tengo para darte.

    Si quieres entender primero cómo funciona el bucle interno del agente — el ciclo percibir-razonar-actuar que subyace a todo esto — el post sobre el agentic loop y la guía sobre qué es un Agentic Engineer completan el contexto antes de aplicarlo a tu arquitectura.

    El flujo práctico es este:

    1. Escribe la spec: entities, use cases, ports, contratos
    2. Configura CLAUDE.md con las reglas de arquitectura
    3. Pide al agente que genere una capa a la vez, en orden
    4. Review: ¿la implementación respeta la spec?
    5. Añade tests que fallen si alguien rompe las capas
    6. Itera

    Cada paso reduce el espacio de decisión del agente. Y reducir el espacio de decisión es reducir el riesgo de que genere spaghetti.

    Si quieres ver este flujo aplicado a proyectos reales — desde la spec hasta el producto funcionando — el curso Construye con IA cubre exactamente esto: cómo trabajar con agentes de IA respetando la arquitectura, con ejemplos en TypeScript y el proceso completo desde idea hasta código en producción.

    FAQ — Preguntas frecuentes

    ¿Clean Architecture en frontend es sobreingeniería para proyectos pequeños?

    Depende del criterio de “pequeño”. Si el proyecto va a crecer, va a tener más de un developer tocando el código o va a ser mantenido más de seis meses, Clean Architecture paga su coste desde el primer mes. El problema no es la arquitectura en sí — es implementarla de forma rígida cuando no añade valor. Para un script de 200 líneas o un prototipo desechable, no la necesitas. Para cualquier producto real, la separación de capas es lo que permite que la IA ayude en lugar de crear deuda.

    ¿Funciona el mismo enfoque con Cursor, GitHub Copilot o cualquier otro agente?

    Sí. El CLAUDE.md es específico de Claude Code, pero el principio es universal: cualquier agente que pueda leer el contexto del proyecto antes de generar código va a producir mejores resultados. En Cursor usas archivos .cursor/rules/*.mdc (la convención actual desde 2025; .cursorrules sigue funcionando por retrocompatibilidad). En GitHub Copilot puedes añadir instrucciones en el repositorio o en el prompt. La estructura de carpetas funciona con todos porque es parte del contexto que el agente lee automáticamente cuando explora el proyecto.

    ¿Cómo testeo que la arquitectura se está respetando?

    La forma más efectiva es con import constraints a nivel de build o linting. En proyectos TypeScript puedes usar eslint-plugin-boundaries para definir reglas de qué capas pueden importar de cuáles. Cuando el agente viola la arquitectura, el linter falla antes de que el código llegue a revisión. Es la red de seguridad que hace que el enfoque sea sostenible en equipos o en proyectos donde usas IA intensivamente.


    Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.

  • Cómo acelerar las entregas de los desarrolladores sénior sin comprometer calidad

    Cómo acelerar las entregas de los desarrolladores sénior sin comprometer calidad

    ¿Por qué los desarrolladores sénior siguen con las entregas lentas (y cómo evitarlo)?

    Tiempo estimado de lectura: 4 min

    • La experiencia introduce sesgos de anticipación: sénior suelen prever fallos y eso añade tiempo (sobreingeniería, refactorización y parálisis por análisis).
    • La solución son procesos y límites: ADRs, timebox, DoD estricta, backlogs separados y automatización reducen la fricción.
    • Automatización y métricas hacen que la rapidez sea sostenible: linters, CI, IA en la primera revisión, PR size y SLAs concretos aceleran sin sacrificar calidad.
    • Cultura y liderazgo determinan la efectividad: valorar decisiones rápidas y reversibles y responsabilizar al equipo sobre la deuda técnica convierte criterio en velocidad.

    ¿Por qué los desarrolladores sénior siguen con las entregas lentas (y cómo evitarlo)? La pregunta duele en equipos que necesitan velocidad sin sacrificar calidad. La respuesta no es moralizante: no es pereza ni incompetencia. Es la suma de experiencia, riesgo y estructuras de trabajo que no alinean incentivos. Si quieres acelerar sin quemar a tu gente ni a tu producto, esto es lo que realmente pasa —y qué hacer al respecto.

    Resumen rápido (lectores con prisa)

    ADRs (Architecture Decision Records): documento para registrar decisiones de arquitectura con fecha y contexto. Útil cuando la decisión puede revertirse o necesitar revisión.

    YAGNI: principio que evita construir soluciones para escenarios hipotéticos; aplicar en MVPs y experimentos.

    Timebox: límite temporal corto (48–72 horas) para decidir; si no hay consenso, define un decisor y registra la decisión en un ADR.

    Automatización + métricas: linters, CI, IA en revisiones iniciales, PR size y SLAs para convertir criterio en velocidad mantenible.

    Patrones que explican la lentitud

    1) Sobreingeniería: el futuro que nadie pidió

    Problema: un sénior tiende a diseñar soluciones que cubran escenarios hipotéticos —microservicios, abstracciones genéricas, event sourcing— para necesidades que hoy son triviales. Violación clásica de YAGNI (Martin Fowler).

    Qué hacer:

    • Define guardrails de arquitectura por contexto (MVP vs core). Un diagrama simple que diga “MVP = soluciones directas” evita debates infinitos.
    • Usa ADRs (Architecture Decision Records) para decisiones importantes y ponles plazo. Recurso.
    • Prioriza experimentos pequeños y medibles antes de diseñar grandes infraestructuras.

    Resultado esperado: menos tiempo invertido en abstracciones sin validación y más entregas que generan aprendizaje real.

    2) Refactorización expansiva: el “ya que estoy aquí”

    Problema: entrar a cambiar una línea y salir con cinco módulos reescritos. La intención es buena, pero el coste de oportunidad es alto.

    Qué hacer:

    • Separa deuda técnica del desarrollo funcional. Crea un backlog de deuda con criterios claros de prioridad y presupuestos de tiempo.
    • Impon una DoD (Definition of Done) estricta por ticket: lo que no está en la DoD no se toca.
    • Introduce reglas de “pequeñas mejoras” (máx. X archivos o Y líneas por PR) o tickets explícitos para refactors grandes.

    Resultado esperado: PRs más pequeñas, revisiones más rápidas y menos regresiones por cambios colaterales.

    3) Parálisis por análisis: debatir hasta el infinito

    Problema: múltiples opciones válidas y ninguna decisión. El coste: semanas de indecisión.

    Qué hacer:

    • Timebox: 48–72 horas para llegar a una decisión técnica informada. Si no hay consenso, define un decisor (Tech Lead o rota).
    • Documenta la decisión en un ADR y planifica re-evaluación tras N sprints.
    • Fomenta prototipos rápidos (spikes) con criterios claros de éxito para reducir la ambigüedad.

    Resultado esperado: decisiones más rápidas, mejores retrospectivas y menos “design by committee”.

    Tácticas operativas que sí funcionan

    Estas prácticas convierten criterio técnico en velocidad real sin sacrificar calidad.

    • Automatiza la fricción: linters, formatos automáticos y análisis estático en CI. Que la máquina rechace fallos triviales.
    • Primer revisión automatizada con IA: un agente (bien entrenado y con límites) puede hacer la primera pasada de code review para detectar complejidad innecesaria. Orquestación de flujos con herramientas como n8n facilita integrarlo en pipelines.
    • Métricas visibles: PR size, lead time, cycle time y tasa de rework (DORA metrics). Google DevOps tiene material útil.
    • Límites de PR y SLA de revisión: por ejemplo, PRs < 400 líneas y revisión en 24–48 horas. Esto fuerza pequeños incrementos.
    • Feature flags y despliegues canary: permiten entregar rápido sin riesgos mayores.
    • Pares en diseño crítico: pairing para decisiones de alto impacto reduce la necesidad de amplias revisiones posteriores.

    Cultura y liderazgo: la palanca que manda

    La técnica sola no basta. Cambiar la forma en que los sénior usan su criterio exige liderazgo que:

    • Valore decisiones rápidas y reversibles.
    • Recompense reducir el tiempo hasta el feedback real del cliente.
    • Promueva responsabilidad compartida sobre la deuda técnica (no que un solo “ángel” la arregle).

    Un buen indicador es si el equipo prioriza entregar aprendizaje al usuario sobre pulir arquitectura invisible.

    Conclusión práctica

    Los desarrolladores sénior no son el problema; son una solución mal encuadrada. Convertir su criterio en velocidad exige:

    • Reglas claras (DoD, backlogs separados).
    • Procesos que forcen decisiones (ADRs + timebox).
    • Automatización para reducir trabajo manual (linters, IA en CI, n8n).
    • Métricas y límites operativos (PR size, SLAs).

    No pidas a los sénior que “vayan más rápido”. Diseña el contexto donde su experiencia se traduce en decisiones efectivas y entregas constantes. Eso sí acelera —y a la larga, es lo que mantiene el código vivo sin quemar al equipo.

    FAQ

     

    ¿Qué es un ADR y para qué sirve?

    Un ADR (Architecture Decision Record) es un documento que registra una decisión arquitectónica, su contexto y sus consecuencias. Sirve para dejar rastro, facilitar re-evaluaciones y evitar repetir debates históricos.

    ¿Cómo evitar la sobreingeniería en un equipo sénior?

    Define guardrails claros (MVP vs core), aplica YAGNI en el contexto del producto y usa ADRs con fecha límite. Prioriza experimentos pequeños y medibles antes de invertir en infraestructuras grandes.

    ¿Qué límites prácticos poner en los PRs?

    Ejemplos prácticos: PRs < 400 líneas, límite de X archivos o Y funciones para pequeñas mejoras, y tickets dedicados para refactors mayores. Acompáñalo con SLA de revisión (24–48 horas).

    ¿Cuándo usar timebox para decisiones técnicas?

    Usa timebox (48–72 horas) cuando hay múltiples opciones válidas y la decisión bloquea progreso. Si no hay consenso, designa un decisor y registra la decisión en un ADR para re-evaluación posterior.

    ¿Qué métricas son útiles para medir velocidad sin sacrificar calidad?

    Métricas útiles incluyen PR size, lead time, cycle time y tasa de rework. Estas, combinadas con controles automáticos en CI, permiten actuar sobre cuellos de botella sin comprometer calidad.

    ¿Cómo integrar IA en la revisión de código sin depender exclusivamente de ella?

    Usa IA para la primera pasada: detectar complejidad innecesaria, problemas de estilo y patrones riesgosos. Mantén revisión humana para decisiones arquitectónicas y contextuales, y establece límites claros al alcance del agente.

  • Cómo Spec-First Optimiza el Desarrollo de Software con IA

    Cómo Spec-First Optimiza el Desarrollo de Software con IA

    Por qué Spec-First cambió mi forma de programar con IA (y por qué debería cambiar la tuya)

    Tiempo estimado de lectura: 4 min

    • Spec-First reduce suposiciones del modelo al definir contratos antes de pedir implementación.
    • Escribir tipos y casos de error toma minutos; arreglar código generado con suposiciones incorrectas puede costar días.
    • Combinar Spec-First con TDD convierte especificaciones en tests ejecutables y acelera desarrollo mantenible.
    • Aplica Spec-First en sistemas críticos, APIs públicas y módulos que deben escalar; evita para prototipos one-off.

    Por qué Spec-First cambió mi forma de programar con IA (y por qué debería cambiar la tuya). Poca gente habla de esto después del entusiasmo inicial. Descubrí algo curioso: no era la IA la que fallaba, era el orden de mis decisiones.

    La primera vez que pides código a un asistente te sientes en una peli de ciencia ficción. La décima vez estás peleando con alucinaciones, nombres mal elegidos y lógica que solo funciona en el mundo ideal del modelo. Spec-First rompió esa dinámica.

    Resumen rápido (lectores con prisa)

    Spec-First: escribe el contrato (tipos, entradas/salidas, casos límite) antes de pedir implementación. Reduce suposiciones del modelo y convierte especificaciones en tests ejecutables. Útil para código mantenible y APIs, menos para prototipos one-off.

    El coste real del Prompt-Driven Development

    El flujo habitual es: pides, pegas, arreglas. Repetir. Para prototipos funciona. Para software que vive y crece, no.

    • El modelo no conoce tu arquitectura.
    • No sabe tus convenciones ni decisiones pasadas.
    • No respeta tus límites de efectos secundarios ni tus políticas de error.

    Resultado: módulos que compilan pero no encajan. Bugs lógicos distribuidos. Revisiones interminables.

    Spec-First no te da respuesta mágica. Te devuelve tiempo y predictibilidad.

    Qué debe contener una spec si vas a usar IA

    No necesitas un documento de 30 páginas. Necesitas lo mínimo imprescindible para quitarle decisiones al modelo:

    Tipos e interfaces

    define entradas y salidas antes de pedir lógica.

    interface CreateUser { email: string; name?: string }
    type Result<T> = { ok: true; value: T } | { ok: false; error: string }

    Casos límite

    nulos, dominios bloqueados, fallos de red, retries, timeouts.

    Comportamiento determinista

    funciones puras, sin efectos laterales, o explícitamente con side effects autorizados.

    Restricciones de integración

    versiones de librería, patrones prohibidos, dónde puede tocar la base de datos.

    Escribir esto toma minutos. Arreglar un desastre generado por IA puede costarte días.

    Spec-First + TDD = velocidad real

    Si ya definiste tipos y casos de error, pedirle al modelo que genere tests primero es natural. Los tests pasan a ser la especificación ejecutable.

    Flujo práctico:

    • 1) Escribe tipos y contratos.
    • 2) Genera tests unitarios con la IA.
    • 3) Pide la implementación hasta que los tests pasen.

    La diferencia: pasas menos tiempo adivinando por qué algo falla y más en ajustar diseño.

    Ejemplo rápido (mental, no código largo)

    En vez de: “Crea función que valide emails”, di:

    “Función pura que recibe string, valida email corporativo (rechaza gmail.com, hotmail.com), retorna Result<Email, ValidationError>, cero excepciones, sin llamadas externas.”

    Esa frase evita que el modelo haga lo que le da la gana y te devuelve algo integrable.

    Cuándo aplicar Spec-First (y cuándo no)

    No es una religión. Úsalo cuando importe la mantenibilidad y la integración:

    • Sistemas críticos, core domain, APIs públicas.
    • Equipos distribuidos con contratos firmes.
    • Proyectos que deben escalar o durar.

    No lo emplees para scripts one-off o prototipos exploratorios donde la velocidad de concepto importa más que la calidad.

    Cambia tu rol profesional: de mecanógrafo a director de orquesta

    La IA está comoditizando la escritura de código. El valor real se desplaza hacia quien define qué construir y por qué. Spec-First es el instrumento para ejercer ese criterio sin perder velocidad.

    Tú no vas a competir con la IA en velocidad de tecleo. Vas a competir en claridad de intención, disciplina arquitectónica y capacidad de traducir requisitos imprecisos en contratos firmes.

    Cómo empezar hoy (3 pasos prácticos)

    1. Antes de pedir código, escribe los tipos. Solo eso.
    2. Genera tests unitarios desde esa spec.
    3. Pide la implementación, haz que los tests pasen.

    Hazlo en el siguiente ticket que abras. No hace falta cambiar todo tu flujo; prueba en un módulo nuevo y compara el resultado.

    Haz esto ahora: la próxima vez que pidas una función al asistente, detente 30 segundos y define solo los tipos. Luego vuelve y genera los tests. Verás la diferencia.

    Esto no acaba aquí: si quieres, puedo convertir tu próxima descripción vaga en una spec lista para usar con cualquier LLM.

    Este artículo trata sobre IA aplicada y flujos de trabajo con modelos, por lo que puede interesarte explorar recursos prácticos y experimentos en Dominicode Labs. Es un complemento natural para probar especificaciones y pipelines de tests en prototipos controlados.

    FAQ

     

     

    ¿Qué es Spec-First?

    Es una práctica que prioriza escribir contratos (tipos, entradas/salidas, casos límite) antes de solicitar la implementación a un asistente IA o a un desarrollador.

     

    ¿Cuándo debo usar Spec-First?

    Cuando la mantenibilidad, integraciones o el dominio crítico importen: APIs públicas, core domain y equipos distribuidos. No es necesario para scripts one-off o experimentos rápidos.

     

    ¿Spec-First reemplaza al TDD?

    No lo reemplaza; se complementan. Spec-First define contratos y TDD convierte esos contratos en tests ejecutables que guían la implementación.

     

    ¿Cuánto tiempo toma crear una spec básica?

    En muchos casos, minutos. Definir tipos y casos límite mínimos suele ser suficiente para reducir suposiciones del modelo y evitar reescrituras costosas.

     

    ¿Es útil para prototipos rápidos?

    No siempre. Para prototipos donde la velocidad de concepto importa más que la calidad, puedes omitirlo. Para piezas que deban mantenerse o integrarse, sí.

     

    ¿Qué incluye una spec mínima?

    Los tipos e interfaces de entradas/salidas, casos límite (nulos, dominios bloqueados, fallos de red), comportamiento determinista (funciones puras o efectos explícitos) y restricciones de integración (versiones, patrones prohibidos).

  • Adopta TDD para implementar pruebas efectivas con agentes de IA

    Adopta TDD para implementar pruebas efectivas con agentes de IA

    Testing en la era de los agentes — TDD + agents, qué tests escribir tú vs cuáles el agente, snapshot testing inteligente

    Tiempo estimado de lectura: 5 min

    Ideas clave:

    • Usa tests como especificación (Test-Driven Prompting) y pide al agente implementar hasta que el test pase.
    • Los humanos deben definir contratos y tests críticos; los agentes pueden generar unit tests, edge cases y boilerplate bajo supervisión.
    • Cambia snapshots textuales por evaluaciones semánticas (LLM-judge) para reducir fragilidad.
    • Implementa un pipeline two-speed con sandboxes efímeros y telemetría sobre prompts y evaluaciones.

    Tabla de contenidos

    Introducción

    Testing en la era de los agentes — TDD + agents, qué tests escribir tú vs cuáles el agente, snapshot testing inteligente debe aparecer en tu playbook desde hoy. Si vas a dejar que un agente (Claude Code, Aider, Cursor u otros) escriba código en tu repo, tienes que reordenar qué pruebas son autoritativas, cuáles automatizas y cómo evitas cobertura falsa.

    Aquí está la estrategia práctica y accionable: cómo usar TDD como especificación, qué pruebas deben ser humanas, cuáles delegar a la IA, y cómo evolucionar los snapshots desde diffs frágiles a evaluaciones semánticas.

    Resumen rápido (lectores con prisa)

    Test-Driven Prompting aplica TDD a agentes: escribe el test como especificación y pide al agente implementar hasta que pase. Usa humanos para contratos, integración crítica y regresiones reales; delega unit tests deterministas y generación de edge cases al agente. Reemplaza snapshots textuales por una evaluación semántica (LLM-judge) que decide si un cambio es cosmético o funcional.

    Test-Driven Prompting: TDD + agents, qué tests escribir tú vs cuáles el agente

    Test-Driven Prompting es TDD adaptado a agentes. Escribes el test primero —no como un ejercicio de documentación, sino como la especificación no ambigua— y pides al agente que implemente hasta que el test pase. El test se convierte en el prompt más estricto que existe.

    Beneficios inmediatos:

    • El agente no improvisa requisitos; el test define el contrato.
    • Evitas cambios colaterales porque la suite actúa como guardrail.
    • La revisión humana se traslada de “¿funciona?” a “¿es esto sostenible y seguro?”.

    Pero atención: si el agente escribe la implementación y el test, obtendrás tautologías. Por eso la división de responsabilidades es crítica.

    División práctica: qué escribe el humano y qué el agente

    Lo que debe escribir el humano (no delegues)

    • Tests de integración críticos: pagos, auth, sincronización entre servicios. Requieren contexto de negocio y pruebas contra fallos reales.
    • Flujos E2E y guiones de usuario (Playwright, Cypress): definen la experiencia que no puede ser inferida por el agente. Playwright / Cypress
    • Tests de regresión con historial real: errores de producción documentados como tests que no pueden ser reinterpretados.
    • Setup de entornos y fixtures confiables: seeds de DB, contratos de mock globales.

    Lo que el agente puede generar (con supervisión)

    • Tests unitarios para funciones puras: transformaciones deterministas, utilidades, algoritmos puros.
    • Generación de edge cases y fuzzing estructurado: inputs nulos, límites, arrays extremos.
    • Boilerplate de mocks simples y factories (bajo reglas estrictas definidas por humanos).

    Pauta de revisión

    Cualquier test con mocking complejo (p. ej. jest.mock con comportamiento dinámico) debe pasar revisión manual antes de merge. Los LLMs tienden a “alucinar” APIs de mocking o a asumir comportamiento de librerías.

    Snapshot testing inteligente: de fragilidad a semántica

    Cómo funciona

    Los snapshots textuales mueren rápidos en repos de ritmo alto. La alternativa es snapshot testing inteligente: comparar semánticamente en lugar de por texto.

    Cómo funciona:

    • Generas snapshot tradicional (DOM/JSON).
    • Si cambia, un módulo de evaluación semántica (LLM-as-a-Judge) recibe: snapshot antiguo, snapshot nuevo y una rúbrica.
    • El modelo decide si el cambio es cosmético (aprobable) o funcional (falla y requiere revisión).

    Aplicaciones

    • UI: detectar si un botón cambió de estilo (aprobable) vs desapareció el control de envío (fallo).
    • APIs: admitir la adición de campos no utilizados por clientes y bloquear cambios en campos requeridos.

    Herramientas/ideas

    Construir un servicio interno que use un modelo de evaluación (ej. GPT-4o / Claude avanzado) y registre justificaciones estructuradas para auditoría.

    Pipeline recomendado y consideraciones operativas

    1. Golden Dataset de tests

    Golden Dataset de tests: 20–50 casos representativos versionados en Git. Sirve como baseline para evaluar cambios de spec.

    2. Two-speed CI

    • Cada PR: ejecución determinista rápida (linters, unit tests generados por agente, AST checks).
    • Merge/main: evaluación semántica completa (LLM-judge, snapshots semánticos).

    3. Sandbox seguro para deterministas

    Sandbox seguro para deterministas: ejecuta tests en contenedores efímeros sin red ni credenciales. Usa Firecracker o gVisor para aislamiento si ejecutas código generado automáticamente.

    4. Métricas y guardrails

    • Pass rate determinista por PR.
    • Delta semántico medio por cambio de spec.
    • Flakiness score (casos inestables entre ejecuciones).
    • Cost per eval (tokens, tiempo).

    Integración de herramientas de observabilidad: Promptfoo para orquestación local de evals, LangSmith para tracing, Braintrust para gestión de datasets.

    Checklist mínimo antes de confiar en un agente

    • Tests críticos escritos por humanos y en el repo.
    • Golden Dataset versionado y ejecutable en CI.
    • Sandbox efímero con timeouts y sin acceso a prod.
    • Reglas claras de qué puede commitear el agente automáticamente.
    • LLM-judge configurado para snapshots y revisiones semánticas.
    • Telemetría: registro de prompts, respuestas, tokens y justificación del juez.

    Conclusión: el rol del Tech Lead

    Testing en la era de los agentes no elimina la responsabilidad humana; la traslada a la definición de contratos, gobernanza y métricas. El Tech Lead debe decidir qué pruebas son la fuente de verdad, cómo se auditan las decisiones del agente y cuándo intervenir manualmente. Si tratas los tests como especificaciones inmutables y habilitas snapshots semánticos, los agentes dejan de ser generadores de ruido y pasan a ser máquinas de productividad que se pueden gobernar.

    Dominicode Labs

    Para equipos que exploran evaluaciones semánticas y pipelines con agentes, Dominicode Labs ofrece recursos y patrones reproducibles para integrar LLM-judges y sandboxes en CI. Considera esta referencia como una continuación práctica de las ideas descritas arriba.

    FAQ

    Respuesta: Test-Driven Prompting aplica la práctica de escribir tests como especificaciones antes de implementar. El test actúa como el prompt más estricto para el agente y define el contrato que debe cumplirse.

    Respuesta: No delegues tests de integración críticos (pagos, auth), flujos E2E, tests de regresión con historial real y el setup de entornos/fixtures. Estos requieren contexto de negocio y control humano.

    Respuesta: Los snapshots semánticos usan un módulo de evaluación (LLM-judge) que recibe el snapshot antiguo, el nuevo y una rúbrica, y decide si el cambio es cosmético o funcional, registrando justificación para auditoría.

    Respuesta: Un Golden Dataset incluye 20–50 casos representativos, versionados en Git y ejecutables en CI. Sirve como baseline para validar cambios de especificación.

    Respuesta: Ejecuta código en contenedores efímeros sin red ni credenciales, aplica timeouts y usa tecnologías como Firecracker o gVisor para aislamiento.

    Respuesta: Sigue métricas como pass rate determinista por PR, delta semántico medio por cambio de spec, flakiness score y cost per eval (tokens, tiempo). Complementa con telemetría de prompts y decisiones del juez.