Category: Blog

Your blog category

  • Cómo diseñar productos donde la IA es el núcleo

    Cómo diseñar productos donde la IA es el núcleo

    Diseño de productos AI-first — no “le pegamos un chatbot”, sino productos donde la IA es el core. Conecta con tu trabajo del AI Spec Builder

    Tiempo estimado de lectura: 4 min

    • Idea clave: Un producto es AI-first cuando deja de tener sentido sin la IA; no basta con añadir un chatbot.
    • Idea clave: Tres pilares técnicos: interfaces generativas, orquestación/agentic workflows y manejo de estado y resiliencia.
    • Idea clave: Implementa outputs estructurados, streaming, RAG y sandboxes; automatiza observabilidad y testea con mocks deterministas.

    Introducción

    “Diseño de productos AI-first — no ‘le pegamos un chatbot’, sino productos donde la IA es el core.” Si eso suena redundante, prueba a eliminar el modelo de tu producto: ¿qué queda? Si queda una app con una feature menos, no construiste un producto AI-first. Construiste lo que todos ya conocen: un chatbot pegado con cinta.

    Este artículo explica, con criterio técnico, qué implica realmente diseñar productos donde la IA es el núcleo —no un accesorio— y cómo ese criterio guió el diseño del AI Spec Builder.

    Resumen rápido (lectores con prisa)

    Qué es: Un enfoque de producto donde la IA es indispensable para entregar valor.

    Cuándo usarlo: Cuando quitar el modelo deja el producto sin sentido.

    Por qué importa: Cambia arquitectura, UX y requisitos de seguridad/observabilidad.

    Cómo funciona: Interfaces generativas + orquestación de tools + outputs estructurados y bucles de corrección.

    Diseño de productos AI-first — no “le pegamos un chatbot”: la regla que lo define todo

    La regla es simple y brutal: la IA es core cuando el producto deja de tener sentido sin ella. Punto.

    Eso cambia la arquitectura. No hablamos de “mejorar formularios” sino de invertir el flujo: el usuario entrega intención desestructurada; el sistema devuelve estructura accionable. Si tu interfaz puede ser reemplazada por un botón “Generar” y todo sigue funcionando, no entraste en el territorio AI-first.

    Tres pilares técnicos imprescindibles

    1) Interfaces generativas (Generative UI)

    El frontend deja de ser un conjunto de pantallas fijas. El LLM decide qué componente mostrar: formulario, tabla, gráfico, snippet de código. En vez de devolver Markdown, el backend debe enviar instrucciones estructuradas que el cliente renderice como componentes React o Web Components.

    2) Orquestación y agentic workflows

    El modelo no solo predice texto. Invoca herramientas: queries a bases de datos, ejecución de tests en sandboxes, llamadas a APIs internas. Diseña un grafo de capacidades (capability graph) y un mecanismo seguro que otorgue permisos granularmente al agente.

    3) Estado y resiliencia frente a la no-determinación

    Los modelos son probabilísticos. Implementa:

    • Outputs estructurados (JSON + esquemas Zod/JSON Schema) para validación automática.
    • Bucles de autocorrección en backend que reintenten o transformen la respuesta antes de exponerla al usuario.
    • Observabilidad: métricas de tokens, latencia, tasa de corrección.

    Caso práctico: AI Spec Builder — arquitectura y flujo

    AI Spec Builder no es un “formulario con IA”. Es una herramienta donde la IA actúa como Tech Lead.

    Flujo resumido:

    1. Usuario envía intención desestructurada.
    2. LLM ejecuta un bucle de clarificación: detecta lagunas y devuelve preguntas técnicas de alto valor.
    3. Respuestas del usuario actualizan en tiempo real un documento estructurado (Spec). El “chat” es control; el Spec es el producto.
    4. Al confirmar, el sistema dispara tools que generan esquema Prisma, contratos OpenAPI y tickets en el tracker.

    Si quitas el LLM, no queda documento útil. Esa dependencia es la prueba de que la IA es el core.

    Obstáculos reales y soluciones prácticas

    • Latencia: streaming obligatorio (SSE/WebSockets) y renderizado optimista. No bloquees la UI; muestra progreso parcial.
    • Costes de contexto: usa RAG y cachés semánticas para inyectar solo lo esencial en cada prompt. Implementa compresión y chunking del historial.
    • Confianza del output: fuerza structured outputs via esquemas; valida con Zod y aplica transformaciones si hace falta.
    • Seguridad de tools: sandboxes para ejecución de código, límites de tiempo y quotas por sesión; audita cada llamada del agente.
    • Testing: crea harnesses que mockeen el LLM con respuestas deterministas y casos de fallo para validar flujos completos.

    Recomendaciones concretas para Tech Leads

    • Pregunta antes de diseñar: “¿qué deja de resolverse si quitamos el modelo?” Si la respuesta no es clara, replantea el scope.
    • Diseña contrato UI ↔ LLM: define los tipos de respuesta esperados y diseña parsers robustos.
    • Implementa streaming desde el primer MVP. El usuario percibe velocidad; la IA necesita tiempo.
    • Externaliza state semántico a una vector DB y usa RAG; no recargues cada prompt con todo el historial.
    • Automatiza observabilidad: errores de parseo, reintentos, uso de herramientas y costes por sesión.
    • Mantén el control humano en las decisiones críticas; la IA sugiere, el humano valida.

    Lecturas y herramientas útiles

    Diseñar AI-first es más disciplina que magia. No se trata de “meter IA” en un producto existente, sino de reimaginar el flujo de valor alrededor de una capacidad que razona, completa y orquesta. Si tu equipo entiende y aplica eso —como hicimos con AI Spec Builder— estás construyendo algo que sobrevivirá más allá del hype.

    FAQ

    Respuesta: ¿Qué significa exactamente “AI-first”?

    AI-first significa que la propuesta de valor del producto depende de la IA; si quitas el modelo, el producto deja de tener sentido o pierde su función principal.

    Respuesta: ¿Cuándo debo considerar rediseñar un producto como AI-first?

    Cuando el flujo de valor puede optimizarse invirtiendo la dirección: el usuario aporta intención desestructurada y la IA devuelve estructura accionable que no sería práctica sin automatización cognitiva.

    Respuesta: ¿Qué es una “Generative UI”?

    Es una interfaz donde el modelo decide qué componente mostrar y en qué formato, y el backend envía instrucciones estructuradas que el cliente renderiza como componentes dinámicos.

    Respuesta: ¿Cómo se protege la ejecución de tools del agente?

    Mediante sandboxes, límites de tiempo, cuotas por sesión y auditoría de cada llamada; además, otorga permisos granularmente según un grafo de capacidades.

    Respuesta: ¿Qué prácticas reducen la latencia percibida por el usuario?

    Streaming (SSE/WebSockets), renderizado optimista y mostrar progreso parcial en vez de bloquear la UI.

    Respuesta: ¿Cómo validar outputs generados por la IA?

    Forzar salidas estructuradas (JSON + esquemas), validar con Zod o JSON Schema y aplicar bucles de corrección antes de exponer al usuario.

    Respuesta: ¿Qué pruebas recomendar para flujos que dependen del LLM?

    Crear harnesses que mockeen el LLM con respuestas deterministas y casos de fallo para validar flujos completos, incluyendo herramientas y errores de parseo.

    Respuesta: ¿Qué debe contener un contrato UI ↔ LLM?

    Definición de tipos de respuesta, esquemas esperados, reglas de reintento y parsers robustos para validar y transformar respuestas antes de renderizar.

  • Comparativa de Claude Code y Cursor para desarrolladores en 2026

    Comparativa de Claude Code y Cursor para desarrolladores en 2026

    Claude Code vs Cursor en 2026: cuándo usar cada uno — Comparativa honesta basada en flujos reales

    Tiempo estimado de lectura: 4 min

    • Claude Code es la herramienta de maquinaria: automatización, pipelines y transformaciones en lote.
    • Cursor es el artesano: edición visual, diffs en contexto y pair programming asistido por IA.
    • Asignar la tarea a la interfaz correcta reduce fricción: uso CLI/agents para procesos reproducibles y el IDE para juicios semánticos.

    Claude Code vs Cursor en 2026: cuándo usar cada uno — eso no es una discusión de modelos, es una discusión de interfaz y fricción. Ambas herramientas sirven a la misma ambición (hacerte más productivo), pero en 2026 la diferencia práctica está en qué tipo de trabajo quieres sacar de tu cabeza y poner en piloto automático. En este artículo comparo Claude Code (CLI/headless) y Cursor (IDE visual) basándome en flujos reales: refactors masivos, creación de features y debugging en producción. No hay benchmarks sintéticos; hay decisiones que rompen builds o liberan producto.

    Resumen rápido (lectores con prisa)

    Claude Code: CLI para automatización, pipelines y transforms en lote. Cursor: IDE visual para edición interactiva, diffs en contexto y pair programming. Usa Claude Code para reproducibilidad y escala; usa Cursor para juicios semánticos y cambios que requieren inspección visual.

    Claude Code vs Cursor en 2026: resumen rápido

    Claude Code (CLI): pensado para automatización, pipelines, scripts y trabajo en lote. Ideal para orquestar agentes sin interfaz gráfica, ejecutar transforms en monorepos y procesar logs pesados. (paquete npm: paquete npm, Anthropic: Anthropic)

    Cursor (IDE): pensado para el trabajo artesanal dentro del editor. Contexto visual, diffs en vivo, edición interactiva y pair programming asistido por IA. (Cursor)

    Ambas pueden usar modelos avanzados; la ganancia real viene de asignar a cada herramienta la tarea que mejor gestiona su interfaz.

    1) Features nuevas: scaffolding y lógica inicial

    Cuando arrancas una funcionalidad, necesitas dos cosas: rapidez para generar boilerplate y control para validar decisiones arquitectónicas.

    Usa Cursor si…

    • tu feature es UI/UX, componentes React/Next/Angular o cambios que requieren vista simultánea de varios archivos.
    • Cursor muestra el diff en contexto, te permite aceptar cambios parciales y mantener el control línea a línea. Es pair programming con atajos.

    Usa Claude Code si…

    • vas a generar servicios backend desde un esquema: scripts que lean un SQL/JSON Schema, generen controladores, tests y terraform en lote.
    • Un workflow típico: un script Bash alimenta Claude con el esquema y crea un PR con estructura inicial, lista para revisión. No abres centenares de archivos; revisas el PR.

    Ejemplo (flujo Claude Code): un comando que toma un esquema y produce controladores, ejecutado desde CI o local en terminal, sin interfaz gráfica interrumpida.

    2) Refactors masivos y migraciones

    Aquí se gana o se pierde integridad del sistema.

    Claude Code brilla cuando…

    • necesitas migraciones sistemáticas: buscar patrones con ast-grep, encadenar transformaciones con sed/perl/jq y delegar la modificación a un agente que produzca PRs.
    • Es fire-and-forget, reproducible y fácil de auditar.

    Cursor es la opción segura cuando…

    • el refactor toca lógica de dominio y contratos implícitos. Necesitas validar cada cambio con pruebas y juicio humano.
    • Cursor te permite intervenir en cada paso con contexto visual.

    Regla práctica: si puedes expresar la transformación como patrón AST y confiar en pruebas automatizadas, usa Claude Code. Si la transformación requiere juicio semántico sobre reglas de negocio, usa Cursor.

    3) Debugging: local vs infra

    Cursor es superior para errores locales: reproduces, el IDE captura stacktrace, envía contexto al asistente y te marca la línea problemática. El ciclo es inmediato y visual.

    Claude Code es la herramienta natural para logs y debugging infra: conecta por SSH, procesa gigas de logs con pipelines (cat error.log | claude --print "resume patrón de errores") y no rompe tu máquina local. Ideal para memory leaks, dumps o análisis de trazas distribuidas.

    Integración práctica (hooks y CI)

    No es “usar uno u otro”; es asignar tareas. Ejemplos concretos:

    • Revisor automático de PRs: Claude Code integrado en un job de CI o hook pre-push con Husky. El agente valida patrones y marca “Missing Tests”.
    • Patch iterativo de UI: Cursor para proponer cambios, revisar visualmente y aceptar commits parciales.

    Tabla de decisión rápida

    Escenario Recomendación
    Componentes UI y revisión visual Cursor
    Migraciones masivas (monorepo) Claude Code
    Debugging local (reproducción en IDE) Cursor
    Análisis de logs/infra remota Claude Code
    Scaffolding backend/infra as code Claude Code
    Refactors de lógica de negocio crítica Cursor

    Riesgos y buenas prácticas

    • Tokens y coste: cualquier workflow que pase megabytes de código a un LLM necesita filtrado (excluir node_modules, builds, package-lock.json) y paginar el contexto.
    • Contexto parcial: Claude Code trabaja con lo que le das. Añade tests y fixtures para reducir falsos positivos.
    • Auditoría: versiona prompts y scripts en el repo. Revisa los PRs generados por agentes como revisas cualquier patch humano.

    Conclusión clara

    No es una elección excluyente. Cursor es el artesano: detalle, iteración y control. Claude Code es la maquinaria: automatización, pipelines y transformaciones en lote. En 2026 los equipos más efectivos combinan ambos: Cursor para diseñar y verificar, Claude Code para escalar y ejecutar. Tu criterio técnico consiste en decidir, a diario, qué tipo de fricción quieres eliminar y cuál quieres mantener para no romper la base de código.

    Para equipos interesados en explorar workflows, agentes y automatización aplicados a ingeniería, consulta Dominicode Labs como continuación lógica para experimentar con pipelines reproducibles y hooks de CI.

    FAQ

    Elige Claude Code para tareas reproducibles y en lote: migraciones sistemáticas, scaffolding backend desde esquemas y análisis de logs a escala.

    Cursor es mejor para cambios que requieren inspección visual, diffs en contexto y juicios semánticos sobre lógica de negocio o UX.

    Sí. Un enfoque práctico es usar Cursor para diseñar y verificar, y Claude Code para ejecutar y escalar los pasos repetibles mediante CI y hooks.

    Filtra el input (excluir node_modules, builds y lockfiles), paginate el contexto y mantén tests/fixtures para validar salidas antes de aplicar cambios.

    Se mencionan ast-grep para patrones AST y Husky para hooks de pre-push. También se refiere al paquete de Claude Code en paquete npm y a Anthropic.

    Versiona prompts y scripts en el repo, revisa PRs generados por agentes como revisas cualquier patch humano y registra cambios automatizados en CI para trazabilidad.

    Cursor se encuentra en Cursor. Claude Code y recursos relacionados están disponibles via paquete npm y Anthropic.

  • Cómo construir un agente de IA con NestJS y Claude API

    Cómo construir un agente de IA con NestJS y Claude API

    Cómo construir un agente de IA con NestJS + Claude API

    Tiempo estimado de lectura: 4 min

    • Separar cliente LLM, registro de herramientas y loop de agente para modularidad y pruebas.
    • Herramientas como contratos JSON-schema y validación antes de ejecución.
    • Agent loop controlado: límites de iteraciones, métricas y manejo de errores normalizado.
    • Producción: no bloquear peticiones HTTP, usar SSE/WebSockets y proteger PII y costes.
    • Observabilidad y testing: trazas por sesión, mocks para provider y canary releases.

    Introducción

    Saber cómo construir un agente de IA con NestJS + Claude API es lo que separa una demo interesante de una pieza de infraestructura que puedas mantener en producción. En este artículo encontrarás la arquitectura, decisiones técnicas y patrones que realmente importan cuando implementas tool-calling de Claude dentro de un backend modular y tipado como NestJS.

    Un agente no es un chatbot: es un bucle de decisión. Recibe objetivo, decide herramientas, ejecuta, observa resultados y vuelve a razonar hasta resolver la tarea o agotar límites.

    Resumen rápido (lectores con prisa)

    Qué: Un agente es un bucle de decisión que orquesta llamadas a herramientas externas desde un LLM.

    Cuándo: Cuando necesitas que un LLM interactúe con sistemas externos (DB, APIs, logs) de forma controlada.

    Por qué importa: Permite trazabilidad, testing y control de costes frente a soluciones ad-hoc.

    Cómo: Separando un provider LLM, un registro de herramientas con schemas JSON y un agente que controla el loop y límites.

    Cómo construir un agente de IA con NestJS + Claude API: arquitectura y flujo

    Ese bucle —Agent Loop— obliga a diseñar responsabilidades claras. El agente recibe un objetivo, decide qué herramienta usar, ejecuta esa herramienta, observa el resultado y repite hasta resolver la tarea o agotar límites.

    Arquitectura mínima recomendada:

    • Proveedor del cliente LLM (Anthropic) como Provider de NestJS.
    • Registro dinámico de herramientas (ToolRegistryService) que mapea nombres/JSON-schema a métodos de servicios.
    • Motor de ejecución (AgentService) que orquesta el loop y gestiona historial, stop reasons y seguridad.

    Referencias: NestJS Docs y Anthropic Tool Use

    Capa 1 — AnthropicProvider: el cliente como dependencia inyectable

    Nunca newees el cliente de Anthropic en controladores o servicios. Crea un provider que se inyecte y centralice la lógica del cliente.

    • Lee ANTHROPIC_API_KEY mediante ConfigService.
    • Envuelve lógica de retries, backoff y métricas (tokens usados, latencia).
    • Permite mockear en tests unitarios.

    Ejemplo conceptual: el provider expone sendMessage(payload) que encapsula anthropic.messages.create() y normaliza la respuesta (stop_reason, content, tool_call).

    Beneficio: centralizas control de coste y modelo (p. ej. cambiar de Claude 3.5 a otro modelo sin tocar el resto).

    Capa 2 — ToolRegistry: herramientas como contratos JSON y servicios

    Claude espera herramientas descritas por JSON-schema. En el backend conviene modelarlas y validar antes de ejecutar.

    • Definir cada herramienta con nombre, descripción y schema (tipado TypeScript).
    • Mapear cada herramienta a un método de servicio inyectable (p. ej. UsersService.getById, LogsService.append).
    • Implementar granularidad: una herramienta = una responsabilidad.

    Diseño práctico:

    • ToolRegistryService mantiene un mapa { toolName -> { schema, executor } }.
    • executor(args) valida los args contra el schema y ejecuta el método correspondiente en try/catch.

    Así el agent loop no necesita switches gigantes; resuelve métodos dinámicamente.

    Capa 3 — AgentService: el bucle, stop_reasons y límites

    El AgentService orquesta el loop de decisión, mantiene el historial y aplica límites y políticas de seguridad.

    Patrón del Agent Loop

    1. Construir messages + tools (esquemas) y llamar a Anthropic.
    2. Leer stop_reason:
      • end_turn: devolver respuesta final.
      • tool_use: extraer tool_name y arguments.
    3. Ejecutar herramienta vía ToolRegistryService y añadir tool_result al historial.
    4. Repetir hasta end_turn o alcanzar un límite de iteraciones.

    Normas prácticas

    • Límite de iteraciones (p. ej. max 5) para evitar bucles y costes excesivos.
    • Cada iteración registra métricas: tokens, latencia, herramienta invocada.
    • Normaliza errores: si la herramienta falla, devuelve { error: 'timeout' } a Claude, no throws.

    Producción: latencia, UX y seguridad

    Al pasar a producción hay que priorizar experiencia de usuario, seguridad y observabilidad.

    Latencia y UX

    • No bloquees la petición HTTP principal. Emite progreso con SSE o WebSockets: “Pensando…”, “Consultando DB…”.
    • Opcional: respuesta rápida + notificación cuando el resultado final esté listo (webhook / push).

    Seguridad y validación

    • Valida argumentos de herramientas con class-validator/schema JSON antes de ejecutar.
    • Logs sensibles: evita enviar secrets o PII a la API de Claude.
    • Rate limits y circuit breakers en el provider para proteger tu backend y controlar facturación.

    Observabilidad

    Traza cada sesión como un árbol de spans: requests al LLM, ejecuciones de herramientas, errores.

    Integra herramientas de visualización y trazabilidad como Langfuse o LangSmith para visualizar flujos y coste por sesión.

    Testing y despliegue

    • Mockea el AnthropicProvider y el ToolRegistryService en tests unitarios.
    • Tests de integración: entorno con Claude sandbox o replay de respuestas deterministas.
    • Canary releases: habilita el agente en subset de usuarios antes de producir a toda la base.

    Coste y gobernanza

    • Mide tokens por iteración; extrapola a coste por sesión.
    • Define políticas: cuándo permitir tool-calling (p. ej. solo usuarios verificados) y límites diarios.

    Qué evitar (errores comunes)

    • Herramientas “dios” que hacen todo: dificultan autorización y testing.
    • Dejar excepciones sin capturar: provoca loops rotos y mala UX.
    • No auditar llamadas: sin trazabilidad no sabrás por qué el agente falló o costó tanto.

    Cierre práctico

    Construir un agente con NestJS + Claude API no es magia, es disciplina arquitectónica. Si abstraes el cliente, modelas herramientas como contratos y controlas el bucle con límites, obtienes un sistema escalable, testeable y seguro.

    En el siguiente artículo veremos ejemplos concretos de ToolRegistryService y patrones para emitir progreso en SSE desde NestJS para mejorar la experiencia del usuario.

    Dominicode Labs

    Para continuidad en temas de automatización y agentes, consulta recursos adicionales en Dominicode Labs. Es una fuente útil para patrones, ejemplos y plantillas prácticas que complementan esta arquitectura.

    FAQ

    Respuesta: Un agente es un bucle de decisión que recibe un objetivo, decide qué herramienta invocar, ejecuta esa herramienta, observa el resultado y repite hasta completar la tarea o agotar límites.

    Respuesta: Un provider centraliza la configuración del cliente (API key, retries, métricas), facilita el mock en tests y permite cambiar de modelo o proveedor sin modificar la lógica de negocio.

    Respuesta: Las herramientas se describen con nombre, descripción y un JSON-schema (tipado TypeScript). Se valida la entrada antes de ejecutar y se mapea a funciones/executors inyectables.

    Respuesta: stop_reason indica la acción del LLM: end_turn para respuesta final o tool_use para invocar una herramienta. El agente interpreta y actúa según ese valor.

    Respuesta: No bloquear la petición HTTP principal; usar SSE o WebSockets para emitir progreso. También considerar respuestas rápidas con notificación posterior y aplicar límites de iteraciones para controlar latencia y coste.

    Respuesta: Mockear el provider y el registry en tests unitarios; usar sandbox o replays deterministas en integración; ejecutar canary releases antes de un despliegue completo.

  • Impacto del compilador Go en TypeScript 7.0 y su migración

    Impacto del compilador Go en TypeScript 7.0 y su migración

    TypeScript con compilador en Go: qué cambia en tu día a día

    Tiempo estimado de lectura: 4 min

    • Rendimiento: TypeScript 7.0 mueve el motor de tipos fuera de Node.js a un binario en Go, prometiendo hasta 10x en chequeo de tipos en repos grandes.
    • Compatibilidad: Dejar de ser paquete Node.js rompe integraciones que importan la API JS del compilador (p. ej. transformers, ts-morph).
    • Migración práctica: Requiere auditoría de dependencias, estrategias de CI para binarios y puentes (IPC/FFI) para plugins críticos.
    • Balance: Beneficios reales en CI y editor, pero coste organizativo técnico en tooling y librerías.

    TypeScript con compilador en Go: qué cambia en tu día a día es la pregunta que tu equipo debería haberse hecho ayer. TypeScript 7.0 reescribe el motor de validación de tipos fuera de Node.js y lo ejecuta como binario en Go. La promesa es velocidad (hasta 10x en chequeo de tipos en repos grandes). La consecuencia práctica: breaking changes reales en tooling, plugins y pipelines. Este artículo ordena el impacto, da criterio y propone un plan de migración accionable.

    Resumen rápido (lectores con prisa)

    Qué es: TypeScript 7.0 reescribe el motor de tipos como binario en Go, fuera de Node.js.

    Cuándo usarlo: Cuando busques chequeos de tipos significativamente más rápidos y puedas auditar dependencias que tocan el AST.

    Por qué importa: Reduce tiempo en CI y mejora la latencia del IDE, pero rompe integraciones que dependen de la API JS del compilador.

    Cómo funciona (resumen): El compilador pasa de paquete Node.js a binario/WASM; consumidores que importan typescript pierden acceso directo a la API JS y se requieren puentes (IPC/FFI) para mantener compatibilidad.

    TypeScript con compilador en Go: impacto técnico y operativo

    Rendimiento

    Mover el compilador de JavaScript a Go no es un simple cambio de implementación; cambia el modelo de extensión y la superficie de integración.

    • Rendimiento: el chequeo de tipos (tsc) se beneficia de concurrencia nativa (goroutines) y memoria más eficiente. Pipelines que tardaban minutos pasan a segundos.

    Forma de consumo

    • Forma de consumo: deja de ser un paquete Node.js importable; pasa a ser un binario (o potencialmente WASM). Los consumidores que usaban import ts from 'typescript' pierden acceso directo a la API JS del compilador.

    Plugins y transformers

    • Plugins y transformers: APIs como ts.Program, ts.Transformer y librerías como ts-morph quedan en una zona de incompatibilidad. Reconstruir puentes implica IPC/FFI y coste de latencia.

    Estrictez y errores emergentes

    • Estrictez y errores emergentes: el nuevo compilador puede ser más estricto en resolución de módulos y rutas, sacando a la luz configuraciones frágiles en tsconfig.json.

    Fuentes útiles: TypeScript, esbuild, swc, Vite.

    Qué mejora en tu día a día (y sin fricción)

    • CI/CD: tsc --noEmit deja de ser el cuello de botella. Menos tiempo en runners reduce facturación en GitHub Actions, CircleCI, etc.
    • IDE: TSServer consume menos RAM y responde mejor en proyectos con tipos complejos (Zod, Prisma, tRPC — Zod, Prisma, tRPC).
    • Monorepos: escalabilidad de chequeos por paquete, menor bloqueo en cambios amplios.

    Estos beneficios son reales y medibles. Pero no son automáticos para todos los proyectos.

    Qué se rompe en la práctica

    • Frameworks que dependen del AST en tiempo de compilación: Angular, NestJS y ORMs que usan transformers y decoradores verán fallos si no migran sus pipelines.
    • Herramientas de generación de código y scripts que importan typescript quedarán sin la API JS directa.
    • Plugins de bundlers y herramientas de análisis estático (p. ej. ts-morph) requieren reescritura o compatibilidad por puente.

    La migración implica trabajo no trivial por parte de mantenedores de librerías. No es sólo actualizar package.json.

    Plan de acción para equipos (prioritario y práctico)

    1. Auditoría de superficie de riesgo

    • Busca en tu árbol de dependencias cualquier uso de import 'typescript' o require('typescript').
    • Lista paquetes que usan transformers o ts.Program. Estas son las integraciones en riesgo inmediato.

    2. Aísla la transpilación del type-checking

    • Usa Vite/esbuild para bundling y transpile rápido.
    • Corre tsc --noEmit como job paralelo en CI. Esto desacopla cambios de runtime del chequeo estricto.

    3. Congela versiones y crea una ventana de transición

    • Si dependes de plugins no migrados (decoradores de NestJS, Angular compilers), fija TypeScript a ~5.x hasta validar compatibilidad.
    • Comunica fechas internas de evaluación y migración para dependencias clave.

    4. Prepara CI y runners

    • Asegúrate de que los runners pueden descargar y ejecutar binarios (amd64/arm64).
    • Considera imágenes Docker con el binario del compilador preinstalado para reproducibilidad.

    5. Estrategia de puentes para plugins

    • Para librerías críticas, evalúa dos alternativas: 1) reescribir transformadores en Go o 2) implementar un proceso IPC que exponga el AST a JS (aceptable temporalmente, pero con latencia).
    • Prioriza reescrituras sólo si la librería es central; para consumo general, pide a mantenedores roadmap y plazos.

    6. Testing y despliegue gradual

    • Canary builds: ejecuta el compilador en Go en un subset de repos o paquetes.
    • Monitorea regresiones en CI (errores nuevos de tipo o resolución) y en IDEs de desarrolladores.

    Criterio técnico final

    Adoptar TypeScript 7.0 por rendimiento sin auditoría es una apuesta peligrosa. El enfoque correcto es pragmático: separar responsabilidades, auditar dependencias que manipulan AST, preparar CI para binarios y coordinar migraciones con mantenedores de librerías críticas.

    La ventaja económica y productiva es real: feedback loops más rápidos, menos microinterrupciones del IDE y menos coste de CI. El precio es técnico y organizativo: trabajo de migración en tooling. Quien lo planifique hoy evita picos de trabajo y bloqueos de entrega mañana.

    FAQ

    ¿Qué cambia con TypeScript 7.0?

    TypeScript 7.0 reescribe el motor de validación de tipos fuera de Node.js y lo ejecuta como binario en Go. Como consecuencia, deja de ser un paquete Node.js importable y puede ofrecer mejoras de velocidad (hasta 10x en chequeo de tipos en repos grandes) gracias a concurrencia nativa y manejo de memoria en Go.

    ¿Afecta esto a mi CI?

    Sí. tsc --noEmit puede dejar de ser el cuello de botella y reducir el tiempo de ejecución en runners, lo que baja costes en servicios como GitHub Actions o CircleCI. Sin embargo, es necesario garantizar que los runners puedan descargar y ejecutar binarios en las arquitecturas requeridas.

    ¿Qué pasa con plugins que usan transformers?

    APIs que manipulan el AST o dependen de la API JS del compilador (por ejemplo, ts-morph) quedan en riesgo de incompatibilidad. Las alternativas son reescribir transformadores en Go o implementar puentes IPC/FFI para exponer el AST a procesos JS, con coste de latencia.

    ¿Debo migrar inmediatamente?

    No necesariamente. Es recomendable auditar dependencias que usen typescript, congelar versiones críticas (p. ej. ~5.x) y crear una ventana de transición hasta validar compatibilidad de librerías y plugins antes de adoptar en producción.

    ¿Cómo mitigo riesgos en monorepos?

    Aísla la transpilación del type-checking usando herramientas como Vite o esbuild, ejecuta chequeos de tipos como jobs paralelos en CI y aplica canary builds para ejecutar el compilador en Go en subsets de paquetes antes del despliegue general.

  • Identificando problemas de vibe coding en equipos empresariales

    Identificando problemas de vibe coding en equipos empresariales

    Problemas de vibe coding para equipos empresariales (2026)

    Tiempo estimado de lectura: 4 min

    • Vibe coding —iterar con un LLM hasta que el código “parece funcionar”— acelera entrega pero genera deuda técnica opaca.
    • Cinco problemas concretos: código huérfano, erosión arquitectónica, riesgos de seguridad en la cadena de suministro, degradación del criterio técnico y sobrecarga en code review.
    • La solución no es prohibir la IA: es imponer controles técnicos y procesos (Design-First, ADRs, testing liderado por humanos, CI/CD restrictivo, verificación de dependencias y rotación de ownership).
    • Permitir vibe coding solo en prototipos desechables, scripts aislados o mocks; evitarlo en autenticación, transacciones y caminos con implicaciones regulatorias.
    ¿Tu repositorio funciona hoy y nadie lo entiende mañana? Los problemas de vibe coding para equipos empresariales (2026) son eso: soluciones rápidas que se convierten en deuda técnica silenciosa. Para Tech Leads, Arquitectos y CTOs, esto ya no es una discusión teórica. Es mantenimiento que se vuelve imposible, incidentes que aparecen a horas raras y una superficie de ataque que crece sin control.

    Resumen rápido (lectores con prisa)

    Vibe coding: iterar con LLMs hasta que el bloque “parece funcionar”. Útil para prototipos; peligroso en código de producción. Obliga a controles: diseño previo, ADRs, testing liderado por humanos, CI/CD restrictivo y validación de dependencias. Evitar en caminos críticos.

    Problemas de vibe coding para equipos empresariales (2026): diagnóstico rápido

    1) Código huérfano: funciona, pero nadie lo mantiene

    La IA entrega un módulo que pasa tests básicos. Nadie lo escribió línea por línea. Nadie puede explicar el flujo en un incidente P1. Eso aumenta el tiempo de resolución dramáticamente: lo que se ahorró en desarrollo se pierde multiplicado en debugging.

    Ejemplo realista: un endpoint de autenticación generado que falla ante tokens caducados en escenarios de reintentos — el path feliz funciona, el resto no. Resultado: latencia, errores y horas de on-call.

    2) Erosión arquitectónica: soluciones locales que rompen el todo

    Los modelos no tienen una visión sistémica del repo. Producen utilidades reinventadas, acoplan capas y rompen contratos explícitos. Cuando varios devs usan prompts distintos, el cóctel es un monolito fragmentado con estilos y anti-patterns mezclados.

    3) Seguridad y cadena de suministro: vulnerabilidades sutiles

    No es solo SQL injection. Son flujos de autorización incompletos, validaciones omitidas en edge cases y dependencias “sugeridas” que están obsoletas o son inexistentes. La comunidad de seguridad ya documentó riesgos de typosquatting y abuso de paquetes; automatizar la adopción de dependencias sin verificación amplifica ese vector (ver OWASP).

    4) Degradación del criterio técnico

    Delegar la implementación en prompts empobrece el aprendizaje. Juniors que se vuelven “prompteadores” no construyen modelos mentales sobre complejidad, rendimiento o diseño de sistemas. A la larga, el activo más valioso —criterio técnico— se erosiona.

    5) Code review convertido en cuello de botella

    Revisar código generado exige más contexto y tiempo. Los patrones de error humano son predecibles; las soluciones de LLM son impecables sintácticamente pero opacas conceptualmente. Los leads pasan de decidir arquitectura a auditar toneladas de PRs.

    Cómo mitigar sin renunciar a la IA

    Prohibir la IA no es opción. Las empresas competitivas aplican control, no veto. Aquí un set de medidas prácticas y verificables.

    • Design-First: define contratos, diagramas y contratos de datos antes de cualquier generación. La IA implementa; no diseña.
    • ADRs obligatorios: cualquier módulo generado con complejidad no trivial debe acompañarse de un Architecture Decision Record. Plantilla y ejemplo: Plantilla y ejemplo
    • Testing humano-led (BDD): el desarrollador define casos, edge cases y aserciones. La IA genera el boilerplate de tests, no la lógica de cobertura.
    • CI/CD restrictivo: integra análisis estático y políticas que bloqueen PRs con saltos bruscos de complejidad ciclomática o inclusión de paquetes no verificados. Herramientas como Semgrep ayudan a automatizar reglas.
    • Verificación de dependencias fuera del flujo PR: antes de aceptar librerías sugeridas por un LLM, pásalas por un proceso de validación de licencias y reputación. Sigue guías de NIST sobre desarrollo seguro.
    • Pares y rotación de ownership: obliga a que otro ingeniero entienda y firme el ADR antes del merge. Pair-programming para integración crítica.
    • Entrenamiento deliberado: formación interna en diseño, debugging profundo y análisis de performance. No atajos educativos.

    Límites claros: cuándo permitir vibe coding y cuándo no

    Permite vibe coding en prototipos desechables, scripts aislados o generación de mocks. Evítalo en autenticación, transacciones, migraciones de estado y cualquier camino con implicaciones regulatorias o legales.

    Conclusión: la IA potencia, pero el criterio no se automatiza

    Los problemas de vibe coding para equipos empresariales (2026) no son culpa de las herramientas. Son consecuencia de adoptarlas sin procesos. La diferencia entre un equipo que escala con IA y uno que se ahoga en deuda técnica está en una palabra: criterio. No lo externalices. Defínelo, mídelo y exige documentación. La IA hará el trabajo pesado; los humanos deben seguir decidiendo qué trabajo merece hacerse.

    Apúntate al newsletter de Dominicode para la siguiente entrega: hablaremos de políticas concretas de CI/CD y reglas Semgrep para detectar “sospecha de generación automática” en PRs.

    Encuentra una continuación práctica y recursos experimentales en Dominicode Labs. Allí publicamos plantillas de ADR, reglas Semgrep y ejemplos de pipelines seguros que complementan este artículo.

    FAQ

    ¿Qué es exactamente “vibe coding”?

    Es el patrón de trabajo donde un desarrollador itera con un modelo de lenguaje (Copilot, Claude, Cursor u otros) hasta que el código “parece funcionar”, sin aplicar diseño previo ni verificación humana exhaustiva.

     

    ¿En qué escenarios es aceptable usar IA para generar código?

    Aceptable en prototipos desechables, scripts aislados y generación de mocks. No es recomendable en autenticación, transacciones, migraciones de estado o caminos con implicaciones regulatorias.

     

    ¿Cómo se evita que las dependencias sugeridas por LLM introduzcan riesgo?

    Implementando un proceso de validación de dependencias fuera del flujo PR que verifique licencias, reputación y coincidencia con políticas internas antes de su aceptación.

     

    ¿Qué debe incluir un ADR cuando el código fue generado por IA?

    Descripción de la decisión, alternativas consideradas, riesgos identificados, responsables y link al módulo generado. La plantilla recomendada se puede consultar en Plantilla y ejemplo.

     

    ¿Cómo cambia el proceso de code review con uso intensivo de LLMs?

    Requiere más contexto en las revisiones, énfasis en arquitectura y pruebas, y posibles políticas de pares y rotación de ownership para asegurar que otro ingeniero pueda explicar y mantener el código.

     

    ¿Qué herramientas ayudan a automatizar políticas que mitiguen vibe coding?

    Herramientas de análisis estático y reglas en CI/CD (por ejemplo, Semgrep), y procesos de verificación de dependencias siguiendo guías como las de NIST.

  • Asegura el tipo de datos en function calling usando TypeScript

    Asegura el tipo de datos en function calling usando TypeScript

    Function calling tipado con TypeScript: deja de adivinar lo que devuelve el modelo

    Tiempo estimado de lectura: 4 min

    • Ideas clave:
    • Los LLMs fallan en formato y semántica: validar la salida evita errores en producción.
    • Define esquemas con Zod, deriva tipos con z.infer<>, y valida antes de ejecutar herramientas.
    • Usa .parse() para fallar rápido en endpoints y .safeParse() para autocorrección en agentes.
    • Mide y registra: trazabilidad completa (prompt, response, error de Zod, tool invocada).

    Introducción

    Cuando un agente llama a una herramienta, el modelo genera un JSON con argumentos. Asumir que ese JSON tendrá la forma correcta es la fuente de la mayoría de fallos en producción. Implementar Function calling tipado con TypeScript: deja de adivinar lo que devuelve el modelo no es opcional: es ingeniería defensiva. Con Zod validas en runtime, con z.infer<> obtienes tipos sincronizados y con un framework que integre ambos cierras el círculo.

    Fuentes útiles: Vercel AI SDK, Zod, OpenAI Structured Outputs.

    Resumen rápido (lectores con prisa)

    Qué es: Validación tipada de la salida de modelos mediante Zod y TypeScript.

    Cuándo usarlo: Siempre que un LLM invoque herramientas, modifique estado o llame APIs críticas.

    Por qué importa: Previene errores por campos faltantes, tipos incorrectos o JSON mal formado en producción.

    Cómo funciona: Define esquemas Zod, deriva tipos con z.infer<>, valida con .parse() o .safeParse() antes de ejecutar.

    Por qué tipar el function calling importa ahora

    Los LLMs fallan de formas predecibles: omiten campos, envían strings en vez de números, rodean JSON con Markdown o inventan claves. Si procesas ese output con JSON.parse() y as Tipo, renuncias a la seguridad de TypeScript en runtime. El resultado: escrituras corruptas en bases de datos, llamadas a APIs con parámetros inválidos y bugs que sólo aparecen semanas después.

    La alternativa técnica es clara:

    • declarar el esquema con Zod,
    • derivar el tipo TypeScript con z.infer<>,
    • validar antes de ejecutar la herramienta.

    Eso convierte la entrada del agente en un contrato matemático que protege tu lógica de negocio.

    Arquitectura práctica: esquema → validación → ejecución

    Patrón recomendado:

    1. Define el esquema Zod y añádele descripciones que el LLM pueda leer.
    2. Expón ese esquema en el prompt (o úsalo con Structured Outputs).
    3. Valida la respuesta del LLM con .safeParse() o .parse() antes de llamar a la función.
    4. Si falla, captura el ZodError, loguéalo y opcionalmente reintenta con autocorrección.

    Código mínimo (ejemplo de consulta de divisas)

    import { tool } from 'ai'; // p. ej. Vercel AI SDK
    import { z } from 'zod';
    
    const ExchangeSchema = z.object({
      base: z.string().length(3).toUpperCase().describe('Moneda base ISO 4217, ej. USD'),
      target: z.string().length(3).toUpperCase().describe('Moneda destino ISO 4217, ej. EUR'),
    });
    
    type ExchangeParams = z.infer;
    
    export const getExchangeRate = tool({
      description: 'Devuelve el tipo de cambio entre dos monedas',
      parameters: ExchangeSchema,
      execute: async ({ base, target }: ExchangeParams) => {
        const res = await fetch(`https://api.exchangerate-api.com/v4/latest/${base}`);
        if (!res.ok) throw new Error('API externa falló');
        const data = await res.json();
        return { rate: data.rates[target] };
      }
    });
    

    Si la validación falla, execute nunca se ejecuta: el SDK/Zod detiene la cadena y devuelve un error estructurado.

    .parse() vs .safeParse() y autocorrección

    Usa .parse() cuando quieras fallar rápido (endpoints HTTP que deben devolver 4xx/5xx). Usa .safeParse() en agentes y workflows que puedan auto‑corregirse sin intervención humana.

    Patrón de autocorrección:

    1. LLM genera JSON.
    2. .safeParse() devuelve success: false y error.
    3. Serializas error.flatten() y lo inyectas en un nuevo prompt: “Tu respuesta falló por X. Corrige el JSON.”
    4. Reintentás N veces con backoff; si sigue fallando, encolas para revisión humana.

    Ese ciclo convierte errores estructurales en una conversación de corrección con el modelo, robusta y trazable.

    Operaciones y observabilidad

    No basta con validar: mide y actúa.

    Métricas recomendadas:

    • tasa de validación fallida por prompt/modelo,
    • latencia media de autocorrección,
    • número de reintentos hasta éxito,
    • porcentaje de degradaciones a intervención humana.

    Registra siempre: prompt, raw response, resultado de Zod (.error.flatten()), y el tool invocado. Eso te da trazabilidad: prompt → response → validación → acción. Sin esos registros no hay postmortem útil.

    Decisiones arquitectónicas y trade‑offs

    – Structured Outputs (OpenAI) y generateObject reducen errores de formato pero no sustituyen la validación semántica: un amount: -5 puede pasar el schema si no validas signo y rango. Siempre valida con Zod (https://zod.dev/).

    – Tipar desde el día 0 exige disciplina: los esquemas son contratos que obligan a diseñar prompts claros y a mantener tests de integración. La deuda que previene compensa la inversión inicial.

    – En entornos orquestados (n8n, XState) preferir que el LLM decida la herramienta y que la ejecución quede en una máquina de estado puede ser más seguro para acciones críticas. Igual aplica: la entrada debe validarse antes de actuar.

    Conclusión: deja de adivinar, empieza a garantizar

    Function calling tipado con TypeScript: deja de adivinar lo que devuelve el modelo — es una fórmula sencilla y comprobada: define el esquema (Zod), extrae el tipo (z.infer<>), valida antes de ejecutar y automatiza la corrección cuando tenga sentido. Esa disciplina transforma un LLM impredecible en un componente confiable de tu arquitectura. Si tu agente escribe en bases de datos, llama APIs facturadas o toma decisiones que afectan a clientes, no hay excusas: valida antes de ejecutar y loguea todo. Así se construyen agentes que pueden correr solos, y no problemas que sólo aparecen en producción.

    Para continuar explorando prácticas operativas y experimentos en automatización e IA aplicada, consulta Dominicode Labs. Esta referencia complementa las técnicas descritas y ofrece recursos prácticos para implementar pipelines seguros y trazables en producción.

    FAQ

    ¿Por qué no basta con hacer JSON.parse() y castear a un tipo?

    Porque JSON.parse() solo asegura formato JSON válido, no la semántica ni la presencia y tipo de campos esperados. Castear con as Tipo ignora la verificación en runtime, lo que permite entradas inválidas que pueden provocar errores en bases de datos o llamadas a APIs en producción.

    ¿Cuándo debo usar .parse() en lugar de .safeParse()?

    Usa .parse() en contextos donde quieras fallar rápido y retornar un error (por ejemplo endpoints HTTP que deben devolver 4xx/5xx). Usa .safeParse() cuando el flujo puede intentar autocorrección o reintentos antes de degradar a intervención humana.

    ¿Qué hago si .safeParse() falla continuamente?

    Serializa el error con error.flatten(), inyecta esa información en un nuevo prompt pidiendo corrección, y reintenta N veces con backoff. Si sigue fallando, encola la unidad para revisión humana y registra el incidente para análisis posterior.

    ¿Debo exponer el esquema Zod en el prompt?

    Sí: exponer el esquema ayuda al modelo a generar la estructura correcta (especialmente con Structured Outputs). Aun así, la validación con Zod debe ejecutarse en runtime; el esquema en el prompt no sustituye la verificación.

    ¿Qué debo registrar para tener trazabilidad adecuada?

    Registra el prompt, la respuesta cruda del modelo, el resultado de Zod (error.flatten()), y la herramienta (tool) invocada. Esos datos permiten reconstruir el flujo prompt → response → validación → acción para postmortems.

    ¿Los Structured Outputs sustituyen la validación con Zod?

    No. Structured Outputs y utilidades como generateObject reducen errores de formato, pero no validan semántica ni rangos (por ejemplo, amount: -5 podría pasar). Sigue validando con Zod en runtime.

  • Cómo gestionar la memoria en agentes entre sesiones de forma eficiente

    Cómo gestionar la memoria en agentes entre sesiones de forma eficiente

    Context Engineering — el arte de gestionar el contexto del agente entre sesiones

    Tiempo estimado de lectura: 5 min

    • Context Engineering es disciplina operativa para mantener la memoria de agentes entre sesiones y evitar que “arranquen desde cero”.
    • Tres archivos clave (CLAUDE.md, AGENTS.md, memory files) convierten reglas, roles y memoria en infraestructura reutilizable.
    • Arquitectura de sub-agentes (orquestador, especialistas, QA) minimiza ruido y mejora precisión, latencia y coste.
    • Prácticas concretas: cierre de sesión obligatorio, outputs estructurados (JSON/Zod), RAG con caché semántico y auditoría por ejecución.

    Context Engineering es la práctica de diseñar y mantener la memoria operativa de agentes entre sesiones. Si aplicas GSD a equipos humanos, Context Engineering aplica GSD a agentes: dividir tareas, documentar decisiones y asegurar que la próxima sesión no sea una pizarra en blanco. Sin esta disciplina, los agentes alucinan, revierten decisiones y se vuelven caras e ineficaces.

    Resumen rápido (lectores con prisa)

    Context Engineering diseña la memoria y reglas permanentes de agentes para mantener continuidad entre sesiones. Úsalo cuando un sistema de agentes necesita precisión, trazabilidad y bajo coste operativo. Importa porque evita alucinaciones, pérdida de progreso y decisiones reversibles. Funciona con tres capas: reglas estáticas, memoria dinámica y sub-agentes especializados.

    El problema

    El problema es elegante y directo: los LLMs razonan bien, pero olvidan. El historial de chat como única memoria funciona en demos; colapsa en repositorios reales. Más tokens en el prompt solo añaden ruido. La solución práctica es convertir el repositorio en la memoria del agente mediante tres capas: reglas estáticas, memoria dinámica y sub-agentes especializados.

    Tres archivos que cambian el juego: CLAUDE.md, AGENTS.md y memory files

    CLAUDE.md (o .cursorrules) — la “constitución” del proyecto

    Propósito: reglas inmutables que el agente debe respetar.

    Contenido práctico: stack exacto (Node 20, React 18), políticas de seguridad, restricciones arquitectónicas y decisiones no negociables.

    Ejemplo (resumen):

    • Stack: Node 20, TypeScript 5.x, Next.js 14.
    • Convenciones: ESLint + Prettier; tests en Vitest.
    • Restricciones: “Nunca acceder a Supabase desde cliente; usar Server Actions”.

    CLAUDE.md es lo primero que un agente debe leer al comenzar.

    AGENTS.md — el organigrama legible por máquinas

    Propósito: definir quién hace qué en un sistema multi-agente.

    Contenido práctico: routing de tareas, roles (FrontendWorker, DBOptimizer, QAReviewer), permisos para commits.

    Resultado: orquestador capaz de delegar la tarea correcta al sub-agente correcto sin mandar TODO el repo como contexto.

    Memory files — la memoria viva (.context/ o .ai/)

    active_task.md: la tarea actual, objetivo y criterios de éxito.

    changelog_ai.md: decisiones y porqués (no sólo el qué).

    lessons_learned.md: problemas recurrentes y soluciones definitivas.

    Rutina obligatoria: al cerrar sesión el agente actualiza estos archivos. Al abrir sesión, los lee y retoma.

    Sub-agentes: aislar contexto, reducir ruido, mejorar precisión

    Arquitectura propuesta:

    Arquitectura propuesta

    • Agente Orquestador (Router): lee AGENTS.md, empaqueta contexto mínimo y llama al especialista.
    • Agente Especialista (Worker): recibe solo lo necesario (e.g., esquema DB + active_task.md) para reducir ruido.
    • Agente Revisor (QA): valida output contra CLAUDE.md y tests antes de aplicar cambios.

    Ventaja: un sub-agente con 10k tokens relevantes produce mejores resultados que un mega-agente con 100k tokens llenos de ruido. También reduce costos y latencia.

    Prácticas operativas (lo que realmente marca la diferencia)

    • Obliga a un “cierre de sesión”: el prompt final del día debe ser “Actualiza active_task.md, changelog_ai.md y sugiere el siguiente paso”.
    • Usa esquemas para outputs: fuerza JSON/Zod para evitar outputs malformados.
    • RAG + caché semántico: externaliza historial pesado en una vector DB y recupera solo lo necesario por tarea. (Ver LangChain)
    • Streaming y UX: implementa streaming token a token para evitar bloqueos de UI. (Vercel AI SDK: Vercel AI SDK)
    • Auditoría y permisos: registra cada ejecución de sub-agente y limita quién puede hacer merges automáticos.

    Estructura mínima recomendada del repo

    /project-root
      /src
      /.ai
        CLAUDE.md
        AGENTS.md
        active_task.md
        changelog_ai.md
        lessons_learned.md
      /.ai/logs
      /docs

    Herramientas y lecturas útiles

    Criterio final para equipos técnicos

    Context Engineering no es documentación bonita. Es infraestructura operativa que convierte agentes en miembros persistentes del equipo. Si inviertes en reglas estáticas (CLAUDE.md), memoria dinámica (memory files) y una red de sub-agentes bien definida (AGENTS.md + orquestador), ganarás precisión, velocidad y trazabilidad. Sin esto, los agentes seguirán siendo costosos “showrooms” en lugar de fuerza productiva real.

    Aplica GSD a tus agentes: trocea, documenta, cierra sesiones. Si lo haces bien, el agente no volverá a arrancar desde cero.

    Dominicode Labs

    Si te interesa profundizar en automatización, agentes y workflows aplicados a equipos técnicos, puedes continuar explorando recursos y experimentos en Dominicode Labs. Es una continuación lógica para poner en práctica patrones de Context Engineering mencionados aquí.

    FAQ

    ¿Qué es Context Engineering?

    Context Engineering es la práctica de diseñar y mantener la memoria operativa y reglas de agentes entre sesiones para mantener continuidad, reducir alucinaciones y preservar decisiones previas.

    ¿Cuándo debo usar CLAUDE.md?

    Usa CLAUDE.md al empezar cualquier sesión de agente: contiene reglas inmutables, stack, convenciones y restricciones que el agente debe respetar. Es el primer archivo que el agente debe leer.

    ¿Para qué sirve AGENTS.md?

    AGENTS.md define roles, routing de tareas y permisos en sistemas multi-agente, permitiendo al orquestador delegar correctamente sin enviar el repo entero como contexto.

    ¿Qué contienen los memory files y quién los actualiza?

    Contain archivos como active_task.md, changelog_ai.md y lessons_learned.md. El agente en sesión debe actualizarlos al cerrar sesión; el próximo agente los lee al abrir sesión.

    ¿Por qué usar sub-agentes en lugar de un mega-agente?

    Porque un sub-agente centrado con contexto relevante (p. ej. 10k tokens) produce resultados más precisos y eficientes que un mega-agente con 100k tokens de ruido. Reduce costos, latencia y errores.

    ¿Qué es RAG y por qué es relevante aquí?

    RAG (Retrieval-Augmented Generation) externaliza historial pesado en una vector DB y recupera solo lo necesario por tarea. Es relevante para evitar enviar todo el historial en cada prompt y mantener precisión.

    ¿Cómo auditar ejecuciones de sub-agentes?

    Registra cada ejecución en logs estructurados (.ai/logs), incluye metadatos (input mínimo, decision hashes) y limita permisos para merges automáticos. La auditoría debe permitir reproducir la decisión y revisar cumplimiento con CLAUDE.md.

  • Cómo especificar un agente SDD antes de su implementación

    Cómo especificar un agente SDD antes de su implementación

    SDD + Agentes: cómo especificar un agente antes de construirlo

    Tiempo estimado de lectura: 5 min

    Ideas clave

    • Especificar antes de construir: define flujos de decisión, límites de herramientas y condiciones de parada antes de programar.
    • SDD para agentes ≠ SDD tradicional: los agentes requieren specs que formalicen libertad, herramientas y puntos de escalado humano.
    • Tres bloques críticos: topología de decisión, contratos de herramienta con schemas y guardrails cuantificables.
    • La spec debe ser ejecutable: tests automatizados, simuladores de fallo y verificación en CI/CD.

     

    Introducción

    SDD + Agentes: cómo especificar un agente antes de construirlo — dilo antes de teclear. Si no documentas la caja de arena cognitiva del LLM, lo que construyas será frágil, caro y peligroso. La especificación no es burocracia: es la diferencia entre un experimento que explota y un servicio que vive en producción.

    En las primeras líneas: especificar un agente significa definir flujos de decisión, límites de herramientas y condiciones de parada antes de escribir una sola línea de código. Hazlo así y reduces bucles infinitos, facturas de API descontroladas y escrituras destructivas en tus bases.

    Resumen rápido (lectores con prisa)

    Qué es: Una spec agéntica formaliza topología de decisión, contratos de herramientas y condiciones de parada.

    Cuándo usarla: Antes de implementar agentes que razonan o que pueden tocar recursos críticos.

    Por qué importa: Evita comportamientos estocásticos dañinos, costes inesperados y fallos de integridad de datos.

    Cómo se aplica: Define un patrón operativo único, schemas de entrada/salida para cada tool, y guardrails cuantificables con telemetría y pruebas.

    Por qué SDD para agentes no es lo mismo que SDD tradicional

    En apps CRUD, spec = modelos de datos + endpoints + contratos. Un 404 es un fallo leve. Un agente sin spec puede intentar cien variaciones de la misma consulta SQL, escribir datos corruptos o invocar herramientas fuera de scope. Aquí falla la arquitectura, no el prompt.

    Los agentes razonan de forma estocástica. Por eso la spec debe formalizar:

    • Qué libertad tiene el agente en cada punto.
    • Qué herramientas puede tocar y cómo.
    • Cuándo debe pararse y llamar a un humano.

    Anthropic recomienda priorizar flujos orquestados sobre autonomía total para casos críticos (ver: Anthropic — Building effective agents). Toma nota: la industria no apuesta por “agentes libres” en producción sin guardrails.

    Tres bloques que debe cubrir tu spec agéntica

    1) Flujos de decisión: topología y patrón operativo

    Decide uno (y solo uno) de estos patrones por caso de uso:

    • Enrutamiento semántico: el LLM clasifica intenciones y delega a código determinista.
    • Máquina de estados orquestada: el LLM elige transiciones entre nodos predefinidos (n8n, LangGraph, XState).
    • Bucle ReAct autónomo: pensamiento-observación-acción libre (solo para experimentos controlados).

    No mezcles sin regla. Define explícitamente qué patrón rige cada intent/endpoint y por qué.

    2) Límites de herramientas (Tool Boundaries)

    Una herramienta para un agente no es un endpoint cualquiera. Tu spec de herramienta debe incluir, al menos:

    • Contrato de datos (Zod o JSON Schema). No aceptes “any”.
    • Descripciones semánticas por campo: guía al LLM sobre qué producir exactamente.
    • Precondiciones de uso: cuándo está permitido invocar la tool.
    • Protocolo de fallo: ¿autocorrección (con el error serializado), retry con backoff, usar valor por defecto o abortar y escalar?

    Ejemplo mínimo (JSON Schema + fallback):

    {
      "name": "createUser",
      "schema": { "type": "object", "properties": { "email": { "type": "string", "format": "email" } }, "required": ["email"] },
      "description": "Crea un usuario. email debe ser un correo válido. No inferir dominios.",
      "precondition": "email provisto por usuario",
      "onError": { "strategy": "abort_and_escalate", "max_retries": 0 }
    }

    Si dejas el onError en blanco, el agente decidirá por su cuenta —y lo hará mal.

    3) Guardrails y condiciones de parada

    Los guardrails no son sugerencias; son límites numéricos y verificables:

    • Max Steps: 5–10 iteraciones razonables por sesión antes de forzar cierre.
    • Retries por herramienta: típicamente 1–3, con backoff y registro.
    • Presupuesto operativo: tokens máximos por ejecución y tiempo máximo (p. ej. 30s wall clock).
    • Reglas de escalado humano: por ejemplo, tres fallos consecutivos de la misma tool o confianza del modelo < 0.6 → escalar.

    Documenta esos números en la spec. Implanta telemetría que lo verifique en tiempo real.

    Ingeniería práctica: plantilla rápida para tu spec agéntica

    Un documento mínimo y accionable debe contener:

    1. Directiva principal (system prompt base, objetivo inmutable).
    2. Fronteras negativas (anti-prompts: qué nunca debe hacer el agente).
    3. Contrato de memoria (qué guarda la memoria episódica y qué va a la semántica, p. ej. pgvector).
    4. Matriz de herramientas (schema, descripciones, precondiciones, fallback).
    5. Criterios de interrupción y política de escalado humano.
    6. Tests de comportamiento (simulaciones de fallo: error DB, timeout API, input malicioso).

    Incluye URLs en la spec para APIs críticas, contratos de datos y documentación de seguridad. Un equipo debe poder reproducir el flujo completo sin leer código.

    Trade‑offs y decisiones reales

    – Ventana de contexto gigante vs memoria estructurada: ventajas teóricas hay, pero en producción la memoria estructurada gana por latencia, coste y precisión (ver problema “lost in the middle”: arXiv:2307.03172).

    – Autonomía vs auditabilidad: cuanto más autónomo, menos auditable. Para negocios, prioriza auditabilidad.

    – Retry agresivo vs abort + humano: lo primero puede romper tu DB; lo segundo ralentiza workflows pero salva integridad.

    Cierre operativo: de la spec al CI/CD

    La spec no es un PDF muerto. Debe formar parte del pipeline:

    • Tests automatizados que validen precondiciones y fallbacks.
    • Simuladores que reproduzcan errores de herramientas.
    • Guardrails chequeados en staging y alertas de telemetría en producción.

    Si tu spec no se puede testear automáticamente, no es spec: es promesa. Y las promesas no pagan facturas.

    Define la caja de arena antes de soltar los músculos del agente. Es la única manera de que tus agentes actúen con intención, no con catástrofe.

    Dominicode Labs

    Para equipos que implementan pipelines y simuladores de fallo como parte de la spec, una referencia práctica y recursos complementarios están disponibles en Dominicode Labs. Considéralo como un recurso adicional para integrar tests y telemetría en tu CI/CD.

     

    FAQ

    ¿Por qué no vale con un buen prompt para controlar un agente?

    Un prompt no formaliza contratos ni límites verificables. Los agentes razonan de forma estocástica; sin schemas, precondiciones y guardrails numéricos, el prompt será frágil frente a inputs inesperados.

    ¿Qué es un contrato de herramienta y por qué usar JSON Schema?

    Un contrato de herramienta define tipos, formatos y campos requeridos. JSON Schema o Zod son formalismos que permiten validar entradas/salidas de forma determinista y evitar “any” que produzca comportamiento impredecible.

    ¿Cuántas iteraciones (Max Steps) son razonables?

    La guía práctica sugiere entre 5 y 10 iteraciones por sesión antes de forzar cierre. Ese rango reduce bucles infinitos y consumo excesivo de recursos.

    ¿Cómo debo manejar fallos recurrentes de una herramienta?

    Define un protocolo de fallo en la spec: retries limitados con backoff, registro y una estrategia de escalado (por ejemplo, abort_and_escalate tras N retries). No dejes el comportamiento en blanco.

    ¿Qué pruebas automatizadas son mínimas para una spec agéntica?

    Al menos: validación de precondiciones, simuladores de fallo de tools (DB error, timeout), y tests que verifiquen que los guardrails se activan (Max Steps, budget, retries).

    ¿Dónde documentar la política de escalado humano?

    La política de escalado debe estar en la spec principal, con reglas verificables (ej. tres fallos consecutivos de la misma tool o confianza < 0.6 → escalado) y enlaces a contactos/runbooks en tu repositorio de operaciones.

  • Cómo manejar errores en agentes de IA usando TypeScript

    Cómo manejar errores en agentes de IA usando TypeScript

    Error handling en agentes de IA: TypeScript te obliga a hacerlo bien

    Tiempo estimado de lectura: 3 min

    Ideas clave

    • Evita try/catch genéricos: ocultan la causa raíz y llevan a reintentos inútiles o a falsos positivos.
    • Usa Result<T, E>: convierte errores en valores tipados que el orquestador y el LLM pueden razonar.
    • Forzar exhaustividad con never: el compilador impide desplegar manejadores incompletos.
    • Persistir errores en memoria: guarda fallos estructurados en la memoria episódica para decisiones posteriores.
    • Instrumenta y prueba: telemetría, tests y SLAs para garantizar conducta operativa.

    Tabla de contenidos

    Introducción

    Error handling en agentes de IA: TypeScript te obliga a hacerlo bien. Dilo alto. Si tu agente llama herramientas, escribe datos o encadena flujos, el modo en que tratas los fallos decide si tendrás un sistema autocorrectivo o un monstruo que consume tokens y rompe tablas.

    Los try/catch genéricos son la forma más rápida de cegar a un agente. TypeScript, usado con disciplina, no te da magia: te da garantías. Garantías que convierten excepciones impredecibles en valores tipados que el agente puede razonar, registrar y recuperar.

    Resumen rápido (lectores con prisa)

    Qué: Trata errores como valores con Result<T,E> en lugar de throw.

    Cuándo: Siempre que tu agente llame herramientas, escriba en DB o coordine flujos.

    Por qué importa: Evita reintentos ciegos, reduce tokens gastados y hace al agente reparable.

    Cómo funciona: Devuelve {ok: true|false} con error tipado y usa checks exhaustivos con never para obligar a manejar nuevos casos.

    Por qué los try/catch genéricos matan tus agentes

    Un humano reintenta después de un HTTP 500. Un agente no. Cuando un LLM recibe solo “Error executing tool”, pierde la causa raíz. ¿Duplicado en la DB? ¿Timeout? ¿Bad payload? Sin esa información, el agente hará una de dos cosas útiles para nadie: reintentar la misma acción hasta agotar tu presupuesto o “alucinar” que la acción fue exitosa para seguir el flujo.

    En sistemas agénticos cada fallo es una señal. Ocultarla con un mensaje opaco equivale a apagar los sensores del coche mientras conduces rápido.

    Result<T, E>: convertir errores en datos con contrato

    La respuesta práctica es sencilla: deja de tirar (throw) y empieza a devolver. El patrón Result<T, E> transforma errores en valores discriminados que obligan al consumidor a lidiar con ellos.

    type Result<T, E> =
      | { ok: true; value: T }
      | { ok: false; error: E };

    Ejemplo de herramienta:

    async function createUser(email: string): Promise<Result<User, 'DUPLICATE_EMAIL' | 'DB_TIMEOUT' | 'INVALID_SCHEMA'>> {
      // nunca throw; siempre retorna ok: true | ok: false
    }

    ¿Qué cambia? Ahora el orquestador recibe información accionable. Si ok: false y error === ‘DUPLICATE_EMAIL’, inyectas esa razón en la memoria episódica y el LLM pregunta por otro email en vez de repetir la misma INSERT. Transformas ruido en contexto.

    Documentación útil sobre Result (concepto inspirado en Rust): Documentación útil sobre Result (concepto inspirado en Rust)

    never y exhaustive checks: el compilador como guardarraíl

    Pasa esto en equipos: alguien añade un nuevo error y olvida manejarlo. Resultado: el agente se comporta de forma impredecible en producción. Aquí entra el patrón de comprobación exhaustiva con never.

    Define tus errores como unión discriminada:

    type AgentError =
      | { type: 'DatabaseError'; code: number }
      | { type: 'AuthError'; reason: string }
      | { type: 'ValidationError'; issues: string[] };

    Y formatea para el LLM con un switch que fuerza exhaustividad:

    function formatErrorForLLM(error: AgentError): string {
      switch (error.type) {
        case 'DatabaseError': return `DB failure (${error.code}). No retry.`;
        case 'AuthError': return `Auth failed: ${error.reason}. Re-auth required.`;
        case 'ValidationError': return `Invalid: ${error.issues.join(', ')}. Fix and retry.`;
        default:
          const _exhaustive: never = error;
          return _exhaustive;
      }
    }

    Si alguien añade { type: 'RateLimit' } a AgentError y no actualiza este switch, TypeScript fallará en compilación. Lee sobre exhaustiveness checks: Lee sobre exhaustiveness checks

    Eso no es paranoia: es disciplina. Tu CI/CD no permitirá desplegar un agente que no explica cada fallo.

    Integración práctica con memoria y orquestación

    Errores tipados deben viajar junto con resultados hacia la memoria episódica. Diseño minimalista:

    • La tool retorna Result.
    • El orquestador persiste tanto éxitos como fallos en la memoria episódica (Redis) y semántica (vector DB si aplica).
    • El prompt incluye el fallo estructurado antes de la siguiente llamada al LLM.
    • El LLM decide la acción (retry con modificación, pedir datos al usuario, escalar).

    Además: valida entradas con Zod/JSON Schema antes de llamar a la tool. Un buen schema reduce la superficie de errores y hace que los fallos restantes sean reales y manejables.

    Operacional: telemetría, tests y SLAs

    No sirve con tipos si no lo verificas. Tienes que medir:

    • Retries por tipo de error (P50/P95).
    • Frecuencia de errores no mapeados (build-breakers).
    • Tokens gastados en reintentos.
    • Casos escalados a humano.

    Incluye tests que simulen fallos de DB, timeouts y errores de validación. Tu pipeline debe romper si un nuevo error llega a producción sin un handler en el switch exhaustivo.

    Cierre operativo

    El try/catch genérico es cómodo. También es la razón por la que tu agente se convierte en una caja negra con facturas altas y datos rotos. Convertir errores en valores tipados (Result<T,E>) y forzar comprobaciones exhaustivas con never no es estilo: es seguridad operativa.

    Aplica esto ya, instrumenta telemetría y haz que tu build falle si alguien olvida un caso de error. En el próximo artículo mostraremos cómo serializar esos errores en memoria episódica y usar feedback estructurado para que el agente aprenda a autocorregirse sin intervención humana.

    Dominicode Labs

    Para equipos que diseñan agentes y pipelines de orquestación, es útil contar con recursos y experimentos que muestren patrones de integración entre memoria episódica y errores tipados. Continúa explorando técnicas y prototipos en Dominicode Labs para ver implementaciones prácticas y ejemplos aplicados a agentes y workflows.

    FAQ

    ¿Por qué no debo usar try/catch genéricos en agentes?

    Porque ocultan la causa raíz y priven al agente de información accionable. Un mensaje opaco lleva a reintentos inútiles o a continuar el flujo como si la acción hubiera tenido éxito.

    ¿Qué es Result<T,E> y cómo cambia la arquitectura?

    Es un patrón que devuelve un valor tipado indicando éxito o fallo ({ok: true; value} | {ok: false; error}). Obliga al consumidor a tratar explícitamente los errores y permite que orquestadores y LLMs actúen sobre causas concretas.

    ¿Cómo obliga TypeScript a manejar nuevos errores?

    Mediante comprobaciones exhaustivas usando never en un switch sobre una unión discriminada. Si se añade un nuevo caso y no se maneja, el compilador falla.

    ¿Dónde guardo los errores para que el agente los use?

    Persiste fallos en la memoria episódica (ej. Redis) y en la memoria semántica si aplica (vector DB). El orquestador debe guardar tanto éxitos como fallos para proporcionar contexto al LLM.

    ¿Qué métricas debo instrumentar primero?

    Retries por tipo de error (P50/P95), frecuencia de errores no mapeados, tokens gastados en reintentos y casos escalados a humano.

    ¿Cómo debo testear los manejadores de error?

    Incluye tests que simulen fallos de DB, timeouts y errores de validación; el pipeline debe fallar si un nuevo error llega a producción sin handler.

    ¿Qué herramientas de validación recomiendan antes de llamar a una tool?

    Valida entradas con Zod o JSON Schema para reducir la superficie de errores y asegurar que los fallos restantes sean reales y manejables.

  • Implementación del RALPH Loop en agentes LLM para evitar fallos

    Implementación del RALPH Loop en agentes LLM para evitar fallos

    ¿Qué es RALPH Loop? Guía técnica para arquitectos de agentes

    Si buscas “que es ralph loop?” necesitas algo más que una definición: necesitas un mapa práctico para diseñar agentes que no se vuelvan peligrosos o caros en producción. El RALPH Loop es un patrón de control iterativo para agentes basados en LLM que añade aprendizaje y gobernanza explícita al ciclo de razonamiento-actuación. Aplicado bien, evita bucles infinitos, ahorra tokens y protege datos críticos. Aplicado mal, convierte tu agente en un script que consume presupuesto y arriesga integridad operacional.

    Resumen rápido (lectores con prisa)

    RALPH Loop organiza cada iteración del agente en cinco fases: Retrieve, Analyze/Act, Learn, Plan y Halt. Funciona combinando LLMs con memoria temporal y reglas deterministas para evitar bucles, reducir coste por tokens y proteger acciones destructivas. Se aplica cuando el agente tiene permisos de escritura, sesiones largas o herramientas múltiples; si no, ReAct o pipelines simples bastan.

    Tiempo estimado de lectura: 4 min

    Ideas clave

    • Cinco fases: Retrieve, Analyze/Act, Learn, Plan, Halt.
    • Halt crítico: combinación LLM + heurísticas deterministas (MaxSteps, token budget, detección de loops).
    • Aprendizaje en ejecución: registrar resultados para no repetir errores en la misma sesión.
    • Stacks recomendados: LangGraph/LangChain, n8n o implementación personalizada en Python.
    • Checklist: sandboxing, trazas JSONL, límites y escalado humano.

    Tabla de contenidos

    ¿Qué es RALPH Loop? Definición y motivación

    El RALPH Loop es un marco que organiza cada iteración del agente en cinco fases: Retrieve, Analyze/Act, Learn, Plan y Halt. Nace como evolución práctica de ReAct (Reason + Act) al responder a dos carencias claras en entornos reales: la incapacidad de aprender de acciones previas en la misma ejecución y la falta de una condición de parada robusta.

    ReAct es un punto de partida académico útil (ver artículo de ReAct). RALPH toma esa base y la convierte en arquitectura productiva: trae memoria temporal, reglas deterministas y heurísticas de seguridad para que el agente no provoque incidentes.

    Las cinco fases del RALPH Loop (implementables)

    R: Retrieve (Recuperar)

    – Recupera sólo el contexto necesario: historial relevante, resultados previos, vectores RAG. Evita saturar la ventana de contexto con ruido. Para RAG y vectores, mira prácticas comunes en Retrieval-Augmented Generation.

    A: Analyze & Act (Analizar y Actuar)

    – El LLM decide la herramienta y emite una llamada estructurada (function calling). Aquí la salida debe ser accionable (API call, ejecución de script, query SQL mockeada en pruebas).

    L: Learn (Aprender)

    – Registra el resultado (success/failure, códigos de error, latencia). Actualiza la memoria de trabajo para no repetir la misma acción inútil. Esta es la diferencia operativa: evita repetir fallos y detectar patrones de error.

    P: Plan (Planificar)

    – Ajusta la estrategia: intentar alternativa, degradar la acción, o solicitar más datos. Mantén un plan explícito serializable (lista de pasos pendientes, prioridad, contexto).

    H: Halt (Detener/Escalar)

    – Evaluación final: ¿objetivo cumplido? ¿sin progreso real? Si no, escalar a humano. La fase Halt combina la opinión del LLM con reglas duras (max steps, token budget, detección de loops).

    Por qué la fase Halt es la más crítica

    Los LLM son probabilísticos. No puedes confiar en que “sabran” cuando deben parar. En producción, la fase Halt se implementa como combinación LLM + heurísticas deterministas:

    • Límite de iteraciones (MaxSteps = 5–15 según complejidad).
    • Timeout absoluto por ejecución.
    • Presupuesto de tokens/coste por ejecución.
    • Detección de bucles semánticos (similitud coseno > 0.95 entre planes consecutivos).
    • Reglas de seguridad para acciones destructivas (p. ej. bloqueo de delete sin aprobación humana).

    Estas reglas son guardrails; no sustituyen la auditoría humana, pero evitan incendios evitables.

    Implementación práctica: stacks y patrones

    LangGraph / LangChain

    – Modela cada fase como nodo del grafo. Usa aristas condicionales en Halt que consulten métricas deterministas y el veredicto del LLM. Documentación útil para orquestación: Documentación de LangChain.

    n8n

    – Construye workflows cíclicos en lugar de un nodo monolítico de agente. Nodifica Retrieve, Analyze, Learn, Plan y un nodo Switch que implemente Halt. n8n facilita observabilidad y reintentos: n8n.

    Implementación personalizada (Python)

    – Clase AgentState serializable: historial, iteraciones, token_cost, last_action. Métodos: retrieve(), act(), learn(), plan(), halt_check(). Esto da máximo control y testabilidad.

    Ejemplo concreto (simplificado)

    Objetivo: “Optimizar consultas lentas”.

    Iteración 1: Retrieve → identifica consulta y plan de índices.

    Act: propone CREATE INDEX (mockeado en harness).

    Learn: índice ya existe → error “duplicate”.

    Plan: intenta analizar plan de ejecución alternativo.

    Halt: si tras 5 intentos sigue sin progreso, escalar a humano.

    Si CREATE INDEX hubiera sido ejecutado en prod sin harness, el agente podría seguir intentando acciones que dañan datos. RALPH previene eso.

    Cuándo aplicar RALPH Loop

    Usa RALPH cuando el agente:

    • Tiene permisos de escritura o acciones con efectos irreversibles.
    • Opera en sesiones largas con múltiples herramientas.
    • Interactúa con APIs externas inestables o con datos sensibles.

    Si tu caso es un simple extractor de texto o clasificación puntual, ReAct o un pipeline lineal bastan.

    Checklist mínimo antes de desplegar

    • Sandboxing y mocks para pruebas.
    • Registro estructurado de trazas (JSONL).
    • MaxSteps y token budget configurados.
    • Mecanismo de escalado humano probado.
    • Métricas: iteraciones por tarea, token cost, tasa de escalation.

    El RALPH Loop no es magia; es disciplina de ingeniería. Si quieres agentes operables, dales memoria, reglas y límites. Sin eso, tendrás un asistente caro y peligroso. Con eso, tendrás una pieza automatizada que escala capacidad sin quemar infraestructura ni reputación.

    Dominicode Labs

    Si trabajas con automatización, agentes o workflows y quieres explorar patrones de producción y orquestación, consulta los recursos y experimentos disponibles en Dominicode Labs. Es una continuación lógica para equipos que buscan implementar guardrails y observabilidad en pipelines de agentes.

    FAQ

    ¿Qué problemas resuelve RALPH Loop?

    Evita bucles infinitos, reduce coste por tokens y protege la integridad operacional al añadir memoria temporal, aprendizaje en ejecución y reglas deterministas de parada.

    ¿En qué se diferencia de ReAct?

    ReAct combina razonamiento y acción, pero no incorpora aprendizaje en la misma ejecución ni condiciones de parada robustas. RALPH añade fases de Learn y Halt para cubrir esas carencias.

    ¿Cuántas iteraciones debo permitir (MaxSteps)?

    Depende de la complejidad: típicamente entre 5 y 15. Ajusta según riesgo, coste de tokens y criticidad de la acción.

    ¿Cómo se detectan bucles semánticos?

    Usando métricas de similitud (por ejemplo, similitud coseno > 0.95 entre planes consecutivos) y comparando estados serializados del plan de acción.

    ¿Qué métricas debo registrar?

    Iteraciones por tarea, token cost, latencia por acción, códigos de error, y tasa de escalado a humano.

    ¿Es necesario usar un stack específico?

    No. LangGraph/LangChain y n8n son prácticas comunes por observabilidad y orquestación, pero una implementación personalizada en Python ofrece máximo control y testabilidad.

    ¿Cómo pruebo acciones destructivas en desarrollo?

    Usa sandboxing y mocks, ejecuta acciones en harness controlado y registra resultados estructurados antes de permitir ejecuciones en producción.