Spec-Driven Development: deixa que la IA escrigui el codi, no els requisits
A l'article anterior d'aquesta sèrie deia que el primer punt d'aprovació en un pipeline d'agents — el que va just després de l'especificació — és el pas que la majoria d'equips es salten primer, i el que més car es paga després. Aquí teniu el perquè, i el que realment hauria de portar aquesta especificació.
Una petició vaga no és una drecera, és una decisió delegada
Fa unes setmanes vaig demanar a un agent que "afegís paginació a l'endpoint de la llista". Cinc paraules, trenta segons escriure-les.
L'agent va triar una mida de pàgina. Va triar paginació basada en offset en lloc de cursor. Va donar forma a la resposta com li va semblar que tenia sentit. Res d'això estava malament exactament — simplement no era el que l'equip de frontend i jo havíem parlat dos dies abans, en una conversa completament diferent que l'agent mai va veure.
No havia estalviat trenta segons. Simplement havia entregat una decisió a qui fos que implementés la petició, i aquesta vegada aquest "qui fos" era un agent que no tenia manera de saber que hi havia una decisió a prendre.
Aquesta és la part que se li escapa a la gent amb els prompts vagues: no eliminen l'ambigüitat, només canvien qui la resol. Amb un company humà, aquesta persona normalment para i pregunta. Un agent, per defecte, tria alguna cosa plausible i continua endavant.
Una especificació és un contracte, no paperassa
"Especificació" sona a document que ningú llegeix. A la pràctica, per a una tasca que un agent està a punt d'implementar, s'assembla més a un contracte curt que ambdues parts es poden exigir:
- Objectiu — què ha d'aconseguir això de debò, no només la petició de superfície.
- Criteris d'acceptació — les condicions concretes que decideixen si està acabat.
- Casos límit — estats buits, límits, accés concurrent, tot el que "el normal" no cobreix.
- Dependències — quines APIs, mòduls o dades toca, i què no hauria de tocar.
- Restriccions — patrons existents, components del design system, límits d'arquitectura que ha de respectar.
- Fora d'abast — el que això no inclou explícitament, perquè ningú ho ampliï "ajudant".
Aquí és on el context que descrivia en articles anteriors deixa de ser coneixement general del projecte i es converteix en alguna cosa específica d'aquesta tasca concreta. El CLAUDE.md li diu a un agent com funciona el projecte. Una especificació li diu què se suposa que ha de fer aquesta peça de feina en particular.
Deixa que la IA escrigui el codi, no que decideixi els requisits
Aquesta és la línia que realment m'importa, i és fàcil que es difumini.
Un agent pot ajudar perfectament a construir l'especificació — convertir una petició en brut en un esborrany estructurat, treure a la llum casos límit que no se us havien acudit, llistar dependències que se us havien oblidat. Per a això és exactament per al que serveix un Refiner Agent.
El que no hauria de fer és resoldre en silenci una pregunta oberta pel seu compte i passar directament a la implementació. Si no s'havia decidit l'estil de paginació, la sortida correcta no és una suposició disfressada de codi — és una ambigüitat senyalada, esperant resposta.
La fallada no és "la IA va escriure mal codi". És "la IA va decidir alguna cosa que ningú li va demanar que decidís, i va resultar que es va equivocar".
Els casos límit són més barats en paper que en un diff
Escriure "què passa quan la llista està buida?" com una línia triga deu segons.
Descobrir que l'agent ho va resoldre retornant null en silenci, tres arxius més endins d'un component que a ningú se li va acudir revisar, costa una sessió de debugging i una volta de PR.
Cada cas límit que detecteu en escriure l'especificació és una frase. Cada cas límit que detecteu a la revisió és una conversa, un diff, i normalment una reimplementació. L'especificació no és feina extra enganxada a la tasca "de debò" — és el punt més barat de tot el procés per detectar un problema.
Els tests s'han de remetre a l'especificació, no a la implementació
Hi ha una trampa subtil aquí: una verificació que només comprova la implementació contra si mateixa no verifica res. Si l'agent escriu el codi i després escriu els tests per al que fa aquest codi, tots dos han estat modelats pel mateix conjunt de suposicions.
Els tests es guanyen el seu lloc quan s'escriuen contra els criteris d'acceptació que existien abans que existís la implementació — no contra el que el codi va acabar fent. Aquesta és l'única versió de "passa els tests" que realment significa que es va complir l'especificació, en lloc de significar que la implementació és coherent amb si mateixa i amb les seves pròpies suposicions.
Conclusió
Spec-Driven Development no va d'escriure més documents. Va de decidir, a propòsit, quines preguntes es responen abans que existeixi codi i quines esteu disposats a deixar en mans de la millor suposició d'un agent.
Una bona especificació no alenteix l'agent. És el que fa que la seva velocitat sigui realment útil, en lloc de ràpida en una direcció que ningú va demanar.
Al pròxim article d'aquesta sèrie ho faré pràctic: Refiner, Implementer, Verifier: A Practical Multi-Agent Workflow — com executo això de debò com tres passades separades en lloc de tres bones intencions que intento sostenir alhora al cap.
Fins llavors, la pregunta que val la pena fer-se abans d'escriure el pròxim prompt no és:
Pot l'agent esbrinar això?
És:
Hi ha una decisió amagada aquí que en realitat encara no he pres?
Si teniu una plantilla d'especificació o una configuració de Refiner que us funcioni bé, m'agradaria veure-la — no dubteu a escriure'm.