Cómo programar con agentes de IA sin escribir una línea de código
te cuento como trabajan los (buenos) ingenieros en 2026
La semana pasada construí una feature compleja — mensajes directos masivos a suscriptores de Substack — sin escribir una sola línea de código. No porque la IA lo hiciera todo, sino porque aprendí a dirigirla correctamente.
Hoy te explico el proceso exacto que seguí. No los detalles técnicos de la feature, sino cómo trabajar con un agente de IA para ir desde una idea hasta código en producción.
Son tres fases: doc funcional, doc técnico, implementación. Y entre cada una hay un paso que la mayoría se salta: el análisis adversario.
El punto de partida: una idea sin forma
Alguien de mi comunidad me pasó un enlace a un producto de la competencia — una extensión de Chrome de pago que enviaba DMs masivos a suscriptores de Substack.
Cobran 20$ por algo que para mi no tiene mucho valor
y ya sabéis que yo me debo a mi comunidad
asi que…
Quería replicarlo como feature gratuita en StackNotes.
Problema: tenía una idea vaga y capturas de pantalla. No sabía exactamente qué hacía, cómo funcionaba por dentro, ni qué necesitaba para construirlo.
y, por supuesto, tampoco me sobra el tiempo para hacer estas cosas.
Ahí empieza el proceso.
inciso.
Por si eres nuevo por aquí, te cuento que hace unos meses construí una herramienta gratuita para gestionar la publicación de notas en substack y ha ido creciendo poco a poco hacia una herramienta completa de gestión de substack.
Se llama Stacknotes y si eres creador, seguro que te interesa.
Como programar tus notas en Substack de forma gratuita
Durante meses he estado trabajando en algo que empezó como un proyecto personal, casi experimental.
Fase 1: El documento funcional
El documento funcional responde a una pregunta simple: ¿qué hace el usuario?
No qué hace el sistema. No cómo se implementa. Solo: ¿qué ve el usuario, qué puede hacer, qué pasa cuando lo hace?
Cómo generarlo con Claude
Lo primero que hice fue darle a Claude toda la información de entrada que tenía: el texto de la página de venta del competidor y siete capturas de pantalla de la extensión en uso.
El prompt fue:
”Analiza este producto competidor. Extrae todas las funcionalidades: qué puede hacer el usuario, qué controles tiene, qué información ve. Sé exhaustivo.”
Claude extrajo:
- Campo de mensaje con `{{USER_NAME}}` para personalización
- Delay configurable entre envíos para no parecer spam
- Filtros por tipo de suscriptor (free / paid / todos)
- Toggle “Only Empty Chat” para no molestar a quien ya tienes conversación
- Toggle “Unique Message” para no repetir mensajes
- Barra de progreso con pausa y reanudación en tiempo real
En tres minutos tenía el inventario completo de lo que necesitaba construir.
Lo que el doc funcional NO incluye
Aquí es donde mucha gente se equivoca: el doc funcional no menciona tecnología. No dice “edge function”, no dice “base de datos”, no dice “API”. Solo describe comportamiento desde el punto de vista del usuario.
Si empiezas a hablar de implementación en esta fase, contaminas el diseño. Las decisiones técnicas deberían seguir a los requisitos funcionales, no al revés.
El primer análisis adversario
Antes de pasar a la doc técnica, hice algo que cambió el diseño por completo.
Un truquito made in Daniel
que a mi me funciona de lujo siempre
le pedí a Claude que atacara su propio trabajo
Hay mil formas de hacerlo, incluso ya he compartido con alguno de vosotros por privado alguna forma más avanzada de robustecer un diseño
Si quieres que hable más en profundidad de ello, déjame un comentario con tus dudas al respecto
”Revisa este documento funcional. ¿Qué casos de uso no hemos contemplado? ¿Qué haría el usuario que no está cubierto? ¿Qué funcionalidad obvia falta?”
Claude me devolvió algo que no había pensado: ¿y si quieres hacer esto automáticamente para cada nuevo suscriptor?
Auto-welcome. Mensaje automático de bienvenida cuando alguien se suscribe.
Una pregunta adversaria cambió el alcance del proyecto. Y lo descubrimos antes de escribir una línea de código, no después de desplegar.
Esta es la clave del análisis adversario en la fase funcional: no es un ejercicio académico. Es encontrar los requisitos ocultos antes de que el diseño técnico los excluya por omisión.
Fase 2: El documento técnico
Con el doc funcional cerrado y validado, pasé a la arquitectura técnica. Esta fase responde a: ¿cómo construye el sistema lo que el usuario necesita?
El prompt:
”Tenemos este documento funcional. Ahora diseña la arquitectura técnica. Considera las restricciones: SPA en React, Supabase como backend, los navegadores bloquean peticiones cross-origin. Dame opciones, no una sola solución.”
“Dame opciones, no una sola solución” — esto es importante. Si no lo pides explícitamente, Claude tenderá a darte la primera opción que encuentre. Pedir múltiples opciones te fuerza a tomar una decisión informada.
Claude presentó tres arquitecturas diferentes. Para cada una describió: cómo funciona, qué ventajas tiene, qué problemas podría causar.
Cómo elegir entre opciones
No le pedí a Claude que eligiera (aunque si no tienes ni idea de lo que está hablando, quizás tu mejor opción es que lo haga).
Yo elegí, con criterios que Claude no podía tener: qué parte del sistema necesito que sea fácil de depurar, cuánto complejidad quiero asumir, qué prefiero que falle de una forma visible.
Claude sabe sobre patrones de arquitectura. Yo sé sobre mis prioridades.
El doc técnico también descubre potenciales fallos
Al diseñar la arquitectura, Claude identificó algo que el doc funcional no había resuelto: para enviar un DM a alguien en Substack necesitas su ID numérico, no su email. ¿Los datos que ya tenemos incluían ese ID?
Claro, para saber esto tuve que hacer alguna prueba manual desde el navegador para ver cómo se mandaban los mensajes.
Aproveché algunos DMs que tenía pendientes de contestar para ver la estructura de la petición
Abrí DevTools en Substack, inspeccioné la respuesta de la API de suscriptores, y le copié lo que veía. Claude lo confirmó: sí, el ID estaba ahí.
Esto ilustra algo que pasa constantemente: el doc técnico descubre incógnitas que el doc funcional asumía resueltas. Es normal. No es un fallo del proceso.
Como siempre digo, esto es algo iterativo
El segundo análisis adversario
Antes de implementar, con la arquitectura sobre la mesa, hice el análisis adversario técnico:
”Asume que esta arquitectura tiene un fallo fundamental que no hemos visto. ¿Cuál sería? ¿Qué supuesto estamos dando por sentado que podría ser falso?”
Claude identificó varios riesgos: que las cookies de sesión podrían expirar, que Substack podría limitar la frecuencia de peticiones, que los delays entre mensajes necesitarían ajuste.
Pero hubo uno que no identificó correctamente — y aquí está la lección más importante del proceso.
Claude propuso que el proxy del servidor podría hacer peticiones a Substack con las cookies del usuario. Eso sonaba razonable. Era incorrecto.
Lo que Claude no sabía (y yo no me acordaba) es que Substack usa Cloudflare Bot Management, que emite cookies de seguridad ligadas a la IP del navegador y su fingerprint TLS. Un servidor en un datacenter, por mucho que tenga las cookies correctas, siempre recibe 403.
Esto no era algo que el análisis adversario sobre papel pudiera descubrir. Solo lo descubrimos al ejecutar el código y leer los logs.
El análisis adversario reduce riesgos, no los elimina. Su valor está en encontrar los problemas obvios antes de implementar. Los problemas no obvios se encuentran en producción.
Fase 3: La implementación
Con doc funcional, doc técnico y análisis adversario completados, la implementación fue la parte más mecánica del proceso.
Agentes en paralelo
En lugar de pedirle a Claude que construyera todo secuencialmente, usé cuatro agentes en paralelo, cada uno con una tarea independiente:
- Agente 1: la migración de base de datos
- Agente 2: las funciones del backend
- Agente 3: el hook de React con la lógica de estado
- Agente 4: la interfaz de usuario
En paralelo. Sin esperar a que uno terminara para empezar el siguiente.
Esto funcionó porque la spec era precisa. Cuando la especificación es ambigua, los agentes toman decisiones de diseño implícitas, y esas decisiones son las que luego provocan bugs difíciles de diagnosticar. Cuando la spec es clara, el código generado es predecible.
Ojo, esto no es necesario, pero te ahorra bastante tiempo. Siempre que los trabajos no se solapen, yo suelo paralelizar lo máximo posible para ahorrar tiempo
Cómo dar contexto a cada agente
Cada agente recibió tres cosas:
1. El fragmento del doc técnico relevante para su tarea
2. El contexto del proyecto (qué stack, qué patrones existen)
3. Una instrucción de límites: qué NO debe tocar
Sin los límites, los agentes tienden a refactorizar cosas que no debían tocar, a añadir abstracciones que no pediste, o a cambiar convenciones existentes porque les parecen mejores.
El debugging como proceso, no como magia
La implementación inicial no funcionó perfectamente. Hubo varios bugs. Aquí es donde mucha gente pierde la fe en el proceso: “la IA rompió algo”.
No es así como funciona. El debugging con IA es un proceso de darle información específica y pedirle hipótesis específicas.
Qué no hacer
”Arréglalo, algo está fallando.”
Esta instrucción es inútil. Claude no puede ver los logs, no sabe qué está pasando, y va a proponer hipótesis a ciegas.
Aquí viene el principal problema del vibe coding cuando lo hace alguien que no sabe ni por donde le da el aire
Qué hacer
1. Copia los logs exactos
2. Describe el comportamiento observado vs el esperado
3. Pide hipótesis ordenadas por probabilidad
4. Valida cada hipótesis antes de pasar a la siguiente
”La campaña se lanza pero no llama a la API de Substack. Los logs muestran [X]. El comportamiento esperado es [Y]. ¿Cuáles son las tres causas más probables?”
Con información específica, Claude puede diagnosticar con precisión. Sin ella, adivina.
Cuándo el diagnóstico de Claude no puede funcionar
Hubo un momento donde Claude identificó una causa probable pero la solución propuesta era arquitecturalmente imposible — el servidor no puede hacer ciertas peticiones a Substack, sin importar cómo se configure.
Esto requirió juicio humano: reconocer que el problema no era de configuración sino de diseño. La solución fue cambiar la arquitectura, no parchear el código.
Claude puede diagnosticar dentro del espacio de soluciones que conoce. Detectar que estás fuera de ese espacio es trabajo tuyo.
El proceso completo
Lo que el humano hace en cada paso:
- Doc funcional: proveer inputs reales (capturas, texto), validar que cubre todos los casos de uso
- Análisis adversario: hacer las preguntas incómodas, no aceptar la primera respuesta
- Doc técnico: elegir entre opciones con criterios propios, no delegar la decisión
- Implementación: definir límites claros para cada agente, revisar que el código generado sea coherente con la spec
- Debugging: proveer información específica, detectar cuándo la solución propuesta no puede funcionar
Lo que Claude hace en cada paso:
- Estructurar y completar lo que describes
- Proponer opciones con trade-offs
- Generar código sobre especificaciones claras
- Diagnosticar con la información que le das
Lo que cambia cuando sigues este proceso
El error más común que veo es saltarse la doc funcional y la doc técnica, ir directamente a “construye esto” y luego intentar arreglar lo que sale.
El código que sale de “construye esto” sin spec es funcional pero frágil. Las decisiones de diseño quedan implícitas en la generación, no en un documento que puedes revisar y cuestionar. Cuando algo falla, no sabes si el error es en los requisitos, en la arquitectura, o en el código.
Cuando sigues el proceso completo, sabes exactamente en qué capa está el problema.
No quiero alargarme mucho, tengo un post explicando por qué es mala idea acumular deuda técnica
El coste oculto de la IA
Entrenar un modelo hoy es gratis. Mantenerlo en producción te puede costar la empresa.
Si has llegado hasta aquí, déjame recordarte varias cosas:
Una parte de mi trabajo consiste en ayudar a empresas y particulares en temas de Inteligencia artificial
Bien desarrollado
o bien aconsejando y/o acompañando
si quieres más información, puedes rellenar el formulario de mi web
Por otro lado, ya sabéis que The Learning Curve es una comunidad gratuita
Considero que la mayoría de contenido de pago que hay por ahí no merece la pena (la herramienta sobre la que hemos trabajado en este post es un ejemplo de ello)
hay gente cobrando 20$/mes por cosas similares
yo intento traerlas gratis
porque entiendo que no todo el mundo está en la misma situación.
Stacknotes para mí es un gasto
Sin embargo, tengo un sistema de mecenas para apoyar el contenido que hago
Es un precio simbólico de 5$/mes pero para mí significa un mundo
Te dejo aquí el enlace








Gracias Daniel, buen trabajo. Aunque no lo uso reconozco su utilidad para los que trabajan más intensivamente sus notes.