El material del módulo 20 son 28 páginas y unos treinta prompts, uno por fichero. No hay explicación de qué es un grafo de estado ni de cómo funciona la transcripción de audio: eso ya está en los módulos 5 y 12. Lo que hay es una cadena de instrucciones para que otro escriba el código.
Merece la pena verlo como lo que es, porque cambia lo que aprendes de ello. Si lo lees como un tutorial, sales sabiendo copiar y pegar. Si lo lees como un ejemplo trabajado de descomposición, sales sabiendo escribir la próxima.
Todos los prompts de la guía tienen la misma estructura. Cuando falta un hueco, el generador lo rellena por su cuenta.
| Hueco | Qué fija | Qué pasa si falta |
|---|---|---|
| Destino | La ruta exacta del fichero | El generador inventa la estructura del paquete |
| Superficie | Imports y de dónde salen | Reinventa helpers que ya existen dos carpetas más allá |
| Firmas | Nombres de clases, funciones y parámetros | Nombres plausibles que no encajan con quien los llama |
| Comportamiento | El paso a paso, incluidos los errores | Camino feliz, sin manejo de errores |
| Formato de salida | «solo el código, nada más» | Prosa, explicaciones y bloques a medias |
Un ejemplo con un fichero que no es del proyecto, para ver la forma sin ver la respuesta:
Genera código Python en utils/retry.py con estas especificaciones:
Importa asyncio y functools, y el logger desde el módulo tools.
Define un decorador asíncrono llamado retry que acepte intentos (int, por
defecto 3) y espera_base (float, por defecto 0.5).
Debe:
- Registrar cada reintento con el número de intento y la excepción.
- Esperar espera_base * (2 ** intento) entre intentos.
- Reintentar solo TimeoutError y ConnectionError; el resto se propaga.
- Al agotar los intentos, relanzar la última excepción.
La salida debe contener solo el código Python que implementa esto.
Las decisiones difíciles ya están tomadas ahí dentro: qué excepciones se reintentan, qué no, y qué pasa al agotarse. Un prompt que dijera «haz un decorador de reintentos» delega esas tres decisiones — y el generador las toma distintas cada vez.
// la spec no es la parte aburrida del trabajo: es el trabajoLo interesante de la guía está al final de cada prompt, no al principio. Cuatro líneas casi idénticas cierran casi todos. Contadas sobre el texto extraído del PDF, no a ojo:
Esas cuatro líneas convierten treinta generaciones sueltas en un proyecto con historia: un
commit por fichero, un README que crece con el código y un agents.md que registra cómo
se generó cada pieza. Sin ellas tendrías el mismo código y ninguna forma de reconstruir de dónde
salió.
Y lo decide distinto cada vez. Un prompt no es determinista, así que la reproducibilidad no viene de repetir el prompt: viene de fijar el resultado en git en cuanto sale bien. Por eso el contrato pone el commit al final de cada fichero y no al final del proyecto.
El agents.md cumple la otra mitad. Es el único sitio donde queda escrito con qué
prompt salió cada fichero. Un README dice qué hace el código; un agents.md dice
cómo llegó a existir.
| Fichero | Responde a | Lo lee |
|---|---|---|
readme.md | ¿Qué hace y cómo se arranca? | Quien usa el proyecto |
agents.md | ¿Cómo se generó cada pieza? | Quien la va a regenerar |
| historia de git | ¿En qué orden apareció? | Quien busca cuándo se rompió |
¿Se puede copiar lo que hay que copiar? El documento existe para pegarse en un generador, y 191 de sus 845 líneas de texto —un 22,6 %— están cortadas al margen derecho. Las frases terminan a mitad de palabra: «…determine if the best next res», «…add the dependencies in re». En las páginas de prompts por fichero son entre 10 y 15 líneas cortadas por página.
La comprobación, midiendo la caja de cada línea del PDF:
>>> import fitz
>>> d = fitz.open("proyecto_final_guia_ia.pdf")
>>> cajas = [l["bbox"][2] for p in d
... for b in p.get_text("dict")["blocks"]
... for l in b.get("lines", [])]
>>> len(cajas), max(cajas)
(845, 548.5039672851562) # ancho de página: 595.92
>>> sum(1 for x in cajas if x > 545)
191
Todas las líneas largas mueren exactamente en el mismo x. No es azar: es un recorte. Si el único uso previsto del documento es copiarlo, ¿qué queda del documento?
¿Y los siete prompts que no piden agents.md? 26 piden commit y solo 19
piden documentar el proceso. Si el agents.md es lo que hace auditable la generación,
¿por qué es justo la línea que más se cae?
¿Qué garantiza «explícalo en 2-3 frases»? Es una instrucción de longitud, no de contenido. Un README de treinta entradas de tres frases, escritas por el mismo modelo que escribió el código, ¿es documentación o es el código otra vez, más corto?
Coge un solo fichero del proyecto — el más pequeño que encuentres — y escribe tú su spec con los cinco huecos de la sección 02, sin mirar la de la guía.
Después genérala dos veces, en dos sesiones limpias, y haz diff de las dos
salidas. Lo que cambie entre las dos es exactamente lo que tu spec no dijo. Reescríbela para cerrar
esos huecos y repite.
Cuando el diff salga vacío, tu spec ya no es un prompt: es una especificación.