← 返回列表

Serie de entrevistas AI 16: ¿Cómo debería ser un buen Spec Coding?

Un buen Spec Coding (programación impulsada por especificaciones) tiene como núcleo convertir "ideas difusas" en "contratos precisos, verificables y ejecutables". No se trata solo de escribir un documento, sino de establecer un lenguaje de comunicación sin ambigüedades entre humanos y AI (o entre humanos). A continuación, desde las dimensiones de estructura de contenido, principios de redacción, flujo de colaboración con AI y verificación de calidad, daré una idea de cómo es un buen spec.


1. Estructura estándar del documento de especificación (tomando como ejemplo un módulo funcional)

Sección Contenido obligatorio Ejemplo
1. Objetivo y alcance Explicar en una frase qué se hace, y claramente qué no se hace "Implementar la API de registro de usuario, no incluye verificación de correo electrónico"
2. Contrato de entrada/salida Estructura de datos, tipo, campos obligatorios/opcionales, valores de ejemplo POST /register cuerpo de solicitud {email: string, password: string}, respuesta 201 o 400 con código de error
3. Comportamiento y lógica Reglas de negocio, condiciones límite, transiciones de estado "La contraseña debe tener entre 8 y 20 caracteres, al menos un dígito; si el correo ya existe, devolver 409"
4. Manejo de errores Todos los escenarios de excepción posibles y los códigos/mensajes de error correspondientes "Falló la conexión a la base de datos → devolver 503, no exponer la traza de pila"
5. Requisitos no funcionales Rendimiento (tiempo de respuesta < 200ms), seguridad (consultas parametrizadas), logs, observabilidad "Todas las consultas SQL deben usar compilación previa; registrar email pero no password"
6. Casos de prueba (clave) Al menos 3 entradas típicas + 2 entradas límite/excepción, con salida esperada Ver tabla siguiente
7. Dependencias y restricciones Librerías, versiones, variables de entorno "Python 3.10+, FastAPI, variable de entorno DB_URL"

Ejemplo de casos de prueba (incrustados en el spec)

Escenario Entrada Salida esperada
Registro normal email: a@b.com, pwd: Pass1234 201, devolver user_id
Contraseña demasiado corta pwd: Ab1 400, código de error WEAK_PASSWORD
Correo ya existe email del anterior 409, código de error EMAIL_EXISTS

Un buen Spec debe escribir primero los casos de prueba, porque el AI puede generar pruebas unitarias directamente a partir de ellos y verificar automáticamente después.


2. Principios básicos para escribir Spec (variante SMART)

Principio Explicación Contraejemplo
Preciso (Precise) Usar números concretos, tipos, condiciones booleanas; evitar "lo más posible", "normalmente" ❌ "La contraseña debe ser suficientemente segura" → ✅ "La contraseña debe tener al menos 8 caracteres, incluir mayúscula, minúscula y dígito"
Verificable (Verifiable) Cada requisito puede ser evaluado como aprobado/fallido mediante pruebas automáticas o revisión manual ❌ "El código debe ser elegante" → ✅ "Complejidad ciclomática de la función ≤ 10, sin bloques de código duplicados"
Sin ambigüedad (Unambiguous) Un mismo término tiene el mismo significado en todo el texto; si es necesario, incluir glosario ❌ "Si el usuario no existe, devolver error" → ✅ "Usuario no existe → devolver 404 y {code: 'USER_NOT_FOUND'}"
Completo (Complete) Cubrir ruta feliz, todas las rutas de excepción y requisitos no funcionales ❌ Solo escribir escenarios exitosos → ✅ Incluir tiempo de espera de base de datos, permisos insuficientes, etc.
Atómico (Atomic) Un spec describe solo un punto funcional que se puede entregar de forma independiente (para que el AI lo complete de una vez) ❌ Usar un spec para "todo el sistema de pago" → ✅ Dividir en "generar orden de pago", "verificar firma de callback", "reembolso"

3. Flujo de Spec Coding en colaboración con AI

  1. Humano escribe el spec (con la estructura anterior, especialmente los casos de prueba y las firmas de funciones).
  2. Alimentar todo el spec al AI de una sola vez (no agregar requisitos de forma conversacional para evitar contaminación por vibe).
  3. AI genera código + pruebas unitarias (el AI debe producir pruebas ejecutables según los casos de prueba del spec).
  4. Ejecutar pruebas: si todas pasan, pasar al siguiente paso; si no, modificar el spec o corregir el código directamente (puede entrar en un bucle pequeño, pero registrar los cambios).
  5. Revisión humana: verificar si se introdujo funcionalidad fuera del spec (scope creep), revisar seguridad/rendimiento.
  6. Consolidación: enviar el documento spec y el código final juntos al repositorio como documentación permanente.

Práctica clave: Spec como código — usar spec.md + test_spec.py, donde el archivo de prueba proviene directamente de los ejemplos del spec, para que al modificar código posteriormente solo se necesite ejecutar las pruebas para verificar si el spec se ha violado.


4. Efectos de un buen Spec (pueden servir como criterios de aceptación)

  • Determinismo: el mismo spec produce implementaciones similares en diferentes AIs (o diferentes personas).
  • Testabilidad: al terminar el código, se puede verificar automáticamente el 90% de la corrección.
  • Mantenibilidad: cualquier persona que vea el spec después de seis meses entenderá la intención de diseño original.
  • Bajo costo de comunicación: el equipo discute solo el spec, no líneas específicas de código.
  • Seguridad/calidad incorporadas: los requisitos de seguridad (como consultas parametrizadas) y condiciones límite están escritos en el spec, el AI debe cumplirlos.

5. Ejemplo de un buen Spec (versión minimalista)

# Spec: API de registro de usuario

## Alcance
- Recibir email, password
- No enviar correo de verificación, no verificar la autenticidad del correo

## Contrato
POST /register
Content-Type: application/json
Request: { "email": string, "password": string }
Response 201: { "user_id": string }
Response 400: { "code": "INVALID_PASSWORD" | "INVALID_EMAIL" }
Response 409: { "code": "EMAIL_ALREADY_EXISTS" }

## Comportamiento
- El email debe cumplir con el formato básico RFC 5322 (a@b.c)
- password: longitud 8-20, al menos un dígito y una letra mayúscula
- Almacenar encriptado con bcrypt, costo de sal 10
- Si se descubre que el email ya existe antes de guardar en la base de datos → 409

## Casos de prueba (entrada -> código de estado esperado + campos de respuesta)
| email de entrada | password | Esperado |
|------------------|----------|----------|
| test@x.com       | Pass1234 | 201, user_id existe |
| test@x.com       | pass     | 400, INVALID_PASSWORD |
| bad              | Pass1234 | 400, INVALID_EMAIL |
| (email ya existente) | Pass1234 | 409, EMAIL_ALREADY_EXISTS |

## No funcional
- Las consultas SQL deben usar parametrización (prevención de inyección)
- Registrar IP de origen del registro, no registrar contraseña
- Tiempo de respuesta: 95% de solicitudes < 100ms (sin incluir bcrypt)

## Dependencias
- Python 3.10+, FastAPI, bcrypt, asyncpg

Un buen Spec Coding = escribir las "decisiones de diseño" humanas como "casos de prueba + firmas de tipos + restricciones de comportamiento" de la máquina, haciendo que el AI solo se encargue de llenar la implementación, mientras que el humano mantiene el control de la calidad y la dirección.

评论

暂无已展示的评论。

发表评论(匿名)