Cómo redactar especificaciones efectivas para IA en desarrollo de software
¿Quieres que la IA escriba código que aguante en producción o prefieres pagar la reescritura con horas de sueño robadas?
Tiempo estimado de lectura: 6 min
- Sin una spec sólida, la IA falla: la salida suele ser “lo más probable” y no lo que tu sistema necesita.
- Una spec funciona como contrato: entradas, salidas y reglas inmutables (TS, DB, validadores).
- Proceso y repo: coloca SPEC.md y reglas globales en el repo; pide tests antes de código.
- Diseña para fallos: idempotencia, retries, observabilidad y mocks de LLM en CI.
Poca gente dice esto claro: sin una spec sólida, la IA no te ayuda —te traiciona con estilo. Te da un PR brillante, lo mergeas, y dos semanas después estás en modo bombero arreglando incoherencias, dependencias raras y bugs que solo existen porque nadie le dijo al modelo las reglas del juego.
Esto no es teoría. Es un manual corto y agresivo para escribir specs que conviertan a la IA en ejecutora precisa, no en improvisadora talentosa.
Resumen rápido (lectores con prisa)
La IA no entiende contexto técnico; genera lo más probable. Para usarla en producción necesitas specs como contratos: define entradas, salidas, validadores y versiones exactas del stack. Pon la spec en el repo, exige tests (mock de LLM en CI) y diseña idempotencia, retries y observabilidad desde el inicio.
Primera verdad incómoda: la IA no piensa, predice
Los modelos son máquinas de probabilidades. No entienden GDPR, SLAs o el negocio que hay detrás del botón. Si no les das límites, rellenan con lo más probable de su entrenamiento. Y lo más probable suele ser un parche bonito… que no encaja en tu arquitectura.
Qué hace una spec que realmente funcione con IA
1) Contexto de negocio (el “por qué”) — 1 párrafo
No le cuentes la historia de tu vida. Di en una frase qué problema resuelve esta feature y qué sería un fallo. Ejemplo: “Crear usuarios con verificación por email. Éxito = usuario activo; fracaso = intento de signup duplicado.” Con eso la IA prioriza seguridad y unicidad, no UX glam.
2) Contratos de datos inmutables — el núcleo
Define TODAS las formas de datos:
- Interfaces TypeScript (ej. CreateUserRequest, UserResponse).
- Esquema de DB (SQL/Prisma).
- Validadores (Zod schemas).
Si el código espera un JSON con { email: string, password: string } dilo. Congela esos contratos. Si cambian, cambia la spec. Esto transforma a la IA en un generador que cumple un contrato, no en un novelista.
3) Stack y versiones exactas — sin ambigüedades
“Usa Next.js” es basura. Di “Next.js 14 — App Router — Node 20 — Postgres 15 — pgvector”. Lista librerías permitidas y las prohibidas. Los modelos tienden a usar patrones históricos; dar versión evita sorpresas.
4) Reglas negativas — lo que NO se debe hacer
La IA ama instrucciones. Si le dices “No hagas X”, lo recuerda. Lista antipatrones:
- No exponer variables de entorno en cliente.
- No añadir dependencias sin revisión CVE.
- No implementar persistencia eventual en endpoints críticos.
5) Criterios de aceptación comprobables
Exige tests. Define qué pruebas deben pasar:
- Unit tests (ej. hashing de password).
- Integration tests (ej. createUser -> DB -> verify hash).
- Tests de resiliencia (reintentos en worker).
Pedir tests antes que código hace que la IA produzca implementaciones testables.
Cómo estructurar la spec en el repo (hazlo ya)
No metas la spec en Google Docs o Notion y esperes que la IA la lea. Ponla en el repo. Que el agente la tenga al lado del código. Dos archivos mínimos:
Archivos mínimos
- .cursorrules / .github/copilot-instructions.md — Reglas globales: stack, estilos, convenciones de nombres, políticas de seguridad. Que el agente lo lea siempre.
- SPEC.md (micro-spec por feature) — Contexto corto, contratos TS, endpoints, criterios de aceptación, reglas negativas, responsables.
Micro-spec vs contexto global: menos es más
Saturar la ventana de contexto con miles de archivos confunde. Alimenta a la IA con:
- SPEC.md del módulo.
- Tipos globales que realmente importan.
- Un archivo de reglas globales.
Menos ruido, más precisión. La IA trabaja mejor con densidad técnica, no con bibliotecas de historia.
Patrón de trabajo: plan antes de código
Nunca pidas “haz el CRUD”. Pide un plan en pasos:
- Interfaces + DB schema.
- Contratos OpenAPI.
- Tests de aceptación.
- Implementación por sprint.
Aprueba cada fase. Así evitas que la IA genere código que contradiga los contratos que aprobaste.
Herramientas que convienen y por qué
– TypeScript + Zod: transforma respuestas en contratos verificables.
– Prisma/SQL: esquemas claros y migraciones.
– OpenAPI: contratos de endpoint.
– pgvector (si usas vectores): evita añadir otro servicio.
– n8n para orquestación: sacas la lógica de integración fuera del repo y manejas retries visuales.
RAG y seguridad: nunca lo tomes a la ligera
Si vas a indexar documentos para chatear con ellos, cada vector debe llevar tenant_id. Punto. No mezcles tenants. Nunca. El filtro por tenant debe aplicarse en la consulta, no en la app. Si mezclas vectores, estás invitando a fugas de datos.
Idempotencia, retries y jobs: diseña para fallos
Asume que la IA y los servicios fallarán. Diseña:
- Jobs con estado (pending, processing, success, failed).
- Workers idempotentes por job_id.
- Dead-letter queues para errores irreparables.
- Retries con backoff exponencial y circuit breaker.
No idempotencia = facturación duplicada + datos duplicados. No es elegante. Es caro.
Observabilidad desde el minuto cero
Si no mides, no mejoras. Instrumenta:
- Traces distribuidos (OpenTelemetry).
- Métricas: latencia por modelo, tokens por job, coste por tenant.
- Logs estructurados con context_id.
- Dashboards y alertas (picos de coste, aumentos de error rates).
Tests: mockea la IA
No dependas de la API real en CI. Mockea respuestas de LLM —positivas y negativas— y tests que simulen timeouts, respuestas malformadas y ataques de prompt injection. Así la spec y los tests te protegen cuando la IA se sale del carril.
Plantilla mínima de SPEC.md (rápida y usable)
Pon esto en la raíz del módulo. No lo copies sin adaptar, pero úsalo como base.
- Título: Objetivo en una frase.
- Contexto: 2 párrafos máximos.
- Stack: versiones exactas.
- Contratos: interfaces TS + esquemas SQL/Prisma.
- Endpoints: método, path, payloads (ej. OpenAPI snippet).
- Regla negativas: lista corta.
- Criterios de aceptación: tests concretos.
- Responsables: quién aprueba merge.
El nuevo rol del senior: menos héroe, más guardián
El valor del senior hoy no es teclear más rápido. Es decidir fronteras. Es escribir specs que no fallen en producción. Si no tienes eso, la IA solo acelera el desastre.
Checklist rápido antes de pedir código a la IA
- ¿SPEC.md está en la raíz del módulo?
- ¿Interfaces TS y esquemas DB están definidos?
- ¿Reglas negativas claras?
- ¿Tests de aceptación definidos?
- ¿El prompt obliga a devolver JSON validable?
Si respondes no a cualquiera, no pidas código.
CTA
Si quieres la plantilla SPEC.md lista para pegar y un prompt maestro para Claude que funcione hoy, respóndeme “Quiero la plantilla”.
Te la envío lista para pegar en el repo y para que la IA empiece a generar código que no te rompa la vida.
Para quienes trabajan en automatización, agentes y workflows este enfoque encaja con prácticas de laboratorio y experimentación. Más recursos y experimentos vinculados a estos patrones están disponibles en Dominicode Labs, que complementan las plantillas y ejemplos prácticos descritos arriba.
FAQ
- ¿Por qué necesito una spec si la IA puede escribir código por mí?
- ¿Qué debe contener obligatoriamente un SPEC.md?
- ¿Cómo evito fugas de datos en sistemas RAG?
- ¿Qué pruebas debo pedir antes de revisar un PR generado por IA?
- ¿Cómo integro mocks de LLM en CI sin perder cobertura realista?
- ¿Qué reglas negativas son las más críticas?
Respuesta: ¿Por qué necesito una spec si la IA puede escribir código por mí?
Porque la IA genera lo más probable, no lo correcto para tu negocio. Una spec transforma requisitos en contratos verificables que la IA puede cumplir de forma repetible.
Respuesta: ¿Qué debe contener obligatoriamente un SPEC.md?
Título objetivo, contexto corto, stack con versiones exactas, contratos (TS + DB), endpoints, reglas negativas, criterios de aceptación y responsables.
Respuesta: ¿Cómo evito fugas de datos en sistemas RAG?
Indexa vectores con tenant_id, aplica el filtro por tenant en la consulta y evita mezclar índices entre tenants.
Respuesta: ¿Qué pruebas debo pedir antes de revisar un PR generado por IA?
Unit tests, integration tests que verifiquen contratos y tests de resiliencia (timeouts, retries, respuestas malformadas).
Respuesta: ¿Cómo integro mocks de LLM en CI sin perder cobertura realista?
Mockea escenarios positivos y negativos, timeouts y prompt injections. Mantén casos representativos que reflejen errores reales observados en producción.
Respuesta: ¿Qué reglas negativas son las más críticas?
No exponer env vars en cliente; no añadir dependencias sin revisión CVE; no usar persistencia eventual en endpoints críticos; exigir tests antes del merge.
