MÓDULO 20 · PROYECTO FINAL · 20 MIN

Especificar para que lo genere otro

La guía del proyecto final no explica cómo se construye un agente: son treinta especificaciones de fichero escritas para que las ejecute un generador de código. Lo que la hace funcionar no es la prosa de cada una, sino el contrato idéntico que cierra todas: dónde se documenta, qué se commitea, qué se hace si falta una dependencia. Ese contrato es la parte transferible — el contenido de los prompts caduca con el proyecto, la forma no.
01 — Qué tienes delante
No es un tutorial

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.

02 — Los cinco huecos
Anatomía de un prompt de fichero

Todos los prompts de la guía tienen la misma estructura. Cuando falta un hueco, el generador lo rellena por su cuenta.

HuecoQué fijaQué pasa si falta
DestinoLa ruta exacta del ficheroEl generador inventa la estructura del paquete
SuperficieImports y de dónde salenReinventa helpers que ya existen dos carpetas más allá
FirmasNombres de clases, funciones y parámetrosNombres plausibles que no encajan con quien los llama
ComportamientoEl paso a paso, incluidos los erroresCamino 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 trabajo
03 — El cierre
El contrato que se repite

Lo 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:

commit en git26
instalar y anotar24
explicar en readme23
proceso en agents.md19 ← el que se cae

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ó.

04 — El límite del método
Lo que el spec no dice, lo decide el generador

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.

FicheroResponde aLo 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ó
Auditoría

¿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?

Para hacer
Haz un diff contra ti mismo

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.