Artículo
Desarrollo Guiado por Handshake: un acuerdo de trabajo para programar con IA
Un patrón práctico para hacer más confiable la programación con IA: definir la spec, el contexto, las herramientas, los guardrails y el ciclo de revisión antes de que el agente empiece a escribir código.
La programación asistida por IA ya cruzó el punto en que se la podía descartar como una novedad. Cambia el trabajo de software porque puede convertir intención en código más rápido de lo que la mayoría de los equipos está acostumbrada a revisarlo.
Esa velocidad es útil. También es donde empieza el riesgo.
La primera vez que un agente toma una idea aproximada y la convierte en una implementación funcional, se siente como un atajo para saltarse las partes aburridas del software. El boilerplate desaparece. Las ediciones repetitivas ocurren en segundos. Una funcionalidad que habría tomado una tarde de pronto puede tomar una conversación.
Durante un tiempo, eso parece ser toda la historia.
Luego los fallos empiezan a ser más difíciles de detectar.
No los fallos catastróficos. Esos son fáciles. Los fallos más peligrosos son los plausibles: código que compila, tests que siguen pasando, una UI que se ve bien, y una pequeña suposición enterrada en un flujo secundario que solo aparece más tarde. Una ruta de importación faltante. Una preocupación de migración omitida. Una diferencia específica de plataforma que nunca se hizo explícita. Un patrón de nombres que se desvía apenas lo suficiente para convertirse en la inconsistencia de mañana.
Ahí es donde la ganancia inicial de productividad se vuelve más complicada. El primer 80% se vuelve dramáticamente más rápido. El último 20% puede volverse más ruidoso, porque ahora no solo estás escribiendo código; estás auditando lo que el agente creyó que significaba el proyecto.
La lección incómoda fue simple: la IA no elimina la necesidad de disciplina de ingeniería. Amplifica la disciplina que ya existe.
Si tu proceso tiene specs claras, buen contexto, tests que funcionan y humanos revisando las cosas correctas, un agente puede acelerar eso. Si tu proceso depende de conocimiento tribal, tickets vagos y "compila, envíalo", el agente también acelera eso.
Este es el patrón que he estado intentando nombrar para mí mismo: no solo mejores prompts, sino un mejor acuerdo de trabajo con el agente antes de que empiece el código.
Con el tiempo empecé a llamar a ese acuerdo un handshake.
No porque la palabra suene formal, sino porque la parte útil ocurre antes de que empiece el trabajo. Ambas partes necesitan saber qué se está construyendo, qué reglas importan, qué herramientas están en juego, qué riesgos hay que vigilar y cómo se comprobará el resultado.
Nota: el título original es Handshake Driven Development. "Handshake" significa literalmente "apretón de manos"; aquí lo uso como imagen de un acuerdo explícito antes de empezar a trabajar juntos.
El resto de este artículo es el camino que me llevó hasta ahí.
Por qué no bastaba con mejores prompts
Muchos consejos sobre programación con IA todavía se reducen a alguna versión de "mejora tus prompts".
La calidad del prompt importa. Una petición clara supera a una vaga. Los ejemplos ayudan. Las restricciones ayudan.
El consejo también se ha vuelto más sofisticado. Ya no es solo "escribe mejores prompts". También es "usa skills", "conecta MCPs", "agrega memoria", "dale herramientas al agente", "escribe reglas de proyecto" y "haz que el modelo conozca más contexto".
Todo eso ayuda. Yo mismo uso versiones de esas ideas.
El primer paso fue aprender a pedir mejor. El siguiente paso fue aprender a moldear el entorno alrededor del agente. Dediqué más tiempo al archivo AGENTS.md, a estándares de código, instrucciones de herramientas, convenciones del repositorio, expectativas de verificación y límites estrictos sobre lo que el agente no debería hacer. En otras palabras, empecé a definir guardrails.
Eso ayudó. El output se acercó más a lo que esperaba. El agente tomó menos decisiones estilísticas aleatorias. Tenía una mejor idea de cómo quería que se hiciera el trabajo, no solo de qué quería construir.
Durante un tiempo, eso se sintió como el siguiente nivel de la programación asistida por IA.
El fallo que cambió mi enfoque
Llevo un par de años trabajando en un proyecto personal, una app llamada FossilVault. Colecciono fósiles, y la app es donde he estado convirtiendo ese hobby en un producto real. Desde principios del año pasado, he usado herramientas de programación agéntica para parte del trabajo.
Uno de los primeros momentos que construyó mi confianza fue un cambio simple de modelo. Necesitaba agregar un nuevo campo al modelo Specimen de la app. Le di al agente lo que consideraba un prompt sólido: la intención, el cambio necesario, las superficies esperadas y los flujos obvios.
El resultado fue mejor de lo que esperaba. Tocó el modelo, actualizó usos relevantes y manejó más comportamiento externo de lo que herramientas anteriores habrían logrado.
Unas semanas después, necesitaba agregar otro campo al mismo modelo usando casi el mismo estilo de prompt. De nuevo, la mayor parte del trabajo fue correcta. El agente actualizó los flujos para agregar y editar especímenes, actualizó la vista de detalles, mantuvo funcionando las estadísticas y agregó el campo a la exportación CSV. Pero omitió un camino importante: la importación CSV.
El fallo: la exportación cambió, la importación no. El flujo obvio funcionaba; el flujo recíproco quedó incompleto en silencio.
Eso parece obvio en retrospectiva. Si un campo puede exportarse, probablemente también debe importarse. Un humano trabajando dentro del contexto del producto normalmente conectaría esos dos flujos. Pero un sistema automatizado no infiere de forma confiable todos los caminos recíprocos a menos que el workflow le pida buscarlos.
Ese fallo fue más interesante que un error duro porque nada explotó de inmediato. El código parecía completo. El flujo obvio funcionaba. El cambio parecía terminado hasta que un flujo real llegó al límite que el agente había omitido.
Ese es el tipo de fallo que vuelve difícil la programación con IA. El resultado puede ser impresionante y aun así estar incompleto. Puede parecer progreso mientras agrega en silencio limpieza futura. El prompt no había sido malo. El agente no había sido inútil. El problema era que yo todavía estaba tratando la tarea como una petición aislada en lugar de un workflow con un contrato explícito.
Para ese tipo de cambio de modelo, un mejor proceso debería haber forzado una checklist antes de que empezara la implementación:
- Rutas del modelo: encontrar cada ruta de lectura y escritura.
- Flujos de usuario: comprobar la UI obvia y los workflows secundarios.
- Límites: comprobar cada lugar donde el modelo entra, sale, aparece, se edita, se serializa o se reconstruye.
- Comportamiento de plataforma: buscar diferencias específicas de plataforma.
- Tests: actualizar tests o agregar un caso de regresión donde encaje.
- Desconocidos: señalar cualquier ruta que no se inspeccionó.
- Aceptación: verificar el resultado contra los criterios de aceptación, no solo contra la compilación.
Ese fue el punto en que empecé a buscar algo más fuerte que buenos prompts más buenos guardrails.
Entra el desarrollo guiado por specs
El siguiente lugar donde miré fue el desarrollo guiado por specs. Si los prompts y los guardrails ayudaban al agente a comportarse mejor, quizá el arreglo más profundo era cambiar aquello desde lo que trabajaba el agente en primer lugar.
El desarrollo guiado por specs me atrajo porque cambia el punto de partida.
En vez de empezar con la implementación y dejar que el código se convierta en el primer artefacto concreto, SDD empieza definiendo qué debe hacer el sistema. La spec captura el comportamiento, los criterios de aceptación, los límites de alcance, los no-objetivos y las restricciones antes de que el agente empiece a escribir código.
Eso importa para el trabajo humano, pero importa aún más para el trabajo asistido por IA. Una spec le da al agente un objetivo estable. También le da al proyecto una pieza de documentación que sobrevive a la conversación individual. Cuando la siguiente funcionalidad toca la misma área, el agente y el humano pueden volver a las decisiones que ya se tomaron en vez de reconstruirlas desde la memoria o desde el código cercano.
En la práctica, SDD me dio tres beneficios inmediatos: claridad, porque las suposiciones ocultas tenían que nombrarse; reproducibilidad, porque la siguiente sesión dependía menos de la formulación exacta del prompt; y mejor output de IA, porque los agentes rinden mejor con un objetivo conductual concreto.
Probé esto en un proyecto nuevo y los resultados fueron sólidos. El trabajo hecho por los agentes estuvo mucho más cerca de lo que quería. Las specs me ayudaron a seguir los cambios, ayudaron al agente a entender funcionalidades y crearon una mejor fuente de verdad.
La mejora fue lo bastante fuerte como para que me pasara de corrección. Durante un tiempo, la spec se sintió como toda la pieza faltante. Presté menos atención a la configuración alrededor del agente: las reglas de AGENTS.md, skills reutilizables, herramientas específicas del proyecto y el resto del armazón que había estado construyendo alrededor del agente. SDD mejoró las cosas tan rápido que era fácil asumir que la spec bastaba.
Pero a medida que el proyecto creció, apareció otro tipo de deriva.
Las funcionalidades estaban mejor especificadas, pero el agente todavía tomaba decisiones sobre arquitectura, estilo, manejo de errores, uso de herramientas y convenciones del proyecto. Algunas de esas decisiones estaban bien de forma aislada. A lo largo de una base de código en crecimiento, empezaron a divergir.
Eso expuso la limitación:
Las specs le dicen a la IA qué construir, pero no cómo comportarse mientras lo construye.
La pieza faltante: el handshake
Así que volví a lo que había funcionado en el proyecto anterior: configuración del agente, guardrails, instrucciones de herramientas y reglas de trabajo explícitas.
Esta vez, combiné eso con el enfoque guiado por specs.
Ahí fue cuando todo encajó. El output del agente se volvió más cercano a lo que esperaba de forma más consistente. Cada iteración tenía menos variabilidad. La spec definía el objetivo, y el contrato del agente definía la forma en que avanzaríamos hacia él.
En ese punto, la palabra anterior empezó a encajar mejor. Un handshake no es una filosofía vaga sobre "alineación". Es un acuerdo concreto entre el ingeniero y el sistema de IA antes de que empiece el trabajo.
Define cómo debe pensar el agente sobre la tarea, qué herramientas debe usar, qué restricciones debe respetar, qué riesgos debe vigilar, cómo debe verificar el trabajo y qué tipo de resultado debe entregar. El punto es convertir la intención en reglas operativas antes de que el agente empiece: trabajar desde la spec, mantenerse dentro del alcance, seguir las convenciones del repositorio, usar las herramientas correctas, verificar el resultado y señalar la incertidumbre.
Esa era la parte que me faltaba. SDD le dio a la tarea un objetivo. La configuración del agente le dio al agente reglas de operación. Los contratos de herramientas hicieron explícitas las capacidades. Los guardrails definieron los límites. La revisión humana mantuvo el juicio dentro del ciclo.
Juntas, esas piezas se convirtieron en el acuerdo de trabajo que ahora pienso como Desarrollo Guiado por Handshake.
Desarrollo Guiado por Handshake
El Desarrollo Guiado por Handshake es la práctica de establecer un acuerdo de trabajo repetible con sistemas de IA antes de escribir cualquier código.
El acuerdo cubre comportamiento, herramientas, restricciones, contexto y verificación. Antes de que empiece la implementación, el agente y el humano se alinean sobre cómo debe entenderse, ejecutarse, comprobarse y reintegrarse el trabajo al proyecto.
Esto no afirma que cada tarea necesite ceremonia. HDD es un patrón pragmático que me ha funcionado cuando la confiabilidad importa más que el golpe inicial de dopamina de la generación rápida.
Mi abreviatura es:
HDD = SDD + contrato del agente + contratos de herramientas + guardrails + ciclo humano
Los componentes son:
| Componente | Rol |
|---|---|
| Spec | Qué necesita construirse, incluyendo requisitos, criterios de aceptación, alcance y no-objetivos. |
| Contrato del agente | Cómo debe trabajar el agente, normalmente capturado en algo como AGENTS.md. |
| Contratos de herramientas | Qué herramientas, APIs, bases de datos y utilidades del proyecto se espera o se permite que use el agente. |
| Guardrails | Lo que el agente no debe hacer, incluyendo límites contra atajos, ediciones inseguras y deuda silenciosa. |
| Ciclo humano | Donde el juicio arquitectónico, los tradeoffs, la intención de producto y las decisiones de deuda se quedan con el ingeniero. |
Cómo se ve un handshake
Un handshake útil no tiene que ser grande. Para un cambio significativo, quiero que el agente sepa al menos seis cosas antes de que empiece la implementación:
- Fuente de verdad: qué spec, issue o nota define el comportamiento esperado.
- Límite de alcance: qué no debería cambiar, incluso si el agente ve oportunidades de limpieza cercanas.
- Barrido de contexto: qué modelos, pantallas, workflows, plataformas, importaciones, exportaciones, tests y docs deben comprobarse.
- Expectativas de herramientas: qué comandos del proyecto, scripts, MCPs o helpers locales deben usarse en vez de adivinar.
- Verificación: qué debe pasar antes de que el trabajo pueda considerarse terminado.
- Handoff: qué conocimiento nuevo debe escribirse de vuelta al contexto del proyecto para que la siguiente sesión empiece menos a ciegas.
Para la actualización del campo en FossilVault, el elemento faltante del handshake fue el barrido de contexto. La tarea no era solo "agregar un campo". Era "encontrar cada lugar donde este modelo entra, sale, aparece, se edita, se serializa o se reconstruye".
El ciclo humano no es solo aprobación final. Es donde permanece el juicio.
El agente puede inspeccionar archivos, proponer cambios, ejecutar tests y resumir tradeoffs. Pero el ingeniero sigue siendo dueño de las decisiones que requieren gusto de producto, memoria arquitectónica, tolerancia al riesgo y juicio sobre deuda.
En la práctica, eso significa que el humano debe decidir si la spec es realmente correcta, si un arreglo local debería convertirse en un refactor más amplio, si un atajo es aceptable, si los tests prueban el comportamiento que importa y si la implementación todavía encaja con el producto.
Por qué esto importa más entre plataformas
FossilVault corre en iOS y Android, lo que hace que la deriva sea fácil de ver. Sin una spec compartida y una línea base de contexto, una plataforma puede implementar la intención de una forma mientras la otra implementa una lectura ligeramente distinta. Las specs vivas reducen esa ambigüedad al transportar intención, restricciones y criterios de aceptación entre bases de código en vez de empezar la conversación desde cero cada vez.
Esa es una razón por la que HDD se siente especialmente valioso para equipos. Cuantas más personas, plataformas, agentes y bases de código haya involucradas, más cara se vuelve la ambigüedad.
El costo es real
HDD agrega overhead, y no tiene sentido fingir lo contrario. Pasas más tiempo al principio escribiendo specs, curando contexto, definiendo guardrails y decidiendo qué debe verificarse antes de hacer merge.
También hay un costo material. El trabajo de agentes consume tokens, y los tokens cuestan dinero. Un workflow suelto puede sentirse más barato porque la primera petición es pequeña, pero el costo a menudo se traslada a ciclos repetidos de aclaración, parches, revisión y limpieza.
Ese costo empeora cuando la programación exploratoria se convierte en el workflow de producción, o cuando la compilación se confunde con validación.
En una ejecución de una funcionalidad pequeña, por ejemplo, le pedí a un agente que moviera un botón de una pantalla a otra y ajustara una pequeña parte de la lógica alrededor. La implementación inicial usó aproximadamente 80.000 tokens. Los arreglos posteriores consumieron otros 60.000 más o menos porque el agente había omitido algo de contexto local. Un pase de HDD más deliberado quizá habría gastado más al principio, pero probablemente habría evitado al menos parte de ese ciclo de limpieza.
El tradeoff es que el overhead se vuelve más liviano después de que existe la línea base. Las specs evolucionan en vez de empezar desde cero. Los artefactos de contexto se acumulan. Los guardrails se vuelven reutilizables. Los tests y checks se afinan a medida que se descubren fallos. El proceso deja de sentirse como ceremonia y empieza a comportarse como infraestructura.
Para equipos, la recompensa suele llegar más rápido porque los contratos compartidos reducen la divergencia arquitectónica. Para desarrolladores en solitario, la recompensa es más lenta pero sigue siendo real, especialmente cuando el proyecto ya tiene suficiente historia como para que la memoria se vuelva poco confiable.
Adapta el patrón, no lo copies
El desarrollo asistido por IA se mueve rápido, así que trataría mi configuración actual de HDD como una foto del momento, no como una plantilla que todos deberían copiar. Las herramientas, los modelos y los nombres cambiarán.
La idea duradera es más simple: haz explícito tu acuerdo con el agente antes de que empiece el código, y luego haz que ese acuerdo sea lo bastante repetible como para que la siguiente ejecución no dependa por completo de la suerte del prompt.
Para mí, HDD trata sobre todo de confianza. No confianza ciega en el modelo, sino confianza ganada en el workflow que lo rodea.
Todavía quiero la velocidad. Todavía quiero los momentos sorprendentes en que un agente maneja una tarea mejor de lo esperado. Pero quiero esos momentos dentro de un proceso que proteja la forma de la base de código.
Eso importa porque la deuda técnica oculta tiene un peso emocional distinto cuando vino de una herramienta que se suponía que debía ayudar. Es aún más frustrante limpiar código que aceptaste porque parecía plausible en el momento.
Lo que quiero de la programación con IA no es solo más código. Quiero seguir trabajando en proyectos que de otro modo serían demasiado grandes para el tiempo que tengo, sin perder lentamente la confianza en el sistema que estoy construyendo.
Si estás usando agentes en serio, escribe el acuerdo antes del próximo cambio significativo. ¿Qué define que algo está bien? ¿Qué contexto debe inspeccionarse? ¿Qué no debería tocar nunca el agente? ¿Qué checks tienen que pasar antes de que creas en el resultado?
Las herramientas cambiarán. El handshake es la parte que vale la pena conservar.