Category: Blog

Your blog category

  • Stack IA agéntica en 2026: qué usar, qué ignorar y cuál elijo

    Stack IA agéntica en 2026: qué usar, qué ignorar y cuál elijo

    El problema no es que falten herramientas para construir agentes de IA. Es que sobran.

    Hace unos meses, en una sesión de Dominicode Labs, me preguntaron cuál era el stack IA agéntica 2026 que recomendaba. Empecé a responder y me di cuenta de que tenía una respuesta para cada capa — pero no tenía una respuesta integrada. Llevo varios proyectos agénticos en producción en Dominicode y cada semana aparece un nuevo framework, un nuevo modelo, un nuevo “estándar imprescindible”.

    Qué modelo. Qué framework de orquestación. Qué hacer con la memoria. Cómo trazar lo que hace el agente. Dónde desplegarlo. Cada capa tiene sus propias opciones, sus propias compensaciones y su propio ecosistema de hype que no para de generar nuevas herramientas.

    Este post es mi respuesta integrada: el stack que yo uso, por qué elegí cada pieza y qué descarto con criterio. No es una lista de todas las herramientas que existen. Es una guía con tesis clara sobre qué funciona en producción cuando construyes con TypeScript, para un proyecto real, sin un equipo de 20 personas.


    Cómo pensar en el stack agéntico: capas, no herramientas

    Antes de hablar de herramientas específicas, el marco que uso para evaluar cualquier stack agéntico. Hay cinco capas y cada una resuelve un problema diferente:

    1. Modelo — el LLM que razona y toma decisiones
    2. Framework de agente — el runtime que envuelve el agentic loop
    3. Memoria y contexto — dónde vive la información entre sesiones y entre agentes
    4. Observabilidad — cómo ves qué está haciendo el agente
    5. Deployment — dónde corre el sistema en producción

    La mayoría de los posts sobre herramientas de IA mezclan estas capas y crean confusión. LangChain no compite con Claude — compite con el SDK de Anthropic. Langfuse no compite con Pinecone — resuelven problemas en capas completamente distintas.

    Cuando tienes claro qué capa resuelve cada herramienta, la decisión se vuelve mucho más simple. Si no tienes claro aún qué es el agentic loop y cómo funciona, empieza por aquí antes de elegir el stack.


    Capa 1: El modelo — quién razona

    La decisión más importante del stack y la que más gente toma al revés: eligen el modelo por el benchmark, no por el comportamiento en producción con herramientas.

    Los benchmarks de razonamiento abstracto no predicen bien si un modelo va a gestionar correctamente el agentic loop: respetar los límites de las herramientas, detectar cuándo ha completado el objetivo, no inventarse argumentos para las tool calls, pedir confirmación cuando tiene ambigüedad.

    Mi ranking para sistemas agénticos en 2026, basado en uso real:

    Claude Sonnet (Anthropic) — mi elección principal. La familia Claude 4.x lidera en comportamiento agéntico: sigue instrucciones complejas del sistema prompt con más fidelidad que los competidores, gestiona bien contextos de 200k tokens, y tiene el menor índice de “tool hallucination” — inventarse argumentos para herramientas que no existen o llamar a herramientas con parámetros incorrectos. Para proyectos donde el agente tiene acceso a herramientas reales con consecuencias (escritura a disco, llamadas a APIs, base de datos), esta fidelidad importa.

    Gemini 2.5 Pro (Google) — segunda opción para tareas de análisis. Tiene una ventana de contexto de 1M tokens que es genuinamente útil cuando el agente necesita procesar documentos grandes. El razonamiento es sólido. La API tiene más latencia que Anthropic en llamadas con herramientas. Lo uso puntualmente para tareas de análisis de documentos extensos, no como backbone de un sistema agéntico.

    GPT-4o (OpenAI) — bueno, pero no es mi primera elección para agentes. Excelente en tareas de generación pura. En agentic loops de más de 15 iteraciones, he visto más context drift que con Claude. Para proyectos que ya tienen infraestructura en el ecosistema OpenAI, es perfectamente válido.

    Llama 3.x local (Meta) — para casos específicos, no como base. Los modelos locales tienen su lugar: privacidad total, sin costos por token, sin latencia de red. Pero para sistemas agénticos complejos, la diferencia en calidad de razonamiento con los modelos de frontera es demasiado grande hoy. Los uso para tareas de clasificación simple o cuando los datos no pueden salir del entorno.

    La conclusión práctica: empieza con Claude Sonnet. Si los costos escalan y la tarea lo permite, evalúa migrar partes del sistema a modelos más baratos para subtareas que no requieren razonamiento complejo.


    Capa 2: El framework de agente — quién orquesta el loop

    Aquí está la decisión que más polémica genera, porque hay muchas opciones y cada una tiene su comunidad apasionada.

    Mi posición es clara: el framework que elijas debería desaparecer de tu código. Si tu lógica de negocio está mezclada con abstracciones del framework, tienes un problema de arquitectura, no de elección de herramienta.

    Vercel AI SDK — mi elección para TypeScript

    Para proyectos TypeScript, el Vercel AI SDK es el estándar más sólido hoy. Tiene tres propiedades que importan:

    Primero, la abstracción es mínima. generateText, streamText, generateObject — funciones que hacen lo que dicen, con un tipo de retorno predecible. Puedes leer el código del SDK y entender qué ocurre.

    Segundo, es agnóstico al proveedor. El mismo código funciona con Claude, GPT-4o y Gemini. Cambias el adaptador, no la lógica. En un año donde los modelos evolucionan rápido, esto no es un detalle menor.

    Tercero, tiene soporte nativo para tool use, streaming de respuestas y generateObject con schemas Zod — lo que significa que puedes hacer que el modelo devuelva JSON tipado sin analizadores de texto frágiles.

    import { generateText } from "ai";
    import { anthropic } from "@ai-sdk/anthropic";
    import { z } from "zod";
    
    

    const result = await generateText({ model: anthropic("claude-sonnet-4-6"), // verifica el modelo vigente en docs.anthropic.com/models tools: { readFile: { description: "Lee el contenido de un archivo del proyecto", parameters: z.object({ path: z.string() }), execute: async ({ path }) => fs.readFile(path, "utf-8"), }, }, messages: [{ role: "user", content: userQuery }], maxSteps: 15, // límite de iteraciones del loop });

    El parámetro maxSteps es el límite de iteraciones del agentic loop. No lo omitas nunca. Un agente sin límite de pasos en producción es un bug esperando a ocurrir.

    LangGraph — cuando necesitas flujos con estado y ramificaciones

    LangGraph (de LangChain) resuelve un problema diferente: orquestación de flujos donde el camino de ejecución no es lineal. Si tienes un sistema donde el agente puede ir por diferentes ramas según el resultado de un paso anterior, donde necesitas estado persistente entre sesiones, o donde hay handoffs entre múltiples agentes con condiciones complejas — LangGraph tiene primitivas para eso.

    No es mi primera elección para proyectos simples porque añade complejidad conceptual. Pero para sistemas multi-agente con lógica de routing elaborada, es genuinamente más potente que construir esa lógica a mano.

    SDK de Anthropic directo — para control total

    Cuando necesito control máximo sobre cada llamada a la API, uso el SDK de Anthropic directamente. Sin abstracciones intermedias. El agentic loop lo implemento yo, con la lógica exacta que necesito.

    Esto es lo que haría si estuviera construyendo el loop desde cero con el SDK directo — el mismo patrón que cubro en detalle en el curso Construye con IA:

    import Anthropic from "@anthropic-ai/sdk";
    
    

    const client = new Anthropic();

    async function runAgentLoop(userMessage: string, tools: Tool[]) { const messages: Anthropic.MessageParam[] = [ { role: "user", content: userMessage }, ];

    let iterations = 0; const maxIterations = 20;

    while (iterations < maxIterations) { const response = await client.messages.create({ model: "claude-sonnet-4-6", // verifica en docs.anthropic.com/models max_tokens: 4096, tools, messages, });

    // Si el modelo no llama a ninguna herramienta, ha terminado if (response.stop_reason === "end_turn") { return extractTextResponse(response); }

    // Procesa las tool calls y añade los resultados al contexto const toolResults = await executeToolCalls(response.content); messages.push({ role: "assistant", content: response.content }); messages.push({ role: "user", content: toolResults });

    iterations++; }

    throw new Error(Agente excedió el límite de ${maxIterations} iteraciones); }

    Lo que no uso: CrewAI, AutoGen, AgentGPT ni la mayoría de frameworks Python-first para proyectos TypeScript. No porque sean malos — CrewAI tiene ideas interesantes sobre roles y colaboración entre agentes — sino porque añadir Python al stack cuando ya tienes TypeScript es complejidad operacional que no se justifica en la mayoría de casos. Si tu equipo es Python, la ecuación cambia.


    Capa 3: MCP — el protocolo que está cambiando todo

    El Model Context Protocol (MCP) merece su propio apartado porque no es un framework de agentes. Es un estándar de comunicación — el equivalente a REST para que los agentes consuman herramientas y contexto de fuentes externas de forma estandarizada.

    Antes de MCP, cada herramienta que querías darle a un agente requería código de integración específico. Con MCP, una herramienta bien construida se puede conectar a cualquier agente que soporte el protocolo — Claude Code, Cursor, tu propio agente custom.

    Las implicaciones son grandes: en lugar de construir integraciones punto a punto, construyes servidores MCP reutilizables. Ya existe un ecosistema de servidores MCP públicos para GitHub, bases de datos, sistemas de archivos, APIs populares.

    // Un servidor MCP mínimo con el SDK oficial
    import { Server } from "@modelcontextprotocol/sdk/server/index.js";
    import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
    import { ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
    
    

    const server = new Server( { name: "dominicode-tools", version: "1.0.0" }, { capabilities: { tools: {} } } );

    server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: "get_post_metrics", description: "Obtiene métricas de un post del blog por slug", inputSchema: { type: "object", properties: { slug: { type: "string" } }, required: ["slug"], }, }, ], }));

    const transport = new StdioServerTransport(); await server.connect(transport);

    En 2026, si construyes herramientas para agentes y no las expones como servidores MCP, estás construyendo para un solo cliente. El ecosistema ya se está moviendo en esta dirección — Anthropic, OpenAI, Google y la mayoría de los frameworks de agentes tienen soporte nativo para MCP.


    Capa 4: Memoria y contexto persistente

    El problema de la memoria en agentes agénticos tiene tres dimensiones distintas y cada una necesita una solución diferente.

    Memoria conversacional (corto plazo) — el historial de mensajes de la sesión actual. La gestión correcta es mantenerlo en el contexto de la llamada al LLM. El truco está en la truncación inteligente: cuando el contexto se acerca al límite, no cortes los mensajes más antiguos a ciegas — resume las iteraciones antiguas y mantén los más recientes completos.

    Memoria semántica (búsqueda por similaridad) — para cuando el agente necesita recuperar información relevante de una base de conocimiento grande. Las opciones que uso:

    • pgvector — extensión de PostgreSQL. Si ya tienes Postgres en el stack (y probablemente lo tienes), añadir pgvector es añadir una extensión. No necesitas otra base de datos. Para la mayoría de proyectos con menos de diez millones de embeddings, pgvector es suficiente y elimina complejidad operacional.
    • Pinecone — la opción gestionada cuando el volumen es grande o quieres zero-ops. Más caro, más simple. Para proyectos en fases tempranas con presupuesto ajustado, pgvector primero.
    • Supabase pgvector — pgvector sobre Supabase. La que uso en proyectos nuevos porque ya tengo Supabase en el stack para auth y database.

    Memoria episódica (estado entre sesiones) — lo que el agente recuerda de sesiones anteriores con un usuario específico. Esto no es búsqueda vectorial: es estado estructurado que guardas en una tabla normal. El patrón que funciona es guardar un JSON con los hechos relevantes del usuario o proyecto y cargarlo al inicio de cada sesión como parte del system prompt.

    // Carga el estado de memoria al inicio de la sesión
    async function buildSystemPromptWithMemory(userId: string): Promise<string> {
      const memory = await db.query<UserMemory>(
        "SELECT facts FROM agent_memory WHERE user_id = $1",
        [userId]
      );
    
    

    const memoryContext = memory.rows[0]?.facts ? \n\nContexto previo del usuario:\n${JSON.stringify(memory.rows[0].facts, null, 2)} : "";

    return Eres un asistente técnico de Dominicode.${memoryContext}; }


    Capa 5: Observabilidad — ver lo que hace el agente

    Sin observabilidad, un agente en producción es una caja negra que factura. Ya hay un post completo en este blog sobre cómo instrumentar tus agentes con Langfuse y OpenTelemetry, así que aquí voy directo a las decisiones de stack:

    Langfuse — la elección por defecto. Open source, autohospedable, SDK para TypeScript con integración nativa en el Vercel AI SDK. Con un experimental_telemetry en la llamada tienes trazas completas:

    const result = await generateText({
      model: anthropic("claude-sonnet-4-6"), // verifica el modelo vigente en docs.anthropic.com/models
      messages,
      tools,
      experimental_telemetry: { // en Vercel AI SDK v4+ puede ser telemetry sin el prefijo
        isEnabled: true,
        metadata: { userId, sessionId, operationType: "support-agent" },
      },
    });

    OpenTelemetry GenAI — si ya tienes infraestructura OTEL en la empresa, las semantic conventions para IA generativa te permiten integrar las trazas de tus agentes en Grafana, Datadog o Honeycomb sin añadir otra plataforma.

    Helicone — proxy sin código si necesitas observabilidad inmediata sin instrumentar. Un cambio de base URL y tienes dashboards. Útil para proyectos donde no puedes tocar el código de integración.


    Capa 6: Deployment — dónde vive el agente en producción

    Las opciones razonables en 2026, con criterio claro sobre cuándo usar cada una:

    Railway — mi primera opción para agentes con estado o procesos de larga duración. Soporta WebSockets, procesos persistentes y tiene buena DX con Docker. Para agentes que necesitan mantener conexiones abiertas o procesar en background, Railway es más natural que Vercel.

    Vercel — ideal para agentes stateless que responden a webhooks o peticiones HTTP. La integración con el Vercel AI SDK es perfecta — maxDuration hasta 300 segundos en planes Pro es suficiente para la mayoría de las respuestas agénticas. Para workflows que duran minutos, necesitas otra opción.

    Cloudflare Workers + Durable Objects — la opción de mayor rendimiento para agentes edge. Durable Objects resuelve el problema de estado en entornos serverless de forma elegante. La curva de aprendizaje es mayor, pero el resultado en latencia y coste a escala es difícil de igualar.

    Docker + VPS — cuando necesitas control total, costos predecibles a escala media y no quieres depender de plataformas específicas. Es lo que uso para los agentes internos de Dominicode que corren de forma continua.

    Una regla práctica: si el agente responde en menos de 30 segundos y no necesita estado entre llamadas, serverless es suficiente. Si el agente trabaja durante minutos, mantiene conexiones o necesita acceso a recursos locales, necesitas un proceso persistente.


    Mi stack en Dominicode: la versión concreta

    Sin rodeos. Esto es exactamente lo que uso:

    Capa Herramienta Por qué
    Modelo principal Claude Sonnet (Anthropic) Mejor comportamiento en agentic loops, 200k contexto
    Modelo para análisis Gemini 2.5 Pro Contexto 1M para documentos grandes
    Runtime Bun Arranque más rápido, compatibilidad TS nativa, fetch nativo
    Framework de agente Vercel AI SDK Tipado TS sólido, agnóstico al proveedor, maxSteps nativo
    Herramientas custom MCP servers propios Reutilizables entre agentes, estándar abierto
    Memoria semántica Supabase + pgvector Postgres ya en el stack, zero overhead operacional
    Memoria episódica Postgres (tabla JSON) No necesita búsqueda vectorial, estado estructurado
    Observabilidad Langfuse cloud Open source, free tier generoso, integración VAISDK
    Deployment (agentes web) Vercel Integración natural con el SDK
    Deployment (procesos) Railway + Docker Agentes de larga duración, procesos internos
    Validación Zod Schemas para tool inputs y outputs tipados

    La parte que más me preguntan es el runtime: por qué Bun y no Node. La respuesta corta: en scripts de agentes que arrancan y terminan frecuentemente, la diferencia de arranque es perceptible. El soporte nativo de TypeScript elimina el paso de transpilación en scripts de herramientas. Y fetch nativo sin polyfills simplifica el código de integración con APIs externas.


    Lo que descarto y por qué

    LangChain (la librería base) — demasiada abstracción sobre abstracciones. El problema no es que sea mala herramienta: es que cuando algo falla en un agente LangChain, la pila de herencia de clases hace que depurar sea más difícil que si hubieras implementado el loop a mano. LangGraph tiene más sentido para flujos complejos, pero la librería base la evito.

    AutoGen (Microsoft) — interesante para investigación, inconsistente en producción. El modelo de conversación entre agentes es elegante en teoría, pero en proyectos reales he visto bucles de conversación que consumen tokens sin converger. Puede mejorar, pero hoy no lo usaría para un sistema que atiende usuarios reales.

    Pinecone como primera opción — no porque sea malo, sino porque pgvector en Postgres elimina una dependencia externa para la mayoría de los casos de uso. Cuando el volumen de embeddings supere los diez millones o necesites búsquedas en milisegundos a escala muy alta, Pinecone tiene sentido. Antes, no.

    Modelos locales como backbone — la brecha de calidad con los modelos de frontera es demasiado grande para sistemas agénticos complejos. Para clasificación de intenciones sencillas o filtros de moderación, tiene sentido. Para el loop principal de un agente que toma decisiones consecuentes, no lo haría hoy.


    El stack no es el problema

    La decisión de stack importa — pero menos de lo que sugiere el volumen de contenido que se publica sobre herramientas de IA cada semana.

    He visto proyectos con el stack perfecto que fallaban en producción por falta de observabilidad. He visto proyectos con stacks “incorrectos” que funcionaban perfectamente porque el equipo entendía qué estaba haciendo.

    El stack es el entorno. Lo que importa es entender cómo funciona el agentic loop, cómo diseñar herramientas que el modelo pueda usar de forma predecible, y cómo instrumentar el sistema para ver qué ocurre cuando algo falla.

    Si quieres construir esto desde cero con criterio — desde el primer loop hasta el sistema completo en producción — en el curso Construye con IA cubrimos exactamente estas decisiones: qué stack elegir para cada tipo de proyecto, cómo estructurar el código para que sea mantenible, y cómo pasar de prototipo a sistema que funciona cuando no estás mirando.

    Y si quieres el marco metodológico para especificar el sistema antes de escribir una línea de código — evitar construir el agente equivocado — el libro de Spec-Driven Development es la guía que yo sigo antes de abrir el editor.


    FAQ — Preguntas frecuentes sobre el stack de IA agéntica

    ¿Qué framework de agentes es mejor en 2026: Vercel AI SDK, LangGraph o el SDK directo de Anthropic?

    Depende de la complejidad del sistema. Para la mayoría de proyectos TypeScript con flujos lineales, el Vercel AI SDK ofrece el mejor equilibrio entre abstracción mínima y productividad: tipado sólido, soporte nativo para tool use y streaming, y compatibilidad con múltiples proveedores. LangGraph añade valor cuando el flujo tiene ramificaciones complejas, estado persistente entre pasos o múltiples agentes con routing condicional. El SDK directo de Anthropic tiene sentido cuando necesitas control total sobre cada llamada o cuando las abstracciones intermedias ocultan comportamiento que necesitas ver.

    ¿Necesito una base de datos vectorial para construir un agente?

    No necesariamente. La memoria vectorial solo es necesaria cuando el agente necesita recuperar información relevante de un corpus grande de documentos. Si el agente trabaja con un contexto fijo que cabe en la ventana de contexto del modelo (y con 200k tokens de Claude, cabe mucho), no necesitas embeddings ni búsqueda vectorial. Cuando el corpus supera lo que cabe en contexto, empieza por pgvector en Postgres antes de añadir Pinecone u otra base de datos vectorial externa.

    ¿Qué es MCP y por qué debería importarme en 2026?

    El Model Context Protocol es un estándar abierto que define cómo los agentes de IA consumen herramientas y contexto de fuentes externas. Su importancia práctica: en lugar de construir integraciones específicas para cada agente que quieras conectar a una herramienta, construyes un servidor MCP una vez y cualquier agente compatible puede usarlo. Claude Code, Cursor y la mayoría de los IDEs con IA ya soportan MCP. Si construyes herramientas para agentes hoy, exponerlas como servidores MCP multiplica su utilidad sin trabajo adicional.

    ¿Puedo usar Python para construir el stack agéntico si ya soy developer Python?

    Sí, y tiene sentido si Python es tu lenguaje principal. El ecosistema de agentes en Python es más maduro en algunos aspectos: LangChain, AutoGen, CrewAI y la mayoría de frameworks de referencia nacieron en Python. Lo que pierdes en TypeScript: algunas integraciones no tienen SDK Python equivalente al mismo nivel de calidad. Lo que ganas: ecosistema de ML más rico y más documentación de referencia. La decisión debe estar en el lenguaje que dominas, no en el que tiene más hype.

    ¿Cómo elijo entre Railway y Vercel para desplegar un agente?

    La regla práctica: si el agente responde a peticiones HTTP en menos de 60 segundos y no necesita mantener estado entre llamadas, Vercel Functions es suficiente y más simple. Si el agente trabaja en procesos de larga duración (más de un minuto), necesita WebSockets, mantiene conexiones persistentes, o accede a recursos locales del servidor, Railway con un contenedor Docker es la opción correcta. Cloudflare Workers + Durable Objects es la tercera opción para máxima performance edge cuando el coste a escala importa.

    ¿Qué herramienta de observabilidad recomendarías empezar primero?

    Langfuse. El plan gratuito en cloud cubre 50.000 observaciones al mes, la integración con el Vercel AI SDK es de una línea de código (el parámetro experimental_telemetry), y si en algún momento necesitas privacidad total de los datos, puedes autohospedarlo con Docker. Si ya tienes infraestructura OpenTelemetry en la empresa, las semantic conventions GenAI de OTEL te permiten integrar sin añadir otra plataforma.


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

  • Las 4 habilidades que definen al programador en la era de la IA

    Las 4 habilidades que definen al programador en la era de la IA

    Un cliente me llamó a las 11 de la noche. Me dijo que su equipo llevaba tres semanas con Claude Code y que la productividad se había disparado. Más código por sprint. Menos bugs. Entregas más rápidas.

    Pero había un problema.

    "Bezael, el equipo construye muy rápido. El problema es que construye muy rápido la cosa equivocada."

    Tres semanas generando código con IA. Código correcto, bien estructurado, con tests. Y un producto que no resolvía lo que el cliente necesitaba.

    Ese es el nuevo riesgo para el programador en la era de la IA. No que la IA te reemplace escribiendo código. Sino que la velocidad de producción amplifique el coste de tomar decisiones equivocadas. Antes tardabas un mes en construir algo mal. Ahora tardas tres días.

    Lo que separa a los developers que avanzan de los que se atascan no son sus habilidades técnicas. Son cuatro habilidades del programador en la era de la IA que ningún LLM puede suplir.


    Las habilidades del programador en la era de la IA que este post desarrolla son cuatro: entender el problema real antes de escribir una línea, comunicar la solución a stakeholders no técnicos, especificar con precisión lo que el agente debe construir, y negociar trade-offs cuando los requisitos chocan. Son las habilidades que la IA no puede ejecutar por ti — y las que determinan si su velocidad se convierte en ventaja o en ruido.


    Por qué el código ya no es el cuello de botella del programador en la era IA

    Durante veinte años el cuello de botella en el desarrollo de software fue escribir el código. Encontrar developers. Escalar equipos. Mantener la velocidad.

    Eso ha cambiado.

    Hoy un developer con Claude Code puede producir en un día lo que antes llevaba una semana. Los agentes no se cansan, no tienen bloqueos creativos, y no discuten sobre si usar tabs o spaces. El Stack Overflow Developer Survey 2025 documenta que más del 75% de developers ya usa o planea usar herramientas de IA en su flujo de trabajo — el cambio está aquí.

    Pero los agentes hacen exactamente lo que les pides. Ni más, ni menos. Y si lo que les pides es impreciso, ambiguo, o directamente equivocado, producen código impecable que resuelve el problema equivocado.

    El cuello de botella se ha desplazado. Ya no está en escribir. Está en pensar.


    Habilidad 1: Entender el problema real antes de abrir el editor

    Esta es la más subestimada y la que más dinero cuesta cuando falla.

    Un cliente te dice: "Necesitamos un dashboard con métricas en tiempo real." Un developer técnico abre el editor y empieza a pensar en WebSockets, en qué charting library usar, en cómo estructurar el backend.

    Un developer con criterio hace una pregunta primero: "¿Para qué vas a usar ese dashboard? ¿Quién lo mira y qué decisión toma a partir de lo que ve?"

    Esa pregunta cambia todo.

    A veces el dashboard en tiempo real que pedían era en realidad un email diario con tres métricas. A veces era un CSV que se cargaba en Excel. A veces ni siquiera era un problema de visualización — era un problema de que nadie en la empresa sabía qué datos tenía disponibles.

    Con IA esto se vuelve crítico. Porque ahora la velocidad de producción es tan alta que el coste de empezar en la dirección equivocada es enorme. Construyes tres features completas en el tiempo que antes tardabas en escribir media. Si las tres están mal orientadas, has quemado tres veces más tiempo que antes.

    La habilidad de entender el problema real — no el síntoma que te describen, sino la causa raíz que lo genera — es la que protege todo lo demás.

    No se aprende con más cursos de programación. Se aprende haciendo preguntas incómodas antes de escribir una línea.


    Habilidad 2: Comunicar la solución a quien no es técnico

    El código más elegante del mundo no vale nada si nadie en la empresa entiende qué resuelve ni por qué importa.

    Esto ha sido siempre un problema para los developers. Pero con IA se vuelve más urgente, porque ahora eres capaz de construir cosas más complejas, más rápido, con más capas de abstracción. Y cuanto más complejo es lo que construyes, más difícil es explicarlo a quien toma las decisiones de negocio.

    La comunicación técnica a stakeholders no técnicos no es "simplificar para que lo entienda un niño". Es traducir impacto.

    Un stakeholder no necesita entender cómo funciona una cola de mensajes asíncrona. Necesita entender que gracias a esa cola, el sistema puede procesar diez mil pedidos en paralelo sin que ningún usuario espere más de dos segundos. Eso sí lo entiende. Y eso sí cambia cómo percibe el valor de lo que has construido.

    Esta habilidad también protege tu trabajo. Si tu contribución es invisible para quien decide los presupuestos, eres vulnerable. Si puedes hacer visible el impacto técnico en términos de negocio, eres indispensable.

    Practica esto: después de cada feature que entregues, escribe en dos frases qué problema de negocio resuelve y qué habría pasado sin ella. Si no puedes hacerlo, tienes un problema antes de que alguien externo lo detecte.

    Hay un ejercicio que funciona muy bien para esto: antes de la próxima reunión de sprint, prepara una explicación de lo que estás construyendo en menos de 60 segundos, sin usar términos técnicos. Si necesitas más tiempo o tienes que recurrir al jargon, la feature aún no está suficientemente clara en tu cabeza. Esa claridad — la que te permite explicarla en voz alta — es exactamente la que también necesitas para especificarla bien para un agente.

    Esta habilidad se conecta directamente con la siguiente. Un developer que no puede explicar lo que construye a un humano tampoco puede especificarlo con precisión para una máquina.


    Habilidad 3: Especificar con precisión lo que el agente debe construir

    Esta es la habilidad nueva. La que no existía como tal hace tres años y que ahora es central.

    Los agentes de IA son ejecutores extraordinarios de instrucciones precisas. Son ejecutores pésimos de instrucciones vagas.

    "Construye un sistema de autenticación" puede producir cualquier cosa desde un JWT básico hasta un sistema OAuth completo con múltiples proveedores y gestión de sesiones. El agente hará algo. Y lo que haga puede ser técnicamente correcto y completamente inadecuado para tu contexto.

    Especificar bien significa definir:

    1. Qué hace el sistema — comportamiento concreto, no intención abstracta
    2. Qué NO hace — los límites son tan importantes como las funcionalidades
    3. Bajo qué restricciones — tecnología, rendimiento, compatibilidad, seguridad
    4. Cómo se valida que está correcto — criterios de aceptación verificables

    Si quieres entender mejor el perfil completo del developer que trabaja con agentes en producción, el post sobre qué es un Agentic Engineer cubre ese rol con detalle. La especificación es su primer requisito.

    Llevo varios años aplicando una metodología para esto que llamo Spec-Driven Development. La idea es que antes de que el agente escriba una línea, tienes un documento que responde esas cuatro preguntas. No un documento largo ni burocrático — uno preciso. El Libro SDD documenta este proceso completo, desde cómo estructurar la especificación hasta cómo convertirla en tareas que un agente puede ejecutar sin desviarse.

    La diferencia entre un developer que especifica bien y uno que no lo hace no se mide en velocidad. Se mide en cuánto código hay que tirar a la basura al final de cada sprint.


    Habilidad 4: Negociar trade-offs cuando los requisitos chocan

    Los requisitos siempre chocan. Siempre.

    "Quiero que sea seguro, rápido, barato, flexible y que esté listo para el martes." No puedes tener las cinco cosas. Nunca has podido. Pero antes la conversación sobre qué sacrificar era más lenta porque construir era más lento. Ahora, con la velocidad que da la IA, la presión para tomarlo todo aumenta.

    Un developer que sabe negociar trade-offs no es el que cede ante la presión del cliente. Es el que hace explícito el coste de cada decisión y ayuda a quien decide a entender qué están eligiendo realmente.

    "Si priorizamos velocidad de lanzamiento, el sistema no va a escalar bien por encima de diez mil usuarios. Podemos lanzar en dos semanas con esa limitación asumida, o lanzar en seis semanas con una arquitectura que aguante cien mil. ¿Qué es más importante ahora mismo para el negocio?"

    Esa conversación requiere que el developer entienda el negocio suficientemente bien como para hacer la pregunta correcta. Requiere que sepa comunicar la implicación técnica en términos de impacto. Y requiere que tenga la seguridad de plantear la conversación antes de que los problemas aparezcan en producción.

    Con agentes de IA esto se vuelve más delicado porque la velocidad de implementación hace que sea tentador no tener esa conversación. "Lo construimos rápido, si no funciona lo cambiamos." Pero cambiar una decisión arquitectural después de que cuatro features dependen de ella no es barato, aunque la IA escriba el código.

    En el curso Construye con IA dedicamos una parte específica a cómo estructurar estas conversaciones antes de empezar a generar código — porque los errores más costosos no son de sintaxis, son de dirección.


    Las habilidades del programador que la IA no puede reemplazar

    La IA escribe código. Lo depura. Lo refactoriza. Lo documenta. Lo testea.

    No puede entrar a una reunión y detectar que lo que el cliente pide en realidad responde a un miedo que no ha verbalizado. No puede leer el contexto político de una organización para entender por qué un requisito existe. No puede mirar los ojos de un stakeholder y saber que cuando dice "necesitamos esto para el viernes" en realidad está diciendo "si esto no sale el viernes, me cuesta el trabajo".

    Esas lecturas son humanas. Y en un entorno donde el código se genera en segundos, son el verdadero diferencial.

    Los developers que van a crecer en los próximos años no son los que más saben de LLMs. Son los que combinan criterio técnico con las habilidades de comunicación, especificación y negociación que hacen que ese criterio tenga impacto.


    El developer que va a sobrevivir a la IA

    No es el que sabe más frameworks.

    No es el que tiene mejores prompts para Claude.

    Es el que puede entrar en una sala con personas técnicas y no técnicas, entender lo que realmente está en juego, definir con precisión lo que hay que construir, y explicar con claridad por qué ciertas cosas no se pueden tener al mismo tiempo.

    Este cambio de rol — de ejecutar tareas a tomar decisiones con criterio — es lo que ya analizamos en profundidad en el post sobre el programador que se convierte en product builder. Las cuatro habilidades de este post son el motor que hace posible ese salto.

    La IA amplifica la velocidad de ejecución. Las cuatro habilidades de las que hablamos hoy amplifican la calidad de las decisiones. Y en software, las decisiones siempre cuestan más que el código.

    En Dominicode Labs trabajamos estos temas con developers que están construyendo con IA en proyectos reales — no ejercicios de academia, sino productos con usuarios, deadlines, y stakeholders que necesitan respuestas los lunes por la mañana.

    Si quieres empezar hoy, elige la habilidad que sabes que tienes más floja de las cuatro y pasa esta semana ejerciéndola deliberadamente. Una conversación con un stakeholder. Un documento de especificación antes de abrir el editor. Una pregunta incómoda que no has hecho todavía.

    El código lo escribe la IA. El criterio lo pones tú.


    Preguntas frecuentes

    ¿Estas habilidades sustituyen al conocimiento técnico profundo?
    No, lo complementan. Sin base técnica sólida no puedes especificar bien ni negociar trade-offs con conocimiento de causa. Lo que cambia es que el conocimiento técnico ya no es suficiente por sí solo — necesitas combinarlo con estas capacidades para que tenga impacto real. Un developer que solo sabe programar pero no puede comunicar ni especificar ni negociar tiene cada vez menos diferencial frente a un agente de IA.

    ¿Cómo se aprende a especificar para agentes de IA si nunca lo he hecho?
    Empieza por escribir, antes de cualquier tarea, un documento de dos párrafos: uno con lo que el sistema debe hacer y uno con lo que no debe hacer. Con ese ejercicio simple ya estás especificando. A medida que lo practiques, irás añadiendo restricciones, criterios de aceptación y contexto. La metodología Spec-Driven Development es un marco más completo para esto, documentado en el Libro SDD.

    ¿Estas habilidades son más importantes para freelancers que para developers en empresa?
    Son importantes en los dos contextos, pero de formas distintas. El freelance que no sabe comunicar ni negociar pierde clientes. El developer en empresa que no sabe hacer estas cosas se queda estancado en roles de ejecución y ve cómo los que ascienden son los que saben tener las conversaciones difíciles. En ambos casos, la consecuencia de no desarrollarlas es la misma: invisibilidad.

    ¿La velocidad que da la IA no hace que estos trade-offs sean menos importantes porque "se puede cambiar todo fácilmente"?
    Es una trampa común. Sí, la IA acelera la implementación. Pero hay decisiones — de arquitectura, de modelo de datos, de contratos de API — que una vez tomadas son costosas de cambiar aunque el código lo escriba un agente.

    Si tu base de datos está mal modelada, reescribir las queries con IA no resuelve el problema. El coste de las malas decisiones estructurales no ha bajado con la IA.

    Lo que ha bajado es el coste de implementar la decisión, buena o mala. Eso amplifica el impacto de decidir bien tanto como el de decidir mal.

    ¿Existe algún perfil técnico donde estas habilidades no importan?
    Si trabajas en investigación pura, en open source sin usuarios directos, o en roles muy especializados de bajo nivel donde el contacto con stakeholders es mínimo, el peso relativo de estas habilidades es menor. Pero para la mayoría de developers que trabajan en productos, servicios o consultoría — que es la mayoría — estas cuatro capacidades son cada vez más determinantes para el crecimiento profesional.


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

  • Proyecto greenfield con SDD: spec global + slices verticales

    Proyecto greenfield con SDD: spec global + slices verticales

    Hace unas semanas un developer del canal me contó lo que había pasado en su último proyecto.

    Seis horas. Eso tardó en planificar un proyecto greenfield con SDD usando slices verticales. Tenía un spec global, features bien definidas, tareas granulares. Parecía perfecto.

    Ejecutó el primer slice con su agente IA. La app funcionaba. Autenticación, flujo de datos, navegación — todo correcto.

    Y era completamente gris. Sin estilos. Sin diseño. Una interfaz que parecía sacada de 1998.

    No había especificado nada sobre la UI en su spec. Ni colores, ni componentes, ni sistema de diseño. El agente hizo exactamente lo que se le pidió: implementar la lógica. Y lo hizo bien.

    El problema no era el agente. Era el spec.

    El error que nadie te dice sobre SDD en proyectos nuevos

    Spec-Driven Development (SDD) es una metodología en la que cada feature comienza con un documento de especificación estructurado — el spec — antes de escribir código. El spec define qué hace la feature, cómo se ve, y qué criterios debe cumplir para considerarse completa.

    Cuando descubres SDD, la primera intuición es clara: especifica todo antes de escribir una línea de código. Visión, usuarios, funcionalidades, arquitectura, flujos.

    Y esa intuición es correcta… pero incompleta.

    Hay dos errores que se cometen casi siempre en un proyecto greenfield con SDD:

    El primero es intentar especificar el proyecto completo antes de tocar el teclado. Un spec monolítico de 40 páginas que detalla hasta la última feature antes de que exista una sola línea de código. Es atractivo. Se siente seguro. Y casi siempre es un error.

    El segundo es lo que le pasó a ese developer: especificar las features en términos de lógica y flujos, pero olvidar que las features tienen una cara visible. Que los usuarios las ven. Que el diseño no es una capa que se añade al final — es parte de la feature.

    Ambos errores llevan al mismo resultado: rediseño tardío, deuda técnica, y la sensación de que SDD no funciona cuando el problema real es la estrategia, no la metodología.


    La estructura que sí funciona: spec global ligero + slices con UI

    La solución tiene dos capas. Una sesión corta de spec global que define las reglas del juego, y luego un ciclo de feature-por-feature donde cada spec incluye explícitamente la UI.

    Capa 1: El spec global ligero

    Este documento no especifica features. Especifica el contexto en el que todas las features van a vivir. Se hace una sola vez, en una sola sesión, y no debería tomar más de 45 minutos.

    # Spec Global — [Nombre del proyecto]
    _Versión: 1.0 | Fecha: YYYY-MM-DD_
    
    ## Visión
    [Una sola frase que describe qué es el producto y para quién.]
    
    ## Stack técnico
    - Frontend: Angular 22 con Signals
    - Backend: NestJS + Supabase
    - Estilos: Tailwind CSS v4
    - Testing: Jest + Testing Library
    
    ## Sistema de diseño
    - Librería de componentes: Angular Material / PrimeNG / custom
    - Paleta de colores: primario #1A73E8, fondo #F8FAFC, texto #0F172A
    - Tipografía: Inter, base 16px
    - Espaciado: escala de 4px (4, 8, 12, 16, 24, 32, 48...)
    - Breakpoints: sm 640px / md 768px / lg 1024px / xl 1280px
    
    ## Convenciones de arquitectura
    - Estructura: feature-based (cada feature es un módulo independiente)
    - Estado global: NgRx Signal Store
    - Llamadas HTTP: Resource API (Angular 22)
    - Validación: Zod en schemas compartidos
    
    ## Decisiones técnicas ya tomadas
    - Autenticación: Supabase Auth (no reinventar)
    - Despliegue: Vercel (frontend) + Railway (backend)
    - No usar: Redux clásico, Class Components, módulos NgModule legacy
    
    ## Features planificadas (sin detallar)
    1. Autenticación
    2. Dashboard principal
    3. Gestión de proyectos
    4. Reportes
    

    Eso es todo. No más. El spec global no detalla cómo funciona cada feature — solo establece las reglas que todas van a respetar.

    Lo más importante de ese documento son las secciones de sistema de diseño y convenciones de arquitectura. Son el contrato que el agente va a respetar en cada feature. Si no las defines aquí, las decide él — y probablemente no va a coincidir con lo que tienes en la cabeza.

    Capa 2: El spec de cada feature — con sección UI obligatoria

    Aquí está el cambio que lo transforma todo. Cuando vas a implementar una feature, escribes su spec detallado en ese momento, no antes. Y ese spec siempre incluye una sección de UI/UX.

    # Feature 1: Autenticación
    _Contexto: spec global v1.0 | Estado: en implementación_
    
    ## Qué hace
    Permite al usuario crear cuenta, iniciar sesión y recuperar contraseña.
    Usa Supabase Auth. No hay lógica de autenticación propia.
    
    ## Flujos principales
    1. Registro: email + contraseña → verificación por email → redirect a dashboard
    2. Login: email + contraseña → redirect a dashboard (o a la ruta que intentaba visitar)
    3. Recuperación: email → link con token → nueva contraseña → login
    
    ## UI/UX (obligatorio)
    - Layout: columna centrada, max-width 400px, padding 24px
    - Componentes a usar: InputField, Button, Alert — todos del sistema de diseño global
    - Estados visuales a implementar:
      - Loading: botón con spinner, campos desactivados
      - Error: Alert rojo con mensaje específico (no "algo salió mal")
      - Éxito: redirect inmediato, sin pantalla intermedia
    - Mobile first: el form debe funcionar bien en 320px
    - No inventar componentes nuevos — usar los del spec global
    
    ## Criterios de aceptación
    - [ ] El usuario puede registrarse con email válido
    - [ ] El usuario recibe email de verificación
    - [ ] El usuario puede iniciar sesión y llega al dashboard
    - [ ] Los estados de loading y error son visibles
    - [ ] El form es usable en móvil
    
    ## Lo que NO hace esta feature
    - No maneja OAuth (Twitter, Google) — queda para v2
    - No maneja roles de usuario — eso es responsabilidad del dashboard
    

    La sección UI/UX no es opcional. Es donde especificas exactamente qué tiene que ver el usuario cuando interactúa con esta feature. Si la omites, el agente tomará esa decisión por ti, y probablemente tomará la decisión más rápida, no la más correcta.


    Spec total upfront vs spec incremental — la comparativa real

    La tentación de escribir el spec completo del proyecto antes de arrancar tiene sentido desde afuera. La realidad es diferente.

    Spec total upfront Spec incremental (global ligero + features)
    Tiempo inicial 2-3 días o más 45 min (spec global) — hasta 20× más rápido para arrancar
    Riesgo Alto — cambias de opinión cuando ves el código real Bajo — ajustas cada feature antes de implementarla
    UI/UX Probablemente omitida o abstracta Concreta en cada feature, con contexto real
    Consistencia Dependes de que el spec inicial fuera perfecto El spec global garantiza coherencia entre features
    Deuda de redesign Alta — aparece cuando el 80% del código ya existe Baja — se elimina en cada ciclo de validación visual
    Útil con agentes IA Solo si el agente tiene memoria perfecta (no la tiene) Sí — cada prompt incluye contexto concreto y actualizado

    El spec incremental no significa improvisación. Significa que el contexto que tienes cuando implementas la feature 4 es mejor que el que tenías antes de escribir una sola línea de código. Y ese contexto — los componentes que ya existen, las decisiones que ya se tomaron, los problemas que ya aparecieron — enriquece el spec de la siguiente feature.

    Este enfoque es una variación de la Vertical Slice Architecture documentada por Jimmy Bogard, aplicada al contexto de specs con agentes IA.

    El rediseño tardío no ocurre porque el spec sea incremental. Ocurre porque no hay spec en absoluto.


    El ciclo de trabajo en un proyecto greenfield SDD

    El flujo que funciona es simple, y se repite para cada feature:

    1. Escribe el spec de esa feature (con sección UI incluida)
    2. Dáselo al agente como contexto completo
    3. Implementa
    4. Valida visualmente antes de marcar como hecho
    5. Usa lo aprendido para enriquecer el spec de la siguiente feature

    El paso 4 es crítico y muchos lo saltan. Validar visualmente significa abrir el navegador, probar el flujo como lo haría un usuario real, y confirmar que los estados de loading, error y éxito se ven como los especificaste. No basta con que los tests pasen.

    Si en el paso 4 descubres que algo no se ve bien, arréglalo antes de avanzar. El coste de arreglar un componente mal implementado en la feature 1 es mínimo. El coste de arreglar el mismo patrón cuando ya está repetido en las features 1, 3, 5 y 7 es considerable.


    Lo que cambia cuando tienes el spec global

    El spec global tiene un efecto que no es obvio hasta que lo usas en producción.

    Cuando llegas a la feature 4, el agente tiene contexto. Sabe que los inputs van con Tailwind, que el estado global es NgRx Signal Store, que los errores se muestran con el componente Alert del sistema de diseño. Si estás usando Angular 22, también puedes aprovechar la Resource API para centralizar las llamadas HTTP en el spec desde el principio — sin que el agente invente su propio patrón. No lo tienes que repetir en cada prompt.

    Y cuando llega alguien nuevo al proyecto — o cuando tú mismo vuelves al código tres meses después — entiende en 10 minutos las decisiones que se tomaron y por qué.

    Eso no lo da el código. Lo da el spec.

    Si quieres profundizar en la metodología completa, en el libro de Spec-Driven Development tienes el framework completo: cómo estructurar specs, cómo trabajar con agentes IA de forma efectiva, y los patrones que se usan en proyectos reales de producción.


    La UI no es una capa. Es un contrato.

    El error del developer que me escribió no fue usar SDD. Fue asumir que SDD significa especificar todo el proyecto antes de arrancar.

    SDD significa especificar lo suficiente, en el momento correcto, con el nivel de detalle correcto. El spec global define el campo de juego. El spec de cada feature define las reglas de ese momento.

    Y la UI no es una capa que se añade al final. Es parte del contrato de cada feature.

    Si quieres ver este flujo en acción — desde el spec hasta el commit — en el curso Construye con IA: De la Idea al Producto aplicamos exactamente esta metodología: spec global, slices verticales, validación visual antes de avanzar. Con agentes IA reales, en proyectos que no son de juguete.

    Y si prefieres el formato comunidad, en Dominicode Labs compartimos los specs reales de los proyectos que construimos juntos — con las decisiones que se tomaron y las que se descartaron.

    El spec no te quita velocidad. Te quita el coste de arreglar lo que nadie especificó.


    FAQ

    ¿Cuánto tiempo debería tardar el spec global de un proyecto real?

    Entre 30 y 60 minutos. Si tardas más, estás especificando features en el spec global, y eso no es su función. El spec global define el contexto y las reglas. Las features se detallan una a una cuando llega su turno.

    ¿Es obligatoria la sección UI/UX en el spec de cada feature?

    En proyectos con interfaz visible, sí. Si estás construyendo una API sin frontend, la sección UI/UX no aplica, pero deberías incluir una sección de contratos de API: endpoints, tipos de respuesta, códigos de error. El principio es el mismo: especifica todo lo que el agente necesita para no tomar decisiones que tú deberías tomar.

    ¿Cómo manejo las features que dependen de otras que aún no están implementadas?

    En el spec de la feature con dependencia, añades una sección “Asunciones” que documenta qué esperas de las features previas. Si la feature A aún no existe, especificas el contrato que A debería cumplir — y cuando implementes A, ese contrato ya está documentado. Es una forma de diseño by contract que funciona muy bien con agentes.


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

  • Harness Engineering con Codex de OpenAI: el arte de que tu agente de IA funcione de verdad

    Harness Engineering con Codex de OpenAI: el arte de que tu agente de IA funcione de verdad

    Llevaba una hora con GPT-4o intentando refactorizar un servicio de autenticación en NestJS. El modelo era bueno. La tarea era sencilla. Y aun así el agente leyó los archivos equivocados, modificó código que nadie le pidió tocar y entró en un bucle explicando por qué había hecho algo que nunca debió hacer.

    Ese día entendí qué es harness engineering — y por qué importa más que el modelo.

    Si tu agente de IA hace cosas raras, borra lo que no debe, o simplemente no termina la tarea, casi nunca es el modelo el problema. Es el sistema que rodea al modelo. Ese sistema tiene nombre: harness. Y diseñarlo bien es la diferencia entre un agente que funciona y uno que frustra.

    En este post vas a ver cómo funciona el harness, qué elementos lo componen y cómo configurarlo con Codex de OpenAI como caso concreto. He aplicado estos principios en proyectos reales de Dominicode — en el curso Angular Moderno, en el repositorio ShopFlow y en varios workflows de automatización — y estos son los patrones que funcionan.


    Qué es harness engineering: definición y concepto clave

    El modelo de lenguaje es solo el cerebro. Un cerebro sin ojos, sin manos y sin memoria no hace gran cosa.

    El harness es todo lo demás: las instrucciones que recibe al arrancar, las herramientas que puede usar, qué archivos puede leer y escribir, qué comandos puede ejecutar, qué recordará la próxima sesión y qué no, cómo escala la complejidad cuando la tarea crece.

    Harness engineering es la disciplina de diseñar, configurar y optimizar ese sistema — no el modelo — para obtener resultados predecibles y de calidad de un agente de IA.

    Piensa en ello como la diferencia entre contratar a un developer senior excelente y meterlo en una empresa sin onboarding, sin acceso a los repositorios correctos, sin saber cuál es el stack ni los estándares del proyecto. Ese developer se va a equivocar. No porque sea malo — sino porque no tiene el contexto para operar.

    Un harness bien diseñado responde estas preguntas antes de que el agente empiece a trabajar:

    • ¿Qué sabe el agente sobre este proyecto?
    • ¿Qué herramientas tiene disponibles?
    • ¿Qué puede hacer sin pedir permiso y qué no?
    • ¿Cómo gestiona situaciones de ambigüedad?
    • ¿Qué pasa cuando algo falla?

    Cada agente de IA moderno — Claude Code, Cursor, Codex — tiene su propio mecanismo para configurar el harness. En Codex de OpenAI, ese mecanismo se llama AGENTS.md.

    Harness vs system prompt: la diferencia que importa

    Mucha gente confunde el harness con un system prompt. No son lo mismo.

    Un system prompt clásico es estático, vive fuera del repositorio y generalmente lo escribe el equipo que construye la herramienta de IA. Es el contexto base del modelo, pero no sabe nada de tu proyecto específico.

    El harness es específico a tu proyecto y tu contexto. Vive dentro del repositorio, se versiona con git, puede tener múltiples capas (uno en la raíz, otros en subdirectorios para módulos específicos), y está diseñado para agentes que operan sobre código concreto. Es la capa que tú controlas — y la que determina si el agente opera en tu proyecto o en uno imaginario.


    Cómo instalar y configurar Codex CLI de OpenAI

    OpenAI lanzó Codex CLI como su apuesta para el desarrollo asistido por agentes directamente desde el terminal. Usa el modelo codex-1, optimizado específicamente para tareas de código, y puede ejecutar comandos, leer y escribir archivos, y razonar sobre tu codebase de forma autónoma.

    Instalación

    npm install -g @openai/codex

    Necesitas una API key de OpenAI exportada como variable de entorno:

    export OPENAI_API_KEY=sk-...

    Modos de operación

    Codex tiene dos modos principales que controlan cuánta autonomía le das al agente:

    # Modo sugerencia — el agente propone, tú apruebas cada acción
    

    codex --approval-mode suggest "refactoriza el servicio de autenticación"

    # Modo automático — el agente ejecuta sin pedir confirmación

    codex --approval-mode auto "añade tests unitarios al módulo de usuarios"

    La diferencia no es trivial. En modo suggest puedes revisar cada paso antes de que ocurra. En modo auto el agente opera con autonomía total — lo que significa que un harness mal configurado puede hacer daño real antes de que te des cuenta.

    Regla básica: empieza siempre con suggest. Mueve a auto solo cuando el harness esté probado y el alcance de la tarea esté bien definido.

    Codex vs otros agentes: comparativa de harness

    Codex CLI Claude Code Cursor Agent
    Archivo de harness AGENTS.md CLAUDE.md .cursorrules
    Soporte MCP Sí (amplio) Limitado
    Modos de aprobación suggest / auto Por herramienta Por acción
    Sandboxing de red Estricto por defecto Configurable No aplica
    AGENTS.md en subdirectorios Sí (monorepo) No
    Modelo base codex-1 (o3) Claude Sonnet/Opus GPT-4o / Claude

    El concepto de harness engineering aplica a los tres. Lo que cambia es el nombre del archivo y algunos detalles de configuración.


    Qué es AGENTS.md y cómo configurarlo en Codex

    Cuando Codex arranca en un directorio, busca AGENTS.md en la raíz del proyecto. En proyectos monorepo también puede leer AGENTS.md en subdirectorios — el más específico tiene precedencia sobre el de la raíz.

    Si no existe, el agente opera sin contexto. Si existe pero está mal escrito, opera con contexto equivocado. Las dos situaciones producen resultados impredecibles.

    Un AGENTS.md bien estructurado tiene estas secciones:

    # AGENTS.md
    

    Contexto del proyecto

    [Qué hace este proyecto, stack tecnológico, arquitectura general]

    Reglas de operación

    [Qué puede y no puede hacer el agente sin preguntar]

    Convenciones del código

    [Estilo, nomenclatura, patrones usados en el proyecto]

    Herramientas disponibles

    [Comandos de build, test, lint que el agente puede ejecutar]

    Flujo de trabajo esperado

    [Cómo debe abordar las tareas: leer primero, preguntar si hay ambigüedad, etc.]

    Ejemplo concreto para un proyecto NestJS:

    # AGENTS.md — ShopFlow API
    

    Contexto del proyecto

    API REST en NestJS 10 + TypeScript. Base de datos PostgreSQL con TypeORM.

    Autenticación con JWT. Testing con Jest. Endpoints bajo /src/modules/.

    Stack

    • Runtime: Node.js 20 + Bun para scripts
    • Framework: NestJS 10
    • ORM: TypeORM
    • Tests: Jest + Supertest
    • Lint: ESLint + Prettier

    Reglas de operación

    • NUNCA modificar archivos en src/migrations/ sin instrucción explícita
    • NUNCA eliminar archivos. Si algo ya no se necesita, comentarlo y avisar
    • Si hay ambigüedad sobre el alcance de la tarea, preguntar antes de ejecutar
    • Ejecutar npm run lint y npm run test después de cualquier cambio

    Convenciones

    • Nombres de archivos: kebab-case
    • Servicios: sufijo .service.ts
    • DTOs: sufijo .dto.ts, ubicados en dto/ dentro de cada módulo
    • Interfaces: prefijo I (IUser, IProduct)

    Comandos disponibles

    • npm run build — compilar
    • npm run test — tests unitarios
    • npm run test:e2e — tests end-to-end
    • npm run lint — verificar estilo

    Flujo esperado

    • Leer los archivos relevantes antes de modificar cualquier cosa
    • Si la tarea afecta a más de un módulo, listar los archivos involucrados antes de empezar
    • Al terminar, ejecutar lint y tests y reportar el resultado

Este AGENTS.md elimina la mayoría de los errores típicos: el agente sabe qué tocar, qué no tocar, cómo llamar a las cosas y cómo verificar que su trabajo está bien hecho.


Los 5 elementos de un harness de agente IA bien diseñado

El AGENTS.md es el núcleo, pero un harness completo tiene más capas. Estos son los cinco elementos que marcan la diferencia.

1. Contexto del proyecto con suficiente densidad

El error más común: escribir un AGENTS.md de tres líneas.

El agente necesita saber lo suficiente para razonar bien. No todo — pero sí el stack, la estructura de directorios, las decisiones de arquitectura más importantes y las restricciones no negociables.

Si el proyecto tiene una convención no obvia (por ejemplo, “todos los handlers de errores van en src/shared/errors/“), escríbelo explícitamente. El agente no puede adivinar convenciones que no están en ningún archivo.

2. Límites claros de autonomía

Define explícitamente qué puede hacer el agente sin preguntar y qué requiere confirmación.

## Autonomía permitida
  • Crear archivos nuevos en src/modules/
  • Ejecutar npm run test y npm run lint
  • Instalar dependencias de desarrollo con npm install --save-dev

Requiere confirmación explícita

  • Modificar package.json en sección scripts
  • Tocar cualquier archivo de configuración de base de datos
  • Eliminar o renombrar archivos existentes

Sin estos límites, el agente toma decisiones basándose en lo que parece razonable. A veces acierta. Muchas veces no.

3. Herramientas y comandos verificables

El agente necesita poder verificar su propio trabajo. Si no tiene acceso a los comandos de test y lint, no puede saber si lo que hizo funciona.

## Verificación

Después de cualquier cambio de código:

  • npm run lint — debe pasar sin errores
  • npm run test -- --passWithNoTests — los tests existentes deben pasar
  • Si hay tests fallando que NO estaban fallando antes, reportarlo antes de continuar

Este punto es especialmente importante en modo auto. Un agente con capacidad de verificación autónoma puede detectar que rompió algo y corregirlo antes de que tú lo veas.

4. Gestión explícita de la ambigüedad

Los agentes tienden a asumir en vez de preguntar. Eso produce trabajo que hay que deshacer.

## Manejo de ambigüedad
  • Si una tarea puede interpretarse de más de una manera, listar las interpretaciones y preguntar
  • Si no encuentras el archivo mencionado en la tarea, preguntar en vez de crearlo desde cero
  • Si la tarea requiere modificar lógica crítica (pagos, auth, permisos), confirmar antes de ejecutar

5. Instrucciones de salida y reporte

El agente necesita saber qué se espera de él al terminar.

## Al finalizar cada tarea

Proporciona:

  • Lista de archivos modificados o creados
  • Resumen en 2-3 líneas de lo que hiciste
  • Resultado de lint y tests
  • Si hay algo que no pudiste completar, explicarlo con el motivo

Sin esta instrucción, algunos agentes terminan con un párrafo de texto que no dice nada concreto. Con ella, tienes un log estructurado que revisas en segundos.


Harness débil vs harness fuerte: la misma tarea, dos mundos distintos

Tarea concreta: “Añade validación de email al endpoint de registro de usuarios.”

Sin harness Con harness
Archivos leídos Varios al azar register.dto.ts y auth.controller.ts
Dependencias Instala class-validator (ya estaba) Detecta que ya existe en package.json
Cambios realizados DTO + guard de auth “por si acaso” Solo @IsEmail() en el DTO
Verificación No ejecuta tests (no sabe el script) npm run lint y npm run test — pasan
Reporte final Dos páginas explicando cada decisión “Un archivo. Lint y tests pasan.”
Tiempo de revisión 20 minutos 30 segundos

La diferencia no está en el modelo. Está en el harness.


Errores comunes al configurar el harness de Codex CLI

Error 1: AGENTS.md demasiado vago

# Proyecto web en TypeScript. Usa buenas prácticas.

Esto no es un harness. Es un deseo. El agente no sabe qué son “buenas prácticas” en tu proyecto.

Error 2: No definir qué NO debe tocar

Si no dices “no toques las migraciones”, el agente podría modificarlas si cree que tiene sentido. Los límites negativos son tan importantes como los positivos.

Error 3: Empezar en modo auto sin probar primero

Úsalo en modo suggest en varias tareas distintas. Observa dónde el agente malinterpreta las instrucciones. Ajusta el AGENTS.md. Luego sube a auto.

Error 4: Un AGENTS.md genérico para todos los proyectos

El harness es específico al proyecto. Un AGENTS.md copiado de Angular en un proyecto NestJS produce confusión. Uno por proyecto, aunque sea corto.

Error 5: No actualizar el harness cuando cambia el proyecto

El stack cambia. Las convenciones evolucionan. Si el AGENTS.md describe el proyecto de hace seis meses, el agente opera con un mapa desactualizado.


Cómo crear tu primer harness con Codex: guía paso a paso

Paso 1: Instala Codex CLI

npm install -g @openai/codex

export OPENAI_API_KEY=tu-api-key

Paso 2: Crea un AGENTS.md mínimo pero útil

Con estos cinco bloques ya tienes algo funcional:

# AGENTS.md

Proyecto

[Descripción en 2-3 líneas. Stack principal.]

Estructura relevante

[Dónde vive el código importante. Directorios a conocer.]

Convenciones

[Nomenclatura. Patrones. Lo que hace raro a este proyecto.]

Comandos

[Build, test, lint — los scripts exactos de package.json]

Restricciones

[Qué no debe tocar nunca. Qué requiere confirmación.]

Paso 3: Prueba con una tarea pequeña en modo suggest

codex --approval-mode suggest "lista los archivos del módulo de usuarios"

Observa cómo razona. Dónde se pierde. Qué asume incorrectamente. Ajusta el AGENTS.md.

Paso 4: Itera subiendo la complejidad

Del “lista archivos” al “añade un campo al DTO” al “crea un nuevo módulo completo con tests”. Cada tarea te dice algo sobre qué falta en el harness.

Paso 5: Documenta los patrones que funcionan

Cuando encuentres una instrucción que produce resultados consistentemente buenos, guárdala. El AGENTS.md es un documento vivo.


El agente que fallaba en NestJS al principio de este post no era el problema. Era yo — operando sin harness, esperando que el modelo adivinara el contexto de un proyecto que nunca le había explicado. Con un AGENTS.md bien escrito, esa misma tarea tarda tres minutos y no requiere revisión manual.

Si quieres profundizar en cómo diseñar sistemas con IA que funcionen en proyectos reales, tengo el curso Construye con IA: de la idea al producto con Claude Code donde aplicamos estos principios desde cero. Y si buscas el marco para especificar antes de soltar al agente, el Libro de Spec-Driven Development te da el sistema completo — que encaja perfectamente con harness engineering.

También publico sobre esto regularmente en el canal de YouTube.


FAQ — Preguntas frecuentes sobre harness engineering y Codex

¿El concepto de harness aplica solo a Codex o también a otros agentes?

Es completamente agnóstico al modelo. Claude Code usa CLAUDE.md con el mismo rol que AGENTS.md en Codex. Cursor usa .cursorrules. La disciplina de harness engineering aplica a cualquier agente porque el problema que resuelve — dar contexto estructurado al sistema que rodea al modelo — es universal. Lo que cambia entre herramientas es el nombre del archivo y algunos detalles de configuración.

¿Qué diferencia hay entre harness engineering e ingeniería de prompts?

La ingeniería de prompts optimiza la instrucción puntual que le das al modelo en una conversación. El harness engineering diseña el sistema persistente que define cómo el agente opera en tu proyecto de forma continua. Un buen prompt en un harness malo produce resultados inconsistentes. Un prompt mediocre en un harness bien diseñado produce resultados predecibles. El harness tiene más impacto a largo plazo.

¿Es seguro usar el modo --approval-mode auto?

Depende del harness. En modo auto el agente ejecuta acciones sin confirmación — comandos de terminal incluidos. Si el harness define bien qué puede y no puede hacer, y el agente tiene acceso a verificación (lint, tests), es razonablemente seguro para tareas bien acotadas. Para operaciones destructivas o sobre sistemas en producción, siempre modo suggest. Y siempre con el repositorio en un estado limpio de git antes de empezar.

¿Cuánto tiempo lleva escribir un buen AGENTS.md?

Para un proyecto nuevo, entre 20 y 45 minutos la primera vez. La clave es empezar con la versión mínima (5 secciones) y enriquecerla después de las primeras sesiones con el agente. En proyectos que ya tienen documentación, muchas veces es adaptar lo que existe al formato del harness.

¿Codex de OpenAI puede conectarse a MCP servers como Claude Code?

Sí, Codex soporta MCP (Model Context Protocol) para conectar herramientas externas — bases de datos, APIs, sistemas de ficheros remotos. La configuración es similar a Claude Code, aunque el ecosistema de servidores MCP disponibles sigue siendo más amplio para Claude. Para la mayoría de casos de uso de desarrollo, las herramientas nativas de Codex son suficientes.

¿Necesito saber usar la API de OpenAI para usar Codex CLI?

Solo necesitas una API key de OpenAI y tener créditos disponibles. No necesitas saber programar contra la API — Codex CLI abstrae todo eso. La curva de entrada es baja: instalar el paquete npm, exportar la API key y escribir el AGENTS.md. El coste por uso depende de cuánto contexto maneja el agente en cada sesión.


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

  • Qué es un agent harness: la anatomía del sistema que rodea al LLM

    Qué es un agent harness: la anatomía del sistema que rodea al LLM

    En AI Engineer 2026, Tejas Kumar (IBM) hizo algo incómodo delante de cientos de ingenieros: cogió GPT-3.5 Turbo — un modelo de 2023, una antigualla — y le pidió completar una tarea con herramientas. El agente falló. Y no solo falló: mintió. Dijo “he votado” sin haber votado. La tool call nunca se ejecutó.

    Entonces hizo lo interesante. No tocó el prompt ni una vez. No cambió de modelo. Solo añadió piezas alrededor — lo que hoy llamamos un agent harness: límites de pasos, un paso de verificación determinista, un handler de login que no dependía del LLM. Mismo modelo viejo, misma tarea. El agente la completó.

    Entender qué es un agent harness — qué piezas lo componen y por qué el modelo es la parte más pequeña del sistema — es probablemente la habilidad más rentable que puedes desarrollar como developer este año.

    La charla de Tejas ya pasa de 132.000 visualizaciones. Martin Fowler publicó sobre harness engineering. LangChain publicó “The Anatomy of an Agent Harness”. MongoDB lo resumió en una frase: el LLM es la parte más pequeña de tu sistema de agentes. Esto no es una moda de Twitter. Es la disciplina consolidándose.

    Y como dijo Tejas: 2025 fue el año de los agentes. 2026 es el año de los harnesses.

    Qué es un agent harness, sin humo

    La definición de Tejas es la mejor que he escuchado: el harness es todo lo que rodea al modelo y le da anclaje en la realidad.

    La metáfora es literal. El arnés de un escalador lo ancla a algo estable: si resbala, no cae. El arnés de un perro evita que se desboque detrás de la primera ardilla. El harness de un agente hace las dos cosas: ancla al modelo a tu sistema real y evita que se desboque.

    ¿Por qué importa tanto? Por una asimetría brutal de control. El modelo es una caja negra que alquilas por tokens. No puedes abrirla, no puedes depurarla, no puedes garantizar nada sobre ella. El harness es la parte que tú controlas al cien por cien. Si quieres fiabilidad — y en producción no hay otra opción — la fiabilidad vive en el harness, no en el modelo.

    Ya escribí sobre el harness desde el lado del usuario en Harness Engineering con Codex de OpenAI: cómo configurar AGENTS.md, modos de aprobación, ese terreno. Este post va por el otro lado. Vamos a abrir el capó.

    La anatomía: las 6 piezas de un harness

    Todo harness serio — Claude Code, Codex, Pi, el que construyas tú — tiene estas seis piezas. Cambian los nombres y la sofisticación, no la anatomía.

    1. Tool registry

    El catálogo de herramientas que el modelo puede invocar: leer archivos, ejecutar comandos, llamar APIs. Sin tools, el modelo solo genera texto. Las tools son sus manos.

    2. El modelo

    Sí, es una pieza más. Una de seis. No el sistema entero. Interiorizar esto cambia cómo diseñas.

    3. Gestión de contexto

    La ventana de contexto se llena, y un contexto saturado degrada al modelo mucho antes de reventar el límite de tokens. El harness necesita primitivas de compaction: resumir lo viejo, descartar lo irrelevante, conservar lo esencial. En Hacker News los devs ya lo dicen abiertamente: la gestión de contexto es hoy un cuello de botella mayor que la calidad del modelo.

    4. Guardrails

    Límites duros que el modelo no puede negociar: máximo de pasos, máximo de mensajes, qué comandos requieren aprobación. Son el código determinista que evita que un agente confundido queme tu presupuesto de API en un bucle infinito.

    5. El agent loop

    El corazón: el ciclo que llama al modelo, ejecuta sus tool calls, le devuelve los resultados y repite hasta terminar. Y alrededor, el “loop sobre el loop”: qué pasa cuando el ciclo interno acaba — ¿se verifica? ¿se reintenta? ¿se escala a un humano? Si quieres ver esta pieza llevada a producción, ya escribí sobre cómo implementar un loop de agente efectivo para LLM en producción.

    6. El verify step determinista

    La pieza que casi todo el mundo omite y la que más fiabilidad compra. Cuando el agente dice “he terminado”, no le crees: lo compruebas con código. ¿Existe el archivo? ¿Pasan los tests? ¿Devuelve 200 el endpoint? Verificación sin LLM. Sobre esta pieza volvemos luego, porque es la moraleja de la demo de Tejas.

    Pi: un harness de cristal

    El problema de estudiar harnesses con Claude Code o Codex es que son opacos. Usas el harness, pero no puedes leerlo.

    Por eso el mejor ejemplo pedagógico ahora mismo es Pi (badlogic/pi-mono en GitHub, hoy bajo la org Earendil). Lo creó Mario Zechner y hoy lo desarrolla junto a Armin Ronacher — sí, el creador de Flask y Jinja2 — y lleva más de 61.000 stars. Es un coding agent de terminal con un harness mínimo a propósito: puedes leerlo entero en una tarde y entender cada pieza.

    Recorre la anatomía con Pi en la mano:

    Tool registry: cuatro tools. Read, Write, Edit, Bash. Nada más. Y con eso un coding agent funciona, porque casi todo lo que hace un developer se reduce a leer, escribir, editar y ejecutar.

    Agent loop: un ReAct mínimo. Streamea la respuesta del modelo, comprueba si hay tool calls, las ejecuta, mete los resultados en el contexto y repite. En pseudocódigo (ilustrativo, no el código real de Pi):

    // Ilustrativo: la forma del loop ReAct de un harness mínimo
    while (true) {
      const response = await model.stream(context);
    
      if (response.toolCalls.length === 0) break; // terminó
    
      for (const call of response.toolCalls) {
        const result = await tools.execute(call); // Read | Write | Edit | Bash
        context.push(toolResult(call, result));
      }
    }
    

    Eso es. Esa docena de líneas es el corazón de todo coding agent que has usado. El resto del harness existe para que ese loop no se estrelle contra la realidad.

    Contexto: Pi inyecta una sola línea de descripción por capacidad instalada. Minimalismo deliberado: contexto pequeño, modelo más fino.

    Extensibilidad: aquí está la filosofía de Pi. Lo que otros agentes traen de fábrica, en Pi lo construyes tú — extensiones en TypeScript con acceso a tools, comandos, atajos, eventos y la TUI completa, más skills, prompt templates y themes. El core no engorda. Y esa decisión lo convirtió en plataforma: tanto Flu (del equipo de Astro) como OpenClaude están construidos sobre Pi.

    Si quieres tocarlo: npm install -g @earendil-works/pi-coding-agent y a leer código.

    La lección del verify step

    Vuelve a la demo de Tejas, porque ahí está la tesis del post.

    GPT-3.5 Turbo sin harness: el agente miente. Afirma haber hecho cosas que no hizo. Y ojo — no es maldad, es la naturaleza del modelo: genera el texto más plausible, y “ya he votado” es texto plausible.

    La solución no fue prompt engineering. Fue un guardrail más una verificación determinista:

    // Ilustrativo: guardrail + verify step alrededor del loop
    const MAX_STEPS = 15;
    
    for (let step = 0; step < MAX_STEPS; step++) {
      await agentLoop(task, context);
    
      if (await verify(task)) return "done"; // código, no LLM:
      // ¿existe el registro? ¿pasó el test? ¿respondió 200?
    
      context.push("La verificación falló. La tarea NO está completa. Continúa.");
    }
    throw new Error("Máximo de pasos alcanzado: escalar a humano");
    

    Con eso, el modelo de 2023 deja de mentir. No porque sea más listo: porque el harness no le permite declarar éxito sin pruebas. El verify step convierte "confío en lo que dice el agente" en "compruebo lo que hizo el agente". Esa es toda la diferencia entre demo y producción.

    Qué significa esto para ti

    Que el valor se está moviendo. De saber elegir modelo a saber construir el sistema alrededor del modelo.

    Con un buen harness, un modelo barato u open source — GPT-OSS, Qwen3 — llega muchísimo más lejos de lo que crees. La demo de Tejas lo prueba con un modelo de hace tres años. Inviertes una vez en el harness (código tuyo, determinista, testeable, versionado en git) y cada modelo nuevo que conectes hereda esa fiabilidad gratis.

    Y hay otra consecuencia que me toca de cerca: un harness se especifica, no se improvisa. Decidir guardrails, criterios de verificación y límites del loop antes de escribir código es exactamente el enfoque Spec-Driven que cuento en el libro de SDD. Un agente sin spec es un loop sin guardrails.

    Si quieres practicar este músculo construyendo productos reales con agentes, es la lógica que aplicamos de principio a fin en el curso Construye con IA: de la idea al producto, con el sistema — no la fe en el modelo — sosteniendo el resultado.

    Tu tarea para hoy es concreta: clona Pi, abre el loop y léelo. Es la mejor clase de arquitectura de agentes disponible, y es gratis.

    Lo que viene: Flu

    Este post es la pieza 1 de la serie "El año de los harnesses".

    En la pieza 2 subo de nivel: video en YouTube sobre Flu, el framework harness del equipo de Astro, construido precisamente sobre Pi. Si Pi es el harness mínimo para entender la anatomía, Flu es lo que pasa cuando un equipo serio construye encima de esa base para producción.

    Suscríbete al canal de YouTube de Dominicode para no perdértelo. Y si quieres discutir tu propio harness con otros developers que están construyendo con agentes, en Dominicode Labs es la conversación de cada semana.

    Preguntas frecuentes

    ¿Qué es un agent harness?

    Es todo el sistema que rodea al LLM y le da anclaje en la realidad: el tool registry, el agent loop, la gestión de contexto, los guardrails y la verificación determinista. El modelo genera decisiones; el harness las ejecuta, las limita y las comprueba. Es la parte del sistema de agentes que tú controlas.

    ¿Cuál es la diferencia entre un harness y un framework de agentes?

    Un framework de agentes (LangChain, CrewAI) te da abstracciones para orquestar LLMs: chains, grafos, equipos de agentes. El harness es más fundamental: es la pieza concreta que conecta un modelo con la realidad — loop, tools, guardrails, verificación. Todo framework de agentes contiene un harness dentro; pero puedes escribir un harness completo en cien líneas sin ningún framework, como demuestra Pi.

    Agent harness Framework de agentes
    Qué resuelve Conectar un modelo con la realidad de forma fiable Orquestar uno o varios agentes entre sí
    Nivel de abstracción Bajo: loop, tools, guardrails, verify Alto: chains, grafos, roles, equipos
    Ejemplos Pi, el harness de Claude Code, Flu LangChain, CrewAI, LangGraph
    Cuándo usarlo Siempre — todo agente corre dentro de uno Cuando orquestas flujos multi-agente complejos

    ¿Necesito construir mi propio harness o uso uno existente?

    Para programar día a día, usa uno existente (Claude Code, Codex, Pi). Construye el tuyo cuando el agente sea parte de tu producto: ahí necesitas controlar guardrails, verificación y costes, y un harness propio mínimo suele ganar a un framework genérico. En cualquier caso, lee uno entero al menos una vez — Pi es la opción perfecta — porque te cambia cómo usas todos los demás.

    ¿Qué es Pi (pi coding agent)?

    Pi es un coding agent open source de terminal creado por Mario Zechner y desarrollado hoy junto a Armin Ronacher (creador de Flask), con más de 61.000 stars en GitHub. Su harness es mínimo a propósito: 4 tools (Read, Write, Edit, Bash) y un loop ReAct que cabe en una pantalla. Todo lo demás se añade con extensiones TypeScript, skills y templates. Es la base sobre la que se construyen Flu y OpenClaude, y el mejor harness para estudiar porque puedes leerlo completo.

    ¿Por qué un modelo viejo con harness supera a un modelo nuevo sin harness?

    Porque los fallos típicos de un agente — declarar éxito sin haber hecho el trabajo, entrar en bucles, perder el contexto — no se arreglan con más inteligencia, se arreglan con estructura: guardrails que cortan los bucles y un verify step determinista que no acepta "ya está" sin pruebas. En la demo de Tejas Kumar (AI Engineer 2026), GPT-3.5 Turbo pasó de mentir a completar la tarea solo añadiendo harness, sin tocar el prompt.


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

  • CLAUDE.md: el system prompt de tu proyecto con Claude Code

    CLAUDE.md: el system prompt de tu proyecto con Claude Code

    El primer día que usé Claude Code en un proyecto real, le pedí que añadiera un endpoint de autenticación. Lo generó en treinta segundos. Perfecto.

    El problema: lo metió en el módulo equivocado, usó una convención de nombres que nadie en el proyecto seguía, y no añadió los tests que el equipo tenía como regla no negociable.

    El agente no era malo. Era que no sabía nada del proyecto. No era un problema del modelo — era un problema de contexto. Y CLAUDE.md es exactamente la solución para eso.

    Estaba generando código de calidad para un proyecto imaginario que él mismo se había inventado.

    Eso cambió cuando añadí el archivo CLAUDE.md en la raíz del repositorio.


    Qué es CLAUDE.md y por qué importa

    CLAUDE.md es el archivo de instrucciones persistentes que Claude Code lee automáticamente al arrancar en un directorio. Es, en la práctica, el system prompt de tu proyecto.

    Sin él, el agente llega a tu codebase sin contexto. Sin saber que usas Bun en lugar de npm. Sin saber que los tests son obligatorios antes de mergear. Sin saber que tu arquitectura tiene capas que no se pueden mezclar.

    Puedes consultar cómo funciona este mecanismo en la documentación oficial de Claude Code.

    Con él, cada sesión empieza con el agente ya orientado. No tienes que repetir las mismas instrucciones en cada prompt. No tienes que corregir los mismos errores una y otra vez.


    Los tres niveles de CLAUDE.md

    Claude Code soporta tres ubicaciones para el archivo, y se aplican en cascada:

    Nivel Ubicación Alcance
    Global ~/.claude/CLAUDE.md Se aplica a todos los proyectos del usuario
    Proyecto CLAUDE.md en la raíz Se aplica a ese repositorio; se puede compartir vía git
    Subdirectorio src/CLAUDE.md, api/CLAUDE.md, etc. Instrucciones específicas de esa carpeta

    El global es para tus preferencias personales: idioma, estilo de commits, herramientas que siempre usas. El de proyecto es el que más importa — contiene la arquitectura, el stack, las restricciones y las convenciones de ese codebase concreto. El de subdirectorio es útil en monorepos donde cada paquete tiene reglas distintas.

    Cuando Claude Code lee un archivo en un subdirectorio, aplica también el CLAUDE.md de la raíz. El contexto se acumula.


    Qué va en un CLAUDE.md de proyecto

    Estas son las secciones que no deberían faltar en ningún proyecto serio:

    Sección Qué contiene Por qué importa
    Descripción del proyecto Qué hace la app, stack principal, versiones clave El agente necesita saber el dominio para tomar buenas decisiones
    Comandos habituales Build, test, lint, dev server — exactamente cómo se ejecutan Evita que el agente proponga npm install cuando usas bun
    Arquitectura y convenciones Estructura de carpetas, patrones usados, capas y sus reglas Sin esto genera código que no encaja en el diseño del proyecto
    Reglas de nomenclatura Cómo se nombran archivos, clases, variables, branches y commits Consistencia automática sin revisión manual
    Restricciones explícitas Qué NO debe hacer el agente — tecnologías prohibidas, capas que no se pueden mezclar Las restricciones son tan importantes como las instrucciones positivas
    Contexto de negocio Decisiones de diseño no obvias y el porqué detrás de ellas El agente que entiende el “por qué” toma mejores decisiones cuando hay ambigüedad

    Cómo crear tu primer CLAUDE.md: plantilla lista para TypeScript

    Este es el mínimo viable que funciona para cualquier proyecto TypeScript. Crea un archivo CLAUDE.md en la raíz del repositorio con esta estructura:

    # CLAUDE.md — Nombre del Proyecto
    
    ## Descripción
    Aplicación [tipo] construida con [stack principal].
    Estado: [desarrollo activo / mantenimiento / producción].
    
    ## Stack y versiones
    - Runtime: Bun 1.2+
    - Framework: [Angular 22 / React 19 / NestJS 11]
    - Lenguaje: TypeScript 5.5 strict mode
    - Testing: Jest + Testing Library
    - Linting: ESLint + Prettier
    
    ## Convenciones de código
    - Usar funciones puras cuando sea posible — evitar efectos secundarios implícitos
    - Todos los tipos deben ser explícitos — prohibido `any`
    - Los imports se ordenan: externos → internos → relativos
    - Archivos: kebab-case. Clases: PascalCase. Variables/funciones: camelCase
    
    ## Reglas de commits
    - Formato: feat|fix|chore|refactor|test|docs: descripción corta
    - En español, imperativo, máximo 72 caracteres
    - Ejemplo: feat: añadir validación de email en registro
    
    ## Tests
    - Todo código nuevo requiere tests — sin excepción
    - Los tests van junto al archivo que prueban: product.service.spec.ts
    - Mocks en __mocks__/ solo para dependencias externas
    
    ## Lo que NO debes hacer
    - No usar `any` — si el tipo es desconocido, usa `unknown` y narrowing
    - No instalar dependencias sin mencionarlo primero
    - No modificar archivos de configuración (.env, tsconfig) sin confirmación
    - No generar código comentado — si no va al PR, no lo escribas

    La sección de comandos va en un bloque separado para que Claude Code los ejecute directamente:

    bun install          # instalar dependencias
    bun run dev          # servidor de desarrollo
    bun run test         # ejecutar tests
    bun run test:watch   # tests en modo watch
    bun run build        # build de producción
    bun run lint         # lint + format check

    Este archivo le da al agente orientación suficiente para trabajar sin supervisión constante en tareas rutinarias.


    Un CLAUDE.md específico para un proyecto NestJS

    Cuando el proyecto tiene arquitectura definida, las instrucciones tienen que ser más precisas:

    # CLAUDE.md — API de Pagos (NestJS)
    
    ## Descripción
    API REST para procesamiento de pagos. Backend crítico — cada cambio
    requiere revisión cuidadosa. En producción desde enero 2025.
    
    ## Stack
    - NestJS 11 + TypeScript 5.5 strict
    - Bun como runtime y gestor de paquetes
    - PostgreSQL 16 vía TypeORM 0.3
    - Autenticación: JWT + Passport
    - Tests: Jest con cobertura mínima del 80%
    
    ## Arquitectura — Módulos por dominio
    src/
      payments/
        payments.module.ts
        payments.controller.ts   (solo routing y validación de input)
        payments.service.ts      (lógica de negocio)
        payments.repository.ts   (acceso a base de datos)
        dto/create-payment.dto.ts
        entities/payment.entity.ts
    
    ## Reglas de arquitectura (OBLIGATORIAS)
    1. Los controllers NO contienen lógica de negocio — solo validan el input y llaman al service
    2. Los services NO acceden directamente a la base de datos — usan el repository
    3. Toda comunicación con servicios externos va en providers dedicados, nunca inline
    4. Las entidades TypeORM y los DTOs son tipos distintos — nunca mezclarlos
    5. Los errores de negocio se lanzan como HttpException con código de error semántico
    
    ## Nomenclatura de archivos
    - Módulos: payments.module.ts
    - Controllers: payments.controller.ts
    - Services: payments.service.ts
    - DTOs: create-payment.dto.ts (verbo + entidad + .dto.ts)
    - Entidades: payment.entity.ts
    - Tests: payments.service.spec.ts
    
    ## Variables de entorno
    - Están en .env.example — usa siempre ese archivo como referencia
    - NUNCA hardcodees secrets ni connection strings en el código
    - Para acceder a env vars, usa el ConfigService de NestJS, no process.env directamente
    
    ## Restricciones críticas
    - NO modificar migraciones ya aplicadas — solo crear nuevas
    - NO cambiar el schema de pagos sin revisión explícita — tiene impacto en contabilidad
    - NO instalar dependencias nuevas sin confirmar primero — hay un proceso de aprobación de seguridad

    Los comandos habituales en bloque separado:

    bun run start:dev          # servidor con hot reload
    bun run test               # unit tests
    bun run test:e2e           # tests end-to-end
    bun run migration:generate # genera migración desde cambio en entidad
    bun run migration:run      # aplica migraciones pendientes

    La diferencia con el archivo básico es la especificidad. Cuanto más específico sea el contexto, menos decisiones ambiguas toma el agente.


    Los errores que convierten un CLAUDE.md en ruido

    Un CLAUDE.md mal escrito es peor que no tenerlo — el agente lo lee, extrae instrucciones contradictorias o vagas, y actúa con falsa confianza.

    Demasiado genérico. “Escribe código limpio y mantenible” no le dice nada al agente que ya no sepa. Las instrucciones tienen que ser concretas: “Los servicios no acceden directamente a la base de datos” es una regla. “Buenas prácticas” no lo es.

    Desactualizado. Si migras de npm a Bun y no actualizas el CLAUDE.md, el agente seguirá proponiendo npm run para todo. El archivo es documentación viva — tiene que evolucionar con el proyecto. Una revisión mensual es suficiente en la mayoría de los casos.

    Sin restricciones explícitas. El 90% de los CLAUDE.md que he visto dicen qué hacer. Muy pocos dicen qué no hacer. Las restricciones son las que evitan los errores más costosos: “no modifiques migraciones ya aplicadas”, “no instales dependencias sin confirmación”, “no uses any“. Sin esta sección, el agente optimiza para completar la tarea por el camino más corto, que no siempre es el correcto.

    Instrucciones que contradicen el código existente. Si el CLAUDE.md dice “usamos Clean Architecture” pero el codebase tiene lógica de negocio en los componentes, el agente entra en conflicto entre seguir las instrucciones o seguir el patrón del código existente.

    Casi siempre gana el código existente. El CLAUDE.md tiene que reflejar la realidad del proyecto, no los deseos del developer.


    CLAUDE.md + SDD: la combinación que multiplica la calidad

    CLAUDE.md da al agente contexto de proyecto. Pero hay algo que va un nivel más arriba: la especificación de cada feature antes de escribir código.

    Cuando combinas un buen CLAUDE.md con Spec-Driven Development — escribir la spec de la feature (qué hace, qué tipos maneja, qué contratos define) antes de pedir al agente que genere código — el resultado es cualitativamente distinto.

    El agente no adivina la arquitectura porque está en el CLAUDE.md. No adivina el comportamiento de la feature porque está en la spec. El espacio de decisión se reduce al mínimo. Y cuanto menor es el espacio de decisión, más predecible y correcto es el output.

    Este es el flujo que aplico en todos los proyectos:

    1. CLAUDE.md en la raíz → contexto permanente del proyecto
    2. Spec de la feature → descripción de entidades, contratos, flujos
    3. Prompt al agente con referencia explícita a la spec
    4. Review del código generado contra la spec
    5. Tests que validan los contratos de la spec

    El libro de Spec-Driven Development documenta todo este proceso con las plantillas, los patrones y los ejemplos concretos que uso en producción. Si buscas el marco metodológico detrás de trabajar con agentes de forma estructurada, es el punto de partida más directo.


    Dónde encaja esto con el resto de tu flujo con Claude Code

    El CLAUDE.md no es el único elemento que necesitas configurar — es el primero.

    En el post sobre Clean Architecture en frontend con IA vimos cómo el CLAUDE.md es la pieza que hace que el agente respete las capas de arquitectura en lugar de generar spaghetti. Y en la guía sobre qué es un Agentic Engineer está el contexto profesional más amplio: por qué dar contexto estructurado al agente es una competencia de ingeniería, no un truco de productividad.

    Si quieres ver todo esto aplicado en proyectos reales — desde el CLAUDE.md inicial hasta el producto funcionando, con SDD, arquitectura limpia y Claude Code — el curso Construye con IA cubre exactamente ese flujo completo.


    El developer que dejó de repetirse

    Hay una forma de saber si tu CLAUDE.md funciona: si dejas de decirle al agente las mismas cosas en cada sesión.

    “No uses any.” “Pon el test junto al archivo.” “Sigue la estructura de módulos del proyecto.” Si lo estás repitiendo en cada prompt, esa instrucción no está en el CLAUDE.md — o está pero de forma demasiado vaga para que el agente la aplique.

    El objetivo del archivo no es documentación. Es eliminar fricción. Cada instrucción que pasa del prompt al CLAUDE.md es tiempo que dejas de invertir en corregir el comportamiento del agente y empiezas a invertir en construir.

    Abre tu proyecto. Crea el CLAUDE.md. Empieza con cinco secciones: descripción, comandos, arquitectura, nomenclatura, restricciones. Puedes tenerlo listo en quince minutos.

    Si quieres ir más allá — aplicar esto junto con SDD, agentes subagentes y el flujo completo de desarrollo con IA — en Dominicode Labs tenemos los proyectos y los recursos que usamos en producción, con análisis y revisión de código en comunidad.


    FAQ — Preguntas frecuentes sobre CLAUDE.md

    ¿Qué es CLAUDE.md en Claude Code?

    CLAUDE.md es un archivo de texto en formato Markdown que Claude Code lee automáticamente al iniciarse en un directorio. Actúa como el system prompt persistente del agente para ese proyecto: define el stack, la arquitectura, las convenciones de código y las restricciones que el agente debe respetar en todas las sesiones, sin necesidad de repetir esas instrucciones en cada prompt.

    ¿Dónde debe estar el archivo CLAUDE.md?

    Puede estar en tres ubicaciones con alcance diferente. En ~/.claude/CLAUDE.md aplica a todos los proyectos del usuario (preferencias globales). En la raíz del repositorio aplica a ese proyecto y se puede compartir con el equipo vía git. En subdirectorios aplica solo a esa carpeta — útil en monorepos. Claude Code aplica todos los que encuentra en la ruta, acumulando el contexto.

    ¿Cuál es la diferencia entre CLAUDE.md y un prompt de sistema en la API?

    Son el mismo concepto en distintos niveles. Un system prompt en la API se configura por llamada o por aplicación. El CLAUDE.md es el system prompt que Claude Code inyecta automáticamente en cada sesión basándose en el directorio de trabajo. La ventaja de CLAUDE.md es que vive en el repositorio, se versiona con git y está disponible para cualquier developer del equipo sin configuración adicional.

    ¿CLAUDE.md funciona también con Cursor o GitHub Copilot?

    El nombre CLAUDE.md es específico de Claude Code (Anthropic). Cursor tiene su propio mecanismo equivalente: archivos .cursor/rules/*.mdc para reglas de proyecto. GitHub Copilot usa copilot-instructions.md en la carpeta .github/. El principio es idéntico en los tres: un archivo de instrucciones persistentes que el agente lee automáticamente antes de actuar. Si usas Claude Code, CLAUDE.md es el estándar.

    ¿Con qué frecuencia debo actualizar el CLAUDE.md?

    Siempre que cambie algo relevante del proyecto: cuando migras de runtime, cuando adoptas una nueva convención, cuando añades una restricción que no estaba. En proyectos activos, una revisión mensual es suficiente para detectar instrucciones obsoletas. El indicador más claro de que el CLAUDE.md está desactualizado es que el agente empieza a proponer patrones que el equipo ya abandonó.

    ¿Puede un CLAUDE.md ser demasiado largo?

    Sí. Un CLAUDE.md de 500 líneas con instrucciones exhaustivas sobre cada posible situación introduce dos problemas: el agente puede no aplicar instrucciones que están enterradas en el archivo, y el mantenimiento se vuelve costoso. La guía práctica: si una instrucción no ha evitado ningún error en los últimos dos meses, probablemente no necesita estar ahí. Menos, mejor — pero con precisión.


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

  • El grafo reactivo de Angular: cómo Signals sabe qué recalcular

    El grafo reactivo de Angular: cómo Signals sabe qué recalcular

    Un junior del equipo me enseñó hace poco un computed() que calculaba el total de un carrito. Funcionaba. Pero me dijo una frase que lo delata todo: “le metí un console.log dentro y no se imprime cuando cambio la cantidad… hasta que abro el modal del total”.

    No estaba roto. Estaba haciendo exactamente lo que debe hacer.

    El problema no era su código. Era su modelo mental. No conocía el grafo reactivo de Angular, la estructura que decide qué se recalcula y cuándo. Pensaba que un computed() se recalcula cuando cambian sus datos. Y no. Se recalcula cuando alguien lo lee. Esa diferencia, que parece un detalle, es la puerta de entrada a entender cómo piensa Angular por dentro.

    Porque eso es justo lo que vive debajo de signal(), computed() y effect(): un grafo que casi nadie se molesta en entender, y que lo explica todo.

    ¿Qué es el grafo reactivo de Angular?

    El grafo reactivo de Angular es la estructura interna que el framework construye con su sistema de Signals para saber, en todo momento, qué valores dependen de qué otros. No es una API que tú llamas. Es el motor que se monta solo cuando declaras signals, computeds y effects, y es lo que permite que Angular recalcule únicamente lo que cambió en lugar de revisar la aplicación entera.

    Los Signals son estables desde Angular 16-17 (2023), y son la base sobre la que se apoya el modo zoneless, disponible como opción de producción a partir de Angular v20.

    Imagínalo literalmente como un grafo: nodos conectados por flechas. Los nodos son tus valores reactivos. Las flechas son las dependencias entre ellos. Cuando un valor cambia, Angular recorre esas flechas para decidir qué tocar y qué dejar en paz.

    Y la clave —la que casi nadie explica— es que esas flechas no las dibujas tú. Las descubre Angular en tiempo de ejecución.

    Vamos por partes.

    Los nodos: productores y consumidores

    Todo en el grafo es una de dos cosas (o las dos a la vez). Te lo presento como modelo conceptual, no como API pública: Angular no te expone estos nombres, pero entenderlos cambia cómo lees tu propio código.

    • Un signal() es un productor puro. Tiene un valor, otros lo leen, pero él no depende de nadie. Es una raíz del grafo.
    • Un computed() es consumidor y productor a la vez. Lee otros signals (consume) y a su vez otros lo leen a él (produce). Es un nodo intermedio.
    • Un effect() es un consumidor puro. Lee signals y reacciona, pero nadie lee a un effect. Es una hoja del grafo, el final de la cadena.
    import { signal, computed, effect } from '@angular/core';
    
    const precio = signal(100);          // productor puro (raíz)
    const cantidad = signal(2);          // productor puro (raíz)
    
    const total = computed(() =>         // consumidor (lee precio y cantidad)
      precio() * cantidad());            // + productor (otros leerán 'total')
    
    effect(() => {                       // consumidor puro (hoja)
      console.log('Total actual:', total());
    });

    El grafo aquí tiene una forma clarísima: precio y cantidad apuntan a total, y total apunta al effect. Cuatro nodos, tres flechas.

    Pero tú no escribiste ni una sola de esas flechas.

    Las aristas: tracking dinámico de dependencias

    Aquí está la primera idea que separa a quien usa signals de quien los entiende.

    Las dependencias no se declaran. Angular las descubre.

    Cuando un computed() o un effect() se ejecuta, Angular activa un registro temporal: “todo signal que se lea durante esta ejecución se anota como dependencia”. Lees precio() dentro del computed → se crea la flecha precio → total. Lees cantidad() → se crea cantidad → total. Termina la ejecución, se cierra el registro.

    Esto tiene una consecuencia preciosa: las dependencias pueden ser condicionales. Cada ejecución puede producir un conjunto distinto de aristas.

    const modoOscuro = signal(false);
    const colorClaro = signal('#ffffff');
    const colorOscuro = signal('#1a1a1a');
    
    const colorFondo = computed(() => {
      if (modoOscuro()) {
        return colorOscuro();   // solo se lee si modoOscuro es true
      }
      return colorClaro();      // solo se lee si modoOscuro es false
    });

    Cuando modoOscuro es false, este computed depende de modoOscuro y de colorClaro. No depende de colorOscuro en absoluto. Si cambias colorOscuro mientras estás en modo claro, colorFondo no se marca como sucio, no se recalcula, no pasa nada.

    Cambia modoOscuro a true y, en el siguiente recálculo, el grafo se reconfigura: ahora la flecha sale de colorOscuro y la de colorClaro desaparece.

    Esto no lo consigues gratis con RxJS combinando observables. Aquí es el comportamiento por defecto, sin esfuerzo. Es exactamente este tipo de detalle el que trabajamos a fondo en el curso de Angular Moderno, porque entender el grafo cambia cómo estructuras el estado de toda la app.

    Push y pull: por qué el computed de mi compañero no se ejecutaba

    Volvamos a la historia del principio. El console.log que no se imprimía.

    El grafo reactivo funciona con dos fases distintas, y casi todo el mundo solo conoce la primera.

    Fase push (cuando cambias un signal). Llamas a cantidad.set(5). Angular recorre el grafo hacia abajo y marca a los consumidores como “sucios” (stale). total se marca sucio. El effect que depende de total se marca sucio. Y ya. No se recalcula nada todavía. Solo se propaga una marca de “esto podría haber cambiado”.

    Fase pull (cuando alguien lee). El valor de un computed() solo se recalcula cuando alguien lo lee y está marcado sucio. Es perezoso (lazy) y memoizado: si nadie lo lee, no se ejecuta jamás.

    const a = signal(1);
    const b = signal(2);
    
    const suma = computed(() => {
      console.log('¡Calculando suma!');   // ¿cuándo se imprime esto?
      return a() + b();
    });
    
    a.set(10);
    a.set(20);
    a.set(30);
    // Hasta aquí: el log NO se ha impreso ni una vez.
    
    console.log(suma());  // AHORA imprime "¡Calculando suma!" y luego 32
    console.log(suma());  // NO vuelve a imprimir: valor memoizado

    Tres cambios en a y cero recálculos, porque nadie leyó suma. La leemos una vez y se calcula una vez. La leemos de nuevo sin cambios de por medio y devuelve el valor cacheado sin recalcular.

    Por eso el computed() del carrito “no se ejecutaba” hasta abrir el modal: ningún template estaba leyendo ese valor. En cuanto el modal lo renderizó, lo leyó, y entonces —y solo entonces— se recalculó.

    No era un bug. Era el grafo trabajando exactamente como debe: no malgastar ni un ciclo de CPU en valores que nadie está mirando.

    Consistencia glitch-free: nunca verás un estado intermedio falso

    Pregunta incómoda: ¿qué pasa cuando un nodo depende del mismo origen por dos caminos distintos?

    const base = signal(10);
    
    const doble = computed(() => base() * 2);
    const triple = computed(() => base() * 3);
    
    const resumen = computed(() => `${doble()} y ${triple()}`);

    resumen depende de doble y de triple, y ambos dependen de base. Hay dos rutas desde base hasta resumen.

    Cuando cambias base, un sistema reactivo mal diseñado podría recalcular resumen dos veces (una por cada ruta) o, peor, calcularlo con doble ya actualizado pero triple todavía viejo. Eso es un glitch: un estado intermedio que nunca debió existir.

    El grafo de Angular es glitch-free. Ante un cambio en base, resumen se recalcula una sola vez, y cuando lo hace, tanto doble como triple ya están coherentes. Nunca observas la mezcla rara. El orden de evaluación del grafo (pull bajo demanda) junto con el versionado de cada nodo garantizan que un consumidor con varias rutas hacia el mismo origen converja en un único recálculo consistente.

    Esto importa de verdad en producción. Es la diferencia entre una UI que parpadea con valores intermedios y una que actualiza limpio.

    Versiones e igualdad: la poda que ahorra renders

    Aquí entra el matiz que convierte el grafo en algo eficiente y no solo correcto.

    Cada productor lleva, conceptualmente, una versión. Cuando un consumidor está sucio y va a recalcular, primero compara: “¿la versión de mis dependencias cambió de verdad respecto a la última vez que las usé?”. Si nada cambió realmente, no recomputa.

    Y hay una segunda poda, más conocida: la función de igualdad. Por defecto, un signal usa Object.is para decidir si el nuevo valor es distinto del anterior. Si haces set con un valor igual al actual, el grafo no propaga nada aguas abajo.

    const estado = signal('activo');
    
    const etiqueta = computed(() => {
      console.log('Recalculando etiqueta');
      return estado().toUpperCase();
    });
    
    etiqueta();              // imprime "Recalculando etiqueta" → "ACTIVO"
    estado.set('activo');    // mismo valor: Object.is da true → NO propaga
    etiqueta();              // NO recalcula: el grafo nunca se marcó sucio

    Puedes personalizar esa comparación cuando trabajas con objetos:

    const usuario = signal(
      { id: 1, nombre: 'Ana' },
      { equal: (a, b) => a.id === b.id }   // igual si el id no cambia
    );

    Ahora, si emites un objeto nuevo con el mismo id, el grafo lo considera igual y corta la propagación ahí mismo. Menos recálculos, menos renders. Esta equal es tu palanca para podar el grafo a mano cuando lo necesitas.

    Effects y el scheduler: por qué no son síncronos

    Un detalle que confunde: los effect() no corren en el instante exacto en que cambias un signal.

    Cuando un signal del que depende un effect cambia, el effect se marca sucio y se agenda (scheduler). Angular lo ejecuta de forma agrupada, ligado normalmente a su ciclo de detección de cambios. Esto evita que un effect se dispare diez veces si haces diez set seguidos en la misma tarea: se ejecuta una vez, con el estado final.

    const x = signal(0);
    
    effect(() => console.log('x es', x()));
    
    x.set(1);
    x.set(2);
    x.set(3);
    // El effect NO imprime tres veces seguidas.
    // Se agenda y corre una vez, con el valor final: "x es 3"

    Si vienes de pensar en callbacks síncronos, este es el ajuste mental que necesitas. El effect reacciona, pero reacciona cuando toca, no a cada microcambio.

    El contraste que lo explica todo: grafo vs. Zone.js

    Ahora la pieza que da sentido a todo lo anterior.

    Durante años, Angular detectó cambios con Zone.js + dirty checking. El modelo era de fuerza bruta: cuando algo podía haber cambiado (un click, un timeout, una respuesta HTTP), Angular recorría todo el árbol de componentes comprobando cada binding por si acaso. Funcionaba, pero el framework no sabía qué había cambiado. Solo sabía que algo pudo cambiar, y revisaba entero por si las moscas.

    El grafo reactivo invierte el modelo. Angular ya no necesita preguntar “¿cambió algo en alguna parte?”. El propio grafo sabe exactamente qué signal cambió y qué nodos dependen de él. La actualización deja de ser una búsqueda y pasa a ser una notificación dirigida.

    Zone.js + dirty checking Grafo reactivo (Signals)
    ¿Qué sabe el framework? Que algo pudo cambiar Qué signal cambió exactamente
    Alcance de la revisión Todo el árbol de componentes Solo el nodo y sus dependientes
    Disparo Cualquier evento async (click, timeout, HTTP) El cambio concreto de un signal
    Coste Proporcional al tamaño del árbol Proporcional a lo que de verdad cambió
    Viabilidad zoneless No (necesita Zone.js) Sí (Angular puede prescindir de Zone.js)

    Esto es la base técnica de zoneless —opción de producción desde Angular v20— y de la detección de cambios granular: si todo tu estado vive en signals, Angular puede prescindir de Zone.js por completo, porque el grafo ya le dice qué refrescar. Pasas de “revisa todo el árbol por si acaso” a “actualiza este nodo y sus tres dependientes, nada más”.

    Si quieres ver dónde encaja esto en la versión actual, lo cuento en detalle en las novedades de Angular v22, y cómo este mismo grafo gobierna la carga de datos asíncrona en el post sobre la Resource API de Angular 22.

    Qué puedes hacer con esto hoy

    No necesitas memorizar internals para escribir signals. Pero con este modelo en la cabeza dejas de programar a ciegas:

    1. Mete tu lógica derivada en computed() sin miedo a la performance: si nadie lo lee, no cuesta nada.
    2. Deja de “optimizar” recálculos a mano — el grafo ya memoiza y poda por ti.
    3. Usa equal personalizado cuando trabajes con objetos y veas renders de más.
    4. Mueve estado de RxJS a signals donde la lógica sea síncrona y derivada; reserva RxJS para flujos de eventos reales.

    La próxima vez que un computed() “no se ejecute cuando esperabas”, ya no vas a pensar que está roto. Vas a saber que el grafo está esperando, perezoso y eficiente, a que alguien lea el valor.

    Si quieres dominar Signals con esta profundidad —el grafo, los effects, la migración desde RxJS y los patrones que aguantan en producción— eso es justo lo que construimos paso a paso en el curso de Angular Moderno. Y si quieres seguir afilando el modelo mental con la comunidad, te espero en Dominicode Labs.

    Preguntas frecuentes

    ¿El grafo reactivo es lo mismo que los Signals?

    No exactamente. Los Signals (signal, computed, effect) son las APIs que tú usas; el grafo reactivo es la estructura interna que Angular construye a partir de ellas para saber qué depende de qué. Tú escribes signals; Angular monta el grafo automáticamente por debajo.

    ¿Necesito entender el grafo reactivo para usar Signals?

    Para escribir código que funcione, no. Para escribir código eficiente y entender por qué un computed() se comporta como lo hace —cuándo recalcula, cuándo no, por qué no parpadea— sí. Es la diferencia entre usar signals y dominarlos.

    ¿El grafo reactivo reemplaza a RxJS?

    No lo reemplaza, lo complementa. El grafo de Signals brilla en estado síncrono y valores derivados. RxJS sigue siendo la mejor herramienta para flujos de eventos complejos, streams asíncronos y operadores como debounce o switchMap. Muchos proyectos usan ambos: signals para el estado, RxJS para los flujos.

    ¿Qué relación tiene con zoneless?

    Total. El modo zoneless elimina Zone.js, y solo es viable porque el grafo reactivo ya le dice a Angular exactamente qué cambió y qué refrescar. Sin el grafo, Angular tendría que volver a revisar todo el árbol de componentes. El grafo es la condición que hace posible zoneless.

    ¿Un computed() se ejecuta siempre que cambian sus datos?

    No. Es perezoso: se marca como “sucio” cuando cambia una dependencia, pero solo se recalcula de verdad cuando alguien lee su valor. Si nadie lo lee, no se ejecuta. Y una vez calculado, devuelve un valor memoizado hasta que cambie alguna dependencia.

    ¿Cómo evita Angular recalcular un valor dos veces ante un mismo cambio?

    Gracias a la consistencia glitch-free y al versionado de nodos. Si un consumidor depende de un mismo origen por varias rutas, el grafo lo recalcula una sola vez y con valores coherentes, sin estados intermedios falsos ni recálculos duplicados.

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

  • Cómo publicar tu libro en Amazon KDP siendo developer

    Cómo publicar tu libro en Amazon KDP siendo developer

    El primer libro que publiqué en Amazon no lo publiqué porque tuviera un plan brillante. Lo publiqué porque llevaba meses explicando los mismos conceptos una y otra vez — en vídeos, en cursos, en respuestas de Discord. En un momento dado me di cuenta de que tenía el contenido. Lo que me faltaba era empaquetarlo de forma que trabajara por mí mientras yo dormía.

    Eso fue hace más de un año. Desde entonces he publicado en KDP y en Leanpub, y he entendido algo que no se dice suficiente: cómo escribir un libro en Amazon KDP no es una cuestión de talento ni de tiempo libre. Es una operación de producto. Las reglas son las mismas que en cualquier software que lanzas al mercado.

    Si eres developer y tienes conocimiento que vale, este post te muestra el camino real. No el camino bonito que venden los gurús de self-publishing. El que funciona.


    Por qué tiene sentido publicar en KDP en 2026

    Amazon KDP (Kindle Direct Publishing) es la plataforma de autopublicación de Amazon que permite a cualquier autor publicar libros digitales e impresos y recibir royalties de entre el 35% y el 70% según el precio y el territorio — sin intermediarios, sin editorial, sin mínimo de ventas.

    Hay algo que los developers subestiman sistemáticamente: su conocimiento tiene un precio de mercado mucho más alto del que cobran.

    Un libro técnico en Amazon en torno a los 9-15 dólares puede venderse durante años sin que hagas nada más. No hay soporte. No hay alumnos que resolver dudas. No hay plataforma que mantener. Es el activo de menor fricción que existe para monetizar lo que ya sabes.

    Pero además del ingreso, hay algo que el dinero no captura del todo: la autoridad. Cuando publicas un libro técnico con tu nombre en Amazon, pasa algo interesante. Los recruiters lo buscan. Los alumnos de tus cursos confían más. Las empresas te contratan para consultorías a tarifas distintas. No porque el libro sea un bestseller — sino porque muy pocos developers dan ese paso.

    La barrera no es técnica. Es psicológica. Y en cuanto la superas una vez, el proceso se vuelve repetible.


    Los 3 pasos reales antes de escribir una sola línea

    La mayoría de developers que intentan escribir un libro fracasan en el mismo sitio: empiezan a escribir antes de tener clara la respuesta a tres preguntas.

    1. ¿Hay gente que busca esto activamente?

    Entra en Amazon y busca tu tema. Si hay libros en inglés con cientos de reseñas, existe mercado. Si no hay nada, tienes dos opciones: eres pionero (raro) o el mercado no existe (más probable). Busca también en Google Trends. Una keyword con búsquedas constantes es más valiosa que una que pica una vez al año.

    2. ¿A quién le escribes exactamente?

    “Developers que quieren aprender testing” no es una audiencia. “Developers Angular con 2-4 años de experiencia que nunca han escrito un test y se sienten avergonzados de ello” sí lo es. Cuanto más específico eres, más resuena tu libro — y paradójicamente, más vendes.

    3. ¿Puedes resolver su problema mejor que lo que ya existe?

    No tienes que ser el más completo. Tienes que ser el más útil para esa persona concreta. Un libro de 80 páginas que resuelve un problema específico de forma directa vende más que un tratado de 400 páginas que lo cubre todo.

    Si puedes responder estas tres preguntas con honestidad, tienes permiso para abrir el editor de texto.


    La tabla de contenidos es tu producto, no tu índice

    Este es el error que cometí en mi primer borrador. Diseñé la tabla de contenidos como si fuera un índice de documentación técnica: exhaustivo, ordenado, completo. El resultado era un libro que un developer leería de principio a fin y luego cerraría.

    La tabla de contenidos de un libro que se vende funciona diferente. Cada capítulo tiene que responder a una pregunta que tu lector se está haciendo. No “Capítulo 3: Configuración del entorno” — sino algo que genere tensión, que haga que el lector piense “esto lo necesito”.

    Antes de escribir nada, escribe los títulos de todos tus capítulos. Léelos como si fueras tu lector ideal. ¿Te dan ganas de seguir? ¿Cada uno promete algo concreto? Si la respuesta es no, reescríbelos antes de escribir el contenido.

    Mi libro Spec-Driven Development lo estructuré exactamente así: cada capítulo resuelve una fricción específica del proceso de desarrollo con IA. No es un manual — es una secuencia de problemas y soluciones.


    El flujo de producción real: de Markdown a Amazon

    Aquí está el proceso que uso. Es simple. No necesitas Word, ni Adobe InDesign, ni herramientas caras.

    1. Escribe en Markdown. Todo en .md. Sin preocuparte del formato mientras escribes. Foco en el contenido. Uso Obsidian o un editor simple — da igual cuál uses mientras no te distraiga del texto.
    1. Convierte a formato KDP con Pandoc. KDP acepta .docx y .epub. Pandoc convierte tu Markdown a cualquiera de los dos en un comando:
       pandoc libro.md -o libro.docx --reference-doc=template.docx
       

    El --reference-doc es una plantilla Word con tus estilos definidos (tipografía, márgenes, encabezados). KDP ofrece plantillas gratuitas que puedes usar como base. Una vez que tienes la plantilla, el proceso tarda minutos.

    1. La portada es lo más importante que no escribes. No uses Canva con una foto de stock genérica. Tampoco uses el generador de portadas de KDP. Las portadas malas matan las ventas. Opciones reales: contratar a un diseñador en Fiverr o Upwork con experiencia en portadas de libros técnicos (“KDP book cover designer”). El presupuesto mínimo viable es entre 50 y 150 dólares. Es la inversión más rentable del proceso.
    1. ISBN y precio. KDP te asigna un ISBN gratuito si lo quieres. Para el precio: KDP ofrece dos planes de regalías. Con el plan del 70% el precio debe estar entre $2,99 y $9,99 — ese es el rango óptimo para libros técnicos de nicho. Fuera de ese rango se aplica el plan del 35%. Para libros técnicos especializados, $9,99 es el punto de entrada mínimo recomendable.

    Errores que cometí y que tú no tienes que cometer

    Estos son los errores que veo repetirse en developers que publican por primera vez — y que yo mismo cometí.

    1. Precio demasiado bajo por miedo a no vender. Poner el libro a $2,99 no genera más ventas — genera la percepción de que el contenido vale $2,99. El precio comunica calidad. Un libro técnico especializado a $9,99 se percibe como serio.
    1. Descripción del libro sin estructura ni keywords. La descripción en Amazon no es un resumen del libro. Es una página de ventas. Tiene que abrir con el problema del lector, prometer la solución, y cerrar con una llamada a la acción. Amazon indexa las palabras de la descripción — úsalas con intención.
    1. Categorías mal elegidas. Amazon te permite elegir hasta 3 categorías desde la interfaz de KDP. No elijas las más obvias — elige las más específicas donde puedas rankear. “Computers & Technology” tiene miles de libros. “Software Testing” o “Web Development” tiene muchos menos. Herramientas como Publisher Rocket te ayudan a encontrar las categorías con mejor relación demanda/competencia.
    1. Lanzar sin reseñas. Las primeras reseñas son las más difíciles de conseguir y las más importantes. Antes de publicar, da acceso al borrador a personas de tu comunidad que puedan dejar una reseña honesta el día del lanzamiento. Sin reseñas, el algoritmo de Amazon no te da visibilidad.

    Cómo optimizar tu listing para que Amazon te encuentre

    El listing de Amazon es tu SEO. Funciona como un motor de búsqueda interno, y si no lo optimizas, el libro no aparece.

    Título y subtítulo. El título incluye la keyword principal. El subtítulo desarrolla la promesa de valor y añade keywords secundarias. Ejemplo: “Testing en Angular — Guía práctica con Jest y Testing Library para developers” incluye “testing Angular”, “Jest” y “Testing Library” de forma natural.

    Backend keywords. KDP te da 7 campos de keywords, cada uno con hasta 50 caracteres. No repitas keywords que ya están en el título. Usa variaciones, términos relacionados y problemas específicos que resuelve el libro. Sepáralas con espacios dentro de cada campo, no con comas — Amazon las trata como términos individuales.

    Descripción con HTML. Amazon acepta HTML básico en las descripciones. Usa para negritas y
    para saltos de línea. Estructura la descripción con un párrafo de gancho, una lista de lo que aprende el lector, y un párrafo de cierre con llamada a la acción.

    Categorías estratégicas. Elige las 3 categorías disponibles con criterio. Usa herramientas como Publisher Rocket o busca manualmente en Amazon qué categorías específicas tienen menos de 5.000 libros y búsquedas reales — ahí es donde un libro nuevo puede rankear.


    Qué pasa después de publicar

    Publicar el libro es el 40% del trabajo. El otro 60% es visibilidad.

    Anuncia el libro en todos tus canales. En mi caso: el canal de YouTube, la newsletter, Dominicode Labs. Pide a tu comunidad que lo comparta si les parece valioso. Crea contenido derivado — un vídeo basado en el primer capítulo, un post basado en el error más común que resuelve el libro.

    Amazon Ads es otra palanca. No para todo el mundo, pero si el libro tiene buen conversion rate (reseñas, descripción sólida, precio correcto), los anuncios de Amazon tienen ROI positivo en nichos técnicos.

    Y si ya tienes una audiencia construida — cursos, comunidad, canal — el libro amplifica todo lo demás. No compite con tus cursos: los legitima.


    FAQ — Preguntas frecuentes sobre publicar en Amazon KDP

    ¿Necesito tener muchos seguidores para que mi libro venda?

    No. Los seguidores ayudan en el lanzamiento, pero Amazon tiene su propio tráfico. Un libro bien optimizado con buenas reseñas puede vender durante años en un nicho específico sin que tengas audiencia previa. La diferencia es que con audiencia el lanzamiento es más rápido.

    ¿Cuánto tiempo lleva escribir un libro técnico?

    Depende del scope. Un libro de 60-80 páginas sobre un tema muy concreto se puede escribir en 4-6 semanas escribiendo entre 500 y 1.000 palabras al día. No intentes escribir un tratado de 400 páginas como primer libro. Empieza pequeño, publica, aprende del proceso.

    ¿Merece la pena publicar en español o solo en inglés?

    En español hay menos competencia y una audiencia hispanohablante técnica hambrienta de buenos recursos en su idioma. Los volúmenes de venta son menores que en inglés, pero la conversión puede ser mejor porque hay menos libros de calidad. Mi recomendación: empieza en español si tu audiencia es hispanohablante, y considera una versión en inglés si el tema tiene demanda global.

    ¿KDP o Leanpub para libros técnicos?

    Son complementarios. Leanpub tiene un modelo de actualización continua ideal para libros técnicos que evolucionan con las versiones del framework. KDP te da acceso al tráfico de Amazon, que es mucho mayor. Yo uso los dos: Leanpub para la comunidad técnica y actualizaciones frecuentes, KDP para distribución masiva.

    ¿Qué pasa si el libro no vende?

    Analiza el listing antes de asumir que el problema es el contenido. La mayoría de las veces el problema es la portada, la descripción o las categorías — no el libro en sí. Itera sobre el listing antes de rendirte. Y si tras optimizar no mueve, eso también es información valiosa sobre la demanda real.


    Si quieres ver cómo aplico todo esto en la práctica — desde la idea hasta el producto publicado — en el curso Construye con IA hay un módulo completo sobre cómo usar Claude para acelerar la escritura técnica sin perder tu voz.

    Si estás en el proceso de construir tu marca como developer y quieres ir más allá del libro, en Dominicode Labs tenemos recursos, proyectos y comunidad para developers que están construyendo activos reales con su conocimiento.


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

  • Cómo correr modelos de IA en local con Ollama

    Cómo correr modelos de IA en local con Ollama

    Era domingo por la noche. Tenía que probar un flujo de extracción de datos con un LLM y el presupuesto del cliente para APIs era cero. Nada aprobado, nada disponible.

    La solución: correr modelos IA en local. Instalé Ollama en diez minutos, bajé Llama 3 y terminé el prototipo antes de medianoche sin gastar un solo centavo en tokens.

    Eso es lo que te da correr modelos en local: velocidad, independencia y control total sobre lo que entra y lo que sale del modelo. Y en 2026, con los modelos open source en el estado en que están, la calidad ya no es una excusa para no hacerlo.

    Correr modelos IA en local significa ejecutar un Large Language Model directamente en tu hardware — sin enviar datos a APIs externas, sin coste por token y con latencia controlada. Herramientas como Ollama hacen que el proceso sea tan sencillo como instalar cualquier CLI.


    Por qué correr modelos en local (y cuándo importa de verdad)

    Hay cuatro razones concretas. Y van más allá del coste.

    Privacidad. Si trabajas con datos sensibles — contratos, código propietario, información médica — mandar esos datos a una API externa es un riesgo legal y contractual. Con modelos IA en local, los datos nunca salen de tu máquina.

    Latencia. Una llamada a GPT-4o tiene entre 300ms y 2 segundos de ida y vuelta dependiendo del tamaño del prompt. Un modelo local bien configurado en una máquina decente responde en milisegundos para tareas simples. Si construyes herramientas de developer experience o pipelines de CI con IA, esa diferencia importa.

    Iteración sin coste. En fases de prototipado puedes hacer miles de llamadas al día para testear prompts, ajustar pipelines y explorar comportamientos del modelo. Con una API de pago, eso se acumula rápido. En local, es gratis.

    Trabajo offline. Aviones, conexiones lentas, redes corporativas con proxies restrictivos. Un modelo local funciona siempre.


    Las dos herramientas que necesitas conocer

    Ollama — la opción de developer

    Ollama es la herramienta que más uso y la que recomiendo si eres developer. Es una CLI + servidor HTTP que gestiona la descarga, configuración y ejecución de modelos como si fueran contenedores Docker.

    Funciona en macOS, Linux y Windows. Tiene una API REST compatible con el formato de OpenAI, lo que significa que puedes usar clientes existentes con un cambio mínimo de URL. Y tiene una comunidad activa con más de 100 modelos disponibles en su registry.

    Si sabes usar Docker, Ollama te va a resultar natural inmediatamente.

    LM Studio — la opción visual

    LM Studio es la alternativa para quienes prefieren una interfaz gráfica. Permite navegar, descargar y comparar modelos con un chat visual, ideal para exploración inicial o para compartir con equipos no técnicos.

    También tiene un servidor local compatible con OpenAI. La diferencia clave: Ollama es mejor para integrar en código y scripts; LM Studio es mejor para explorar modelos de forma interactiva.

    Para este post me centro en Ollama porque es donde vive el flujo de trabajo real de un developer.


    Tutorial: instalar Ollama y correr tu primer modelo

    1. Instalación

    macOS:

    brew install --cask ollama

    Linux:

    curl -fsSL https://ollama.com/install.sh | sh

    Windows:
    Descarga el instalador desde ollama.com/download y ejecútalo. Ollama se instala como servicio y arranca automáticamente.

    Una vez instalado, verifica que funciona:

    ollama --version

    2. Descargar y correr un modelo

    # Descargar y correr Llama 3.2 (3B — ligero, ideal para empezar)
    ollama run llama3.2
    
    # Descargar sin abrir el chat
    ollama pull llama3.2
    
    # Descargar Mistral 7B
    ollama pull mistral
    
    # Descargar Gemma 3 (Google, muy eficiente)
    ollama pull gemma3
    
    # Descargar Qwen 2.5 (excelente en código)
    ollama pull qwen2.5-coder
    
    # Descargar Phi-4 (Microsoft, pequeño y capaz)
    ollama pull phi4

    Al ejecutar ollama run se abre un REPL interactivo en la terminal. Escribe tu prompt y responde como cualquier chat. Para salir: /bye.

    3. Gestionar modelos

    # Ver modelos descargados
    ollama list
    
    # Eliminar un modelo
    ollama rm mistral
    
    # Ver información de un modelo
    ollama show llama3.2

    4. Usar la API REST de Ollama

    Cuando Ollama está corriendo, expone una API en http://localhost:11434. Puedes usarla directamente con curl:

    # Generar una respuesta (completions)
    curl http://localhost:11434/api/generate \
      -H "Content-Type: application/json" \
      -d '{
        "model": "llama3.2",
        "prompt": "Explica qué es un closure en JavaScript en dos frases",
        "stream": false
      }'
    
    # Formato compatible con OpenAI (chat completions)
    curl http://localhost:11434/v1/chat/completions \
      -H "Content-Type: application/json" \
      -d '{
        "model": "llama3.2",
        "messages": [
          { "role": "user", "content": "Qué es un closure en JavaScript?" }
        ]
      }'

    El endpoint /v1/chat/completions es compatible con el SDK oficial de OpenAI. Solo tienes que cambiar la baseURL.


    Modelos recomendados según caso de uso

    Estos son los modelos IA en local con mejor rendimiento según el hardware disponible y el caso de uso:

    Modelo Tamaño Ideal para RAM mínima
    llama3.2:3b ~2 GB Tareas simples, prototipado rápido 8 GB
    llama3.1:8b ~5 GB Razonamiento general, chat 8 GB
    mistral:7b ~4 GB Instrucciones, resumen, generación de texto 8 GB
    qwen2.5-coder:7b ~4 GB Generación y revisión de código 8 GB
    gemma3:9b ~6 GB Tareas multilingues, contexto largo 16 GB
    phi4:14b ~9 GB Razonamiento complejo, análisis 16 GB
    llama3.3:70b ~40 GB Calidad cercana a GPT-4o 64 GB
    deepseek-r1:14b ~9 GB Razonamiento con chain-of-thought 16 GB

    Para una máquina de desarrollo con 16 GB de RAM, qwen2.5-coder:7b para tareas de código y llama3.1:8b para texto general cubren el 90% de los casos.


    Local vs nube: cuándo usar cada uno

    Criterio Local (Ollama) Nube (OpenAI, Anthropic, Google)
    Coste por llamada Gratis $0.001–$0.015 por 1K tokens
    Privacidad de datos Total Depende del proveedor y contrato
    Calidad en tareas complejas Buena (modelos 7B–14B) Excelente (modelos frontier)
    Latencia (primer token) Baja en hardware potente Varía: 300ms–2s
    Escalabilidad Limitada por tu hardware Prácticamente ilimitada
    Modelos de razonamiento avanzado Limitado o1, Claude Sonnet 4, Gemini 2.5 Pro
    Setup inicial 10 minutos Registro + API key
    Trabajo offline No
    Ideal para Prototipado, privacidad, CI/CD, dev tooling Producción con usuarios reales, tareas complejas

    La regla que uso: local para desarrollar, nube para producir. Prototipa barato, valida rápido, y cuando el producto necesita escalar o resolver tareas de mayor complejidad, mueve las llamadas críticas a un modelo cloud.


    Integración con TypeScript y JavaScript

    Ollama tiene su propio cliente oficial para Node.js. Dado que expone un endpoint compatible con OpenAI, puedes usar el paquete openai directamente — sin reescribir nada en tus proyectos existentes. Después de integrar modelos IA en local en varios proyectos TypeScript, estos son los tres patrones que más uso en producción:

    Con el SDK de OpenAI (compatibilidad directa)

    import OpenAI from "openai";
    
    const client = new OpenAI({
      baseURL: "http://localhost:11434/v1",
      apiKey: "ollama", // cualquier string no vacío
    });
    
    async function ask(prompt: string): Promise<string> {
      const response = await client.chat.completions.create({
        model: "llama3.2",
        messages: [{ role: "user", content: prompt }],
      });
    
      return response.choices[0].message.content ?? "";
    }
    
    const answer = await ask("Genera un schema Zod para un usuario con nombre y email");
    console.log(answer);

    Nota: El await en nivel superior requiere ESM. Añade "type": "module" en tu package.json o usa extensión .mts.

    El prompt del ejemplo genera un schema Zod. Si quieres dominar la validación de datos con TypeScript para estos pipelines, el curso de Zod cubre exactamente ese flujo con ejemplos reales.

    Con el cliente nativo de Ollama

    import { Ollama } from "ollama";
    
    const ollama = new Ollama({ host: "http://localhost:11434" });
    
    // Respuesta completa
    const response = await ollama.chat({
      model: "qwen2.5-coder",
      messages: [
        {
          role: "user",
          content: "Escribe una función TypeScript que valide un email con regex",
        },
      ],
    });
    
    console.log(response.message.content);
    
    // Streaming
    const stream = await ollama.chat({
      model: "qwen2.5-coder",
      messages: [{ role: "user", content: "Explica el patron Repository" }],
      stream: true,
    });
    
    for await (const chunk of stream) {
      process.stdout.write(chunk.message.content);
    }

    Instala el cliente oficial:

    npm install ollama
    # o con bun
    bun add ollama

    Cambiar entre local y nube con una variable de entorno

    Este patrón es el que más uso en proyectos reales — permite alternar entre Ollama y OpenAI sin cambiar código:

    import OpenAI from "openai";
    
    const isLocal = process.env.USE_LOCAL_LLM === "true";
    
    const client = new OpenAI({
      baseURL: isLocal ? "http://localhost:11434/v1" : "https://api.openai.com/v1",
      apiKey: isLocal ? "ollama" : process.env.OPENAI_API_KEY,
    });
    
    const model = isLocal ? "llama3.2" : "gpt-4o-mini";

    Con USE_LOCAL_LLM=true en desarrollo y la variable desactivada en producción, tienes el mejor de los dos mundos sin duplicar lógica. Esta es exactamente la clase de arquitectura que trabajamos en el curso Construye con IA, donde construimos productos completos con IA desde la especificación hasta el despliegue.


    FAQ — Preguntas frecuentes sobre modelos IA en local

    ¿Qué hardware necesito para correr modelos IA en local?

    Para modelos de 7B parámetros necesitas un mínimo de 8 GB de RAM y cualquier CPU moderna (últimos 5 años). Con GPU dedicada (NVIDIA o Apple Silicon) la inferencia es entre 5x y 10x más rápida. Un MacBook Pro M2 con 16 GB corre llama3.1:8b sin problemas. Para modelos de 70B necesitas al menos 64 GB de RAM o una GPU con suficiente VRAM.

    ¿Son los modelos locales comparables a GPT-4o o Claude?

    No para tareas complejas de razonamiento multi-paso o generación de código sofisticado. Pero para clasificación, resumen, extracción de información estructurada, generación de texto simple y asistencia en código básico, modelos como qwen2.5-coder:7b o llama3.1:8b son más que suficientes. La brecha se ha reducido mucho en el último año.

    ¿Puedo usar Ollama en un servidor de CI/CD?

    Sí. Ollama funciona en Linux sin cabecera y puede correr en Docker. El caso de uso más habitual: un runner de GitHub Actions con un runner self-hosted que tiene Ollama instalado para ejecutar checks de calidad de código o validaciones automáticas sin coste por llamada.

    ¿Cuánto espacio en disco ocupan los modelos?

    Depende del modelo y la cuantización. llama3.2:3b ocupa unos 2 GB. llama3.1:8b unos 5 GB. llama3.3:70b alrededor de 40 GB. Ollama descarga versiones cuantizadas (Q4 por defecto) que reducen el tamaño a la mitad aproximadamente manteniendo el 90–95% de la calidad del modelo original.

    ¿Qué diferencia hay entre Ollama y LM Studio?

    Ollama es una herramienta CLI-first, sin interfaz gráfica, pensada para integración en scripts y aplicaciones. LM Studio tiene una UI de escritorio con chat visual, gestor de modelos y comparador integrado. Ambas exponen una API local compatible con OpenAI. Si eres developer y quieres integrar el modelo en código, Ollama. Si quieres explorar modelos visualmente o presentarlos a stakeholders, LM Studio.

    ¿Puedo hacer fine-tuning de modelos con Ollama?

    Ollama no está diseñado para fine-tuning. Su función es servir modelos, no entrenarlos. Para fine-tuning de modelos open source necesitas herramientas como Unsloth, LoRA con Hugging Face o plataformas como Together AI y Replicate. Ollama puede servir después el modelo fine-tuneado si lo exportas en formato GGUF.

    ¿Es seguro usar modelos locales en producción?

    Depende del caso. Para un servicio interno o una herramienta de developer experience, perfectamente. Para un producto con miles de usuarios concurrentes, los modelos locales tienen limitaciones de escalabilidad obvias: un solo servidor solo puede atender las peticiones que su hardware permite procesar en paralelo. En ese escenario, la nube escala horizontalmente de forma que local no puede igualar.

    ¿Cómo elijo entre los modelos disponibles en Ollama?

    Empieza con llama3.2:3b para validar el flujo de tu aplicación (descarga rápida, responde rápido). Sube a llama3.1:8b o qwen2.5-coder:7b cuando necesites mejor calidad. Si tu máquina tiene 32 GB+ de RAM, phi4:14b o gemma3:27b son excelentes opciones intermedias antes de saltar a los modelos de 70B.


    Para ir más lejos

    Si estás construyendo productos con IA — integrando modelos IA en local en pipelines completos, agentes y herramientas que lleguen a usuarios reales — el siguiente paso es estructurar esa arquitectura desde el principio.

    El post sobre CLAUDE.md: el system prompt de tu proyecto explica cómo dar contexto permanente al agente. Clean Architecture en frontend con IA muestra cómo mantener las capas limpias cuando el agente genera código. Y si te preguntas hacia dónde va todo esto profesionalmente, la guía sobre qué es un Agentic Engineer cierra el mapa.

    En Dominicode Labs encontrarás proyectos completos, recursos avanzados y una comunidad de developers que están exactamente en esa fase: construyendo con IA en producción, no en tutoriales de YouTube.


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

  • Product builder: el cambio de mentalidad que la IA hace posible

    Product builder: el cambio de mentalidad que la IA hace posible

    Hace tres años me llegó un mensaje de un developer con siete años de experiencia en React. Me decía:

    “Bezael, sé hacer cualquier cosa que me pidan. Pero no tengo nada propio. Ni una app, ni un proyecto, ni un ingreso fuera de mi salario.”

    Lo que describía no era un problema de habilidades técnicas. Era un problema de identidad.

    Se veía a sí mismo como alguien que ejecuta. Alguien que recibe tickets, los cierra, y espera el siguiente. Un programador en el sentido más literal del término.

    Y eso, en 2026, es el camino más directo a la irrelevancia.

    Lo que ese developer necesitaba — lo que muchos developers necesitan — es pasar de ejecutar a construir: convertirse en un product builder.


    El developer que ejecuta vs. el product builder que construye

    Un product builder es un developer que combina criterio técnico con pensamiento de producto: no solo implementa soluciones, sino que decide qué problemas merecen ser resueltos y para quién.

    Hay una diferencia fundamental entre los dos perfiles, y no tiene nada que ver con el nivel técnico.

    Programador tradicional Product builder
    Pregunta: “¿Cómo lo implemento?” Pregunta primero: “¿Debería implementarlo?”
    Espera que alguien le diga qué construir Tiene una tesis propia sobre qué problema merece ser resuelto
    Mide su valor en líneas de código o tecnologías que domina Mide su valor en si algo que construyó funciona para alguien real

    No estoy diciendo que uno sea mejor persona que el otro. Estoy diciendo que el mercado está cambiando a una velocidad que hace que el primer perfil sea cada vez más reemplazable — y el segundo, más valioso que nunca.


    Por qué ahora es el momento exacto para hacer este cambio

    La barrera técnica para construir un producto ha colapsado.

    Antes, si querías lanzar algo solo, necesitabas dominar frontend, backend, base de datos, autenticación, despliegue, y probablemente seis frameworks distintos. Necesitabas un equipo o años de práctica en cada capa.

    Hoy, con herramientas como Claude Code, un developer con criterio puede tener un MVP funcionando en días. No porque la IA programe por ti — sino porque amplifica lo que ya sabes y elimina la fricción entre la idea y el código que la materializa.

    Eso cambia la ecuación por completo. Ya no es técnica la limitante. Es saber qué construir, para quién, y por qué alguien pagaría por ello.

    Eso es exactamente lo que trabajo en el curso Construye con IA: usar la IA no para generar código al azar, sino para ir de una idea real a un producto real con criterio de producto desde el principio.


    Qué comportamientos concretos tiene un product builder

    No voy a darte una lista de buzzwords. Te voy a decir cómo actúa alguien que ya hizo el cambio.

    Empieza por el problema, no por la tecnología. Antes de elegir un stack, un product builder ya sabe a qué usuario le duele qué cosa. La tecnología es una consecuencia de la solución, no el punto de partida.

    Shipea antes de que esté perfecto. El perfeccionismo técnico es el enemigo número uno de construir productos. Un product builder sabe que una versión imperfecta en manos de usuarios reales vale más que una versión perfecta en un repositorio privado.

    Habla con usuarios. No con amigos que te dicen que tu idea es buena. Con personas que tienen el problema que quieres resolver. Y aprende a distinguir entre lo que dicen que quieren y lo que realmente usarían.

    Entiende el negocio. No necesitas un MBA. Necesitas entender por qué alguien pagaría, cuánto pagaría, y cómo llegas a esa persona. Un product builder piensa en distribución desde el día uno.

    Itera con datos. No con opiniones. Lanza, mide, ajusta. El ciclo es corto y deliberado.


    Las cinco habilidades que nadie te enseñó en ningún bootcamp

    1. Pensamiento de producto

    No es saber usar Figma ni saber escribir user stories. Es desarrollar el hábito de preguntarte: “¿Qué problema real resuelve esto? ¿Para quién específicamente?”

    Cuando ves una app que usas cada día, un product builder la desmonta mentalmente: qué decisiones tomaron, qué sacrificaron, por qué funciona.

    2. Velocidad de validación

    La idea de construir durante meses antes de mostrar algo a alguien es una trampa. El objetivo no es construir — es aprender lo antes posible si lo que estás construyendo tiene sentido.

    Eso significa aprender a hacer prototipos rápidos y demos que generan feedback real. Una landing page que vende antes de que exista el producto ya es validación.

    3. Escritura que convierte

    Un product builder sabe explicar su producto en una frase. Sabe escribir una descripción que hace que alguien quiera probarlo. Sabe comunicar valor, no features.

    Esta habilidad — que parece ajena al mundo técnico — es una de las más diferenciadoras.

    4. Distribución y audiencia

    El código más limpio del mundo no vale nada si nadie lo usa. Un product builder piensa desde el principio en cómo va a llegar a sus usuarios: SEO, comunidad, contenido, partnerships, cold outreach.

    No tienes que hacerlo todo. Pero tienes que tener una respuesta a la pregunta: “¿Cómo van a enterarse de que esto existe?”

    5. Tolerancia a la ambigüedad

    Este es el más difícil para muchos developers, porque venimos de entornos donde los requisitos están (supuestamente) definidos. Construir un producto propio significa tomar decisiones con información incompleta, constantemente.

    Aprender a avanzar sin certeza total es una habilidad que se entrena, no que se tiene o no se tiene.


    El rol de la IA en todo esto

    La IA no te convierte en product builder. Eso lo haces tú con las decisiones que tomas.

    Lo que sí hace la IA es eliminar excusas.

    Antes, “no tengo tiempo para construir algo propio porque el backend me llevaría meses” era una razón real. Hoy no lo es. Hoy puedes hacer el backend en días, el frontend en días, el despliegue en horas.

    Lo que la IA no puede hacer por ti es decidir qué problema merece tu atención. No puede hablar con tus usuarios potenciales. No puede construir la audiencia que va a usar lo que hagas.

    Esa es tu parte. Y es la parte que más importa.

    Si quieres ver cómo trabajo este proceso — de la idea al producto con criterio de ingeniería y de negocio — en Dominicode Labs tenemos proyectos reales donde aplicamos exactamente esto: spec, validación, shipping, iteración.


    Cómo empezar el cambio hoy (sin abandonar tu trabajo)

    No te estoy pidiendo que renuncies ni que lances una startup la semana que viene. Te estoy pidiendo algo mucho más concreto.

    Elige un problema que tengas tú mismo — algo que te frustra como developer, como usuario, como persona — y pasa dos semanas construyendo una solución mínima. No perfecta. Mínima.

    Compártela con cinco personas que tengan el mismo problema. Observa qué pasa.

    Eso es un ciclo completo de product builder. Y lo puedes hacer este mes.

    La metodología que uso para estructurar este proceso — desde la especificación hasta el producto funcionando — está documentada en el Libro SDD. No es solo para proyectos grandes: es para cualquier developer que quiera pasar de “tengo una idea” a “tengo algo que funciona y que alguien usa”.


    El cambio no es técnico. Es de identidad.

    Volviendo al developer que me escribió hace tres años.

    Le dije algo simple: deja de pensar en qué tecnologías sabes y empieza a pensar en qué problema puedes resolver para alguien esta semana.

    No le dije que aprendiera product management. No le dije que hiciera un curso de negocios. Le dije que eligiera un problema pequeño y real, y que construyera algo — no para su portfolio, sino para alguien que lo necesita.

    Hoy tiene un producto SaaS que le genera ingresos recurrentes, lo sigue manteniendo como side project, y lleva ocho meses sin depender de que alguien le diga qué ticket hacer.

    Eso es lo que significa ser un product builder. No es un título. Es una forma de relacionarte con lo que construyes.

    Y la IA ha puesto esa posibilidad al alcance de cualquier developer que decida tomarla.


    Preguntas frecuentes

    ¿Un product builder necesita saber de diseño?
    No necesitas ser diseñador. Sí necesitas entender los principios básicos de UX y tener criterio para cuando algo es demasiado confuso para un usuario. Herramientas como Figma o incluso componentes UI prefabricados resuelven la mayor parte del problema visual. Lo que no puede resolver una herramienta es saber si tu producto tiene sentido.

    ¿Se puede ser product builder trabajando para una empresa?
    Sí, y de hecho es uno de los perfiles más buscados en empresas de producto. La diferencia es que aplicas el pensamiento de producto dentro de un equipo: cuestionas los requisitos, propones soluciones, mides el impacto real de lo que construyes. No eres el que ejecuta tickets — eres el que ayuda a decidir qué tickets merece la pena hacer.

    ¿La IA reemplaza al product builder?
    La IA reemplaza al developer que ejecuta tareas sin criterio. Al product builder lo amplifica, porque puede construir más rápido y experimentar más sin necesitar un equipo grande. La IA toma decisiones técnicas; el product builder toma decisiones de producto. Son funciones distintas.

    ¿Por dónde empiezo si nunca he lanzado nada propio?
    Empieza por un problema que conozcas bien — preferiblemente uno que tú mismo tengas. Construye la versión más pequeña posible que lo resuelva. Compártela con gente real antes de que esté “lista”. El error más común es esperar a tenerlo perfecto antes de mostrárselo a alguien. La retroalimentación temprana es lo que convierte una idea en un producto.

    ¿Cuánto tiempo lleva la transición de programador a product builder?
    No es una transición con fecha de fin — es un cambio de mentalidad que se profundiza con cada proyecto. El primer ciclo completo (idea, construcción mínima, usuarios reales, iteración) ya te cambia cómo ves el trabajo. La mayoría de developers que conozco que hicieron el cambio notan la diferencia después del primer proyecto propio que alguien usa de verdad.


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