Tag: AI

  • Implementación de memoria en agentes de IA para una gestión eficiente

    Implementación de memoria en agentes de IA para una gestión eficiente

    Memoria en agentes de IA — CoALA, Mem0, Letta, Zep

    Tiempo estimado de lectura: 4 min

    Ideas clave

    • La memoria separada convierte demos en productos: el diseño determina seguridad, costo y utilidad.
    • CoALA propone cuatro capas de memoria para organizar responsabilidades y políticas.
    • Mem0, Letta y Zep cubren distintos niveles: personalización entre sesiones, RAM operativa y memoria a escala respectivamente.
    • Implementa gates, versionado, trazabilidad y pruebas de regresión para evitar drift y conflictos.

    Introducción

    La memoria en agentes de IA — CoALA, Mem0, Letta, Zep no es un tema académico bonito: es la diferencia entre un asistente útil y un agente que toma decisiones peligrosas después de tres días de uso. Si construyes agentes, tienes que decidir qué recordar, cómo hacerlo y quién corrige cuando la memoria miente. Punto.

    Resumen rápido (lectores con prisa)

    CoALA: arquitectura conceptual con cuatro capas de memoria para separar responsabilidades. Mem0: persistencia de perfil y preferencias entre sesiones. Letta: gestión del contexto operativo (RAM vs disco) para agentes de larga duración. Zep: infraestructura asíncrona para memoria a escala y baja latencia. Usa gates, versionado y trazabilidad para mitigar drift y conflictos.

    Memoria en agentes de IA — qué propone CoALA (y por qué importa)

    CoALA (Cognitive Architectures for Language Agents) es el mapa mental que deberías leer antes de elegir tecnología. No es una librería; es una arquitectura conceptual que separa responsabilidades de memoria en cuatro capas:

    Memoria de trabajo

    la ventana de contexto activa del LLM — efímera y cara.

    Memoria episódica

    historial de eventos y acciones — útil para debugging y trazabilidad.

    Memoria semántica

    hechos estables y preferencias del usuario — lo que define el perfil.

    Memoria procedimental

    herramientas, prompts y rutinas — cómo actúa el agente.

    Diseñar según CoALA significa decidir por anticipado qué pertenece a cada capa y qué políticas aplicas para mover datos entre ellas. Sin ese mapa, cualquier solución termina en un RAG desordenado o en una “caja negra” que acumula ruido.

    Mem0: memoria de usuario para personalización

    Mem0 es la categoría de herramientas centradas en persistir hechos del usuario y preferencias. En la práctica:

    • Extrae entidades y preferencias desde la conversación.
    • Las indexa en un vector store + metadatos.
    • Cuando el usuario regresa, inyecta solo lo necesario: preferencias, roles, restricciones.

    Cuándo usar Mem0: productos donde la coherencia entre sesiones importa (soporte, asistentes personales, CRMs conversacionales). No esperes de Mem0 la gestión de contexto operativo de un agente que corre tareas autónomas por horas; su foco es perfilización y personalización.

    Letta: el agente que administra su propia RAM

    Letta aborda la memoria como un sistema operativo para agentes. Conceptualmente:

    • Divide el contexto en Main Context (RAM) y External Context (disco).
    • El agente tiene funciones para decidir qué traer a RAM, cuándo resumir episodios y cuándo purgar información.
    • Aplica paginación y compactación automática para mantener la relevancia dentro del límite de tokens.

    Cuándo usar Letta: agentes autónomos de larga duración — research agents, asistentes de coding que mantienen estado operativo o pipelines que deben razonar sobre eventos pasados extensos. Letta añade autonomía, pero también complejidad operacional: monitorización, logs y políticas de gobernanza son obligatorios.

    Zep: memoria a escala y baja latencia para producción

    Zep es la opción de infraestructura: microservicio que procesa memoria de forma asíncrona y entrega contexto prefiltrado con baja latencia.

    • Extrae hechos, construye resúmenes y grafos de conocimiento en background.
    • Reduce el coste en inferencia en tiempo real porque el trabajo pesado está hecho antes.
    • Ideal para entornos B2B de alto tráfico donde milisegundos y consistencia importan.

    Cuándo usar Zep: productos que atienden muchos usuarios concurrentes y necesitan recuperar relaciones complejas entre entidades sin sacrificar SLA.

    Criterio para elegir (resumen práctico)

    • Necesitas perfilamiento entre sesiones → Mem0.
    • Necesitas un agente que se gestione a sí mismo durante horas/días → Letta.
    • Necesitas latencia baja a escala y relaciones entre entidades → Zep.
    • Necesitas diseñar el sistema completo antes de implementar → CoALA como guía.

    Riesgos técnicos que no puedes ignorar

    Memory drift: si un agente almacena una inferencia incorrecta, esa “mentira” contamina decisiones futuras. Implementa mecanismos de verificación y anclaje (por ejemplo, expiración automática o validación humana).

    Conflictos de memoria: cuando dos hechos contradictorios coexisten, la resolución automática es no determinista. Loggear confianza, orígenes y versiones de cada hecho ayuda a auditar.

    Derecho al olvido y cumplimiento: borrar vectores y metadatos es posible, pero garantizar que el agente “olvide” inferencias derivadas de esos datos es técnicamente complejo. Diseña flujos de eliminación y revisiones humanas para datos sensibles.

    Observabilidad y gobernanza: sin trazabilidad de qué dato fue recuperado y por qué, no puedes depurar ni atribuir responsabilidad. Cada recuperación debe registrar fuente, score y prompt usado.

    Implementación: checklist mínimo antes de producción

    • Define qué tipos de memoria necesita tu agente (CoALA).
    • Añade gates en la recuperación: score mínimo, límite de tokens y razón de inclusión.
    • Versiona la memoria: cada actualización con sello temporal y origen.
    • Pruebas de regresión para el comportamiento basado en memoria (no solo unitarias).
    • Monitoreo de drift: alertas automáticas cuando la tasa de correcciones humanas sube.

    La memoria transforma agentes de demos en productos reales. No es una feature; es una capa de infraestructura con requerimientos de producto, seguridad y mantenimiento. Si vas a construir agentes que duren, diseña memoria con criterio ahora — después ya será demasiado caro corregirlo. En los próximos posts de Dominicode veremos ejemplos prácticos: pipeline de Mem0 para asistentes y cómo instrumentar Letta en un agente de investigación.

    Dominicode Labs

    Si trabajas en automatización, agentes o IA aplicada y quieres ejemplos prácticos y pipelines listos para producción, explora recursos y experimentos en Dominicode Labs. Es una continuación lógica para ver implementaciones de Mem0, Letta y arquitecturas inspiradas en CoALA.

    FAQ

    ¿Qué es CoALA?

    CoALA es una arquitectura conceptual que separa responsabilidades de memoria en cuatro capas: memoria de trabajo, episódica, semántica y procedimental. No es una librería, sino un mapa mental para diseñar memoria en agentes.

    ¿Para qué sirve Mem0?

    Mem0 persiste hechos del usuario y preferencias entre sesiones. Se usa para perfilamiento y personalización en productos donde la coherencia inter-sesiones importa (por ejemplo, CRMs conversacionales o asistentes personales).

    ¿Cuándo debo usar Letta?

    Usa Letta para agentes autónomos de larga duración que necesitan gestionar activamente su contexto (RAM vs disco), como research agents o asistentes de coding que operan durante horas o días.

    ¿Qué aporta Zep a producción?

    Zep ofrece una capa de infraestructura que procesa memoria en background, construye resúmenes y grafos, y entrega contexto prefiltrado con baja latencia, útil en entornos B2B de alto tráfico.

    ¿Cómo mitigo el memory drift?

    Implementa mecanismos de verificación, expiración automática, validación humana, trazabilidad de orígenes y versionado para detectar y corregir inferencias incorrectas almacenadas en memoria.

    ¿Qué pruebas son críticas antes de lanzar?

    Además de pruebas unitarias, haz pruebas de regresión específicas para comportamiento influido por memoria, monitoriza drift y añade alertas cuando sube la tasa de correcciones humanas.

  • Cómo gestionar PRs generadas por agentes en la revisión de código

    Cómo gestionar PRs generadas por agentes en la revisión de código

    Code review en equipos con agentes — qué cambia cuando el 60% del código no lo escribió un humano

    Tiempo estimado de lectura: 4 min

    • La revisión pasa de comprobación sintáctica a auditoría semántica y arquitectónica.
    • El volumen y la fatiga de revisión aumentan; los humanos agregan criterio, no velocidad pura.
    • Reglas operativas: prompts en PR, PRs pequeñas, tests deterministas y gates automáticos.
    • Responsabilidad y formación deben definirse: ownership legal y mentoría combinada hombre-máquina.

    Code review en equipos con agentes — qué cambia cuando el 60% del código no lo escribió un humano: esa frase ya debería sonar como una alarma. Si tu repositorio empieza a parecer una fábrica de PRs escritas por LLMs, no estás ante una mejora de productividad: estás ante un cambio de paradigma en la gobernanza del código.

    El problema no es que el código generado sea malo. Es que es convincente. Y lo convincente pasa sin pedir permiso por la puerta de revisión.

    Resumen rápido (lectores con prisa)

    Qué es: Código producido por agentes (LLMs/agentes automatizados) que entra al repositorio vía PR.

    Cuándo usarlo: Cuando buscas acelerar tareas repetibles, con controles automáticos y ownership claro.

    Por qué importa: Cambia la revisión de sintaxis a auditoría de dominio, coherencia y riesgos.

    Cómo funciona: Implementa gates automáticos, exige prompts en PRs, fragmenta PRs grandes y usa agentes como primer filtro.

    Cuando la mayoría del código viene de agentes

    Cuando la mayoría del código viene de agentes, la revisión deja de ser corrección ortográfica. Pasa a ser auditoría semántica, arquitectónica y de riesgos. La prioridad deja de ser “¿compile?” y pasa a ser “¿esto respeta nuestro dominio, nuestras abstracciones y nuestras reglas de operación?”.

    A partir de ahí, todo cambia: volumen de PRs, tipos de errores dominantes, responsabilidad técnica y los criterios mínimos para aceptar cambios.

    Los cuatro efectos inmediatos que verás

    1. Fatiga de revisión a escala

    Un agente puede abrir varias PRs en minutos. Leer código cuesta. El riesgo real es aprobar por inercia. No es moral; es una falla de proceso.

    2. Ruido ejecutivo: syntactic correctness ≠ business correctness

    Linters y tipado son una alfombra. Bajo ella puede haber duplicaciones, incompatibilidades con contratos internos o decisiones de diseño rotas.

    3. Pérdida de contexto global

    Los agentes funcionan bien en ámbitos locales. Fallan cuando hay decisiones históricas, utilidades compartidas o patrones no escritos. El repo se fragmenta si nadie vigila la coherencia.

    4. Reasignación del valor humano

    El humano deja de competir en velocidad y pasa a proporcionar criterio: editor, arquitecto y protector de deuda técnica.

    Reglas prácticas para revisar PRs generadas por IA

    Obligatoriedad del prompt en la PR

    Cada PR que provenga de un agente debe incluir: el prompt completo, parámetros del agente (temperature, model, herramientas usadas) y, si aplica, los snippets intermedios que el agente evaluó. Sin esto, rechaza la PR.

    PRs pequeñas y cambiables

    Límite duro: <400 líneas por PR. Si un agente genera más, fracciona. Revisa unidades pequeñas y reusables, no borradores monolíticos.

    Pipeline que no negocia: tests + validadores automáticos

    Nada pasa si no hay tests deterministas. Añade validadores automatizados (SAST, DAST, complejidad ciclomática) y gates en CI que bloqueen merges hasta cumplir umbrales.

    Agentes revisando a agentes (primer filtro)

    Usa workflows (p. ej. n8n) para que un agente verificador haga la primera pasada: seguridad, duplicados, dependencias nuevas. Solo PRs filtradas llegan a humanos.

    Código como contrato: exige integraciones con Code Owners

    Que las áreas propietarias (backend, auth, shared-utils) deban aprobar cambios automáticos en su zona. No delegues ownership a un bot.

    Criterios claros para aprobar o rechazar (chequeo rápido)

    Aprueba manualmente si:

    • Prompt incluido y comprensible.
    • PR ≤ 400 líneas.
    • Tests cubren casos límite relevantes.
    • No introduce dependencias externas sin aprobación.
    • Integra con abstractions/shared modules existentes.

    Rechaza o solicita rework si:

    • No hay prompt o está incompleto.
    • Replica utilidades existentes.
    • Falla validadores automáticos de seguridad o complejidad.
    • No hay evidencia de decisión humana sobre trade-offs.

    Riesgos no técnicos que debes tener en cuenta

    Responsabilidad y ownership: una vulnerabilidad surgida de un output de IA que fue aprobada por cansancio recae en personas y procesos. Define legalmente quién firma cambios críticos.

    Formación del equipo: si los juniors solo “pegotean” código generado, la curva de aprendizaje se aplana. Plan de mentoría obligatorio: revisiones combinadas hombre-máquina para formación.

    Conclusión: el criterio gana peso

    Si 60% del código viene de agentes, tu ventaja competitiva no estará en cuánto puedes generar, sino en cuánto puedes coordinar, auditar y dar criterio sobre ese output. El trabajo humano deja de ser teclear y pasa a ser decidir.

    ¿Quieres dejar de sufrir LGTM y convertir a tus agentes en productores útiles en lugar de ruido? Empieza por exigir prompts en cada PR, probar todo y automatizar el primer filtro con agentes. Si lo haces, ganarás velocidad sin perder control.

    Apúntate a la newsletter de Dominicode para recibir plantillas de prompts, ejemplos de pipelines en n8n y una checklist lista para aplicar mañana.

    Dominicode Labs

    Si trabajas con automatización, IA aplicada, n8n, agentes o workflows, puedes encontrar recursos y ejemplos prácticos en Dominicode Labs. Es una continuación lógica para plantillas de prompts y pipelines aplicables de inmediato.

    FAQ

    Respuesta: Cada PR debe incluir el prompt completo, parámetros del agente (por ejemplo: temperature, model, herramientas usadas) y los snippets intermedios que el agente evaluó. Sin esto, la PR debe rechazarse.

    Respuesta: Aplica un límite duro: <400 líneas por PR. Si un agente genera más, fracciona en unidades pequeñas y revisables. Revisa unidades reusables, no borradores monolíticos.

    Respuesta: Nada debe pasar sin tests deterministas. Añade validadores automatizados (SAST, DAST, complejidad ciclomática) y gates en CI que bloqueen merges hasta cumplir umbrales.

    Respuesta: Usa workflows para que un agente verificador haga la primera pasada (seguridad, duplicados, dependencias). Ejemplo de herramienta citada: n8n. Solo las PRs filtradas llegan a revisión humana.

    Respuesta: La responsabilidad recae en personas y procesos si una vulnerabilidad aprobada por cansancio entra en producción. Define legalmente quién firma cambios críticos.

    Respuesta: Implementa un plan de mentoría obligatorio: revisiones combinadas hombre-máquina para asegurar que los juniors aprendan criterio, no solo a pegar código generado.

  • Cómo garantizar la confiabilidad del código generado por IA

    Cómo garantizar la confiabilidad del código generado por IA

    Vibe Coding: la trampa del 84%

    Tiempo estimado de lectura: 3 min

    Ideas clave

    • El 84% de desarrolladores usa IA a diario, pero solo el 29% confía en el código generado — la brecha es riesgo operativo.
    • Los LLMs generan código verosímil pero frágil: happy-paths, alucinaciones de API y antipatrones a escala.
    • Auditoría práctica: validar dependencias, exigir sad-paths desde el prompt, tests humanos para edge cases, auditar queries y requerir métricas.
    • Aplicar Zero Trust: checklist de confianza y CI que impida merges sin cobertura e instrumentación.

    Introducción

    Vibe Coding: la trampa del 84% no es un titular sensacionalista: es una advertencia práctica. El 84% de los desarrolladores usa IA diariamente, pero solo el 29% confía en el código que obtiene. Esa brecha no es una estadística; es un agujero por donde entra la deuda técnica, la fuga de datos y las regresiones en caliente. (Fuente: Stack Overflow Developer Survey 2024)

    Este artículo te da un marco operativo: cómo revisar, auditar y —sobre todo— confiar en código generado por modelos de lenguaje sin que la velocidad mate la fiabilidad.

    Resumen rápido (lectores con prisa)

    Los LLMs generan código verosímil pero no garantizan manejo de errores ni adaptación al dominio. Valida dependencias, exige sad-paths desde el prompt, escribe tests humanos para edge cases y exige métricas y trazas antes de mergear.

    Vibe Coding: la trampa del 84% — por qué sucede y qué rompe

    El problema no es que la IA escriba mala sintaxis. Es que escribe código verosímil. Y lo verosímil engaña al ojo. Un LLM predice tokens; no entiende tu dominio, tus SLAs ni tu topología de datos. Eso genera tres fallos constantes:

    • Happy-path en serie: el código funciona cuando todo va bien. No maneja latencias, timeouts o datos corruptos.
    • Alucinaciones de API: métodos que “suenan” correctos pero no existen en tu versión de la librería.
    • Antipatrones a escala: consultas N+1, bloqueos por locks mal usados, o rutas críticas sin instrumentación.

    Aceptar ese output sin auditoría es como aceptar un merge request sin tests: rápido, pero peligroso.

    Auditoría práctica: pasos que aplicas hoy mismo

    Cambia tu rol: con IA, no recibes código; recibes la propuesta de un “junior hiperproductivo”. Revíalo como tal.

    1) Valida dependencias antes de instalar

    • No copies imports sin comprobar. Busca la API en la documentación oficial.
    • Consulta npm para fecha de publicación y descargas.
    • Ejecuta npm audit tras añadir paquetes y antes de mergear. Herramienta: docs.npmjs.com/cli/v9/commands/npm-audit

    2) Obliga el Sad Path desde el prompt

    • No pidas solo “la función”. Pide manejo de fallos, retries y logging contextual.
    • Prompt débil: “Genera una función que llame a la API de pagos”
    • Prompt fuerte:
      "Genera una función que llame a la API de pagos. Incluye:
       - timeout y retry con backoff exponencial,
       - logging con requestId y contexto,
       - pruebas de unidad para timeouts y respuestas 5xx,
       - no devolver datos sensibles en la respuesta."

    3) Tests: el humano decide los edge cases

    • No dejes que la IA escriba tanto la función como los tests críticos.
    • Define tú los casos límite y las aserciones. La IA puede generar mocks y el setup repetitivo.
    • Cubre: inputs inválidos, latencias extremas, concurrencia (race conditions) y fallos de autenticación.

    4) Base de datos: audita las queries antes de producción

    • Habilita logging de queries en dev y revisa el número de hits por operación.
    • Verifica índices para columnas filtradas.
    • Comprueba serialización de objetos para no exponer campos sensibles.

    5) Métricas y observabilidad como contrato

    • Exige que cualquier cambio generado incluya: métricas (latencia, error rate), trazas correlacionadas y logs estructurados.
    • Si el PR no contiene instrumentación mínima, reviértelo.

    Checklist de confianza (Zero Trust aplicado)

    • [ ] Prompts que exigen Sad Path y límites de recursos.
    • [ ] Dependencias verificadas y npm audit limpio.
    • [ ] Tests escritos por humanos para edge cases críticos.
    • [ ] Logging y tracing incluidos en el cambio.
    • [ ] Revisión de queries e índices en DB.
    • [ ] Branch aislado y CI que rechaza merge sin cobertura mínima.

    Cuándo delegar y cuándo no

    Usa IA para acelerar tareas repetitivas y de bajo riesgo:

    • Boilerplate, DTOs, validaciones simples, plantillas de tests, conversiones de sintaxis.

    No delegues a la IA decisiones de criterio:

    • Modelado de dominio, reglas de autorización, diseño de esquemas, SLAs o decisiones que impacten seguridad y privacidad.

    Cierre directo

    La diferencia entre el 84% que usa IA y el 29% que confía en ella no es tecnología: es proceso y criterio. Si tu equipo aprende a auditar como si cada PR viniera de un “junior sin contexto”, reducirás fallos graves sin renunciar a la velocidad.

    La IA debe ahorrar tipeo; no debe asumir la responsabilidad arquitectónica. Haz que ese sea tu contrato interno hoy.

    Una continuación práctica y recursos relacionados están disponibles en Dominicode Labs, donde se publican frameworks y workflows para auditoría y observabilidad integrables en equipos que usan IA.

    FAQ

    ¿Por qué no confiar de entrada en código generado por IA?

    Porque los LLMs generan código verosímil sin comprender tu dominio, SLAs o topología de datos. Ese código puede funcionar en happy-paths pero fallar en latencia, datos corruptos o versiones de librerías.

    ¿Qué preguntas agregar al prompt para obtener código más fiable?

    Exige manejo de fallos, retries con backoff, timeouts, logging contextual (requestId), pruebas unitarias para errores 5xx y restricciones sobre datos sensibles.

    ¿Cómo validar dependencias antes de instalarlas?

    Comprueba la API en la documentación oficial, revisa fecha de publicación y descargas en npm y ejecuta npm audit tras añadir paquetes y antes de mergear.

    ¿Qué tests deben escribir los humanos?

    Los humanos deben definir y escribir tests para edge cases críticos: inputs inválidos, latencias extremas, condiciones de carrera y fallos de autenticación. La IA puede generar mocks y setups repetitivos.

    ¿Qué instrumentación mínima exigir en un PR?

    Métricas de latencia y tasa de error, trazas correlacionadas y logs estructurados. Si el PR no contiene instrumentación mínima, debería revertirse.

    ¿Cuándo es apropiado delegar tareas a la IA?

    Para tareas repetitivas y de bajo riesgo: boilerplate, DTOs, validaciones simples, plantillas de tests y conversiones de sintaxis. No para modelado de dominio, reglas de autorización, diseño de esquemas o decisiones que afecten seguridad y privacidad.

  • Cómo implementar un loop de agente efectivo para LLM en producción

    Cómo implementar un loop de agente efectivo para LLM en producción

    El loop de agente que sí funciona en producción

    Tiempo estimado de lectura: 5 min

    • Contrato y salida clara: fuerza una condición de salida semántica explícita (herramienta finalizar / AgentFinish con respuesta_final).
    • Validación antes de actuar: validar payloads con Pydantic y devolver errores estructurados como observaciones.
    • Errores como contexto: convertir fallos de herramientas en observaciones legibles (p. ej. ERROR_TOOL: nombre — detalle).
    • Límites y circuit breakers: limitar iteraciones con MAX_STEPS y cortar si el mismo error aparece repetidamente.

    ¿Quieres que tu agente deje de repetir el mismo error a las 3 a. m. y empiece a resolver problemas reales? El loop de agente que sí funciona en producción es exactamente eso: una celda de contención determinista alrededor de un motor estocástico.

    En las primeras líneas: El loop de agente que sí funciona en producción obliga al agente a operar con contratos claros (plan), validar antes de actuar (act), convertir fallos en contexto (observe) y respetar límites duros (reflect). Si no aplicas estas reglas, el agente acabará en bucles infinitos, consumiendo tokens y creando deuda técnica.

    Resumen rápido (lectores con prisa)

    Qué es: un patrón de control que encierra un LLM estocástico en un loop determinista con contratos claros y límites.

    Cuándo usarlo: flujos síncronos y de corta duración (consultas DB, enriquecimiento, generación de artefactos pequeños).

    Por qué importa: evita bucles infinitos, reduce deuda técnica y mejora la capacidad de recuperación ante errores de herramienta.

    Cómo funciona: usar una herramienta de cierre (finalizar), validar entradas con Pydantic, registrar errores como observaciones y aplicar límites de iteración.

    El loop de agente que sí funciona en producción: diseño y principios

    Los LLMs no tienen intención ni memoria fiable. Son modelos probabilísticos que requieren disciplina del lado del ingeniero. Esto significa aplicar cuatro reglas innegociables:

    1. Forzar una condición de salida semántica explícita

    Define la herramienta de cierre del flujo. Llama a la función finalizar o AgentFinish y exige que incluya respuesta_final. Ese es el interruptor lógico que separa “sigo pensando” de “he terminado”.

    2. Validar todos los argumentos antes de ejecutar herramientas

    Valida con Pydantic cada payload que el modelo devuelve. Si no pasa validación, no ejecutes nada: devuelve el error al agente como observación estructurada.

    3. Inyectar errores técnicos al historial como observaciones

    Si una herramienta falla (timeout, DB deadlock, error de tipo), captura la excepción y agrega al historial un mensaje tipo: “ERROR_TOOL: nombre — detalle”. No ocultes fallos: convertirlos en contexto mejora la capacidad del agente para corregir su siguiente plan.

    4. Imponer límites duros de iteración y circuit breakers semánticos

    Finalmente, limita las iteraciones con MAX_STEPS. Si el agente alcanza ese límite, devuelve un error controlado y registra el incidente. Implementa circuit breakers si el mismo error aparece repetidamente.

    Ejemplo práctico en Python

    Aquí tienes un esqueleto funcional, pensado para integrarse con cualquier cliente LLM que soporte tool-calling. Incluye validación Pydantic y la inyección de errores al historial.

    import json
    from pydantic import BaseModel, ValidationError
    
    MAX_STEPS = 5
    
    # Ejemplo de validator para una tool
    class CreateTicketArgs(BaseModel):
        title: str
        priority: str  # 'low'|'medium'|'high'
    
    # Simulación de herramientas
    def create_ticket(title: str, priority: str):
        # lógica real aquí (DB, API)
        return {"ticket_id": "TCK-123", "title": title, "priority": priority}
    
    TOOLS = {
        "create_ticket": (create_ticket, CreateTicketArgs),
        # "finalizar" no necesita validator complejo; solo espera respuesta_final
    }
    
    def run_agent(user_prompt: str, llm_client) -> str:
        messages = [
            {"role": "system", "content":
             "Eres un agente. Devuelve siempre JSON con 'tool_call' o 'final_text'. "
             "Usa la herramienta 'finalizar' con {'respuesta_final': '...'} para terminar."},
            {"role": "user", "content": user_prompt}
        ]
    
        seen_errors = {}
        for step in range(MAX_STEPS):
            response = llm_client.chat(messages=messages, tools=get_tool_schemas(TOOLS))
    
            # respuesta textual sin tool_call
            if response.finish_reason == "stop" and not response.tool_calls:
                return response.content
    
            for tc in response.tool_calls:
                name = tc.name
                args_raw = json.loads(tc.arguments)
    
                if name == "finalizar":
                    return args_raw.get("respuesta_final", "")
    
                tool_fn, validator = TOOLS[name]
    
                # VALIDACIÓN (Act)
                try:
                    args = validator(**args_raw)
                except ValidationError as ve:
                    observation = f"VALIDATION_ERROR: {ve.json()}"
                    messages.append({"role": "assistant", "content": response.content})
                    messages.append({"role": "tool", "tool_call_id": tc.id, "content": observation})
                    # registro para circuit breaker
                    seen_errors.setdefault(str(ve), 0)
                    seen_errors[str(ve)] += 1
                    if seen_errors[str(ve)] >= 2:
                        return f"Interrumpido: error recurrente de validación: {ve}"
                    continue
    
                # EJECUCIÓN segura (Observe)
                try:
                    result = tool_fn(**args.dict())
                    observation = f"RESULT: {json.dumps(result)}"
                except Exception as e:
                    observation = f"ERROR_TOOL: {name} — {str(e)}"
                    seen_errors.setdefault(str(e), 0)
                    seen_errors[str(e)] += 1
                    if seen_errors[str(e)] >= 2:
                        return f"Interrumpido: error recurrente en herramienta: {e}"
    
                messages.append({"role": "assistant", "content": response.content})
                messages.append({"role": "tool", "tool_call_id": tc.id, "content": observation})
    
        return "Error: el agente superó el límite de pasos permitidos."

    Operaciones que debes instrumentar desde el día uno

    • Logging estructurado por paso: step, tool, args, resultado, tokens consumidos.
    • Conteo de tokens del historial; si supera el 75–80% de la ventana del modelo, ejecuta resumen (ver técnicas de resumen).
    • Circuit breaker semántico: si el mismo error aparece dos veces, corta y alerta.
    • Métricas SLIs: tiempo por petición, reintentos por herramienta, tasa de finalización exitosa.

    Cuándo no usar este loop y optar por orquestación

    Usa este loop en procesos síncronos y de corta duración: consultas DB, enriquecimiento de datos, generación de artefactos pequeños. Si tu flujo dura horas/días, incluye pasos humanos o requiere durabilidad de estado, cambia a un orquestador (n8n, LangGraph) que persista estado y permita reprogramación.

    Cierre práctico

    El loop de agente que sí funciona en producción no es una trick de prompts: es ingeniería. Forzar salida semántica (finalizar), validar antes de actuar (Pydantic), convertir fallos en contexto y aplicar límites duros son las piezas que convierten un prototipo ruidoso en un agente fiable. Implementa esto, instrumenta y repite: la estabilidad viene de la disciplina, no de la magia.

    Para recursos experimentales y proyectos relacionados con automatización y agentes, considera explorar los trabajos y laboratorios prácticos en Dominicode Labs. Es una referencia contextual para implementar pipelines y pruebas prácticas en entornos de ingeniería.

    FAQ

    ¿Cuál es la función de la herramienta finalizar?

    Es el interruptor semántico que indica que el agente ha terminado su trabajo. Debe devolver un objeto que incluya respuesta_final, que el loop interpreta como salida definitiva.

    ¿Por qué usar Pydantic para validar payloads?

    Porque ofrece validación estructurada y errores claros. Validar evita ejecuciones inseguras y permite convertir fallos en observaciones reutilizables por el agente.

    ¿Qué hacer si una herramienta externa falla repetidamente?

    Registrar el fallo como ERROR_TOOL: nombre — detalle, aplicar un circuit breaker y, si el error se repite, interrumpir el loop con un error controlado para evitar consumo indefinido de recursos.

    ¿Cómo definir MAX_STEPS?

    Depende del dominio y del coste por iteración. Empieza con un valor conservador (p. ej. 5) y monitoriza reintentos y tiempo por petición para ajustarlo.

    ¿Cuándo prefiero un orquestador en lugar de este loop?

    Si el flujo requiere durabilidad, pasos humanos o puede durar horas/días, usa un orquestador como n8n o LangGraph para persistir estado y reintentar tareas.

    ¿Qué métricas debo recolectar desde el día uno?

    Tiempo por petición, reintentos por herramienta, tasa de finalización exitosa, conteo de tokens y registros estructurados por paso (tool, args, resultado).

  • Cómo mejorar la calidad del código con Spec-Driven Development

    Cómo mejorar la calidad del código con Spec-Driven Development

    Spec-Driven Development en la práctica: del prompt al código mantenible — Un walkthrough real mostrando cómo una buena spec cambia la calidad del output de Claude Code o Cursor. Caso antes/después

    Tiempo estimado de lectura: 6 min

    • Ideas clave:
    • Una spec técnica reduce la ambigüedad en prompts y convierte salidas generativas en contratos verificables.
    • Sin spec, los LLMs tienden a producir código rápido pero frágil y con deuda técnica.
    • Una spec mínima (stack, artefactos, contratos, edge cases) es suficiente para outputs reproducibles y testeables.
    • Integra specs en CI/PR para automatizar comprobaciones y mantener control humano sobre arquitectura.

    Spec-Driven Development en la práctica: del prompt al código mantenible — esto no es una etiqueta elegante. Es la diferencia entre código que sobrevive y código que tendrás que reescribir dentro de tres sprints. Si usas Claude Code, Cursor o cualquier herramienta generativa, sin una spec clara estás empujando decisiones arquitectónicas a un modelo estadístico.

    En estas primeras líneas: definimos el problema, mostramos un caso antes/después y entregamos una receta práctica para que tu equipo obtenga salidas reproducibles y revisables por humanos.

    Resumen rápido (lectores con prisa)

    Qué es: Una spec técnica es un documento corto que define stack, artefactos, contratos de datos y criterios de aceptación.

    Cuándo usarla: Antes de pedirle a un LLM que genere código o acciones automáticas; imprescindible para features que afectan arquitectura o seguridad.

    Por qué importa: Reduce ambigüedad, limita el espacio de decisión del modelo y convierte output en un contrato auditables y testeable.

    Cómo funciona: Provee stack y contratos (ej. Zod schemas, tipos TS, API contracts) que el agente implementa exactamente, produciendo artefactos modulares y testeables.

    Por qué una spec cambia todo

    Los LLMs son excelentes en patrones, no en contexto de producto. Cuando reciben un prompt abierto, generan la solución más probable según su entrenamiento: ejemplos de tutoriales y antipatrón comunes. Esa es la razón por la que el output suele ser rápido pero frágil.

    Una especificación técnica (spec) reduce el “espacio de probabilidad” del modelo. Le das:

    • el stack exacto,
    • las restricciones arquitectónicas,
    • los contratos de datos,
    • y los criterios de aceptación/edge cases.

    Con esa entrada, herramientas como Cursor o Claude dejan de improvisar y comienzan a implementar un contrato.

    Walkthrough real: formulario de registro en Next.js

    Escenario: crear un registro de usuario con validación Zod y Server Actions (Next.js App Router). Te muestro el antes y el después, sin adornos.

    Antes — Prompt conversacional (vibe coding)

    Prompt enviado al modelo:

    “Crea un formulario de registro en Next.js con email, password y confirmación. Conéctalo a la API.”

    Salida típica:

    • Un solo archivo RegisterForm.tsx con JSX, estado useState y fetch mezclados.
    • Validación DIY con regex.
    • Manejo de errores = console.log.
    • Tipos débiles (any o sin tipos).
    • No hay tests ni contractos reutilizables.

    Resultado: funciona en local. Falla en producción. Es deuda técnica con firma.

    Después — Prompt con spec (Spec-Driven Development)

    Antes de preguntar al modelo, escribes spec-auth-register.md y lo adjuntas.

    Fragmento de spec:

    # Spec: Registro de usuario
    Stack: Next.js App Router, React Hook Form, Zod
    Outputs: 3 archivos
      - src/lib/validations/auth.ts (registerSchema)
      - src/actions/auth.actions.ts (Server Action) -> devuelve { success: boolean; error?: string }
      - src/components/auth/RegisterForm.tsx
    UI: usar useTransition para isPending; mostrar errores por campo; redirigir a /dashboard en éxito.
    Edge cases: handling de timeouts, duplicados, validación server-side.
    

    Prompt al modelo:

    “Lee @spec-auth-register.md e implementa exactamente los archivos descritos, respetando tipos y contratos.”

    Salida típica con spec:

    • registerSchema en auth.ts (Zod) reutilizable en cliente y servidor.
    • Server Action tipada que devuelve { success, error }.
    • Componente de presentación que usa React Hook Form y solo hace binding.
    • Estados de UI y manejo de errores explícito.
    • Código modular, testeable y legible.

    La diferencia es clara: la spec obliga al modelo a ceñirse a un contrato verificable. Lo que se genera se puede code-reviewar, testear e integrar.

    Plantilla mínima de spec que funciona

    No necesitas escribir una novela. Esta plantilla (portable en .specs/feature.md) es suficiente:

    1. Contexto de negocio (1-2 líneas).
    2. Stack y restricciones (libraries permitidas/prohibidas).
    3. Artefactos esperados (files + path).
    4. Contratos de datos (TS interfaces o Zod schemas).
    5. Estados UI y criterios de aceptación.
    6. Edge cases y métricas de éxito.

    Incluye URLs útiles en la spec para librerías: Zod, OWASP para seguridad, documentación de Cursor si lo usas.

    Integración práctica en el flujo de trabajo

    • Guarda specs en .specs/ y referencia el archivo en el prompt (Cursor soporta @Files).
    • Automatiza comprobaciones básicas con linters/CI: que exista un schema Zod, que acciones devuelvan un tipo estándar, que tests unitarios pasen.
    • Añade una regla en code review: si el cambio viene de un agente, el PR debe acompañar la spec original y un ADR si la modificación afecta arquitectura.
    • No olvides observabilidad y testing: cada tool o action generada debe tener tests unitarios independientes del LLM.

    Conclusión: la IA ejecuta, el ingeniero decide

    Spec-Driven Development no elimina la IA; la pone en su lugar. En lugar de confiar en la creatividad del modelo, confías en el criterio técnico del equipo para dirigirlo. Los equipos que adoptan specs claras convierten a Claude Code y Cursor en herramientas productivas en lugar de fuentes de deuda técnica. Implementar specs no es una carga extra: es la inversión que transforma prototipos de IA en software mantenible y auditable.

    La siguiente pieza en esta serie mostrará ejemplos de specs reales y scripts de CI que validan la conformidad automática entre spec y código.

    Para continuidad con iniciativas de automatización y prácticas de ingeniería aplicadas a IA, revisa recursos adicionales y experimentos en Dominicode Labs. Estos materiales complementan la adopción de specs y proporcionan plantillas y scripts para integrar comprobaciones automatizadas en CI/PR.

    FAQ

     

    ¿Qué es una spec técnica y cuánto debe medir?

    Una spec técnica es un documento conciso que define contexto, stack, artefactos requeridos, contratos de datos y criterios de aceptación. Suele medir entre 1 y 2 páginas; la clave es ser suficiente para convertir decisiones arquitectónicas en reglas ejecutables.

     

    ¿Qué diferencia hay entre una spec y una historia de usuario?

    Una historia de usuario describe el problema de negocio y la necesidad. La spec técnica traduce esa necesidad en artefactos técnicos concretos (files, tipos, contratos, edge cases) que un agente o desarrollador implementará.

     

    ¿Qué herramientas debo pedir en la spec para validación de datos?

    Especifica la librería (por ejemplo, Zod), el archivo donde residirá el schema y el contrato de retorno esperado para server actions. Indica validación client/server y casos límite relevantes.

     

    ¿Cómo integro specs en CI?

    Automatiza comprobaciones que verifiquen la presencia de schemas Zod, la firma de acciones y tests unitarios mínimos. Añade una regla en PRs que requiera la spec original cuando cambios provengan de un agente.

     

    ¿Qué hacer si el LLM ignora la spec?

    Ajusta el prompt para referenciar explícitamente la spec (ej. @spec-auth-register.md), valida output contra tests automatizados y rechaza cambios que no cumplan contratos en CI. Mantén revisión humana obligatoria para PRs generados por agentes.

  • Construye un agente de IA en TypeScript: stack mínimo para 2026

    Construye un agente de IA en TypeScript: stack mínimo para 2026

    El stack mínimo para un agente de IA en TypeScript en 2026

    Tiempo estimado de lectura: 4 min

    Ideas clave

    • Anthropic SDK + Zod + tsx + dotenv es la combinación práctica para agentes en producción: observabilidad, tipado y control.
    • Zod como frontera: declara schemas de herramientas, valida args y convierte a JSON Schema para pasar al modelo.
    • Bucle explícito: orquesta tool-calls en un único proceso, limita iteraciones y registra cada uso.
    • No es minimalismo estético: es técnica operativa para que el equipo pueda depurar y reparar a cualquier hora.
    • Escala solo cuando métricas y requisitos lo exijan: añade memoria, orquestadores o trazas distribuidas según necesidad.

    Tabla de contenidos

    El stack mínimo propuesto es una combinación práctica y limitada de dependencias enfocadas a reducir superficie de fallo, mantener trazabilidad y controlar consumo de tokens: Anthropic SDK para el motor, Zod para contratos, tsx para ejecución TypeScript rápida y dotenv para gestionar secretos.

    Resumen rápido (lectores con prisa)

    Stack: Anthropic SDK + Zod + tsx + dotenv. Usa Zod para declarar y validar schemas de herramientas, convierte Zod a JSON Schema para pasárselo al modelo y orquesta tool-calls en un bucle explícito. Añade PostgreSQL+pgvector, orquestadores o trazas solo cuando lo exijan métricas y requisitos.

    tsx + dotenv — entorno y secretos

    tsx te permite ejecutar TypeScript directamente en Node sin compilar manualmente. En desarrollo y CI rápidos esto reduce ciclos de retroalimentación.

    dotenv mantiene las claves fuera del repo: ANTHROPIC_API_KEY, DATABASE_URL, etc. Ambos son higiene operativa, no glamour.

    Anthropic SDK — motor cognitivo directo

    Usa el SDK oficial: Anthropic SDK. Evita enrutadores genéricos que suavizan diferencias entre modelos y esconden comportamientos de tool-calling. Anthropic devuelve explícitamente cuándo el modelo quiere invocar una herramienta; tú ejecutas la función y devuelves el resultado, con control total del flujo.

    Zod — contrato entre texto probabilístico y tipos

    Zod es la frontera. Define los schemas de herramientas y valida los argumentos que el modelo genera. Convierte Zod a JSON Schema con zod-to-json-schema para declarar las herramientas al modelo. Resultado: menor tasa de alucinaciones en tool_use y errores tipo detectables y manejables.

    Por qué este stack vence en producción (ejemplos técnicos)

    1) Trazabilidad total

    Cuando el modelo pide usar una herramienta, el SDK devuelve nombre + args. Antes de ejecutar, haces schema.safeParse(args). Si falla, capturas el error, lo loggeas y agregas ese fallo al historial que reenvías al modelo. No hay retries automáticos “mágicos” que oculten la causa.

    2) Menor latencia y coste

    Un único proceso que orquesta tool-calls evita encadenados innecesarios. Si cada handoff fuera otra llamada LLM, multiplicas tokens y TTFT. Con un loop explícito controlas el número máximo de iteraciones y evitas bucles de cortesía.

    3) Menos superficie de bugs

    Las capas extra (framework + adaptadores) introducen incompatibilidades y reintentos implícitos. Tener cuatro dependencias estables reduce puntos de falla.

    El patrón de implementación: el loop explícito

    Escribes un bucle claro. Pseudodiagrama:

    1. Inicializar cliente Anthropic con la API key desde dotenv.
    2. Preparar mensajes (system + user + tool_history).
    3. Llamar a client.messages.create(…) con tool definitions derivadas de Zod.
    4. Si respuesta es texto → devolver.
    5. Si respuesta es tool_use → validar con Zod; si válido ejecutar función; añadir resultado al historial; repetir.

    Ese flujo se implementa en 30–80 líneas y es 100% controlable. No es necesario heredar de clases ni integrar callbacks crípticos.

    Validación práctica y contratos: ejemplo de herramientas

    Define una tool con Zod:

    - ticketId: z.string().regex(/^[A-Z]+-\d+$/)
    - includeComments: z.boolean().default(false)

    Convierte esto a JSON Schema y pásalo a Anthropic. Cuando el LLM devuelva args, safeParse te dice inmediatamente si se puede ejecutar. Si no, devuelves el error al modelo como contexto y le pides corrección. Ese patrón reduce las llamadas inválidas y mejora la seguridad.

    Qué no cubre este stack y cuándo añadir componentes

    • Memoria de largo plazo: integra PostgreSQL + pgvector si necesitas retrieval persistente.
    • Flujos empresariales largos (days/weeks): añade un orquestador (n8n o LangGraph) para persistencia de estado y control de aprobaciones humanas.
    • Observabilidad distribuida: añade OpenTelemetry o similar si tu cluster requiere trazas correlacionadas a escala.

    Empieza simple; añade estas piezas solo con datos que demuestren necesidad.

    Reglas operativas antes de desplegar

    • Nunca expongas una herramienta sin Zod schema.
    • Registra cada tool_use y su validación. Logs estructurados; no texto plano.
    • Limita iteraciones del loop por petición (por ejemplo, max 5 reintentos).
    • Implementa el patrón Result (ok/error) en todas las funciones ejecutadas por el agente.

    Conclusión práctica

    El stack mínimo para un agente de IA en TypeScript en 2026 devuelve poder al equipo de ingeniería: trazabilidad, tipos y control operativo. Para la mayoría de agentes productivos —consultas a APIs, limpieza de datos, consultas SQL parametrizadas— esta pila es suficiente y más fiable que una montaña de frameworks. Escala solo cuando las métricas (latencia, coste por token, fallos en producción) y los requisitos (memoria, durabilidad) lo exijan. Así evitas añadir complejidad por moda y mantienes un sistema que puedas entender, auditar y mejorar.

    Dominicode Labs

    Para quienes construyen agentes y workflows, una referencia útil y complementaria sobre prácticas operativas y plantillas de integración está disponible en Dominicode Labs. Considera consultarlo como continuación lógica al patrón de loop explícito y validación con Zod.

    FAQ

    ¿Por qué usar Anthropic SDK en vez de adaptadores genéricos?

    Porque el SDK oficial expone el comportamiento nativo del modelo (por ejemplo, tool_use) sin abstracciones que oculten diferencias entre modelos. Esto permite un control más preciso sobre cuándo y cómo ejecutar herramientas.

    ¿Cuál es el papel exacto de Zod en este stack?

    Zod define los schemas de las herramientas y valida los argumentos generados por el modelo. Convertir esos schemas a JSON Schema permite declararlos al modelo y reducir llamadas inválidas y alucinaciones en tool_use.

    ¿Necesito tsx en producción?

    tsx facilita ciclos de desarrollo y CI al evitar compilación manual. En producción puedes seguir usándolo o compilar, según tu pipeline; la recomendación es usarlo para reducir fricción durante desarrollo y pruebas.

    ¿Cómo reducir costes de tokens con este patrón?

    Orquesta tool-calls en un único proceso, limita iteraciones del loop y evita encadenar llamadas LLM por cada handoff. Controlar explícitamente el número de iteraciones reduce tokens enviados y latencia.

    ¿Cuándo añadir bases de datos y vectores (pgvector)?

    Añade PostgreSQL + pgvector cuando necesites retrieval persistente y la memoria a corto plazo del agente no sea suficiente para tus casos de uso.

    ¿Qué límites de seguridad operativa aplicar al expositor de herramientas?

    Nunca expongas una herramienta sin schema Zod, registra cada tool_use con logs estructurados, limita reintentos y aplica validaciones estrictas (Result ok/error) en todas las funciones ejecutadas por el agente.

  • Cómo medir el rendimiento de agentes de IA con evals efectivos

    Cómo medir el rendimiento de agentes de IA con evals efectivos

    Evals para código generado por IA — cómo medir si tu agente está mejorando o empeorando con tu spec

    Tiempo estimado de lectura: 6 min

    • Combina validación determinista y semántica: ambas dimensiones son necesarias para señales accionables.
    • Golden Dataset + rúbricas: versiona casos reales con criterios explícitos para comparar versiones del spec.
    • Two-speed pipeline: validación determinista en cada PR; juez LLM y revisiones completas en merges/release.
    • Métricas operativas clave: pass rate, semantic score, flakiness, coste por eval y regression rate.

    Si cambias una línea en tu CLAUDE.md o ajustas las instrucciones del sistema y luego aceptas código “porque se ve bien”, estás apostando a que la intuición compense la probabilidad. No lo hace. Necesitas implementar evals para código generado por IA — cómo medir si tu agente está mejorando o empeorando con tu spec para convertir esa intuición en métricas reproducibles.

    Este artículo explica qué medir, cómo construir un pipeline fiable, qué herramientas usar y las decisiones operativas que separan a los equipos que gestionan agentes con criterio de los que lo hacen por esperanza.

    Resumen rápido (lectores con prisa)

    Qué es: Un enfoque combinado de evals deterministas y semánticos para código generado por IA.

    Cuándo usarlo: Siempre que tu agente genere código que afecte producción o el diseño arquitectónico.

    Por qué importa: Transforma intuición en métricas reproducibles y reduce regresiones al cambiar el spec.

    Cómo funciona: Golden Dataset versionado + pipeline: determinista rápido en PRs, juez LLM y/o humanos en merges y releases.

    ¿Qué miden los evals para código generado por IA — cómo saber si tu agente mejora o empeora?

    Un eval profesional mide dos dimensiones complementarias:

    • 1. Validación determinista — ¿el output cumple reglas objetivas?
    • 2. Validación semántica — ¿el output cumple criterios arquitectónicos, de seguridad y estilo que sólo pueden evaluarse con criterio?

    Si sólo ejecutas una, te quedas cojo. Combínalas y obtendrás señales accionables.

    Validación determinista

    Objetivos claros y automatizables:

    • Síntaxis / AST: el código parsea sin errores.
    • Linter/style: ESLint/Prettier pasan según la configuración del repo.
    • Tests unitarios de integración en sandbox: el código generado se inyecta en un contenedor efímero y ejecuta Jest/Vitest/PyTest.
    • Reglas binarias del spec: por ejemplo, “no usar fetch en cliente” → comprobación estática.

    Resultado: métricas binarias y tasas de paso (pass rate) que puedes agregar y comparar entre versiones del spec.

    Validación semántica — LLM-as-a-Judge y estrategias híbridas

    Algunos criterios no son booleanos: diseño, seguridad implícita, uso idiomático. Aquí entra un juez LLM:

    • El juez recibe: el spec original, el código generado, y una rúbrica estructurada.
    • Produce: una puntuación y un reasoning structured (json) que explica fallos de arquitectura, riesgos de seguridad, o desviaciones de estilo.

    Precaución: existe sesgo de auto-preferencia. Mitigaciones prácticas:

    • Usar un modelo juez distinto y preferible más capaz (ej. GPT‑4o o Claude avanzado).
    • Ensembles: combinar juicios de 2–3 modelos y una muestra humana para calibrar.
    • Registrar justificaciones (no sólo la puntuación).

    Cómo construir un pipeline de Evals paso a paso

    1. Golden Dataset (20–50 casos reales)

    • Casos representativos del código y dominios del producto.
    • Cada caso: input, contexto (memory files relevantes), criterios de éxito explícitos.
    • Versionado en Git junto al spec.

    2. Frameworks y herramientas

    • Promptfoo — orquestación de evals en CLI.
    • LangSmith (observabilidad y tracing).
    • Braintrust (plataformas de evals y datasets).
    • Integrar linters, AST analyzers y runners de tests (Jest/Vitest/PyTest).

    3. Sandbox seguro para deterministas

    • Contenedores efímeros sin red ni credenciales, preferiblemente con políticas de seccomp/gVisor o Firecracker para microVMs.
    • Tiempo límite por test y quotas de CPU/RAM.

    4. LLM-as-a-Judge

    • Definir rúbricas concretas (JSON schema) por caso del Golden Dataset.
    • Ejecutar juez sólo en merges o nightly builds si el coste es alto; o en un flujo “two-speed” (ver abajo).

    5. Métricas y alertas

    • Pass rate determinista por caso y agregado.
    • Puntuación semántica media y desviación estándar.
    • Flakiness rate (casos con resultados inconsistentes entre corridas).
    • Cost per eval (tokens, wall time).
    • Guardrails: bloquear PRs si la adherencia agregada cae por debajo de un umbral (ej. 85–90%).

    6. Integración CI/CD

    • Disparar evals cuando cambie el spec (CLAUDE.md, AGENTS.md, memory files).
    • Pipeline típico: generar → determinista (rápido) → reporte → si pasa, opcional: juez LLM → aprobar o bloquear PR.

    Estrategia operativa: coste vs seguridad vs velocidad

    • Two-speed pipeline: Validación determinista ligera en cada PR; validación semántica completa en merges a main o releases. Reduce coste y mantiene seguridad.
    • Ensembles y muestreo: Si el coste de juez LLM es prohibitivo, ejecuta juez en una muestra estadística del Golden Dataset por cada cambio mayor.
    • Human-in-the-loop: para nuevas rules o casos edge, requiere revisión humana antes de aceptar un cambio en el spec.

    Métricas que realmente importan

    • Regression rate por cambio de spec (número de casos del Golden Dataset que empeoran).
    • Mean Semantic Score delta entre versiones del spec.
    • Time-to-fix promedio cuando un eval falla.
    • Token cost por ejecución y coste por PR.
    • Porcentaje de automatización (qué % de PRs infractions se bloquean automáticamente vs requieren intervención humana).

    Conclusión operativa

    Trata tu spec como código crítico: versiona, prueba y monitoriza. Implementar evals para código generado por IA transforma la gestión de agentes de una caja de sorpresas a un proceso auditable. Si quieres que el agente mejore con cambios en tu spec, mide, automatiza y obliga a retroalimentación continua. Sin datos no hay control; sin control, el agente termina rompiendo más de lo que arregla.

    Si trabajas con automatización, agentes o workflows y quieres ejemplos prácticos y experimentos reproducibles, revisa Dominicode Labs. Encontrarás recursos y prototipos alineados con pipelines de evals y prácticas de integración.

    FAQ

    Respuesta: Miden dos dimensiones complementarias: validación determinista (sintaxis, linters, tests, reglas binarias) y validación semántica (diseño, seguridad, estilo evaluados por un juez LLM o humanos).

    Respuesta: Es la comprobación automática y objetiva: el código parsea, pasa linters, ejecuta tests en sandbox y cumple reglas estáticas definidas en el spec.

    Respuesta: Reúne 20–50 casos reales representativos. Cada caso debe incluir input, contexto relevante y criterios de éxito explícitos; versiona el dataset en Git junto al spec.

    Respuesta: Ejecuta juez LLM en merges o nightly builds si el coste es alto, o en un flujo two-speed donde aplicas juez a cambios aprobados determinísticamente o a muestras estadísticamente relevantes.

    Respuesta: Pass rate determinista, mean semantic score, regression rate por cambio de spec, flakiness rate, token cost por ejecución y time-to-fix promedio.

    Respuesta: Usa una validación determinista ligera en cada PR y ejecuta validación semántica completa en merges/releases. Muestrea casos para reducir coste y aplica ensembles o revisión humana en casos críticos.

  • Implementación de Generics para Wrappers de IA en TypeScript

    Implementación de Generics para Wrappers de IA en TypeScript

    Generics para wrappers de IA en TypeScript

    Tiempo estimado de lectura: 4 min

    • Evita desincronización: usa un wrapper genérico withAI<T>() para enlazar firma TypeScript y validación Zod.
    • Zod‑first: Zod en runtime + z.infer en TypeScript ofrece validación práctica frente al type erasure.
    • Autodocumentación y registros: genera descripciones básicas y registra prompt, rawResponse y resultado de Zod.
    • Operación segura: define límites de reintentos y métricas; en sistemas críticos separa intención (LLM) de efecto (máquina de estado).

    Generics para wrappers de IA en TypeScript: si vas a exponer funciones de negocio a agentes, necesitas una forma segura y mantenible de hacerlo. En las primeras líneas: usar generics y Zod evita duplicar contratos y convierte la exposición de funciones en un proceso reproducible y tipado. Aquí explico por qué funciona, cómo implementarlo y qué decisiones arquitectónicas debes tomar.

    Resumen rápido (lectores con prisa)

    Patrón Zod‑first: pasa un esquema Zod al wrapper y usa z.infer<…> para que TypeScript infiera tipos. El wrapper genérico withAI<T> enlaza la firma de la función con el esquema, validando en runtime y detectando incompatibilidades en compilación.

    Úsalo cuando expongas funciones a LLMs o agentes; mejora seguridad estática, validación runtime y trazabilidad.

    Por qué necesitas Generics para wrappers de IA en TypeScript

    Exponer una función como herramienta para un LLM suele generar cuatro elementos repetitivos: descripción, esquema de validación, bindings del SDK y la ejecución. Ese boilerplate se desincroniza con el tiempo: la firma cambia, el esquema no, y el error aparece en producción, no en el IDE.

    La solución es un wrapper genérico —withAI<T>()— que capture la firma de la función mediante tipos TypeScript y reciba un esquema Zod en runtime. Zod vive en ejecución; TypeScript no. Esta combinación (TypeScript + Zod) te da lo mejor de ambos mundos: seguridad estática y validación runtime.

    Limitación real: type erasure y la decisión Zod‑first

    TypeScript suprime tipos en runtime (type erasure). No puedes inspeccionar en ejecución que un parámetro se llama userId y es string. Por eso hay dos rutas:

    • Extraer metadatos en build time (AST/JSDoc) — viable pero compleja.
    • Patrón Zod‑first — práctico y fiable: pasas un esquema Zod al wrapper, Zod valida en runtime y TypeScript infiere tipos con z.infer<…>.

    Recomiendo Zod‑first. Es simple, robusto y encaja con flujos CI/CD.

    Implementación: withAI<T> paso a paso

    Idea: recibir la función original, su esquema Zod y devolver una herramienta lista para el SDK de IA (p. ej. Vercel AI SDK https://sdk.vercel.ai/docs). El genérico obliga a coherencia entre firma y esquema.

    Ejemplo reducido

    import { z } from 'zod';
    import { tool } from 'ai'; // Vercel AI SDK
    
    export function withAI>(
      fn: T,
      schema: z.ZodType<Parameters<T>[0]>,
      description?: string
    ) {
      const autoDesc = description ?? generateDescription(fn.name, schema);
    
      return tool({
        description: autoDesc,
        parameters: schema,
        execute: async (args) => {
          // args ya validado por Zod cuando el SDK integra la validación
          return await fn(args as Parameters<T>[0]);
        },
      });
    }
    

    Claves:

    • Parameters<T>[0] enlaza el tipo esperado del primer argumento de fn con el esquema.
    • Si la firma de fn cambia y el esquema no, TypeScript marcará el error en compilación.
    • tool() es una abstracción; adapta al SDK que uses (Vercel, OpenAI, etc.).

    Autodocumentación práctica

    El wrapper puede generar una descripción básica a partir del nombre de la función y las claves del esquema. No es NLP mágico, pero reduce trabajo manual y mejora la señal hacia el modelo.

    function generateDescription(name: string, schema: z.ZodTypeAny) {
      const readable = name.replace(/([A-Z])/g, ' $1').trim().toLowerCase();
      const params = schema instanceof z.ZodObject ? Object.keys(schema.shape).join(', ') : 'input object';
      return `Use this tool to ${readable}. Parameters: ${params}.`;
    }
    

    Para funciones críticas, proporciona siempre una descripción manual y ejemplos de uso. Puedes enriquecer la doc con ejemplos JSON y constraints — los modelos modernos respetan instrucciones claras (ver Structured Outputs de OpenAI: https://platform.openai.com/docs/guides/structured-outputs).

    Buenas prácticas operativas

    • Valida con .safeParse() en agentes que puedan autocorregirse; usa .parse() para endpoints que deban fallar rápido.
    • Registra siempre: prompt, rawResponse, resultado de Zod (error.flatten()), la herramienta invocada y contexto. Sin esto, los postmortems son inútiles.
    • Mide: tasa de validación fallida, latencia de autocorrección, reintentos por prompt y degradaciones a humano.
    • Define límites: si tras N reintentos no hay corrección, encola para revisión humana. Evita loops que consuman tokens/requests.

    Trade‑offs y decisiones arquitectónicas

    • Autogeneración vs. precisión: la descripción automática agiliza pero no sustituye documentación humana para casos sensibles.
    • Structured Outputs + generateObject (OpenAI) reducen errores de formato, pero no reemplazan validaciones semánticas (p. ej. rangos, signos). Zod sigue siendo necesario.
    • En sistemas críticos, deja que el LLM decida la herramienta, pero que una máquina de estado (n8n, XState) controle la ejecución final; así separas intención y efecto.

    Ejemplo completo: patrón en producción

    1. Define la función pura:

    async function getOrder(args: { orderId: string }) { /* ... */ }

    2. Define esquema Zod:

    const OrderSchema = z.object({ orderId: z.string().uuid() });

    3. Envuelve:

    const getOrderTool = withAI(getOrder, OrderSchema, 'Obtiene estado de un pedido por ID');

    4. Registra y mide cada llamada. Si Zod falla, serializa error.flatten() y envíalo al LLM para autocorrección o al equipo de soporte.

    Conclusión

    Generics para wrappers de IA en TypeScript no es un truco académico: es una medida práctica para escalar agentes sin introducir deuda técnica. El patrón Zod‑first con withAI<T> convierte la exposición de funciones en una operación segura, rastreable y testeable. Si tu agente escribe en bases de datos, llama APIs facturadas o ejecuta efectos críticos, aplica este patrón hoy: te evitará errores que sólo descubres en producción.

    Para equipos que diseñan flujos de agentes y workflows relacionados con automatización e IA aplicada, puede ser útil revisar trabajos y herramientas experimentales. Más recursos y experimentos están disponibles en Dominicode Labs.

    FAQ

     

     

    ¿Qué es exactamente el patrón Zod‑first?

    Es la práctica de definir esquemas de validación con Zod en runtime y usar z.infer<…> para que TypeScript derive los tipos, evitando depender de metadatos de tipos en ejecución.

     

     

    ¿Cuándo debo usar safeParse() vs parse()?

    Usa safeParse() cuando el agente pueda autocorregirse o cuando quieras manejar errores sin lanzar. Usa parse() en endpoints que deban fallar rápido y propagar excepciones.

     

     

    ¿Cómo detecta TypeScript desalineaciones entre firma y esquema?

    El wrapper genérico usa tipos como Parameters<T>[0]. Si la firma de la función cambia y el esquema suministrado no coincide, TypeScript emitirá un error en compilación por incompatibilidad de tipos.

     

     

    ¿Qué hacer si Zod falla de forma recurrente?

    Registra el resultado de error.flatten(), envía el fallo al LLM para autocorrección o encola el caso para revisión humana si supera N reintentos. Mide la tasa de validación fallida para priorizar correcciones.

     

     

    ¿Puedo usar este patrón con otros SDKs además de Vercel?

    Sí. tool() en el ejemplo es una abstracción; adapta la forma de registrar parámetros, validar y ejecutar según el SDK (Vercel, OpenAI u otros).

     

     

    ¿Cómo debo registrar errores y métricas?

    Registra prompt, rawResponse, resultado de Zod (error.flatten()), herramienta invocada, contexto y métricas como latencia y reintentos. Estos datos son esenciales para postmortems y mejoras iterativas.

  • Cómo acelerar las entregas de los desarrolladores sénior sin comprometer calidad

    Cómo acelerar las entregas de los desarrolladores sénior sin comprometer calidad

    ¿Por qué los desarrolladores sénior siguen con las entregas lentas (y cómo evitarlo)?

    Tiempo estimado de lectura: 4 min

    • La experiencia introduce sesgos de anticipación: sénior suelen prever fallos y eso añade tiempo (sobreingeniería, refactorización y parálisis por análisis).
    • La solución son procesos y límites: ADRs, timebox, DoD estricta, backlogs separados y automatización reducen la fricción.
    • Automatización y métricas hacen que la rapidez sea sostenible: linters, CI, IA en la primera revisión, PR size y SLAs concretos aceleran sin sacrificar calidad.
    • Cultura y liderazgo determinan la efectividad: valorar decisiones rápidas y reversibles y responsabilizar al equipo sobre la deuda técnica convierte criterio en velocidad.

    ¿Por qué los desarrolladores sénior siguen con las entregas lentas (y cómo evitarlo)? La pregunta duele en equipos que necesitan velocidad sin sacrificar calidad. La respuesta no es moralizante: no es pereza ni incompetencia. Es la suma de experiencia, riesgo y estructuras de trabajo que no alinean incentivos. Si quieres acelerar sin quemar a tu gente ni a tu producto, esto es lo que realmente pasa —y qué hacer al respecto.

    Resumen rápido (lectores con prisa)

    ADRs (Architecture Decision Records): documento para registrar decisiones de arquitectura con fecha y contexto. Útil cuando la decisión puede revertirse o necesitar revisión.

    YAGNI: principio que evita construir soluciones para escenarios hipotéticos; aplicar en MVPs y experimentos.

    Timebox: límite temporal corto (48–72 horas) para decidir; si no hay consenso, define un decisor y registra la decisión en un ADR.

    Automatización + métricas: linters, CI, IA en revisiones iniciales, PR size y SLAs para convertir criterio en velocidad mantenible.

    Patrones que explican la lentitud

    1) Sobreingeniería: el futuro que nadie pidió

    Problema: un sénior tiende a diseñar soluciones que cubran escenarios hipotéticos —microservicios, abstracciones genéricas, event sourcing— para necesidades que hoy son triviales. Violación clásica de YAGNI (Martin Fowler).

    Qué hacer:

    • Define guardrails de arquitectura por contexto (MVP vs core). Un diagrama simple que diga “MVP = soluciones directas” evita debates infinitos.
    • Usa ADRs (Architecture Decision Records) para decisiones importantes y ponles plazo. Recurso.
    • Prioriza experimentos pequeños y medibles antes de diseñar grandes infraestructuras.

    Resultado esperado: menos tiempo invertido en abstracciones sin validación y más entregas que generan aprendizaje real.

    2) Refactorización expansiva: el “ya que estoy aquí”

    Problema: entrar a cambiar una línea y salir con cinco módulos reescritos. La intención es buena, pero el coste de oportunidad es alto.

    Qué hacer:

    • Separa deuda técnica del desarrollo funcional. Crea un backlog de deuda con criterios claros de prioridad y presupuestos de tiempo.
    • Impon una DoD (Definition of Done) estricta por ticket: lo que no está en la DoD no se toca.
    • Introduce reglas de “pequeñas mejoras” (máx. X archivos o Y líneas por PR) o tickets explícitos para refactors grandes.

    Resultado esperado: PRs más pequeñas, revisiones más rápidas y menos regresiones por cambios colaterales.

    3) Parálisis por análisis: debatir hasta el infinito

    Problema: múltiples opciones válidas y ninguna decisión. El coste: semanas de indecisión.

    Qué hacer:

    • Timebox: 48–72 horas para llegar a una decisión técnica informada. Si no hay consenso, define un decisor (Tech Lead o rota).
    • Documenta la decisión en un ADR y planifica re-evaluación tras N sprints.
    • Fomenta prototipos rápidos (spikes) con criterios claros de éxito para reducir la ambigüedad.

    Resultado esperado: decisiones más rápidas, mejores retrospectivas y menos “design by committee”.

    Tácticas operativas que sí funcionan

    Estas prácticas convierten criterio técnico en velocidad real sin sacrificar calidad.

    • Automatiza la fricción: linters, formatos automáticos y análisis estático en CI. Que la máquina rechace fallos triviales.
    • Primer revisión automatizada con IA: un agente (bien entrenado y con límites) puede hacer la primera pasada de code review para detectar complejidad innecesaria. Orquestación de flujos con herramientas como n8n facilita integrarlo en pipelines.
    • Métricas visibles: PR size, lead time, cycle time y tasa de rework (DORA metrics). Google DevOps tiene material útil.
    • Límites de PR y SLA de revisión: por ejemplo, PRs < 400 líneas y revisión en 24–48 horas. Esto fuerza pequeños incrementos.
    • Feature flags y despliegues canary: permiten entregar rápido sin riesgos mayores.
    • Pares en diseño crítico: pairing para decisiones de alto impacto reduce la necesidad de amplias revisiones posteriores.

    Cultura y liderazgo: la palanca que manda

    La técnica sola no basta. Cambiar la forma en que los sénior usan su criterio exige liderazgo que:

    • Valore decisiones rápidas y reversibles.
    • Recompense reducir el tiempo hasta el feedback real del cliente.
    • Promueva responsabilidad compartida sobre la deuda técnica (no que un solo “ángel” la arregle).

    Un buen indicador es si el equipo prioriza entregar aprendizaje al usuario sobre pulir arquitectura invisible.

    Conclusión práctica

    Los desarrolladores sénior no son el problema; son una solución mal encuadrada. Convertir su criterio en velocidad exige:

    • Reglas claras (DoD, backlogs separados).
    • Procesos que forcen decisiones (ADRs + timebox).
    • Automatización para reducir trabajo manual (linters, IA en CI, n8n).
    • Métricas y límites operativos (PR size, SLAs).

    No pidas a los sénior que “vayan más rápido”. Diseña el contexto donde su experiencia se traduce en decisiones efectivas y entregas constantes. Eso sí acelera —y a la larga, es lo que mantiene el código vivo sin quemar al equipo.

    FAQ

     

    ¿Qué es un ADR y para qué sirve?

    Un ADR (Architecture Decision Record) es un documento que registra una decisión arquitectónica, su contexto y sus consecuencias. Sirve para dejar rastro, facilitar re-evaluaciones y evitar repetir debates históricos.

    ¿Cómo evitar la sobreingeniería en un equipo sénior?

    Define guardrails claros (MVP vs core), aplica YAGNI en el contexto del producto y usa ADRs con fecha límite. Prioriza experimentos pequeños y medibles antes de invertir en infraestructuras grandes.

    ¿Qué límites prácticos poner en los PRs?

    Ejemplos prácticos: PRs < 400 líneas, límite de X archivos o Y funciones para pequeñas mejoras, y tickets dedicados para refactors mayores. Acompáñalo con SLA de revisión (24–48 horas).

    ¿Cuándo usar timebox para decisiones técnicas?

    Usa timebox (48–72 horas) cuando hay múltiples opciones válidas y la decisión bloquea progreso. Si no hay consenso, designa un decisor y registra la decisión en un ADR para re-evaluación posterior.

    ¿Qué métricas son útiles para medir velocidad sin sacrificar calidad?

    Métricas útiles incluyen PR size, lead time, cycle time y tasa de rework. Estas, combinadas con controles automáticos en CI, permiten actuar sobre cuellos de botella sin comprometer calidad.

    ¿Cómo integrar IA en la revisión de código sin depender exclusivamente de ella?

    Usa IA para la primera pasada: detectar complejidad innecesaria, problemas de estilo y patrones riesgosos. Mantén revisión humana para decisiones arquitectónicas y contextuales, y establece límites claros al alcance del agente.

  • Cómo Spec-First Optimiza el Desarrollo de Software con IA

    Cómo Spec-First Optimiza el Desarrollo de Software con IA

    Por qué Spec-First cambió mi forma de programar con IA (y por qué debería cambiar la tuya)

    Tiempo estimado de lectura: 4 min

    • Spec-First reduce suposiciones del modelo al definir contratos antes de pedir implementación.
    • Escribir tipos y casos de error toma minutos; arreglar código generado con suposiciones incorrectas puede costar días.
    • Combinar Spec-First con TDD convierte especificaciones en tests ejecutables y acelera desarrollo mantenible.
    • Aplica Spec-First en sistemas críticos, APIs públicas y módulos que deben escalar; evita para prototipos one-off.

    Por qué Spec-First cambió mi forma de programar con IA (y por qué debería cambiar la tuya). Poca gente habla de esto después del entusiasmo inicial. Descubrí algo curioso: no era la IA la que fallaba, era el orden de mis decisiones.

    La primera vez que pides código a un asistente te sientes en una peli de ciencia ficción. La décima vez estás peleando con alucinaciones, nombres mal elegidos y lógica que solo funciona en el mundo ideal del modelo. Spec-First rompió esa dinámica.

    Resumen rápido (lectores con prisa)

    Spec-First: escribe el contrato (tipos, entradas/salidas, casos límite) antes de pedir implementación. Reduce suposiciones del modelo y convierte especificaciones en tests ejecutables. Útil para código mantenible y APIs, menos para prototipos one-off.

    El coste real del Prompt-Driven Development

    El flujo habitual es: pides, pegas, arreglas. Repetir. Para prototipos funciona. Para software que vive y crece, no.

    • El modelo no conoce tu arquitectura.
    • No sabe tus convenciones ni decisiones pasadas.
    • No respeta tus límites de efectos secundarios ni tus políticas de error.

    Resultado: módulos que compilan pero no encajan. Bugs lógicos distribuidos. Revisiones interminables.

    Spec-First no te da respuesta mágica. Te devuelve tiempo y predictibilidad.

    Qué debe contener una spec si vas a usar IA

    No necesitas un documento de 30 páginas. Necesitas lo mínimo imprescindible para quitarle decisiones al modelo:

    Tipos e interfaces

    define entradas y salidas antes de pedir lógica.

    interface CreateUser { email: string; name?: string }
    type Result<T> = { ok: true; value: T } | { ok: false; error: string }

    Casos límite

    nulos, dominios bloqueados, fallos de red, retries, timeouts.

    Comportamiento determinista

    funciones puras, sin efectos laterales, o explícitamente con side effects autorizados.

    Restricciones de integración

    versiones de librería, patrones prohibidos, dónde puede tocar la base de datos.

    Escribir esto toma minutos. Arreglar un desastre generado por IA puede costarte días.

    Spec-First + TDD = velocidad real

    Si ya definiste tipos y casos de error, pedirle al modelo que genere tests primero es natural. Los tests pasan a ser la especificación ejecutable.

    Flujo práctico:

    • 1) Escribe tipos y contratos.
    • 2) Genera tests unitarios con la IA.
    • 3) Pide la implementación hasta que los tests pasen.

    La diferencia: pasas menos tiempo adivinando por qué algo falla y más en ajustar diseño.

    Ejemplo rápido (mental, no código largo)

    En vez de: “Crea función que valide emails”, di:

    “Función pura que recibe string, valida email corporativo (rechaza gmail.com, hotmail.com), retorna Result<Email, ValidationError>, cero excepciones, sin llamadas externas.”

    Esa frase evita que el modelo haga lo que le da la gana y te devuelve algo integrable.

    Cuándo aplicar Spec-First (y cuándo no)

    No es una religión. Úsalo cuando importe la mantenibilidad y la integración:

    • Sistemas críticos, core domain, APIs públicas.
    • Equipos distribuidos con contratos firmes.
    • Proyectos que deben escalar o durar.

    No lo emplees para scripts one-off o prototipos exploratorios donde la velocidad de concepto importa más que la calidad.

    Cambia tu rol profesional: de mecanógrafo a director de orquesta

    La IA está comoditizando la escritura de código. El valor real se desplaza hacia quien define qué construir y por qué. Spec-First es el instrumento para ejercer ese criterio sin perder velocidad.

    Tú no vas a competir con la IA en velocidad de tecleo. Vas a competir en claridad de intención, disciplina arquitectónica y capacidad de traducir requisitos imprecisos en contratos firmes.

    Cómo empezar hoy (3 pasos prácticos)

    1. Antes de pedir código, escribe los tipos. Solo eso.
    2. Genera tests unitarios desde esa spec.
    3. Pide la implementación, haz que los tests pasen.

    Hazlo en el siguiente ticket que abras. No hace falta cambiar todo tu flujo; prueba en un módulo nuevo y compara el resultado.

    Haz esto ahora: la próxima vez que pidas una función al asistente, detente 30 segundos y define solo los tipos. Luego vuelve y genera los tests. Verás la diferencia.

    Esto no acaba aquí: si quieres, puedo convertir tu próxima descripción vaga en una spec lista para usar con cualquier LLM.

    Este artículo trata sobre IA aplicada y flujos de trabajo con modelos, por lo que puede interesarte explorar recursos prácticos y experimentos en Dominicode Labs. Es un complemento natural para probar especificaciones y pipelines de tests en prototipos controlados.

    FAQ

     

     

    ¿Qué es Spec-First?

    Es una práctica que prioriza escribir contratos (tipos, entradas/salidas, casos límite) antes de solicitar la implementación a un asistente IA o a un desarrollador.

     

    ¿Cuándo debo usar Spec-First?

    Cuando la mantenibilidad, integraciones o el dominio crítico importen: APIs públicas, core domain y equipos distribuidos. No es necesario para scripts one-off o experimentos rápidos.

     

    ¿Spec-First reemplaza al TDD?

    No lo reemplaza; se complementan. Spec-First define contratos y TDD convierte esos contratos en tests ejecutables que guían la implementación.

     

    ¿Cuánto tiempo toma crear una spec básica?

    En muchos casos, minutos. Definir tipos y casos límite mínimos suele ser suficiente para reducir suposiciones del modelo y evitar reescrituras costosas.

     

    ¿Es útil para prototipos rápidos?

    No siempre. Para prototipos donde la velocidad de concepto importa más que la calidad, puedes omitirlo. Para piezas que deban mantenerse o integrarse, sí.

     

    ¿Qué incluye una spec mínima?

    Los tipos e interfaces de entradas/salidas, casos límite (nulos, dominios bloqueados, fallos de red), comportamiento determinista (funciones puras o efectos explícitos) y restricciones de integración (versiones, patrones prohibidos).