Category: AI

  • Cómo evitar que los agentes elijan mal sus herramientas en proyectos de IA

    Cómo evitar que los agentes elijan mal sus herramientas en proyectos de IA

    El problema real del tool_use: cuándo los agentes eligen mal sus herramientas

    Tiempo estimado de lectura: 4 min

    • Diseña cada tool como un contrato: propósito claro, condición binaria de activación, restricciones negadas y un schema de salida.
    • Reduce la superficie de decisión: retrieval dinámico y máquinas de estado cuando el catálogo supera ~10–15 tools.
    • Valida estrictamente: enums, formatos concretos y validación back-end (ej. Zod) para evitar argumentos corruptos.
    • Mide lo que importa: precisión de selección, retries, tokens gastados y casos de misuse en staging.

    Si tu agente tiene acceso a muchas herramientas y no defines reglas explícitas, no estás ante un fallo del modelo: estás ante un diseño roto. Este artículo explica por qué ocurren elecciones equivocadas y cómo diseñar descripciones de herramientas que reducen errores de selección hasta en ~80% en implementaciones reales. Conectar APIs es trivial; conseguir que un LLM seleccione la herramienta correcta, con argumentos válidos y sin invocar capacidades fuera de scope, es ingeniería.

    Resumen rápido (lectores con prisa)

    Define cada herramienta como un contrato: una frase de propósito, una condición de activación binaria, restricciones explícitas de uso y un schema de salida mínimo. Usa retrieval dinámico para reducir opciones y máquinas de estado para limitar permisos. Valida en back-end (ej. Zod) y mide precisión de selección y retries.

    El problema real del tool_use: cuándo los agentes eligen mal sus herramientas — causas

    Tres causas estructurales explican la mayoría de las fallas en producción:

    1. Solapamiento semántico. Dos o más tools parecen válidas para la misma intención; el modelo elige por probabilidades.
    2. Ausencia de fronteras negativas. Documentas qué hace la tool pero no cuándo está prohibida; el modelo probará usos peligrosos.
    3. Sobrecarga del contexto. Inyectar 30–40 esquemas en el prompt produce “lost in the middle” y pérdida de atención (ver estudio).

    Si no mitigues estas tres fuentes de ambigüedad, el agente duplicará llamadas, generará argumentos corruptos o intentará acciones destructivas.

    Cómo diseñar descripciones que reducen errores de selección (estructura de 4 campos)

    Piensa la descripción de cada herramienta como un contrato para una red neuronal: precisa, restrictiva y ejecutable. Sigue estos cuatro campos en todas las tools:

    1. Propósito (What) — Una sola frase: acción exacta.
    2. Condición de activación (When) — “Úsalo SOLO cuando…” (condición binary o claramente verificable).
    3. Restricción excluyente (When NOT) — “NO lo uses para…” y alternativa sugerida.
    4. Formato de salida (Expected Output) — JSON schema mínimo que el agente puede comprobar antes de llamar.

    Ejemplo práctico

    Descripción:

    “Recupera el estado y el último comentario de un ticket de Jira. Úsalo SOLO con un ticket ID válido (PROJ-123). NO lo uses para búsquedas por texto; usa search_jira_tickets para eso.”

    Schema (JSON / Zod-like)

    {
    “type”: “object”,
    “properties”: {
    “ticketId”: { “type”: “string”, “pattern”: “^[A-Z]+-\\d+$” }
    },
    “required”: [“ticketId”]
    }

    Ese nivel de precisión elimina ambigüedad en cuándo y cómo llamar la tool.

    Schemas como enrutadores: reglas prácticas

    • Evita tipos genéricos. Si esperas fecha, exige format: “date-time”.
    • Describe cada propiedad. El LLM usará esa descripción para construir el valor.
    • Forza enums para valores discretos. Los LLM respetan enums con alta consistencia.
    • Implementa validación estricta (Zod) en el back-end y devuelve errores estructurados (Result pattern) si el LLM envía datos inválidos.

    Arquitectura para catálogos grandes: Dynamic Tool Retrieval y State Machines

    Cuando tienes >10–15 tools, las descripciones no bastan. Aplica dos patrones:

    • Dynamic Tool Retrieval (RAG de herramientas). Embeddiza la intención del usuario y busca en una DB vectorial las 3–4 tools más relevantes; solo esas se inyectan en el prompt. Implementaciones prácticas usan pgvector o sistemas vectoriales gestionados. Reducir la superficie de decisión aumenta la precisión drásticamente.
    • Máquinas de estado / orquestación. Divide responsabilidades entre sub-agentes con permisos limitados. Herramientas de orquestación: n8n, LangGraph o XState. El nodo de “consulta” solo expone tools de lectura; el nodo de “modificación” habilita herramientas de escritura tras condiciones de validación.

    Restricción por estado = seguridad + predictibilidad.

    Métricas y pruebas que importan

    No te fíes de sensaciones. Mide:

    • Precisión de selección (tool chosen vs. tool expected).
    • Retries por tipo de error.
    • Tokens gastados en reintentos inútiles.
    • Casos de “tool misuse” detectados en staging.

    Introduce tests que simulen entradas ambiguas y fallos de herramientas. Si una nueva tool aumenta la entropía del sistema, el pipeline debe bloquear el cambio hasta ajustar descripciones/schemas o introducir retrieval/state gating.

    Conclusión operativa

    El problema real del tool_use no se arregla con prompts más largos ni con nombres más creativos. Se arregla con contratos: descripciones inmutables que indiquen qué hacer y qué no hacer; schemas que validen argumentos; retrieval que reduzca la superficie de decisión; y orquestación que limite permisos por estado. En la práctica, aplicar esta disciplina reduce los errores de selección de herramientas en la mayoría de despliegues (hasta ~80% en nuestras pruebas) y convierte agentes ruidosos en sistemas previsibles y auditablemente seguros.

    Si vas a exponer nuevas herramientas a un agente, no te preguntes si el LLM “entenderá”. Pregunta primero: ¿puede automatizarse la verificación de la condición de activación y la restricción excluyente? Si la respuesta es no, no la expongas todavía. Limita opciones, mejora instrucciones y mejora tus probabilidades de tener un agente que elige bien.

    Para experimentos, plantillas y recursos relacionados con agentes y workflows, revisa Dominicode Labs. Es una extensión natural de las prácticas descritas aquí, con ejemplos aplicables a despliegues reales.

    FAQ

    ¿Por qué el LLM elige la herramienta equivocada?

    Porque hay ambigüedad: solapamiento semántico entre tools, falta de fronteras negativas o sobrecarga del contexto. Si no se reducen estas fuentes, el modelo elige por probabilidades y puede fallar.

    ¿Qué debe contener una descripción de tool?

    Cuatro campos: Propósito (una frase), Condición de activación (¿cuándo usarla? — binaria), Restricción excluyente (¿cuándo NO usarla? con alternativa) y Formato de salida (schema mínimo verificable).

    ¿Qué es Dynamic Tool Retrieval y cuándo usarlo?

    Es el patrón de embeddizar la intención y recuperar las N tools más relevantes desde una DB vectorial (RAG de herramientas). Úsalo cuando tengas más de ~10–15 tools para reducir la superficie de decisión.

    ¿Cómo aplicar validación estricta en producción?

    Define schemas concretos (fechas con format, enums, patterns), valida en back-end (ej. Zod) y devuelve errores estructurados. Bloquea ejecuciones si la validación falla.

    ¿Qué métricas debo medir primero?

    Precisión de selección (tool chosen vs. expected), retries por tipo de error y tokens gastados en reintentos. También monitorea casos de tool misuse en staging.

    ¿Cuándo no exponer una nueva tool al agente?

    Si no puedes automatizar la verificación de la condición de activación y de la restricción excluyente, no la expongas. Mejor ajusta instrucciones, schemas o añade gating por retrieval/state antes de desplegar.

  • Qué es un Agentic Engineer y cómo convertirte en uno en 2026

    Qué es un Agentic Engineer y cómo convertirte en uno en 2026

    El año pasado hablé con un developer que llevaba tres meses usando Claude como copiloto. Me dijo: “Bezael, soy un 30% más rápido. Pero sigo sin entender lo que ocurre debajo.”

    Tres meses. Treinta por ciento más de velocidad. Y la sensación de que le faltaba algo.

    Le faltaba exactamente esto: pasar de usar agentes de IA a diseñarlos. De consumir herramientas a entender qué las hace funcionar en producción, dónde fallan, cómo orquestarlas para que resuelvan problemas complejos sin supervisión constante.

    Eso es agentic engineering — y en 2026 se está convirtiendo en la disciplina más relevante para cualquier developer que construya con IA.

    Qué es exactamente el agentic engineering

    El agentic engineering es la ingeniería de software especializada en diseñar, construir y operar sistemas de agentes de IA que trabajan de forma autónoma para completar objetivos.

    No es usar ChatGPT para escribir código más rápido. No es añadir un botón de “generar con IA” a tu app. Es una disciplina de arquitectura de sistemas con sus propios patrones, sus propias decisiones de diseño y sus propios problemas de producción.

    La diferencia práctica: un developer que usa IA como copiloto recibe sugerencias y decide qué aceptar. Un agentic engineer diseña el sistema donde la IA toma decisiones, ejecuta acciones y se corrige a sí misma — y lo hace de forma predecible, trazable y fiable.

    Esa es la distancia. No es trivial.

    Por qué importa ahora y no en dos años

    Hasta 2024, los agentes eran demos. Impresionantes en vídeo, rotos en producción. El modelo se confundía, las herramientas fallaban, el contexto se perdía a las diez iteraciones.

    En 2025 cambió algo fundamental: los modelos de frontera dieron un salto cualitativo en razonamiento. Claude Sonnet 4 (Anthropic, 2025), GPT-4o y Gemini 2.5 Pro pueden mantener objetivos complejos durante decenas de ciclos de herramienta sin perder el hilo — algo que sus predecesores de 2023 no podían hacer de forma fiable.

    Eso abrió una ventana que no va a durar indefinidamente: los developers que entiendan cómo orquestar estos sistemas tienen una ventaja real ahora, antes de que esto se empaquete en herramientas de no-code para cualquiera.

    La demanda ya está llegando. Las empresas no buscan developers que sepan usar IA como asistente. Buscan developers que sepan construir sistemas donde la IA hace trabajo autónomo de verdad — revisión de código, análisis de datos, procesamiento de documentos, automatización de pipelines enteros.

    El mercado se está moviendo. La pregunta es si tú te mueves con él o lo observas desde fuera.

    La diferencia real con vibe coding (y por qué importa)

    Hay que nombrarlo porque está en todas partes: el vibe coding — dejar que el modelo genere código mientras tú aceptas todo sin entender qué hace.

    No es necesariamente malo para prototipar. Pero confundir vibe coding con agentic engineering es uno de los errores más caros que puedo ver en un developer que quiere construir cosas serias.

    El vibe coding asume que el modelo siempre sabe lo que hace. El agentic engineering parte de la premisa contraria: el modelo es poderoso pero falible, y tu trabajo como ingeniero es diseñar el sistema que lo hace fiable.

    La diferencia concreta:

    Vibe coding Agentic Engineering
    Acepta la sugerencia del modelo Diseña el sistema que valida la salida del modelo
    Trabaja con prompts sueltos Trabaja con pipelines de contexto, memoria y herramientas
    No entiende por qué funciona Entiende el agentic loop y puede depurarlo
    Falla en producción sin saber por qué Instrumenta observabilidad para ver qué hace el agente
    Escala hasta el primer bug complejo Escala porque el sistema tiene controles de calidad

    El vibe coding te da velocidad al principio. El agentic engineering te da sistemas que funcionan en producción durante meses, sin que tengas que apagar el servidor a las 2 de la mañana porque el agente tomó una decisión que no deberías haberle permitido.

    Qué sabe hacer un Agentic Engineer

    Esto no es una lista de tecnologías. Es un mapa de competencias — cada una representa una decisión de diseño real que separa un sistema de agentes que funciona de uno que falla.

    Habilidades técnicas core

    Habilidad Por qué importa en producción
    Diseño de flujos multi-agente Saber cuándo descomponer en subagentes y cuándo no — la descomposición innecesaria multiplica los puntos de fallo
    Gestión de contexto y memoria El contexto mal diseñado es la causa número uno de degradación en agentes de larga ejecución
    Tool design y herramientas seguras Las herramientas mal diseñadas son el vector de ataque más común en sistemas agénticos
    Orquestación y handoffs Cómo un agente pasa trabajo a otro sin perder información crítica en la transferencia
    Observabilidad y trazabilidad Sin trazas, depurar un agente en producción es imposible — solo ves inputs y outputs, no el razonamiento
    Límites y control humano Definir qué acciones requieren confirmación y cuáles pueden ser autónomas — no todo el tiempo, no nunca
    Evaluación de agentes Cómo medir si el agente está haciendo bien su trabajo, más allá de “parece correcto”

    Habilidades de sistema

    Un agentic engineer también tiene que pensar en capas más amplias:

    • Arquitectura de prompts de sistema — no es escribir un prompt, es diseñar las instrucciones que gobiernan el comportamiento del agente en todos los escenarios posibles
    • Gestión de errores en pipelines asíncronos — los fallos en sistemas multi-agente no se propagan como en código síncrono normal
    • Estrategias de retry y fallback — qué hace el sistema cuando el modelo devuelve una respuesta malformada o una herramienta falla en el ciclo 8 de 15
    • Cost management — los tokens tienen precio; un agente que entra en bucle puede consumir más en una hora que todo un mes de uso normal

    La diferencia con el developer tradicional

    Un developer tradicional escribe código que ejecuta instrucciones exactas. Sabes exactamente lo que hará tu función processPayment() si la lees línea a línea.

    Un agentic engineer trabaja con sistemas donde el comportamiento exacto es no determinista. El mismo input puede producir outputs ligeramente diferentes. El agente puede resolver el problema de tres maneras distintas y todas pueden ser válidas — o puede fallar de formas que no estaban en ningún test.

    Esto no hace el trabajo más fácil. Lo hace diferente. Requiere un cambio de mentalidad: de “verificar que el código es correcto” a “diseñar el sistema para que los errores sean detectables, contenidos y recuperables”.

    También requiere entender el negocio a un nivel más profundo. Cuando un agente tiene autonomía para tomar decisiones, las consecuencias de una decisión incorrecta son mayores que cuando un developer escribe código que hace exactamente lo que le dicen.

    El agentic engineer tiene que entender qué acciones son reversibles, cuáles tienen consecuencias económicas y cuáles requieren supervisión humana.

    Cómo convertirte en un Agentic Engineer: roadmap práctico

    No hay un título. No hay una certificación que lo valide todavía. Lo que hay es experiencia construyendo sistemas reales y la capacidad de razonar sobre ellos.

    Este es el roadmap que yo seguiría si empezara hoy:

    Fase 1 — Entiende el mecanismo antes de las abstracciones (2-3 semanas)

    Implementa un agentic loop desde cero con la API de Anthropic o OpenAI. Sin LangChain. Sin frameworks. Solo el bucle percibir-razonar-actuar con tres herramientas básicas: leer archivos, escribir archivos, ejecutar comandos. Si no has leído el post sobre el agentic loop, empieza por ahí — cubre exactamente esta capa.

    La estructura mínima en TypeScript tiene este aspecto:

    while (objective.isNotComplete()) {
      const observation = await perceive(environment);  // leer contexto
      const decision = await llm.reason(observation);   // razonar con el modelo
      const result = await tools.execute(decision);     // ejecutar herramienta
    
      if (decision.type === "final_answer") break;
      environment.update(result);                       // actualizar estado
    }

    No es código de producción — es el esqueleto. Entender qué entra y qué sale en cada paso es lo que te permite depurar cuando el agente toma una decisión inesperada en el ciclo 12.

    El objetivo no es llegar rápido a producción. Es entender qué ocurre en cada iteración para poder diagnosticar problemas después.

    Fase 2 — Diseña tu primer agente con propósito real (3-4 semanas)

    Coge un problema concreto de tu trabajo diario y construye un agente que lo resuelva. No un agente genérico. Uno que haga una cosa específica bien: revisar PRs, procesar facturas, generar reportes a partir de datos, lo que sea que tenga valor en tu contexto.

    La restricción de “un problema específico” es intencional. Los agentes generalistas fallan más que los especializados. Empieza acotado.

    Fase 3 — Introduce observabilidad desde el principio (paralelo a Fase 2)

    Antes de confiar en que tu agente funciona, instrumenta lo que hace. Registra cada herramienta que llama, cada decisión que toma, cuántos tokens consume por ciclo. Sin esta capa no puedes mejorar el sistema — solo puedes rezar para que funcione.

    Fase 4 — Construye tu primer sistema multi-agente (4-6 semanas)

    Aquí está el salto real. Diseña un sistema donde dos o más agentes colaboran: un orquestador que divide el trabajo y subagentes que lo ejecutan. Implementa los handoffs. Entiende dónde se pierde contexto en la transferencia y cómo evitarlo.

    Este es el nivel donde empieza a tener sentido hablar de agentic engineering como disciplina, no como experimento.

    Fase 5 — Opera en producción (continuo)

    Despliega. Observa los fallos reales. Itera. Los problemas que solo aparecen en producción — usuarios que hacen cosas inesperadas, APIs externas que fallan en el momento equivocado, el modelo que decide hacer algo creativo con un input ambiguo — son los que te convierten en engineer de verdad.

    Dónde aprenderlo hoy

    La teoría ya no es el problema. Lo que falta en casi todo el material disponible es el criterio: cuándo usar qué patrón, cómo depurar cuando el sistema falla, qué decisiones de arquitectura importan en producción y cuáles son optimización prematura.

    En el curso Construye con IA cubrimos exactamente este criterio: desde el agentic loop hasta el diseño de sistemas multi-agente, pasando por las decisiones de arquitectura que hacen que un agente funcione en producción y no solo en demos.

    Y si quieres el marco estructural para diseñar antes de construir — la metodología que evita construir el sistema equivocado — el libro de Spec-Driven Development explica cómo especificar sistemas de agentes antes de escribir una sola línea de código.

    El developer que llegó a tiempo

    Vuelvo al developer del principio. El que era un 30% más rápido pero no entendía lo que ocurría debajo.

    Le dije que esa sensación era buena. No porque ser ignorante sea bueno, sino porque reconocer el gap es el primer paso para cerrarlo.

    La mayoría de los developers que usan IA hoy están en ese punto. Más rápidos. Más productivos. Pero construyendo sobre una caja negra que no controlan.

    El agentic engineering es la disciplina que convierte esa caja negra en un sistema que entiendes, que puedes depurar y que puedes confiar en que funciona cuando no estás mirando.

    Eso no es el futuro. Es lo que los mejores developers están haciendo ahora mismo.

    Si quieres ver cómo aplicamos estos principios en proyectos reales — con análisis de arquitecturas, sesiones de revisión de código y una comunidad de developers que ya construyen sistemas de agentes en producción — pásate por Dominicode Labs.

    FAQ — Preguntas frecuentes sobre Agentic Engineering

    ¿Qué es el agentic engineering exactamente?

    El agentic engineering es la disciplina de ingeniería de software especializada en diseñar, construir y operar sistemas de agentes de IA autónomos. A diferencia del desarrollo de software tradicional, trabaja con sistemas donde el comportamiento es no determinista y los agentes pueden tomar decisiones, ejecutar acciones y corregirse a sí mismos en tiempo real. El foco está en hacer esos sistemas predecibles, trazables y fiables en producción, no solo en demos controladas.

    ¿En qué se diferencia un Agentic Engineer de un developer que usa IA?

    Un developer que usa IA la utiliza como asistente: genera código, sugiere soluciones, responde preguntas. El agentic engineer diseña sistemas donde la IA actúa con autonomía: orquesta tareas, gestiona herramientas, mantiene contexto y opera sin supervisión constante. La diferencia no es de herramientas sino de nivel de abstracción y responsabilidad sobre el sistema.

    ¿Se necesita experiencia con LLMs para convertirse en Agentic Engineer?

    No es imprescindible, pero acelera mucho entender cómo funcionan los LLMs internamente: cómo procesan el contexto, por qué el tamaño del contexto importa, cómo el diseño del prompt afecta al comportamiento. Un developer con experiencia en arquitecturas de backend distribuidas tiene una ventaja real — los problemas de fiabilidad, observabilidad y gestión de errores son conceptualmente similares.

    ¿Cuáles son los frameworks más usados en agentic engineering hoy?

    En 2026 los más extendidos son LangGraph (para flujos con estado y ramificaciones complejas), las primitivas nativas de Anthropic con tool use, y las de OpenAI con function calling. Claude Code es una implementación completa de un agentic loop para desarrollo de software. Para orquestación visual y automatizaciones de negocio, n8n tiene nodos de AI Agent que implementan el loop sin escribir código. La recomendación es aprender el mecanismo antes que el framework — los frameworks cambian, el agentic loop no.

    ¿El agentic engineering reemplaza al desarrollo de software tradicional?

    No lo reemplaza, lo extiende. Los sistemas de agentes necesitan infraestructura, APIs, bases de datos, autenticación — todo el stack de desarrollo tradicional. Lo que cambia es la capa de lógica de negocio: en lugar de escribir código imperativo que ejecuta pasos exactos, el agentic engineer diseña el sistema que permite a la IA razonar sobre esos pasos. Ambas capas son necesarias y complementarias.

    ¿Qué diferencia hay entre agentic engineering y prompt engineering?

    El prompt engineering es una técnica dentro del agentic engineering — diseñar las instrucciones que gobiernan el comportamiento del agente. Pero el agentic engineering es mucho más amplio: incluye arquitectura de sistemas, diseño de herramientas, gestión de memoria y contexto, observabilidad, estrategias de fallback y operaciones en producción. Un buen prompt es necesario pero no suficiente para construir un agente que funcione en producción.


    Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.

    Si este post te ha sido útil, hay más contenido técnico sobre IA aplicada al desarrollo en el canal de YouTube de Dominicode.

  • Clean Architecture en frontend con IA: respeta las capas

    Clean Architecture en frontend con IA: respeta las capas

    Le pedí a un agente que generara la feature de listado de productos para un proyecto frontend.

    Veinte segundos después tenía el código listo. Funcionaba. Los datos aparecían en pantalla.

    Y entonces abrí el componente y vi esto:

    // ProductListComponent.tsx — lo que el agente generó sin contexto
    const ProductListComponent = () => {
      const [products, setProducts] = useState([]);
    
      useEffect(() => {
        fetch("https://api.myapp.com/products")
          .then(res => res.json())
          .then(data => setProducts(data));
      }, []);
    
      return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
    };

    Una llamada HTTP directamente en el componente. Sin interface. Sin use case. Sin repository. Sin manejo de errores. La lógica de negocio mezclada con la presentación, exactamente lo que llevaba seis meses evitando en ese proyecto.

    El agente no hizo lo que yo quería. Hizo lo que era más rápido de generar.

    Ese es el problema real cuando usas IA en un proyecto con clean architecture frontend: la IA optimiza para el camino más corto, no para el más correcto. Y sin guía, el camino más corto siempre es el spaghetti.

    (Los ejemplos de este post usan TypeScript 5.4 con Angular 19 / React 18 como referencia, y Claude Code en su versión de 2026. El CLAUDE.md y los principios aplican igualmente a Cursor y GitHub Copilot.)

    Por qué la IA destroza la arquitectura si la dejas sola

    Clean Architecture en frontend no es difícil de entender. Es difícil de sostener.

    Cualquier developer senior entiende la separación de capas. El problema es que cuando el equipo crece, cuando hay presión de tiempo, cuando alguien nuevo entra al proyecto — las capas se erosionan. Un fetch aquí, una lógica de transformación allá directamente en el componente.

    La IA acelera exactamente este problema.

    Los LLMs aprenden de código real que existe en internet. Y el código real que existe en internet está lleno de llamadas HTTP en componentes, lógica de negocio en controllers, transformaciones de datos sin tipado. Los modelos han visto millones de ejemplos de ese código. Lo reproducen con total confianza porque estadísticamente es el patrón más frecuente.

    Si no le dices al agente qué arquitectura sigue tu proyecto, asumirá que no tienes ninguna.

    Las capas que importan en frontend

    Clean Architecture en frontend es un patrón de organización de código que divide la aplicación en tres capas independientes (Domain, Data, Presentation) con una regla de dependencia estricta: las capas externas dependen de las internas, nunca al revés.

    En frontend, estas tres capas se pueden modelar de forma clara — independientemente de si usas Angular, React o Vue:

    Domain — El núcleo. Aquí viven las entities (los modelos de negocio), los use cases (la lógica que define qué puede hacer el sistema) y los ports (las interfaces que definen contratos sin implementación concreta).

    Data — La capa de acceso a datos. Repositories (implementaciones concretas de los ports), DTOs (los objetos que llegan de la API tal como los devuelve el servidor), y adapters/mappers (la transformación de DTO a entity).

    Presentation — Lo que el usuario ve. Componentes, páginas, ViewModels (la forma específica en que la presentación necesita los datos), y el estado de UI.

    La regla de dependencia es simple: las capas externas dependen de las internas. La Presentation conoce el Domain. El Data implementa los contratos del Domain. El Domain no sabe que existe ninguna de las otras dos.

    Presentation → Domain ← Data

    El componente no habla con la API. Habla con un use case. El use case habla con un repository port. El repository concrete habla con la API y transforma los datos antes de devolverlos.

    Eso es lo que el agente rompió cuando puso el fetch directamente en el componente.

    Dónde la IA puede ayudarte más en Clean Architecture

    La IA es extraordinariamente buena en el trabajo más aburrido de Clean Architecture.

    Crear interfaces de repositorios. Generar mappers entre DTOs y entities. Escribir use cases que siguen un patrón uniforme. Crear tests unitarios de use cases que no tienen dependencias externas. Esas son tareas repetitivas, con patrones claros, donde el agente brilla.

    Y son exactamente las tareas que los developers saltamos “para ir más rápido” y que luego generan deuda técnica durante meses.

    Tarea de Clean Architecture IA sin contexto IA con contexto
    Generar entity con validación Genera clase plana sin contratos Sigue el patrón de entity existente
    Crear repository port (interface) Puede saltárselo e ir a la implementación Crea interface primero, luego implementación
    Escribir adapter/mapper DTO → Entity Transforma inline en el componente Crea mapper en capa Data con tipos explícitos
    Implementar use case Mezcla lógica de UI con lógica de negocio Separa correctamente, inyecta el port
    Manejo de errores en Data layer Try/catch en el componente Manejo en el repository, domain errors tipados
    Test de use case Test de integración con API real Unit test con mock del repository port

    La diferencia entre las dos columnas no es el modelo. Es el contexto que le das.

    Cómo darle contexto al agente para que respete la arquitectura

    Hay tres mecanismos que uso y que funcionan en producción.

    1. Estructura de carpetas que documenta la arquitectura

    Si tu estructura de carpetas refleja las capas, el agente las ve antes de generar código. Cuando lee el proyecto antes de actuar, el patrón es obvio:

    src/
    ├── domain/
    │   ├── entities/
    │   │   └── product.entity.ts
    │   ├── use-cases/
    │   │   └── get-products.use-case.ts
    │   └── ports/
    │       └── product.repository.port.ts
    ├── data/
    │   ├── repositories/
    │   │   └── product.repository.ts
    │   ├── dtos/
    │   │   └── product.dto.ts
    │   └── mappers/
    │       └── product.mapper.ts
    └── presentation/
        ├── components/
        │   └── product-list/
        └── view-models/
            └── product-list.vm.ts

    Un agente que lee esta estructura sabe dónde va cada pieza. La carpeta es la arquitectura documentada.

    2. CLAUDE.md con reglas de arquitectura

    Si usas Claude Code, el archivo CLAUDE.md en la raíz del proyecto es leído automáticamente antes de que el agente actúe. Es tu oportunidad de definir las reglas del juego:

    # Arquitectura del proyecto
    
    Este proyecto sigue Clean Architecture con tres capas:
    
    ## Reglas de dependencia (OBLIGATORIAS)
    - Los componentes en presentation/ NUNCA importan directamente de data/
    - Los componentes solo usan use cases de domain/use-cases/
    - Los use cases solo conocen ports de domain/ports/, nunca implementaciones concretas
    - Todo acceso a API externo va en data/repositories/, nunca en componentes ni use cases
    
    ## Antes de generar código nuevo
    1. Si es lógica de negocio → crea use case en domain/use-cases/
    2. Si es acceso a datos → crea o modifica el repository en data/repositories/
    3. Si es transformación de datos → crea mapper en data/mappers/
    4. Si el port no existe → créalo en domain/ports/ antes de la implementación
    
    ## Naming conventions
    - Entities: *.entity.ts
    - Use cases: get-products.use-case.ts (verbo + sustantivo)
    - Ports: product.repository.port.ts
    - DTOs: product.dto.ts
    - Mappers: product.mapper.ts

    Esto no es opcional. Es la diferencia entre un agente que genera spaghetti y uno que genera código que encaja en tu arquitectura.

    3. Prompt con diagrama de capas

    Cuando pides una feature específica, incluye siempre la capa donde debe vivir:

    Necesito implementar la feature "obtener lista de productos" siguiendo la arquitectura del proyecto.
    
    Genera en este orden:
    1. ProductDTO en data/dtos/ (tal como viene de la API)
    2. ProductEntity en domain/entities/ (modelo de negocio limpio)
    3. ProductMapper en data/mappers/ (transforma DTO → Entity)
    4. IProductRepository port en domain/ports/ (interface del contrato)
    5. ProductRepository en data/repositories/ (implementación concreta que usa fetch)
    6. GetProductsUseCase en domain/use-cases/ (orquesta el repositorio, devuelve entities)
    
    El componente ya existe — no lo modifiques. Solo genera las capas de dominio y datos.

    Ejemplo práctico: de DTO a Use Case con el agente

    Así es como queda el código cuando el agente tiene contexto. Le pedí exactamente las piezas del ejemplo anterior con el CLAUDE.md activo:

    // domain/entities/product.entity.ts
    export interface ProductEntity {
      id: string;
      name: string;
      price: number;
      inStock: boolean;
    }
    
    // data/dtos/product.dto.ts
    export interface ProductDTO {
      id: string;
      nombre: string;         // la API devuelve en español
      precio_eur: number;     // con otro nombre
      stock: number;          // número, no boolean
    }
    
    // data/mappers/product.mapper.ts
    import { ProductDTO } from "../dtos/product.dto";
    import { ProductEntity } from "../../domain/entities/product.entity";
    
    export const toProductEntity = (dto: ProductDTO): ProductEntity => ({
      id: dto.id,
      name: dto.nombre,
      price: dto.precio_eur,
      inStock: dto.stock > 0,
    });
    
    // domain/ports/product.repository.port.ts
    import { ProductEntity } from "../entities/product.entity";
    
    export interface IProductRepository {
      getAll(): Promise<ProductEntity[]>;
      getById(id: string): Promise<ProductEntity | null>;
    }
    
    // data/repositories/product.repository.ts
    import { IProductRepository } from "../../domain/ports/product.repository.port";
    import { ProductEntity } from "../../domain/entities/product.entity";
    import { ProductDTO } from "../dtos/product.dto";
    import { toProductEntity } from "../mappers/product.mapper";
    
    export class ProductRepository implements IProductRepository {
      private readonly baseUrl = "https://api.myapp.com";
    
      async getAll(): Promise<ProductEntity[]> {
        const response = await fetch(`${this.baseUrl}/products`);
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        const dtos: ProductDTO[] = await response.json();
        return dtos.map(toProductEntity);
      }
    
      async getById(id: string): Promise<ProductEntity | null> {
        const response = await fetch(`${this.baseUrl}/products/${id}`);
        if (response.status === 404) return null;
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        const dto: ProductDTO = await response.json();
        return toProductEntity(dto);
      }
    }
    
    // domain/use-cases/get-products.use-case.ts
    import { IProductRepository } from "../ports/product.repository.port";
    import { ProductEntity } from "../entities/product.entity";
    
    export class GetProductsUseCase {
      constructor(private readonly productRepository: IProductRepository) {}
    
      async execute(): Promise<ProductEntity[]> {
        // El use case no tiene try/catch — delega el manejo de errores al repository.
        // Los errores de infraestructura suben como excepciones; la capa de presentación decide cómo mostrarlos.
        return this.productRepository.getAll();
      }
    }

    El componente ahora solo necesita instanciar el use case e invocar execute(). No sabe que existe una API. No sabe el formato de los DTOs. No hace transformaciones. Solo le habla al dominio.

    Eso es Clean Architecture aplicada. Y el agente lo generó todo en un solo turno porque sabía exactamente dónde iba cada pieza.

    Dónde la IA falla aunque tengas contexto

    El CLAUDE.md no es una bala de plata.

    Hay situaciones donde el agente ignora las reglas o las interpreta de forma inesperada. Las más comunes:

    Features cross-capa sin spec previa. Si le pides “añade filtros al listado de productos”, el agente puede añadir el estado del filtro en el use case (lógica de UI en el dominio), en la URL de la API directamente, o en el componente — sin pasar por el use case. La feature es compleja y el agente toma atajos.

    Refactorizaciones de archivos existentes. Al modificar código que ya existe y que no sigue la arquitectura, el agente tiende a preservar el patrón existente en lugar de corregirlo. Si el archivo ya tiene un fetch en el componente y le pides que añada una funcionalidad, lo más probable es que añada otro fetch.

    Código sin tests previos. Sin tests que fallen cuando se rompe la arquitectura, el agente no recibe feedback negativo cuando viola las capas. El código compila, parece correcto, y el problema solo aparece cuando otro developer intenta extender la feature meses después.

    La solución a los tres casos es la misma: spec primero, código después.

    La hoja de ruta correcta: SDD + IA

    Lo que marca la diferencia no es qué agente usas. Es si empiezas con una especificación o si vas directo al código.

    Cuando escribes la spec primero — qué entities existen, qué use cases necesita la feature, qué contratos definen los ports — el agente tiene un mapa. No adivina la arquitectura. La sigue porque está documentada antes de que genere la primera línea.

    Spec-Driven Development (SDD) es exactamente esta metodología: especificar antes de implementar, usar la spec como contrato entre el developer y el agente. He documentado todo el proceso — con plantillas, ejemplos y el flujo completo — en el Libro SDD. Si tu proyecto tiene problemas de arquitectura cuando usas IA, el libro es el punto de partida más directo que tengo para darte.

    Si quieres entender primero cómo funciona el bucle interno del agente — el ciclo percibir-razonar-actuar que subyace a todo esto — el post sobre el agentic loop y la guía sobre qué es un Agentic Engineer completan el contexto antes de aplicarlo a tu arquitectura.

    El flujo práctico es este:

    1. Escribe la spec: entities, use cases, ports, contratos
    2. Configura CLAUDE.md con las reglas de arquitectura
    3. Pide al agente que genere una capa a la vez, en orden
    4. Review: ¿la implementación respeta la spec?
    5. Añade tests que fallen si alguien rompe las capas
    6. Itera

    Cada paso reduce el espacio de decisión del agente. Y reducir el espacio de decisión es reducir el riesgo de que genere spaghetti.

    Si quieres ver este flujo aplicado a proyectos reales — desde la spec hasta el producto funcionando — el curso Construye con IA cubre exactamente esto: cómo trabajar con agentes de IA respetando la arquitectura, con ejemplos en TypeScript y el proceso completo desde idea hasta código en producción.

    FAQ — Preguntas frecuentes

    ¿Clean Architecture en frontend es sobreingeniería para proyectos pequeños?

    Depende del criterio de “pequeño”. Si el proyecto va a crecer, va a tener más de un developer tocando el código o va a ser mantenido más de seis meses, Clean Architecture paga su coste desde el primer mes. El problema no es la arquitectura en sí — es implementarla de forma rígida cuando no añade valor. Para un script de 200 líneas o un prototipo desechable, no la necesitas. Para cualquier producto real, la separación de capas es lo que permite que la IA ayude en lugar de crear deuda.

    ¿Funciona el mismo enfoque con Cursor, GitHub Copilot o cualquier otro agente?

    Sí. El CLAUDE.md es específico de Claude Code, pero el principio es universal: cualquier agente que pueda leer el contexto del proyecto antes de generar código va a producir mejores resultados. En Cursor usas archivos .cursor/rules/*.mdc (la convención actual desde 2025; .cursorrules sigue funcionando por retrocompatibilidad). En GitHub Copilot puedes añadir instrucciones en el repositorio o en el prompt. La estructura de carpetas funciona con todos porque es parte del contexto que el agente lee automáticamente cuando explora el proyecto.

    ¿Cómo testeo que la arquitectura se está respetando?

    La forma más efectiva es con import constraints a nivel de build o linting. En proyectos TypeScript puedes usar eslint-plugin-boundaries para definir reglas de qué capas pueden importar de cuáles. Cuando el agente viola la arquitectura, el linter falla antes de que el código llegue a revisión. Es la red de seguridad que hace que el enfoque sea sostenible en equipos o en proyectos donde usas IA intensivamente.


    Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.

  • Cómo implementar memoria en agentes antes de herramientas para mejorar la efectividad

    Cómo implementar memoria en agentes antes de herramientas para mejorar la efectividad

    Por qué tu agente necesita memoria antes de herramientas

    Tiempo estimado de lectura: 4 min

    • Memoria antes de herramientas: Sin memoria contextual, las herramientas incrementan errores, coste y riesgo de daño a datos y presupuesto.
    • Episódica vs semántica: Episódica = historial reciente; semántica = hechos persistentes indexados por similitud.
    • Run loop recomendado: Buscar semántica → recuperar episódica → ensamblar prompt → validar argumentos → ejecutar → persistir resultados.
    • Métricas y trazabilidad: Mide validaciones fallidas, reintentos, TTFT, coste por request y porcentaje de intervención humana.

    Si tu primer movimiento fue añadir herramientas al agente, lo estás haciendo al revés. Entender por qué tu agente necesita memoria antes de herramientas es la diferencia entre un sistema que actúa y uno que razona. Sin memoria contextual, un agente repite errores, alucina resultados y convierte cada tool en una bomba de relojería para tus datos y tu presupuesto.

    Resumen rápido (lectores con prisa)

    Qué es: La memoria provee contexto (episódico y semántico) que evita repetir errores y reduce alucinaciones.

    Cuándo usarla: Antes de permitir que un agente invoque herramientas en producción o gestione datos persistentes.

    Por qué importa: Mejora coherencia, reduce coste y riesgo, y permite recuperación cuando una tool falla.

    Cómo funciona (resumen): Buscar en memoria semántica → recuperar historial episódico → ensamblar prompt → validar y ejecutar herramientas → persistir resultados.

    Por qué tu agente necesita memoria antes de herramientas

    Las herramientas son los actuadores; la memoria es el mapa. Cuando una llamada a una API falla o una transacción SQL choca, el agente sin memoria solo ve el último input. Reintenta lo mismo, consume tokens y, en el peor de los casos, escribe datos corruptos en producción. Con memoria —episódica y semántica— el agente sabe qué intentó, qué falló y cómo adaptar su estrategia sin volver a romper nada.

    Aumentar la capacidad de acción sin dotar de historia al agente es ampliar su radio de daño.

    Memoria episódica vs semántica: función y uso práctico

    Memoria episódica (corto plazo)

    • Qué es: historial cronológico de la sesión —mensajes, decisiones del modelo y resultados de herramientas.
    • Para qué sirve: coherencia conversacional y rastreo de pasos en flujos multilargo.
    • Implementación típica: Redis o caché en memoria con TTL y extracción de los últimos N eventos.
    • Estrategias: sliding window (mantén los N mensajes más recientes) y resumen periódico (el modelo genera una síntesis que reemplaza bloques antiguos).

    Memoria semántica (largo plazo)

    • Qué es: hechos persistentes sobre usuarios, reglas, configuraciones y decisiones previas, indexados por similitud semántica.
    • Para qué sirve: recuperar contexto relevante que trasciende sesiones (preferencias, infraestructuras, políticas).
    • Implementación típica: bases de datos vectoriales (pgvector sobre PostgreSQL es una opción pragmática: pgvector).
    • Patrón habitual: RAG aplicado a la memoria del agente —consulta embeddings antes de ensamblar el prompt.

    No son intercambiables: la episódica responde “qué pasó ahora”, la semántica responde “qué deberías saber de antes”.

    El run loop correcto (práctico y reproducible)

    Antes de permitir que el agente invoque una tool, sigue este flujo:

    1. Embeddiza el input del usuario y consulta la memoria semántica (top-k).
    2. Recupera los últimos N eventos de la memoria episódica.
    3. Ensambla el prompt: instrucciones base + hechos semánticos verificados + resumen episódico + herramientas disponibles.
    4. Envía al modelo; si decide llamar una tool, valida los argumentos con un esquema antes de ejecutar.
    5. Persiste la decisión y el resultado en la memoria episódica.
    6. Si la llamada falla, serializa el error (estructura ZodError o equivalente) y úsalo para autocorrección o para encolar revisión humana.

    sem = searchSemanticMemory(userVector)
    epi = loadEpisodic(sessionId, N)
    context = buildContext(systemPrompt, sem, epi, toolsMeta)
    decision = model.decide(context)
    if decision.tool → validate → execute → saveEpisodic(result)

    Ese orden evita que las herramientas actúen en el vacío.

    Por qué no basta con ventanas de contexto gigantes

    Modelos con contexto masivo (Gemini, Claude) tienta a inyectar todo el historial en cada petición. En teoría funciona; en producción falla por tres razones:

    • Latencia (TTFT): enviar 100k–1M tokens degrada la experiencia.
    • Coste: procesar historial enorme en cada request sale caro.
    • Precisión: la atención se degrada cuando la información clave está enterrada (lost in the middle). Ver discusión técnica.

    La memoria estructurada filtra, prioriza y entrega solo lo relevante; es más eficiente, auditable y económico.

    Operacionalidad: métricas y señales que importan

    Mide para poder decidir:

    • tasa de validación fallida de herramientas (/% llamadas rechazadas por schema),
    • reintentos por fallo (media y P95),
    • latencia TTFT y costo por request (tokens consumidos),
    • porcentaje de decisiones que derivaron en intervención humana.

    Registra siempre: prompt construido, fragments recuperados, rawResponse del LLM, result de Zod (.error.flatten()), y la tool invocada. Sin trazabilidad no hay postmortem útil.

    Criterio para arquitectos y equipos

    Antes de añadir una nueva tool, pregúntate: si esa tool falla, ¿el agente tiene suficiente historia para entender por qué y recuperarse sin crear daño? Si la respuesta es no, diseña memoria. Empieza con episodic + semántic básico (Redis + pgvector), políticas de resumen y validación estricta de inputs. Solo entonces añade más herramientas.

    La memoria no es una mejora incremental: es la infraestructura que permite que las herramientas sean seguras, eficaces y escalables. Construir al revés es barato hoy y peligroso mañana. En el siguiente artículo veremos patrones de resumen semántico y cómo integrar autocorrección de argumentos usando errores estructurados (Zod) para convertir fallos en aprendizaje automático.

    Para equipos que trabajan con agentes y workflows, una referencia práctica y recursos adicionales están disponibles en Dominicode Labs. Considera esto como continuidad técnica: plantéalo si necesitas plantillas de run loops, patrones de memoria y ejemplos de validación de herramientas.

    FAQ

    ¿Qué diferencia práctica hay entre memoria episódica y memoria semántica?

    La memoria episódica guarda el historial reciente de la sesión (mensajes, decisiones, resultados) y sirve para coherencia conversacional y seguimiento de flujos multilargo. La memoria semántica guarda hechos persistentes indexados por similitud (preferencias, reglas, configuraciones) que se recuperan entre sesiones.

    ¿Por qué validar argumentos antes de ejecutar una herramienta?

    Validar previene ejecuciones incorrectas que consumen tokens, fallan o dañan datos en producción. Es la barrera que evita que inputs malformados o decisiones erróneas se conviertan en efectos adversos.

    ¿Qué métricas debo priorizar al operar agentes en producción?

    Tasa de validación fallida de herramientas, reintentos por fallo (media y P95), latencia TTFT, coste por request (tokens) y porcentaje de decisiones que derivaron en intervención humana. Registra también prompt construido, fragments recuperados y rawResponse del LLM para trazabilidad.

    ¿Es suficiente aumentar el contexto del modelo en cada petición?

    No. En producción esto aumenta latencia y coste, y puede degradar la precisión cuando información clave se pierde en un contexto enorme. La memoria estructurada entrega solo lo relevante de forma priorizada y auditable.

    ¿Qué hacer cuando una call a la tool falla repetidamente?

    Serializa el error (estructura ZodError o equivalente), persiste el fallo en memoria episódica, usa la información para autocorrección y, si es necesario, encola revisión humana. Registra detalles para postmortem.

    ¿Qué herramientas tecnológicas se recomiendan para empezar?

    Empezar con una memoria episódica en Redis y una memoria semántica en una base vectorial práctica como pgvector sobre PostgreSQL. Añade políticas de resumen y validación estricta de inputs antes de expandir herramientas.

  • Cómo redactar una spec efectiva para Claude Code

    Cómo redactar una spec efectiva para Claude Code

    Anatomía de una buena spec para Claude Code

    Tiempo estimado de lectura: 6 min

    • Una spec compacta y accionable evita suposiciones del agente y reduce iteraciones.
    • La estructura mínima: Requirements → Design → Tasks → Implementation.
    • Para bugs: seguir Report → Analyze → Fix → Verify.
    • Coloca SPEC.md junto al código y versiona la spec con el PR.

    Introducción

    Anatomía de una buena spec para Claude Code: si esperas que un agente genere código alineado con tu arquitectura, la spec es el mínimo imprescindible. Sin ella, Claude Code (o cualquier agente) hará suposiciones; con ella, ejecutará decisiones coherentes desde la primera iteración.

    Claude Code opera sobre repositorios y contexto local; el modelo subyacente (Claude) razona según la información que le entregues. Documenta la intención antes de pedir implementación y evitarás iteraciones costosas. Referencias útiles: Anthropic — Claude Code overview y Claude.

    Resumen rápido (lectores con prisa)

    Qué es: Una spec compacta y accionable que define comportamiento observable, diseño, tareas y criterios de aceptación para que Claude Code ejecute sin inventar.

    Cuándo usarla: Antes de pedir a un agente que implemente features o arregle bugs en un repositorio.

    Por qué importa: Minimiza suposiciones del agente, reduce iteraciones y evita parches superficiales.

    Cómo funciona: Estructura mínima: Requirements → Design → Tasks → Implementation; para bugs: Report → Analyze → Fix → Verify.

    Anatomía de una buena spec para Claude Code: estructura y propósito

    Una spec útil no es un tratado largo. Es un artefacto compacto y accionable, pensado para que un agente pueda ejecutar sin inventar. Su estructura mínima:

    1. Requirements → 2. Design → 3. Tasks → 4. Implementation

    Para bugs: Report → Analyze → Fix → Verify.

    Cada bloque reduce incertidumbre y acota el espacio de decisiones del agente.

    1. Requirements — qué debe hacer el sistema (externo)

    Define el comportamiento observable, no la implementación.

    Incluye:

    • Comportamiento nominal: qué hace la API/función.
    • Casos de borde: inputs nulos, límites, formatos erróneos.
    • Restricciones no funcionales: latencia p95 < 200 ms, tamaño máximo de payload 2 MB.
    • Dependencias permitidas/prohibidas.

    Ejemplo (sin spec vs con spec):

    Sin spec: “Crea endpoint para usuarios”.
    Con spec: “POST /users: recibe {email, name}. Valida email según RFC 5321. Inserta en PostgreSQL usando el ORM X. Devuelve 201 con {id, email, name} o 409 si email existe. No usar nuevas dependencias.”

    2. Design — cómo debe integrarse la solución (interno)

    Define firmas, modelos y patrones. Evita que el agente elija un estilo distinto al del repo.

    Incluye:

    • Firma de funciones/handlers (tipado).
    • Modelos DTO/Entity.
    • Patrones obligatorios (repositorio, servicios, inyección).
    • Efectos secundarios permitidos (logs, eventos, mutaciones).

    Plantilla mínima:

    Function: createUser(payload: CreateUserDto): Promise
    Models: CreateUserDto, UserDto, UserEntity (campos, tipos)
    Patterns: usar userRepository.insert, no acceso directo a SQL.

    3. Tasks — pasos atómicos y ordenados

    Desglosa el trabajo en tareas verificables. Un agente ejecuta mejor secuencias claras.

    Ejemplo de Tasks para feature nueva:

    1. Añadir CreateUserDto en src/models.
    2. Implementar userRepository.insert según patrón existente.
    3. Implementar handler POST /users con validación.
    4. Añadir tests unitarios (caso feliz, email duplicado, payload inválido).
    5. Actualizar documentación OpenAPI.

    Cada tarea debe producir un artefacto comprobable.

    4. Implementation — criterios de aceptación y pruebas

    Define qué significa “terminado”. No dependas solo de que compile o pase CI.

    Incluye:

    • Cobertura mínima (ej. 80% sobre módulo).
    • Tests obligatorios (unit + integración básica).
    • Requisitos de performance y seguridad.
    • Revisión arquitectónica (no introducir dependencias nuevas, mantener separaciones).

    Ejemplo: “Merge solo si tests pasan y cobertura del módulo ≥ 85%; latencia p95 < 200ms en test de integración local.”

    Flujo para bugs: Report → Analyze → Fix → Verify

    Para corrección de errores, no saltes al fix. Sigue este flujo:

    • Report: pasos reproducibles, logs, versión del commit.
    • Analyze: causa raíz documentada (por el agente o humano) con ubicación del código.
    • Fix: parche mínimo que restaure el contrato.
    • Verify: tests que confirmen el caso original y aseguren regresión negativa.

    Pedir “arregla X” sin Analyze genera parches superficiales que reaparecen.

    Ejemplos reales (comparativa rápida)

    Caso: validar emails

    Sin spec: agente instala validator.js y devuelve distinto comportamiento al estándar del proyecto.

    Con spec: “validateEmail(input: string): boolean — RFC 5321, rechaza dominios locales, no usar libs externas.” Resultado: implementación consistente y sin nuevas dependencias.

    Caso: feature auth token

    Sin spec: token store ad-hoc en memoria.

    Con spec: define AuthToken interface, TTL, almacenamiento en redis existente y tests. Resultado: integración correcta con infra existente.

    Práctica recomendada y colocación en repo

    • Coloca SPEC.md junto al test file o en la carpeta del feature.
    • Versiona la spec con el mismo PR.
    • Incluye ejemplos de I/O y criterios de aceptación textuales.
    • Si usas herramientas visuales, añade diagramas Mermaid (https://mermaid.js.org/) o contrato OpenAPI (https://spec.openapis.org/).

    Conclusión

    Claude Code puede automatizar implementaciones, pero su fidelidad depende de tu spec. La diferencia entre un parche plausible y una integración sostenible es específica: Requirements → Design → Tasks → Implementation para features; Report → Analyze → Fix → Verify para bugs. Escribe la spec antes de ejecutar al agente. Lo barato es ahorrar minutos ahora; lo caro es rehacer horas después.

    Dominicode Labs

    Si trabajas con automatización, agentes o workflows, considera recursos prácticos y experimentos en Dominicode Labs. Es una continuación lógica para explorar patrones operativos y plantillas de spec aplicables a pipelines de IA y automatización.

    FAQ

    Respuesta — ¿Qué debe contener la sección Requirements de la spec?

    Debe definir el comportamiento observable: casos nominales, bordes, restricciones no funcionales (p. ej. latencia, tamaño de payload) y dependencias permitidas o prohibidas.

    Respuesta — ¿Por qué es importante definir el Design explícitamente?

    Porque evita que el agente elija un estilo distinto al del repositorio. Definir firmas, modelos y patrones garantiza consistencia con la arquitectura existente.

    Respuesta — ¿Cómo se desglosan las Tasks de forma efectiva?

    Divídelas en pasos atómicos y ordenados que produzcan artefactos comprobables (archivos, tests, cambios en la API). Cada tarea debe ser verificable aisladamente.

    Respuesta — ¿Qué criterios deben incluirse en Implementation?

    Criterios de aceptación claros: cobertura mínima de tests, pruebas obligatorias (unit/integración), requisitos de performance y restricciones de seguridad o dependencias.

    Respuesta — ¿Cuál es el flujo recomendado para corregir bugs?

    Report (pasos reproducibles y logs) → Analyze (causa raíz y ubicación) → Fix (parche mínimo) → Verify (tests que confirmen y prevengan regresiones).

    Respuesta — ¿Dónde debo colocar la SPEC.md en el repo?

    Junto al test file o en la carpeta del feature. Versiona la spec en el mismo PR para mantener trazabilidad.

  • Cómo construir un producto de software desde cero usando IA

    Cómo construir un producto de software desde cero usando IA

    Cómo construyo un producto de software desde cero usando IA (mi proceso real)

    Tiempo estimado de lectura: 4 min

    Ideas clave

    • Construir un producto con IA es un proceso disciplinado: define el problema, escribe una spec como única fuente de verdad y deja que un agente implemente bajo revisión.
    • Spec‑Driven Development (SDD) es la columna vertebral: spec.md debe contener stack, modelado de datos, contratos API, reglas de negocio y casos de aceptación.
    • Uso un agente en terminal (Claude Code) para implementar desde el repo leyendo la spec; interactúo revisando diffs y actualizando la spec cuando cambia el comportamiento.
    • Pipelines: tests, linters y CI antes de merge; deploy en Vercel para front o infra reproducible para backend.

    Construir un producto de software desde cero usando IA no es “pedir código al chat”. Es un proceso disciplinado: idea → spec con SDD → código con Claude Code → deploy. Aquí tienes mi walkthrough real, probado en proyectos que pasaron de prototipo a producción sin incendiar la base de código.

    Resumen rápido (lectores con prisa)

    Qué es: Un proceso disciplinado que usa Spec‑Driven Development (SDD) como única fuente de verdad y un agente en terminal (Claude Code) para ejecutar la implementación bajo revisión humana.

    Cuándo usarlo: Para productos escalables y mantenibles donde la coherencia arquitectónica y la gestión de deuda técnica importan.

    Por qué importa: Evita ambigüedades, reduce deuda técnica y permite iteraciones rápidas sin romper coherencia del sistema.

    Cómo funciona: Define problema → escribe spec.md detallada → ejecuta al agente que lee el repo y la spec → revisa diffs → tests/CI → deploy.

    1) Del problema a la frontera del producto (no a la idea vaga)

    La diferencia entre una idea y un producto es la frontera: cuándo, quién, condiciones y consecuencias. Define el problema en 3–5 oraciones concretas. Quién sufre, cuándo ocurre, qué le frustra hoy y qué mediremos para saber si la solución funciona.

    Usa IA aquí como auditor: hazle preguntas para descubrir supuestos y casos edge. Pero no le pidas código aún. Resultado: una descripción del problema que cualquier dev pueda leer en frío y entender.

    2) Escribir la spec: Spec‑Driven Development (SDD)

    SDD es la columna vertebral. Antes de una sola línea de código:

    • Crea spec.md en el repo. Será la única fuente de verdad.
    • Incluye stack exacto (ej.: Next.js 16, React 19, Tailwind 4).
    • Modelado de datos: tablas, campos, relaciones, índices y restricciones.
    • Contratos API: endpoints, payloads, respuestas, errores y códigos HTTP.
    • Reglas de negocio claras: qué está permitido y qué nunca.
    • Casos de prueba de aceptación (no tests automatizados, sino escenarios).

    La spec elimina ambigüedad. Si algo no está en la spec, no existe para el agente.

    Recurso práctico: Spec-Driven Development

    3) Implementación con Claude Code (agente en terminal)

    Claude Code vive en la terminal, lee archivos y puede ejecutar comandos. No es un chat: es un agente con acceso al repo.

    Flujo estándar

    1. git init + estructura base según spec.md.
    2. Llamada inicial al agente con instrucción precisa:
    Claude Code (Anthropic).
    3. Reviso los diffs que propone como si fueran PRs. Aprobación explícita o feedback.
    4. Si hay cambio de comportamiento, actualizo spec.md y pido refactor.

    Regla innegociable: nunca corregir código sin actualizar la spec. Corrige la spec, suprime la ambigüedad, manda refactor. Así el agente aprende reglas permanentes del proyecto.

    Ejemplo de prompt maestro (simplificado): “Contexto: repo vacío, spec.md adjunto. Tarea: implementar la API de autenticación según spec. Antes de modificar, lista ambigüedades. Compara con stack y patrones del repo.”

    4) Tests, CI y deploy

    El código sigue buenas prácticas: tests unitarios básicos, linters y pipelines en GitHub Actions. Deploy en Vercel para front o en un VPS/Cloud con infra reproducible para backend.

    Pipeline típico:

    • PR generado por agente → revisión humana → GitHub Actions (lint, test) → merge → deploy.

    Cuando necesito añadir features: actualizo spec.md, ejecuto al agente con el repo y la spec actualizada. El contexto persistente evita “olvidos” que generan deuda técnica.

    Buenas prácticas operativas (evitan dolor después)

    • Versiona spec.md. Cada cambio debe tener justificación y número de versión.
    • Usa ejemplos concretos en la spec (payloads de ejemplo, respuestas de error).
    • Limita el scope por iteración. Un sprint = 1–2 features bien especificadas.
    • Rechaza cambios grandes mediante parches rápidos: si la spec cambia radicalmente, crea una rama de arquitectura.
    • Mantén un humano con criterio técnico revisando cada PR del agente.

    Cuándo usar este proceso (y cuándo no)

    Úsalo si necesitas un producto escalable, con datos complejos o que deba mantenerse en el tiempo. No lo burocratices para un script de 100 líneas o un prototipo desechable: ahí el prompt‑driven rápido sigue siendo válido.

    Esto no es un truco mágico: es disciplina. La IA ejecuta, pero la arquitectura y el criterio técnico siguen en tus manos. Si mantienes la spec como la fuente única de verdad y tratas al agente como un colaborador que trabaja sobre ese contrato, podrás iterar rápido sin destruir la coherencia del sistema. Esto es solo la base: la próxima iteración debe cubrir cómo redactar specs resistentes y ejemplos prácticos de prompts maestro para Claude Code.

    Si trabajas en automatización, agentes o workflows, este enfoque encaja con iniciativas prácticas de investigación y experimentación de herramientas y procesos. Sigue explorando en Dominicode Labs como continuación lógica para prototipado y validación de pipelines con agentes.

    FAQ

    ¿Qué es Spec‑Driven Development (SDD)?

    SDD es un marco donde una spec.md actúa como la única fuente de verdad para el desarrollo. Define stack, modelos de datos, contratos API, reglas de negocio y casos de aceptación antes de escribir código.

    ¿Por qué usar un agente en terminal como Claude Code?

    Porque puede leer el repo, ejecutar comandos y proponer cambios como si fueran PRs. Esto permite automatizar implementaciones repetibles mientras el humano revisa y guía el resultado.

    ¿Qué debe contener spec.md?

    Debe incluir stack exacto, modelado de datos (tablas, campos, relaciones), contratos API (endpoints, payloads, respuestas y errores), reglas de negocio y casos de aceptación con ejemplos concretos.

    ¿Cómo se gestionan los cambios de comportamiento?

    Actualiza spec.md y crea un refactor controlado. Nunca corrijas código sin primero cambiar la spec. Esto mantiene la coherencia y enseña al agente las reglas permanentes del proyecto.

    ¿Cuándo no aplicar este proceso?

    No lo burocratices para scripts pequeños o prototipos desechables (por ejemplo, un script de ~100 líneas). En esos casos, un enfoque prompt‑driven rápido es más eficiente.

    ¿Qué herramientas de CI/Deploy recomiendas?

    Usa pipelines en GitHub Actions para lint y tests, y Vercel para frontends. Para backends, despliega en VPS/Cloud con infraestructura reproducible según la spec.

  • Cómo monitorear efectivamente agentes de IA en producción

    Cómo monitorear efectivamente agentes de IA en producción

    Cómo monitorear tus agentes de IA en producción

    Tiempo estimado de lectura: 5 min

    Ideas clave

    • Instrumentación desde el día 0: traces y spans que representen sesiones completas y decisiones individuales.
    • Métricas triples: rendimiento (TTFT, percentiles), coste (tokens/coste por span/sesión) y calidad (feedback y señales automáticas).
    • Elegir plataforma según arquitectura: LangSmith para stacks centrados en LangChain; Langfuse (+ ClickHouse) para portabilidad y escala.
    • Cultura operacional: versionado de prompts, tests de regresión y despliegue progresivo son obligatorios.

    Cómo monitorear tus agentes de IA en producción debería ser la primera conversación del equipo antes de lanzar una beta. Si no instrumentas traces, spans, costes y calidad desde el día 0, tu siguiente sprint será apagar fuegos y explicar facturas inexplicables.

    Este artículo explica el diseño mínimo de observabilidad para agentes (LLM Observability), las métricas que importan y las decisiones tecnológicas prácticas entre plataformas como Langfuse y LangSmith. Incluye enlaces directos a recursos: Langfuse, LangSmith y ClickHouse.

    Resumen rápido (lectores con prisa)

    Qué es: Observabilidad para agentes de IA: traces distribuidos y spans que capturan prompts, llamadas a LLM, búsquedas vectoriales y tool calls.

    Cuándo usarlo: desde el día 0 en cualquier beta u ambiente productivo que use agentes/LLMs.

    Por qué importa: APMs tradicionales no detectan fallos semánticos ni picos de coste por tokens.

    Cómo funciona (resumen): instrumenta spans por acción, mide rendimiento/coste/calidad, y almacena traces para query analítica y alertas.

    Principio: los APM tradicionales no son suficientes

    APM como Datadog o Prometheus miden latencia HTTP, errores y consumo de CPU. Perfecto para servicios deterministas. Un agente de IA devuelve HTTP 200 y puede a la vez fabricar información falsa, ejecutar llamadas externas y disparar costes por token. En ese escenario, el APM dice “todo bien” mientras tu soporte recibe tickets.

    Necesitas telemetría diseñada para flujos probabilísticos: rastreo distribuido con traces que representen sesiones completas y spans que documenten cada decisión y llamada (LLM, búsqueda vectorial, tool calls, llamadas externas).

    Traces y spans: la unidad mínima de diagnóstico

    Diseña cada interacción como un trace. Cada acción —prompts, retrievals, llamadas a herramientas, transformaciones— es un span con metadata.

    Trace: session_42
    ├─ Span 1: receive_prompt (userId=42, promptHash=…)
    ├─ Span 2: vector_search (index=kb_v1, hits=3, latency=320ms)
    ├─ Span 3: LLM_call (model=gpt-4o, tokens_in=1800, tokens_out=120, cost=$0.012)
    └─ Span 4: synthesize_response (format=short-answer)

    Con esto puedes responder rápido: ¿por qué tardó 12s? ¿qué span generó el mayor coste? ¿qué prompts producen más fallos semánticos?

    Métricas imprescindibles (no negociables)

    Rendimiento

    • Time to First Token (TTFT): impacto directo en la UX.
    • Latencia por span y percentiles: p50 / p95 / p99 por tipo de span.

    Coste

    • Tokens y coste por span: calcular coste por span y por session/userId.
    • Coste acumulado por workflow: agente que llama al LLM varias veces debe sumar costes por workflow.
    • Alertas de coste: activar alertas cuando una sesión supera un umbral definido.

    Calidad

    • Feedback explícito: thumbs up/down ligado al trace.
    • Señales implícitas: tiempo de interacción, copias realizadas.
    • LLM-as-a-judge: usar un modelo más económico para evaluar respuestas automáticamente como señal de calidad (no como veredicto absoluto).

    Langfuse vs LangSmith: criterio técnico para elegir

    LangSmith es excelente si tu stack está centrado en LangChain/LangGraph: integración out-of-the-box, datasets de evaluación y UI lista para depurar agentes complejos. El coste es acoplamiento: extraer datos o migrar a otro sistema será costoso.

    Langfuse es agnóstico y open source; se integra con llamadas directas a APIs, Vercel AI SDK, n8n, etc. La reciente incorporación de ClickHouse al ecosistema refuerza su escalabilidad analítica: consultas sobre millones de traces con latencias bajas y análisis de coste en tiempo real. Si prevés escala o necesitas evitar vendor lock-in, Langfuse+ClickHouse es una apuesta sólida.

    Decisión práctica

    • Si dependes de LangChain → LangSmith.
    • Si buscas portabilidad, alto throughput analítico y autoalojamiento → Langfuse (+ ClickHouse).

    Implementación práctica: checklist mínimo viable

    1. Wrap de llamadas al LLM: envuelve cada llamada con un SDK de observabilidad (Langfuse/LangSmith) que capture prompt, model, tokens, cost y versión del prompt.
    2. Correlación: adjunta userId, sessionId y deployment/version tags a cada trace.
    3. Ignorar ruido: no envíes node_modules, logs grandes o secretos. Usa reglas de exclusión (.lfignore / .langsmith-ignore).
    4. Costeo por sesión: suma tokens y coste por sessionId y expón dashboards con coste por feature o cliente.
    5. Evaluación automatizada: configura un pipeline de “LLM-as-a-judge” para marcar respuestas sospechosas y crear datasets de retraining.
    6. Sandboxing y alertas: ejecuta tool calls en entornos aislados y genera alertas cuando spans ejecutan operaciones potencialmente destructivas.
    7. Auditoría y retenimiento: guarda prompts y respuestas (con enmascarado si hay datos sensibles) para reproducibilidad y cumplimiento.

    Operación y cultura: monitoreo como contrato

    No es sólo técnica: es proceso. Cada cambio en prompts o pipelines debe ir acompañado de: etiquetas de versión, tests de regresión en datasets de evaluación y despliegue progresivo (canary). Sin estos pasos, la observabilidad será un registro pasivo en lugar de un control activo.

    La regla final es simple: ningún agente a producción sin traces, coste por session y un mecanismo automático de evaluación. Si ignoras eso, no estás operando IA; estás apostando.

    Implementa observabilidad desde el primer sprint, usa Langfuse o LangSmith según tu arquitectura y organiza tus dashboards en rendimiento, coste y calidad. La visibilidad no es un lujo: es la única forma de mantener agentes de IA útiles, seguros y rentables en producción.

    Para equipos que construyen flujos, agentes o automatizaciones, una referencia práctica y recursos adicionales están disponibles en Dominicode Labs. Es una continuidad natural para explorar integración, pipelines de evaluación y despliegue controlado en proyectos de IA aplicada.

    FAQ

    ¿Por qué los APM tradicionales no detectan problemas de agentes de IA?

    Porque miden señales infraestructurales (HTTP, CPU, errores) pero no la veracidad semántica ni el consumo de tokens. Un agente puede devolver HTTP 200 y producir contenido incorrecto o costoso.

    ¿Qué debe contener un span para ser útil?

    Metadata mínima: tipo de acción (prompt, search, tool call), timestamps, latencia, modelo, tokens_in/tokens_out, coste estimado, userId/sessionId y versión del prompt.

    ¿Cómo calcular el coste por sesión?

    Suma los tokens y el coste asociado de todos los spans pertenecientes al mismo sessionId. Agrupa por workflow o por cliente para dashboards y alertas.

    ¿Cuándo elegir LangSmith sobre Langfuse?

    Elige LangSmith si tu stack está fuertemente integrado con LangChain/LangGraph y aprecias integración out-of-the-box. Evita si necesitas portabilidad o evitar vendor lock-in.

    ¿Qué es LLM-as-a-judge y para qué sirve?

    Es usar un modelo más económico para evaluar respuestas automáticamente como señal de calidad. Sirve para priorizar revisiones humanas y construir datasets de retraining, pero no debe ser el veredicto final.

    ¿Qué datos debo enmascarar al guardar prompts?

    Enmascara datos sensibles: PII, credenciales, secretos y cualquier información regulada. Guarda versiones y hashes cuando sea posible para reproducibilidad sin exposición directa.

  • Cómo estructurar patrones de indicaciones para Claude Code

    Cómo estructurar patrones de indicaciones para Claude Code

    Patrones de indicaciones, memoria, estructura del proyecto, subagentes, habilidades para Claude Code

    Tiempo estimado de lectura: 5 min

    • Ideas clave:
    • Claude Code necesita prompts estructurados y deterministas para operar de forma segura y efectiva.
    • Una memoria explícita (ej. CLAUDE.md) y una estructura de repo modular son indispensables.
    • Orquestar subagentes (p. ej. con n8n) reduce riesgo y carga cognitiva del agente principal.
    • Control estricto de habilidades (tool use) y entornos sandbox evita daños en producción.

    Introducción

    Patrones de indicaciones, memoria, estructura del proyecto, subagentes y habilidades para Claude Code son los cinco pilares que determinan si un agente CLI acelera tu ingeniería o genera deuda técnica silenciosa. Si no defines cómo hablarle, qué puede recordar, cómo está organizado el repo, cómo se subdividen las tareas y qué permisos tiene, Claude actúa a ciegas. Aquí tienes una guía práctica y accionable para poner orden.

    Resumen rápido (lectores con prisa)

    Claude Code es un operador que modifica código y ejecuta shells; requiere prompts deterministas, una memoria persistente en raíz (p. ej. CLAUDE.md), una estructura de repo modular, subagentes/orquestación para QA y control estricto de habilidades. Usa TDD y sandboxes antes de delegar cambios en producción.

    Claude Code como operador

    Claude Code no es un chatbot; es un operador que puede leer y modificar tu código, ejecutar shells y (en previews) automatizar UIs. La diferencia clave: requiere prompts estructurados, memoria explícita del proyecto, una arquitectura de repositorio que el agente pueda razonar, subagentes u orquestadores para tareas auxiliares y un control estricto de habilidades (tool use). Documentación útil: docs.anthropic — Claude Code y, para orquestación, n8n. Para novedades y previews (p. ej. Computer Use) revisa releasebot.dev.

    1) Patrones de indicaciones — cómo pedirle cosas a Claude Code

    No escribas prompts vagos. Usa plantillas deterministas:

    Patrón Contexto‑Restricción‑Acción

    Contexto: qué módulo, stack, rama. (“Servicio payments — Node.js/TS — branch feat/rate-limit”)

    Restricción: reglas innegociables. (“No tocar DB schema; no añadir deps externas”)

    Acción: objetivo con criterio verificable. (“Implementa rate limiting y añade tests que cubran 429; PR con test passing en CI es criterio de éxito”)

    Prompt de TDD (Test-Driven Prompting)

    – Paso 1: “Escribe el test que debería fallar”

    – Paso 2: pedir ejecución del test

    – Paso 3: solicitar la implementación hasta que los tests pasen

    Ejemplo de prompt (compacto):

    “Contexto: /services/payments, Node 18, TS. Restricción: no tocar migraciones. Acción: añade rate limiter en /api/charge; escribe tests unitarios y de integración; criterio: pipeline CI verde. Empieza por crear tests que fallen.”

    2) Memoria — cómo mantener contexto útil y persistente

    Claude Code construye su contexto leyendo el repo; no tiene intuición humana. Dos mecanismos clave:

    • Memoria de sesión (corto plazo): archivos abiertos y árbol activo. Evita saturarla con monorepos gigantes; abre solo lo necesario.
    • Memoria persistente (largo plazo): un archivo en la raíz que Claude lee siempre. Recomendación práctica:

    CLAUDE.md o .clauderc con:

    • Convenciones de estilo y nomenclatura
    • Comandos claves (tests, build, dev)
    • ADRs esenciales
    • Dependencias permitidas/prohibidas
    • Checklists de seguridad y compliance

    Este archivo convierte normas humanas en reglas ejecutables por el agente y reduce ambigüedad.

    3) Estructura del proyecto — diseño para agentes

    Diseña el repo pensando en unidades pequeñas y autocontenidas:

    • Modularidad: archivos <300 líneas, responsabilidades únicas.
    • Rutas semánticas: /auth/use-cases/login.ts en vez de /utils/helper9.ts.
    • Tipado estricto: TypeScript/Rust/Go ayudan al agente a validar cambios antes de ejecutarlos.
    • Tests como contrato: TDD + coverage mínimo hacen al agente predecible.

    Si el repo es un monolito acoplado, prioriza una fase de refactor (extract module) manual antes de delegar en agentes.

    4) Subagentes y orquestación — dividir para no perder contexto

    Claude Code aún no gestiona subagentes complejos de forma nativa. La práctica efectiva es orquestar subagentes externos:

    – Usa n8n o un orquestador propio para:

    • Ejecutar análisis estático en entornos aislados
    • Lanzar pipelines de seguridad y escaneo de dependencias
    • Devolver reportes al CLI para que Claude actúe sobre ellos

    Patrón típico:

    1. Claude genera un PR provisional.
    2. n8n ejecuta linters, SCA y tests en una VM sandbox.
    3. Resultado vuelve al CLI; Claude corrige y reitera.

    Así evitas que un único agente cargue demasiado contexto o tome decisiones incompletas.

    5) Habilidades (Tool Use) — permisos y límites

    Define explícitamente qué puede ejecutar el agente. Habilidades críticas:

    • Bash Execution: npm test, git, docker-compose — imprescindible para feedback real.
    • File System Access: lectura/escritura de archivos.
    • Semantic Search / Repo Index: para referencias cruzadas antes de modificar.
    • (Preview) Computer Use: interacción con UIs nativas — potente, frágil y debe usarse solo en sandboxes.

    Regla de oro: nunca habilites habilidades destructivas en máquinas con credenciales reales. Usa contenedores o VMs aisladas.

    Checklist mínimo de adopción antes de delegar tareas

    1. CLAUDE.md en raíz con políticas y comandos.
    2. Tests automatizados que sirvan de contrato.
    3. Entorno sandbox (Docker/VM) para ejecución.
    4. CI que valide PRs generados por el agente.
    5. Orquestador (n8n o similar) para subagentes de QA/security.
    6. Prompts basados en Contexto‑Restricción‑Acción y TDD.

    Conclusión

    Patrones de indicaciones, memoria, estructura del proyecto, subagentes y habilidades para Claude Code no son conceptos teóricos: son requisitos operativos. Implementados juntos, convierten a Claude en un multiplicador de capacidad. Si fallas en cualquiera, el agente acelera errores, no entrega. Empieza por documentar: CLAUDE.md, tests firmes y sandboxes. Luego automatiza, orquesta y vigila. Esto no acaba aquí: quien domine estas cinco piezas tendrá ventaja real al escalar agentes en ingeniería.

    Dominicode Labs

    Para equipos que integran automatización y orquestación de subagentes como parte de su plataforma de ingeniería, una continuación natural es explorar herramientas y patrones documentados en Dominicode Labs. La referencia ayuda a unir prácticas de prompts, memoria y sandboxes con flujos de trabajo reproducibles.

    FAQ

    ¿Qué es Claude Code y en qué se diferencia de un chatbot?

    Claude Code es un operador diseñado para leer y modificar repositorios, ejecutar comandos de shell y automatizar tareas. A diferencia de un chatbot, espera prompts estructurados y tiene habilidades (tool use) que deben definirse y limitarse explícitamente.

    ¿Qué debe contener un archivo CLAUDE.md?

    Debe incluir convenciones de estilo, comandos claves (tests/build/dev), ADRs importantes, dependencias permitidas/prohibidas y checklists de seguridad. Su propósito es convertir reglas humanas en referencia legible por el agente.

    ¿Cuándo debo usar subagentes u orquestadores?

    Úsalos cuando el pipeline requiera aislamiento (análisis estático, SCA, pruebas en sandbox) o cuando el agente principal necesite retroalimentación externa antes de cometer cambios. Orquestadores como n8n facilitan este patrón.

    ¿Qué habilidades del agente debo deshabilitar en producción?

    Deshabilita cualquier ejecución con acceso a credenciales reales o capacidad destructiva directa sobre entornos de producción. Mantén ejecución de bash y acceso a filesystem solo en contenedores/VMs aisladas.

    ¿Cómo aplicar TDD con Claude Code?

    Sigue el patrón: pide primero tests que fallen, ejecuta tests en sandbox, luego solicita la implementación hasta que los tests pasen. Define criterios de éxito claros (por ejemplo, pipeline CI verde) en el prompt.

    ¿Por qué modularizar archivos en <300 líneas?

    Archivos pequeños y responsabilidades únicas facilitan que el agente razone sobre cambios y reduzcan el riesgo de efectos colaterales imprevistos.

    ¿Qué papel juega CI en el flujo con agentes?

    CI actúa como guardián: valida PRs generados por el agente, ejecuta tests y linters y evita que cambios automatizados lleguen a producción sin verificación.

  • 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.

  • Implementando Claude Code para la automatización de desarrollo en Angular y NestJS

    Implementando Claude Code para la automatización de desarrollo en Angular y NestJS

    Claude Code como herramienta diaria de desarrollo

    Tiempo estimado de lectura: 5 min

    • Orquestación de tareas multi-archivo y ejecución de CLI para migraciones, generación de boilerplate y correcciones automáticas.
    • Requiere contexto persistente (ej. archivo CLAUDE.md) para evitar alucinaciones y errores arquitectónicos.
    • Útil para flujos repetibles y tests automatizados; no ideal para retoques UI o tareas atómicas simples.

    Resumen rápido (lectores con prisa)

    Claude Code es un agente orientado a orquestar tareas que implican múltiples archivos y ejecución de CLI. Úsalo cuando necesites migraciones, generación de boilerplate, tests y correcciones automáticas a partir de stack traces. No es la mejor opción para escribir una sola función o pulir UI.

    Por qué usar (o no) Claude Code en tu flujo diario

    Claude Code Claude Code está pensado para tareas que van más allá del autocompletado: migraciones, generación de boilerplate, tests y correcciones automáticas tras detectar fallos en la terminal. No es mejor que Copilot para escribir una función; es más útil cuando la tarea implica múltiples archivos y ejecución de CLI.

    Ventajas reales:

    • Orquestación multi-archivo y ejecución de comandos.
    • Correcciones automáticas tras leer stack traces.
    • Generación de tests y refactors repetibles.

    Limitaciones reales:

    • Consumo alto de contexto/token en sesiones largas.
    • Riesgo de sobreescritura si la instrucción es ambigua.
    • Posible bucle de corrección ante errores complejos.

    Decisión simple: úsalo para tareas de orquestación; no para retoques visuales ni diseño fino de UI.

    Preparación: cómo darle contexto al agente

    Sin contexto, el agente alucina. La práctica que funciona es tener un archivo de contexto que el agente lea antes de actuar. Crea CLAUDE.md en la raíz:

    # CLAUDE: reglas del repo
    Stack:
    - Backend: NestJS 10 (TypeScript estricto)  https://nestjs.com/
    - Frontend: Angular 17 (standalone components, Signals)  https://angular.io/
    
    Convenciones:
    - DTOs con class-validator
    - Servicios inyectados por constructor
    - Componentes standalone, sin NgModules
    - Commits en Conventional Commits
    

    Ese archivo actúa como prompt persistente. Reduce alucinaciones arquitectónicas y mejora resultados.

    Tutorial práctico: flujo real con NestJS y Angular

    Objetivo: crear recurso Products en backend (NestJS) y consumirlo desde Angular, con tests básicos.

    1) Generar recurso en NestJS

    En la carpeta del backend:

    # instrucción al agente
    claude "Lee CLAUDE.md. Genera recurso Products en NestJS: Controller, Service, DTO CreateProductDto con class-validator. Ejecuta npm run build y corrige errores."
    

    Qué hará:

    • Ejecutará nest g res products o creará manualmente los archivos.
    • Insertará DTOs con validaciones (@IsString, @IsNumber).
    • Ejecutará npm run build; si TypeScript falla, leerá el stack trace y aplicará correcciones iterativas.

    Ejemplo mínimo de DTO que el agente debe crear:

    // create-product.dto.ts
    import { IsString, IsNumber } from 'class-validator';
    export class CreateProductDto {
      @IsString()
      name: string;
    
      @IsNumber()
      price: number;
    }
    

    2) Consumir endpoint desde Angular

    En la carpeta del frontend:

    claude "Crea ProductService usando provideHttpClient y un componente ProductFormComponent standalone. Usa Signals para estado de formulario. Ejecuta ng build y corrige tipados."
    

    Qué esperar:

    • Creación de product.service.ts con funciones que llaman al endpoint.
    • ProductFormComponent standalone con Signals para isLoading y errors.
    • ng build que verifica tipado y dependencias; el agente corrige importaciones o tipos si hay fallos.

    Fragmento esperado en Angular:

    // product.service.ts (simplificado)
    import { inject } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    export const ProductService = () => {
      const http = inject(HttpClient);
      return {
        create: (payload: any) => http.post('/api/products', payload)
      };
    };
    

    3) Generar tests automatizados

    Comando recomendado:

    claude "Genera tests Jest para products.service.ts y products.controller.ts. Ejecuta npm run test y corrige mocks hasta que la suite pase."
    

    Valor: te ahorra el 70% del trabajo repetitivo de mocks y boilerplate.

    Riesgos y contramedidas operativas

    1. Trabaja siempre en una rama aislada:
      git checkout -b feat/claude-codex
      – Nunca en main o develop.
    2. Limita la ventana de contexto:
      – Corta sesiones largas. Ejecuta tareas atómicas y revisa resultados antes de continuar.
    3. Evita permisos globales de escritura en archivos sensibles:
      – Usa .claudeignore para bloquear rutas (si la herramienta lo soporta) o un wrapper que restrinja paths.
    4. Plan para fallos en node_modules:
      – Si entra en bucle, interrumpe y ejecuta npm ci o reinstala dependencias; luego reintenta con más contexto.

    Checklist para adopción en equipo

    • [ ] CLAUDE.md con convenciones del repo.
    • [ ] Branching obligatorio para sesiones de agente.
    • [ ] Scripts de CI que validen outputs generados por el agente.
    • [ ] Monitoreo de consumo de API/tokens.
    • [ ] Política interna para revisar commits automáticos antes de merge.

    Claude Code no es una varita mágica; es una herramienta poderosa si la gobiernas. Si empiezas documentando el proyecto y limitando sus permisos, te dará horas de productividad en tareas repetitivas y orquestación. Si no, corregirás borradores y rollbacks a mano. La diferencia está en las reglas y la disciplina.

    Relacionado: visita Dominicode Labs para ver experimentos y guías sobre agentes y automatización. Esta mención encaja como continuación lógica para equipos que exploran flujos de IA aplicada y agentes.

    FAQ

    ¿Qué es Claude Code y para qué sirve?

    Claude Code es un agente diseñado para orquestar tareas que implican múltiples archivos y comandos de terminal: migraciones, generación de boilerplate, tests y correcciones automáticas tras fallos. Es especialmente útil cuando la tarea requiere ejecutar CLI y aplicar cambios iterativos.

    ¿Cuándo debería usar Claude Code en lugar de Copilot?

    Usa Claude Code cuando la tarea sea multi-archivo, requiera ejecución de comandos o correcciones a partir de stack traces. Para pequeñas funciones o autocompletado local, Copilot suele ser más eficiente.

    ¿Cómo debo preparar mi repo antes de usar el agente?

    Crea un archivo de contexto persistente (por ejemplo CLAUDE.md) con stack, convenciones y reglas del repo. Trabaja en una rama aislada y asegúrate de tener scripts de CI que validen cambios automáticos.

    ¿Qué riesgos operativos debo mitigar?

    Principales riesgos: sobreescritura de archivos, consumo excesivo de tokens en sesiones largas y bucles de corrección. Mitígalo con ramas aisladas, límites de sesión y mecanismos para restringir paths sensibles (por ejemplo .claudeignore o wrappers).

    ¿Cómo integro tests automatizados en el flujo del agente?

    Pide al agente generar tests Jest para servicios y controladores, ejecutar npm run test y corregir mocks hasta que la suite pase. Complementa con scripts de CI que validen los cambios generados antes del merge.

    ¿Qué hacer si el agente entra en bucle de correcciones?

    Interrumpe la sesión, ejecuta npm ci o reinstala dependencias, revisa el contexto y reintenta con instrucciones más atómicas y detalladas. Limitar la ventana de contexto también ayuda a evitar bucles.