What 'a good task spec for an agent' looks like (a sub-articulated discipline)
Por qué esto importa ahora
Llevo un tiempo dándole vueltas a una observación deflacionaria: el artefacto se movió. Lo que tu equipo produce de manera durable ya no es el sistema corriendo — es la meta que se le entrega al agente para que produzca ese sistema. El código sigue ahí, claro. Pero el código es ahora un sub-producto del executable knowledge que tu organización deposita en la spec.
Y la calidad del agente está acotada por la calidad de la meta que le entregas. Esto es independiente del modelo que corra debajo. Puedes cambiar de Claude a otro proveedor, de un sonnet a un opus, de un harness a otro — y si la meta está mal formada, el resultado va a estar mal formado. La meta es el cuello de botella, no el modelo. Es una observación incómoda porque mueve el problema de "qué LLM uso" a "qué disciplina escribo".
Lo que en la era del sombrero era "un ticket bien escrito" es hoy una disciplina con peso estructural. Y, sin embargo, está sub-articulada — no tenemos vocabulario compartido, cada equipo la reinventa, y las guías de prompting cubren forma sin cubrir estructura cognitiva. Lo separo en cuatro pedazos: setpoint, constraints, done criteria, fallback. Es una propuesta de partida, no un estándar.
Componente 1 — Setpoint
El setpoint es el estado que el sistema debe alcanzar. No la acción a ejecutar. Esta distinción parece sutil y no lo es. Cuando escribes "agrega un endpoint POST /users", le estás diciendo al agente qué hacer. Cuando escribes "el sistema acepta creación de usuarios con email único, password hasheado, y emite un evento user.created", le estás diciendo qué estado debe existir. La segunda forma deja al agente decidir cómo llegar — y lo deja libre para proponer una mejor ruta si la encuentra.
La prueba ácida es esta: si no puedes escribir el setpoint sin escribir el código, la meta todavía no está formada. Estás pensando en implementación disfrazada de objetivo. Cuando esto ocurre, lo que entregas al agente es ruido — un fragmento de implementación parcial que le impide pensar por sí solo y le obliga a completar tu boceto. El resultado típico: el agente entrega exactamente lo que pediste, y exactamente lo que pediste resulta ser lo equivocado.
Una heurística que me ha servido: escribe el setpoint en términos observables desde fuera. Si el comportamiento que describes se puede verificar desde un cliente del sistema, sin abrir el código, vas bien. Si la única forma de verificarlo es leyendo la implementación, todavía estás pensando como implementador.
Hay un sub-pliegue acá que vale la pena nombrar. El setpoint también describe qué no tiene que estar en el estado final. Una creación de usuario que deja datos residuales en una tabla temporal cumple el setpoint funcional y rompe la limpieza del sistema. Por eso conviene pensar el setpoint con su negativo en paralelo — qué quiero ver, qué no quiero ver. Cuando ambos están escritos, el agente tiene un blanco completo y no solo una mitad ambigua.
Componente 2 — Constraints
Las constraints son lo que la solución no puede hacer. Es la otra mitad del problema, y la que más se olvida. Cuando un humano escribe código en un equipo maduro, opera sobre cientos de constraints implícitas — "siempre usamos pgvector", "nada que rompa aislamiento de tenant", "el deploy tiene que pasar por feature flag". Nadie las dice porque todo el equipo las da por descontado.
El agente no las da por descontado. El agente no las infiere. Si la constraint no está escrita, la constraint no existe para él. Y aquí está el punto que duele: la mayoría de los problemas que vemos en agentes "que toman atajos extraños" no son problemas del agente — son constraints implícitas del equipo que nunca se hicieron explícitas porque nunca habían tenido que serlo.
Las categorías que aparecen una y otra vez: performance (latencia, throughput), compatibilidad (versiones, contratos), seguridad (qué no tocar, qué no exponer), dependencias (qué librerías sí, cuáles no), costo operacional (qué patrones evitar porque cuestan en producción). Una buena spec las nombra una por una, aunque suene redundante. La redundancia es el costo de hacer audit-able lo que antes era tácito.
Me parece que vale la pena un movimiento organizacional adicional: mantener un repositorio vivo de constraints estándar de tu equipo, que las specs puedan referenciar por nombre. "Aplica constraints-base/seguridad y constraints-base/datos". Eso evita reescribirlas cada vez y, más importante, las convierte en un activo organizacional versionado — cuando una constraint cambia, todas las specs que la referencian se enteran. Es la diferencia entre disciplina individual y disciplina sistémica.
Componente 3 — Done criteria
Done tiene que ser programáticamente verificable. No de buena fe. Si tu criterio de "listo" es "cuando alguien lo aprueba en review", la disciplina sigue siendo de la era del sombrero — en vestido nuevo. Estás moviendo el cuello de botella humano un paso más adelante, pero no lo estás resolviendo.
Lo que sí cuenta como done criteria: tests que deben pasar (con nombres específicos, no "los tests"), evals que deben superar un umbral, métricas observables post-deploy que indican que el comportamiento es el esperado. Y crucialmente: done criteria que el agente puede ejecutar por sí mismo para verificar antes de entregar. Si el agente no puede saber si terminó, depende del humano para saberlo — y volvimos al embudo.
Una nota honesta: hay clases de outputs donde el done criteria programático no existe todavía. Diseño de UX, decisiones de arquitectura de alto nivel, ciertas formas de comunicación. Para esos casos el done criteria es necesariamente humano, y está bien. Lo importante es no fingir que todo es verificable cuando no lo es — esa autoengaño es lo que produce deuda silenciosa.
Componente 4 — Fallback / Escalation
El fallback es qué hacer si el agente no puede alcanzar el setpoint dentro de las constraints. Esta es la parte que casi nadie escribe, y es la que separa el agente que falla limpio del que falla generando deuda silenciosa.
Las ramas legítimas son tres. Pedir clarificación — cuando la spec tiene una ambigüedad que el agente identifica antes de actuar. Proponer una alternativa con trade-off documentado — cuando el agente ve una solución viable que viola una constraint, y prefiere preguntar a violar. Detener y escalar — cuando el agente no encuentra ruta y sabe que no la encuentra. Cualquiera de las tres es preferible a la cuarta opción, que es la default cuando no especificas: improvisar.
La improvisación del agente es lo más peligroso. Porque entrega algo, ese algo pasa los tests superficiales, y el costo aparece tres sprints después. Y para entonces el contexto se perdió — nadie recuerda exactamente qué pidió, qué entregó el agente, dónde apareció el atajo. Por eso el fallback explícito es una inversión de claridad ahora a cambio de no tener que arqueologizar después.
Por qué sigue sub-articulado
No tenemos vocabulario compartido. Cada equipo está reinventando esto desde cero, y la consecuencia es que las lecciones no se acumulan. Lo que un equipo aprende sobre cómo escribir un buen setpoint no llega al equipo del piso siguiente, porque ni siquiera comparten el concepto "setpoint" como categoría diferenciada.
Los estándares de prompting que sí han emergido — PromptML, structured outputs, schemas — cubren la forma del mensaje. Cubren cómo serializar la meta. No cubren la estructura cognitiva de la meta misma. Es como tener una gramática sin tener una retórica: necesario pero insuficiente.
Me parece que esto es el equivalente de TDD circa 2002 — los practitioners están ensamblando la disciplina antes de que tenga nombre. Y eso es completamente normal. Pero también significa que ahora es cuando vale la pena nombrarla, porque el costo de no nombrarla es que cada equipo la pague por separado.
De hecho, sospecho que en los próximos dieciocho meses vamos a ver emerger libros, certificaciones, frameworks competitivos sobre cómo se escribe una task spec agéntica. Y la mayoría serán parciales — cubrirán uno de los cuatro componentes y lo presentarán como suficiente. Mi apuesta es que el corte de cuatro va a sobrevivir como mínimo común, aunque los nombres cambien. Pero esa apuesta es falsable, y voy a estar atento al primer corte de cinco o seis que me convenza con un caso concreto.
Postura honesta
Ofrezco esto como un primer frame para discusión, no como un estándar. Los cuatro componentes — setpoint, constraints, done, fallback — son un corte útil, no una derivación cerrada. Si encuentras que falta un quinto componente, dímelo. El corte de cuatro podría ser arbitrario y no me molestaría descubrirlo.
La validación de este frame es operacional, no retórica. La pregunta no es "¿suena bien?" sino "¿cuando lo aplicas, el agente falla menos en lo que importa?" Esa es la única validación que cuenta. Y es una validación que cada equipo tiene que hacer por sí mismo, en su contexto, con sus dolores.
Esto ya estaba en ti — si has trabajado escribiendo specs para humanos, las cuatro categorías te resultan familiares, solo que se aplicaban implícitamente. Ahora hay que aprender a aplicarlas explícitamente, porque el destinatario cambió.
¿Cuál de los cuatro componentes falla más seguido en tu equipo — setpoint poco claro, constraint implícita, done criterion débil, o fallback ausente? Coméntalo.