Category: AI

  • NestJS + Vercel AI SDK: backend streaming IA en producción

    NestJS + Vercel AI SDK: backend streaming IA en producción

    ANTHROPIC_API_KEY=sk-ant-xxxxxxxx

    
    En `app.module.ts`, registra `ConfigModule`:
    
    ```typescript
    // src/app.module.ts
    import { Module } from '@nestjs/common';
    import { ConfigModule } from '@nestjs/config';
    import { AiModule } from './ai/ai.module';
    
    @Module({
      imports: [
        ConfigModule.forRoot({ isGlobal: true }),
        AiModule,
      ],
    })
    export class AppModule {}
    

    isGlobal: true significa que ConfigService está disponible en todos los módulos sin importarlo individualmente. Práctico.


    La estructura del AiModule

    Antes de escribir código, la estructura:

    src/
      ai/
        ai.module.ts
        ai.controller.ts
        ai.service.ts
        dto/
          chat.dto.ts
    

    Cuatro archivos. Eso es todo lo que necesita un endpoint de streaming limpio.


    Paso 1: El DTO de validación

    El primer punto de defensa es el DTO. Define el contrato del request:

    // src/ai/dto/chat.dto.ts
    import { IsArray, IsIn, IsString, ValidateNested, ArrayMinSize } from 'class-validator';
    import { Type } from 'class-transformer';
    
    export class ChatMessageDto {
      @IsIn(['user', 'assistant', 'system'])
      role: 'user' | 'assistant' | 'system';
    
      @IsString()
      content: string;
    }
    
    export class ChatRequestDto {
      @IsArray()
      @ArrayMinSize(1)
      @ValidateNested({ each: true })
      @Type(() => ChatMessageDto)
      messages: ChatMessageDto[];
    }
    

    @ValidateNested({ each: true }) valida cada elemento del array individualmente. Si el frontend manda un mensaje con role: 'hacker' o sin content, el request rebota antes de tocar el servicio.

    Para que ValidationPipe funcione globalmente, añádelo en main.ts:

    // src/main.ts
    import { NestFactory } from '@nestjs/core';
    import { ValidationPipe } from '@nestjs/common';
    import { AppModule } from './app.module';
    
    async function bootstrap() {
      const app = NestFactory.create(AppModule);
    
      app.useGlobalPipes(new ValidationPipe({
        transform: true,
        whitelist: true,    // elimina propiedades no declaradas en el DTO
        forbidNonWhitelisted: true,
      }));
    
      // CORS para el frontend Angular en desarrollo
      app.enableCors({
        origin: process.env.FRONTEND_URL ?? 'http://localhost:4200',
        methods: ['POST', 'OPTIONS'],
      });
    
      await app.listen(process.env.PORT ?? 3000);
    }
    
    bootstrap();
    

    whitelist: true es especialmente importante aquí: elimina cualquier campo del body que no esté declarado en el DTO. Si alguien intenta inyectar propiedades extra en el request, NestJS las ignora antes de que lleguen al servicio.


    Paso 2: El AiService

    El servicio encapsula toda la lógica de llamada al modelo. El controlador no sabe qué modelo usamos ni cómo se configura — solo llama al servicio y recibe el stream.

    // src/ai/ai.service.ts
    import { Injectable } from '@nestjs/common';
    import { ConfigService } from '@nestjs/config';
    import { streamText, CoreMessage } from 'ai';
    import { createAnthropic } from '@ai-sdk/anthropic';
    
    @Injectable()
    export class AiService {
      private readonly anthropic;
    
      constructor(private readonly config: ConfigService) {
        this.anthropic = createAnthropic({
          apiKey: this.config.getOrThrow<string>('ANTHROPIC_API_KEY'),
        });
      }
    
      streamChat(messages: CoreMessage[]) {
        return streamText({
          model: this.anthropic('claude-sonnet-4-6'),
          system: `Eres un asistente técnico especializado en desarrollo de software.
    Responde en español de forma concisa y directa.
    Si el usuario pregunta sobre código, incluye ejemplos concretos.`,
          messages,
          maxTokens: 1024,
        });
      }
    }
    

    Dos decisiones importantes aquí:

    createAnthropic({ apiKey }) en el constructor — el cliente de Anthropic se crea una sola vez cuando NestJS instancia el servicio. No se recrea en cada petición. Eso evita overhead innecesario.

    config.getOrThrow<string>('ANTHROPIC_API_KEY') — si la variable de entorno no existe, la app falla en el arranque con un error claro en lugar de fallar silenciosamente en el primer request. Fail fast.

    maxTokens: 1024 es un límite defensivo. Sin él, un usuario puede hacer una pregunta que genere una respuesta de 8.000 tokens, multiplicando el costo por 8. Ajusta según tu caso de uso.


    Paso 3: El AiController con streaming

    El controlador es donde ocurre la magia del streaming. La clave está en cómo NestJS maneja la respuesta HTTP nativa:

    // src/ai/ai.controller.ts
    import {
      Controller,
      Post,
      Body,
      Res,
      HttpCode,
      HttpStatus,
    } from '@nestjs/common';
    import { Response } from 'express';
    import { AiService } from './ai.service';
    import { ChatRequestDto } from './dto/chat.dto';
    import { CoreMessage } from 'ai';
    
    @Controller('api')
    export class AiController {
      constructor(private readonly aiService: AiService) {}
    
      @Post('chat')
      @HttpCode(HttpStatus.OK)
      async chat(
        @Body() body: ChatRequestDto,
        @Res() res: Response,
      ): Promise<void> {
        const messages = body.messages as CoreMessage[];
    
        const result = this.aiService.streamChat(messages);
    
        // toUIMessageStreamResponse() genera una Response Web estándar
        // con el protocolo SSE del AI SDK
        const streamResponse = result.toUIMessageStreamResponse();
    
        // Propagamos los headers del AI SDK a la respuesta de Express
        streamResponse.headers.forEach((value, key) => {
          res.setHeader(key, value);
        });
    
        res.status(streamResponse.status);
    
        // Volcamos el body del ReadableStream a la respuesta de Express
        if (streamResponse.body) {
          const reader = streamResponse.body.getReader();
    
          const pump = async () => {
            while (true) {
              const { done, value } = await reader.read();
              if (done) {
                res.end();
                break;
              }
              res.write(value);
            }
          };
    
          pump().catch((err) => {
            console.error('[AiController] Error en stream:', err);
            if (!res.headersSent) {
              res.status(500).json({ error: 'Error interno del stream' });
            } else {
              res.end();
            }
          });
        } else {
          res.status(500).json({ error: 'No se pudo iniciar el stream' });
        }
      }
    }
    

    ¿Por qué este patrón de pump manual en lugar de pipe()?

    toUIMessageStreamResponse() devuelve una Response Web estándar (la del spec WHATWG), no un stream de Node.js. Express trabaja con streams de Node.js. El pump manual convierte uno en el otro sin dependencias adicionales. Es verboso pero explícito — sabes exactamente qué hace cada línea.

    El bloque catch en el pump gestiona dos escenarios: si el error ocurre antes de enviar headers, devuelve un 500 con JSON. Si ocurre después (cuando el stream ya está activo), llama a res.end() para cerrar la conexión limpiamente. Sin este manejo, el cliente se quedaría esperando indefinidamente.


    Paso 4: El AiModule

    El módulo agrupa las tres piezas:

    // src/ai/ai.module.ts
    import { Module } from '@nestjs/common';
    import { AiController } from './ai.controller';
    import { AiService } from './ai.service';
    
    @Module({
      controllers: [AiController],
      providers: [AiService],
      exports: [AiService], // por si otros módulos necesitan AiService
    })
    export class AiModule {}
    

    Exportar AiService es una decisión de diseño: si en el futuro un módulo de AgentsModule o DocumentModule necesita llamar al modelo, importan AiModule y tienen el servicio disponible sin duplicar configuración.


    Rate limiting: el paso que nadie incluye

    Sin rate limiting, un solo usuario puede vaciar tu cuota de Anthropic en minutos. NestJS tiene @nestjs/throttler para esto:

    npm install @nestjs/throttler
    

    Configúralo en AppModule:

    // src/app.module.ts
    import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
    import { APP_GUARD } from '@nestjs/core';
    
    @Module({
      imports: [
        ConfigModule.forRoot({ isGlobal: true }),
        ThrottlerModule.forRoot([{
          name: 'short',
          ttl: 60_000,   // 1 minuto en ms
          limit: 10,     // máximo 10 requests por minuto por IP
        }]),
        AiModule,
      ],
      providers: [
        {
          provide: APP_GUARD,
          useClass: ThrottlerGuard,
        },
      ],
    })
    export class AppModule {}
    

    10 requests por minuto por IP es un límite conservador para un chat. En producción, ajusta según el plan de Anthropic que tengas y el perfil de uso esperado. Si tus usuarios son developers que mandan snippets de código largos, 10 puede ser demasiado restrictivo. Si es un chat de soporte con usuarios anónimos, puede ser demasiado permisivo.

    ThrottlerGuard como APP_GUARD aplica el límite a todos los endpoints automáticamente. Si quieres excluir algunos endpoints del límite, usa el decorador @SkipThrottle() en el controlador correspondiente.


    Conectar con el frontend Angular

    Este backend está diseñado para ser el complemento del post Angular v22 + Vercel AI SDK: streaming de IA en tu app en 20 minutos.

    El frontend Angular usa fetch nativo con ReadableStream. El cambio que necesitas en el componente Angular es mínimo: actualizar la URL del endpoint del servidor Bun del post anterior (típicamente en el puerto 4000) a http://localhost:3000/api/chat de este servidor NestJS. El contrato del API no cambia — misma ruta, mismo formato de mensajes.

    La diferencia está en el protocolo de stream. El servidor Bun del post anterior usa toTextStreamResponse(), que devuelve texto plano. Este NestJS usa toUIMessageStreamResponse(), que usa el protocolo SSE estructurado del AI SDK. Para consumir este protocolo desde Angular sin la librería useChat de React, el componente Angular necesita parsear los chunks SSE en lugar de concatenarlos directamente.

    Si ya tienes el frontend del post anterior y quieres migrar a este backend sin tocar el componente, cambia en AiService.streamChat() el retorno a toTextStreamResponse():

    // AiService — variante compatible con el componente Angular del post anterior
    streamChat(messages: CoreMessage[]) {
      return streamText({
        model: this.anthropic('claude-sonnet-4-6'),
        system: 'Eres un asistente técnico...',
        messages,
        maxTokens: 1024,
      });
      // En el controlador usar toTextStreamResponse() en vez de toUIMessageStreamResponse()
    }
    

    Y en el controlador, sustituye result.toUIMessageStreamResponse() por result.toTextStreamResponse(). El componente Angular del post anterior funciona sin cambios.

    La versión con toUIMessageStreamResponse() es la recomendada para proyectos nuevos porque soporta tool calls, metadatos de uso de tokens, y datos personalizados dentro del mismo stream — funcionalidades que toTextStreamResponse() no puede transmitir.

    Característica toUIMessageStreamResponse() toTextStreamResponse()
    Protocolo AI SDK SSE estructurado Texto plano
    Tool calls
    Metadatos de tokens
    Compatible con useChat
    Parsing manual en cliente Necesario sin useChat No necesario
    Cuándo usarlo Proyectos nuevos Compatibilidad con cliente simple

    Manejo de errores: más allá del try/catch

    El error handling que ya tenemos en el pump del controlador cubre los fallos en el stream activo. Pero hay errores que ocurren antes del stream — cuando la API de Anthropic devuelve un 429 (rate limit) o un 500:

    // src/ai/ai.controller.ts — versión con manejo de errores completo
    import { APICallError } from 'ai';
    
    @Post('chat')
    @HttpCode(HttpStatus.OK)
    async chat(
      @Body() body: ChatRequestDto,
      @Res() res: Response,
    ): Promise<void> {
      try {
        const messages = body.messages as CoreMessage[];
        const result = this.aiService.streamChat(messages);
        const streamResponse = result.toUIMessageStreamResponse();
    
        streamResponse.headers.forEach((value, key) => {
          res.setHeader(key, value);
        });
        res.status(streamResponse.status);
    
        if (streamResponse.body) {
          const reader = streamResponse.body.getReader();
    
          const pump = async () => {
            while (true) {
              const { done, value } = await reader.read();
              if (done) { res.end(); break; }
              res.write(value);
            }
          };
    
          await pump();
        }
      } catch (error) {
        if (APICallError.isInstance(error)) {
          // Error de la API del LLM (429, 500, etc.)
          console.error('[AiController] Error API LLM:', error.message, error.statusCode);
    
          if (!res.headersSent) {
            const statusCode = error.statusCode === 429 ? 429 : 502;
            res.status(statusCode).json({
              error: error.statusCode === 429
                ? 'Demasiadas peticiones al modelo. Inténtalo en unos segundos.'
                : 'Error al conectar con el modelo de IA.',
            });
          } else {
            res.end();
          }
        } else {
          console.error('[AiController] Error inesperado:', error);
          if (!res.headersSent) {
            res.status(500).json({ error: 'Error interno del servidor.' });
          } else {
            res.end();
          }
        }
      }
    }
    

    APICallError.isInstance(error) es el type guard del AI SDK para distinguir errores de la API del LLM de errores genéricos. Útil para devolver mensajes de error específicos al cliente sin exponer detalles internos.


    Ejecutar el servidor

    # Desarrollo con hot reload
    npm run start:dev
    
    # Producción
    npm run build && npm run start:prod
    

    El servidor levanta en http://localhost:3000. Prueba el endpoint:

    curl -X POST http://localhost:3000/api/chat \
      -H "Content-Type: application/json" \
      -d '{"messages": [{"role": "user", "content": "Qué es NestJS en una frase"}]}' \
      --no-buffer
    

    Verás los chunks SSE llegar en tiempo real en la terminal. Eso confirma que el streaming funciona.


    El AiModule en producción: qué añadir después

    Lo que hemos construido es una base sólida. En un entorno de producción real, los siguientes pasos son:

    1. Autenticación. Añadir un AuthGuard de JWT al endpoint chat para que solo usuarios autenticados consuman tokens. Sin esto, cualquiera con la URL puede vaciar tu cuota.

    2. Logging estructurado. Usar @nestjs/winston o Pino para loguear cada request con userId, messageCount, y tokensUsed. El AI SDK expone usage en el stream — puedes capturarlo en el onFinish callback de streamText.

    3. Persistencia del historial. El backend actual es stateless — el historial viene del cliente en cada request. En producción con usuarios autenticados, guarda el historial en base de datos y envía solo el conversationId desde el frontend. El servidor reconstruye el historial antes de llamar al modelo.

    4. Selección de modelo por request. Si tu app da a los usuarios la opción de elegir entre Claude Sonnet y Claude Haiku (más barato), añade un campo model al DTO y pásalo al servicio. La abstracción del AI SDK hace que el cambio sea trivial.

    Si quieres profundizar en este tipo de decisiones de arquitectura — cómo estructurar un producto completo con IA desde la idea hasta producción — en el curso Construye con IA: de la idea al producto con Claude Code lo vemos con proyectos reales, no con demos de laboratorio.


    FAQ

    ¿Puedo usar este módulo con Fastify en lugar de Express?

    Sí, pero el pump manual del controlador cambia. Fastify usa Reply en lugar de Response de Express, y el método para escribir chunks es reply.raw.write(). El @Res() res: Response del controlador funcionará si configuras passThrough: true en el decorador: @Res({ passThrough: false }). La lógica del pump en sí no cambia — solo los métodos de la respuesta.

    ¿El rate limiting con ThrottlerGuard funciona bien detrás de un proxy o load balancer?

    Por defecto, ThrottlerGuard usa la IP del request. Si tu app está detrás de un proxy (Nginx, Cloudflare, etc.), la IP será siempre la del proxy. Configura ThrottlerModule con throttlers y usa ThrottlerGuard extendido que lea X-Forwarded-For. Alternativamente, delega el rate limiting al proxy — Nginx tiene limit_req_zone para esto.

    ¿Cómo evito que el stream consuma tokens si el cliente desconecta?

    streamText del AI SDK no cancela automáticamente la petición a Anthropic cuando el cliente cierra la conexión HTTP. Para implementar cancelación, pasa un AbortSignal a streamText:

    streamChat(messages: CoreMessage[], signal?: AbortSignal) {
      return streamText({
        model: this.anthropic('claude-sonnet-4-6'),
        messages,
        abortSignal: signal,
      });
    }
    

    En el controlador, escucha el evento close de la respuesta y llama a abortController.abort(). Esto cancela la llamada a la API antes de que el modelo termine de generar.

    ¿Puedo usar @ai-sdk/openai o @ai-sdk/google en lugar de Anthropic?

    Sí. Cambia createAnthropic por createOpenAI o createGoogleGenerativeAI en AiService y actualiza el nombre del modelo. El resto del módulo — controlador, DTO, rate limiting, manejo de errores — no cambia. Esa es exactamente la ventaja de usar el AI SDK como capa de abstracción: cambias de proveedor en un sitio.

    ¿CoreMessage[] es compatible con el formato de mensajes que manda el componente Angular del post anterior?

    CoreMessage del AI SDK acepta objetos con role ('user', 'assistant', 'system') y content (string). El ChatMessage del componente Angular del post anterior tiene exactamente esa forma. El cast body.messages as CoreMessage[] funciona directamente — no necesitas transformar nada.


    Cierre

    Un backend de streaming de IA no es complicado. Lo que sí es complicado es hacerlo bien desde el principio: que valide los inputs, que no queme tokens cuando el cliente desconecta, que no se caiga cuando Anthropic devuelve un 429, que tenga un límite razonable de peticiones por IP.

    NestJS más el Vercel AI SDK resuelven ese conjunto de problemas con una arquitectura que ya conoces si llevas tiempo en el ecosistema TypeScript. No hay magia — hay módulos, servicios, inyección de dependencias, y un stream que fluye limpio de principio a fin.

    El AiModule que has construido hoy es reutilizable. Impórtalo en cualquier NestJS existente, ajusta el system prompt y el modelo, y tienes un endpoint de IA en producción en menos de una hora.

    Si quieres llevarlo más lejos — tool calls, agentes con memoria, pipelines de documentos — en Dominicode Labs tenemos los proyectos completos con los patrones que usamos en producción, incluyendo ejemplos de NestJS con AI SDK con autenticación, persistencia y cancelación de streams.


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

  • Prompt Caching en Claude: reduce tu factura de API un 90%

    Prompt Caching en Claude: reduce tu factura de API un 90%

    El mes pasado revisé los gastos de API de un proyecto que lleva seis semanas en producción. Un agente conversacional para análisis de documentos legales. El cliente lo usa unas 40 veces al día.

    La factura: $340 en un mes.

    El system prompt tenía 8.000 tokens. Las definiciones de herramientas, otros 3.000. En cada llamada, esos 11.000 tokens se procesaban desde cero. Cuarenta veces al día. Treinta días al mes.

    Activé prompt caching. La siguiente factura: $38.

    No cambié la lógica del agente. No modifiqué los prompts. Solo añadí tres líneas de configuración.

    Eso es lo que hace el prompt caching de Claude. Y la mayoría de developers que trabajan con la API de Anthropic aún no lo tienen activado.


    Qué es el prompt caching y cómo funciona

    Cuando haces una llamada a la API de Claude, pagas por cada token que el modelo procesa. System prompt, herramientas, historial de conversación, contexto de documentos: todo se cobra como tokens de entrada.

    El problema es que en la mayoría de aplicaciones reales, una parte enorme de esos tokens es idéntica en cada llamada. Tu system prompt no cambia. Las definiciones de tus herramientas no cambian. El contexto de un documento que estás analizando no cambia entre preguntas del usuario.

    El prompt caching te permite marcar esas partes estáticas para que Claude las almacene en caché. La documentación oficial de prompt caching cubre todos los modelos y casos edge. La primera vez que se procesa ese contenido, se escribe en caché. En las llamadas posteriores, en lugar de reprocesar esos tokens, Claude los lee desde el caché.

    El coste de un cache write es 1.25x el precio base — ligeramente más caro que una llamada normal. El coste de un cache read es 0.1x el precio base. Es decir, un 90% más barato.

    En un agent loop con 40 llamadas al día, pagas el 1.25x una vez. Las otras 39 veces pagas el 0.1x. La aritmética es brutal a tu favor.

    El TTL del caché

    El caché tiene un TTL (Time To Live) de 5 minutos por defecto. Mientras haya llamadas dentro de esa ventana, el caché se renueva automáticamente sin coste adicional. Si una conversación tiene mensajes frecuentes, el caché se mantiene activo.

    Existe también un TTL de 1 hora, que cuesta 2x el precio base en la escritura. Útil cuando tienes contextos que se reutilizan con menos frecuencia pero son muy costosos de regenerar.

    El mínimo de tokens para activar el caché

    No todo se puede cachear. El sistema exige un mínimo de tokens para crear una entrada de caché. Para claude-sonnet-4-6 y claude-opus-4-8, el mínimo es 1.024 tokens. Para claude-haiku-4-5, el umbral sube a 4.096 tokens — cuatro veces más alto, relevante si usas Haiku con prompts cortos. Si tu system prompt tiene menos tokens que el mínimo de tu modelo, el caché no se activa.

    En proyectos donde el system prompt es corto, la estrategia correcta es incluir el contexto del dominio directamente en el system prompt hasta superar ese umbral, o cachear las definiciones de herramientas junto con el sistema.


    Cómo habilitarlo: código TypeScript con el SDK oficial

    Aquí está el patrón que uso en producción. Nada de magia — tres cambios concretos en tu código.

    Habilitación básica: system prompt con cache_control

    import Anthropic from "@anthropic-ai/sdk";
    
    const client = new Anthropic();
    
    const response = await client.messages.create({
      model: "claude-sonnet-4-6",
      max_tokens: 1024,
      system: [
        {
          type: "text",
          text: `Eres un asistente especializado en análisis de documentos legales.
          
    Tu rol es:
    - Identificar cláusulas de riesgo en contratos
    - Resumir términos clave de forma clara y precisa
    - Señalar inconsistencias o ambigüedades legales
    - Comparar términos con estándares del sector
    
    [...aquí va el resto del system prompt extenso, con contexto del dominio,
    instrucciones detalladas, ejemplos de formato de respuesta, etc.
    Debe superar los 1.024 tokens para activar el caché...]`,
          cache_control: { type: "ephemeral" }, // <-- esto es todo lo que necesitas
        },
      ],
      messages: [
        {
          role: "user",
          content: "Analiza la cláusula de terminación de este contrato: ...",
        },
      ],
    });
    
    console.log(response.usage);
    

    En la primera llamada, usage mostrará:

    {
      "input_tokens": 45,
      "cache_creation_input_tokens": 1280,
      "cache_read_input_tokens": 0,
      "output_tokens": 312
    }
    

    En la segunda llamada (dentro de los 5 minutos):

    {
      "input_tokens": 45,
      "cache_creation_input_tokens": 0,
      "cache_read_input_tokens": 1280,
      "output_tokens": 289
    }
    

    cache_read_input_tokens tiene el 10% del coste. El system prompt completo se leyó desde caché. Esos 1.280 tokens no se procesaron desde cero.

    Cacheando herramientas y system prompt juntos

    Cuando tienes definiciones de herramientas largas — algo habitual en agentes con MCP o con múltiples funciones — el ahorro se multiplica. Aquí el patrón para cachear ambas cosas:

    import Anthropic from "@anthropic-ai/sdk";
    
    const client = new Anthropic();
    
    // Las definiciones de herramientas son estáticas — candidatas perfectas para caché
    const tools: Anthropic.Tool[] = [
      {
        name: "search_legal_database",
        description: `Busca en la base de datos legal precedentes y jurisprudencia relevante.
        Usa esta herramienta cuando necesites comparar cláusulas con casos anteriores o
        encontrar interpretaciones judiciales de términos específicos. La búsqueda incluye
        bases de datos de España, México, Argentina y Colombia. Devuelve hasta 10 resultados
        ordenados por relevancia con fecha, tribunal y resumen del caso.`,
        input_schema: {
          type: "object" as const,
          properties: {
            query: {
              type: "string",
              description: "Término o frase legal a buscar",
            },
            jurisdiction: {
              type: "string",
              enum: ["ES", "MX", "AR", "CO", "ALL"],
              description: "Jurisdicción a consultar",
            },
            date_range: {
              type: "string",
              description: "Rango de fechas en formato YYYY-YYYY",
            },
          },
          required: ["query"],
        },
      },
      {
        name: "analyze_clause_risk",
        description: `Analiza el nivel de riesgo de una cláusula contractual.
        Evalúa factores como onerosidad excesiva, cláusulas abusivas según legislación
        vigente, asimetría de obligaciones y exposición a penalidades. Devuelve un score
        de riesgo del 1 al 10 con justificación detallada y recomendaciones de negociación.`,
        input_schema: {
          type: "object" as const,
          properties: {
            clause_text: {
              type: "string",
              description: "Texto completo de la cláusula a analizar",
            },
            contract_type: {
              type: "string",
              description: "Tipo de contrato (laboral, mercantil, arrendamiento, etc.)",
            },
          },
          required: ["clause_text"],
        },
      },
      // cache_control al final del array de tools — marca el punto de caché
    ];
    
    // Añadimos cache_control al último tool para cachear todo el bloque
    const toolsWithCache = tools.map((tool, index) =>
      index === tools.length - 1
        ? { ...tool, cache_control: { type: "ephemeral" as const } }
        : tool
    );
    
    const response = await client.messages.create({
      model: "claude-sonnet-4-6",
      max_tokens: 2048,
      system: [
        {
          type: "text",
          text: "Eres un asistente especializado en análisis legal...",
          cache_control: { type: "ephemeral" }, // system prompt cacheado
        },
      ],
      tools: toolsWithCache, // tools cacheadas
      messages: [
        {
          role: "user",
          content: "¿Cuál es el riesgo de esta cláusula de no competencia?",
        },
      ],
    });
    

    Monitorizar el ahorro en tiempo real

    Esta función te dice exactamente cuánto has ahorrado en cada llamada:

    interface CostMonitor {
      inputTokensCost: number;
      cacheWriteCost: number;
      cacheReadCost: number;
      outputTokensCost: number;
      totalCost: number;
      savings: number;
      savingsPercent: number;
    }
    
    // Precios para claude-sonnet-4-6 por millón de tokens (en dólares)
    const PRICING = {
      input: 3.0,
      cacheWrite: 3.75, // 1.25x
      cacheRead: 0.3,   // 0.1x
      output: 15.0,
    };
    
    function calculateCallCost(usage: Anthropic.Usage): CostMonitor {
      const inputCost = (usage.input_tokens / 1_000_000) * PRICING.input;
      const cacheWriteCost =
        ((usage.cache_creation_input_tokens ?? 0) / 1_000_000) * PRICING.cacheWrite;
      const cacheReadCost =
        ((usage.cache_read_input_tokens ?? 0) / 1_000_000) * PRICING.cacheRead;
      const outputCost = (usage.output_tokens / 1_000_000) * PRICING.output;
    
      const totalCost = inputCost + cacheWriteCost + cacheReadCost + outputCost;
    
      // Coste hipotético sin caché (todos los tokens al precio base)
      const totalInputTokens =
        usage.input_tokens +
        (usage.cache_creation_input_tokens ?? 0) +
        (usage.cache_read_input_tokens ?? 0);
      const costWithoutCache =
        (totalInputTokens / 1_000_000) * PRICING.input + outputCost;
    
      const savings = costWithoutCache - totalCost;
      const savingsPercent =
        costWithoutCache > 0 ? (savings / costWithoutCache) * 100 : 0;
    
      return {
        inputTokensCost: inputCost,
        cacheWriteCost,
        cacheReadCost,
        outputTokensCost: outputCost,
        totalCost,
        savings,
        savingsPercent,
      };
    }
    
    // Uso:
    const monitor = calculateCallCost(response.usage);
    console.log(`Ahorro: $${monitor.savings.toFixed(6)} (${monitor.savingsPercent.toFixed(1)}%)`);
    

    Qué debes cachear y qué no

    Los mejores candidatos para el caché

    System prompts largos. Es el caso más obvio. Si tu system prompt tiene instrucciones de rol, reglas de formato, contexto del dominio y ejemplos, estás mirando fácilmente 2.000-8.000 tokens que se repiten en cada llamada. Cachear el system prompt es lo primero que debes activar.

    Definiciones de herramientas (tools). Especialmente en agentes con MCP o con muchas funciones. Las definiciones de tools incluyen nombres, descripciones detalladas y schemas completos. Pueden sumar 3.000-5.000 tokens fácilmente. Son siempre estáticas dentro de una sesión.

    Contexto de documentos. Si tu aplicación analiza un documento largo (un contrato, una especificación técnica, un PDF), ese documento va en el mensaje del usuario pero cambia muy poco. Puedes cachearlo con cache_control en el bloque del contenido del mensaje.

    Historial de conversación en agent loops. En un loop donde el agente tiene muchos turnos, cachear el historial acumulado evita pagar por reprocesar el contexto completo en cada iteración.

    Qué NO debes cachear

    El turno actual del usuario. Es el error más común. El mensaje que el usuario acaba de escribir cambia en cada llamada — si intentas cachearlo, el caché nunca tendrá un hit porque el contenido es siempre distinto.

    Tokens de extended thinking. Si usas extended thinking con Claude, los tokens del proceso de razonamiento interno no se cachean. Esto es relevante si estás midiendo ahorros en pipelines que usan thinking — los números no escalarán de la misma forma.

    Contenido que cambia con frecuencia. Si tienes un bloque de contexto que se actualiza cada pocos minutos (resultados de una búsqueda en tiempo real, estado de una sesión volátil), no tiene sentido marcarlo para caché porque nunca habrá un hit.

    Bloques demasiado pequeños. Si un bloque tiene menos de 1.024 tokens, el sistema no lo cacheará. No añadas cache_control a fragmentos pequeños — solo añade latencia sin beneficio.


    Comparación de coste: sin caching vs con caching

    Escenario real: un agente con 40 llamadas diarias durante 30 días.

    • System prompt: 5.000 tokens
    • Tools: 3.000 tokens
    • Pregunta del usuario: ~100 tokens (variable)
    • Respuesta del modelo: ~400 tokens (variable)
    • Modelo: claude-sonnet-4-6
    Escenario Coste por llamada Total mensual
    Sin caching (8.100 input + 400 output) $0.0303 $36.36
    Con caching — 1ª llamada del día (cache write 8.000 + 100 input + 400 output) $0.037
    Con caching — llamadas 2–40 (cache read 8.000 + 100 input + 400 output) $0.0084
    Con caching — total diario (1ª + 39 × $0.0084) $0.365/día $10.95

    Ahorro: 70%. Y esto asumiendo que el caché expira cada día. Con conversaciones más densas donde el TTL de 5 minutos se aprovecha bien, el ahorro sube al 85-90%.


    Preguntas frecuentes sobre prompt caching en Claude

    ¿El caché es compartido entre usuarios?
    No. El caché es privado por workspace de Anthropic. Desde febrero de 2026, hay aislamiento completo por workspace. Los datos de un usuario nunca se mezclan con los de otro.

    ¿Qué pasa si cambio el system prompt? ¿Se invalida el caché?
    Sí. El caché funciona por contenido exacto. Si modificas un solo carácter del bloque cacheado, se genera una nueva entrada de caché (cache write) en la siguiente llamada. El caché anterior expira según su TTL sin coste adicional.

    ¿Puedo cachear múltiples bloques en la misma llamada?
    Sí, hasta un máximo de cuatro breakpoints de caché por request. La restricción importante es el orden: los bloques con TTL más largo (1 hora) deben aparecer antes que los de TTL más corto (5 minutos) en la estructura del request.

    ¿El caching funciona con streaming?
    Sí. El prompt caching es compatible con la API de streaming de Claude. Los campos cache_creation_input_tokens y cache_read_input_tokens aparecen en el evento message_start del stream — no en message_delta. Es el primer evento emitido, antes de que lleguen los tokens de respuesta.


    El siguiente nivel: combinar con Claude Code

    Si ya estás explorando agentes más complejos, el prompt caching cambia la ecuación de coste de forma radical. Un agent loop sin caching que hace 10 iteraciones paga los tokens del system prompt y las tools diez veces. Con caching, los paga una vez y lee el resto.

    En Claude Code: Effort, Models, Tools y Context hay una sección completa sobre cómo gestiona Claude Code el contexto en agent loops largos — es el contexto perfecto para entender dónde encaja el caching a nivel de infraestructura.

    Y si quieres construir productos reales sobre la API de Anthropic con esta clase de optimizaciones ya integradas desde el primer sprint, el curso Construye con IA: De la Idea al Producto con Claude cubre el stack completo — desde la arquitectura del agente hasta el control de costes en producción.


    Lo que puedes hacer hoy

    Si tienes una aplicación que usa la API de Claude en producción, abre el código y busca dónde defines el system prompt. Si es una cadena de texto plana, conviértela en un array con cache_control: { type: "ephemeral" }.

    Eso solo. Una línea de cambio. Comprueba la siguiente factura.

    Si además tienes tools largas, aplica el mismo patrón al último elemento del array de herramientas. Tendrás dos puntos de caché activos y el ahorro será inmediato.

    El prompt caching no es una optimización avanzada que requiere rediseñar tu arquitectura. Es una configuración de tres minutos que debería estar activa en cualquier aplicación seria sobre la API de Claude. Si no la tienes, estás pagando de más desde el primer día.


    Bezael Pérez — Fundador de Dominicode. Developer senior con 15+ años construyendo software. Si construyes con IA y quieres profundizar más allá de los tutoriales, en Dominicode Labs estamos trabajando en proyectos reales con la API de Anthropic, arquitecturas de agentes y todo lo que no cabe en un post.

  • Claude Fable 5 vuelve: qué pasó y qué cambia para developers

    Claude Fable 5 vuelve: qué pasó y qué cambia para developers

    El 12 de junio de 2026, Anthropic apagó Claude Fable 5 de golpe.

    Sin aviso previo. Sin fecha de vuelta. Sin explicación técnica completa. El modelo que llevaba apenas tres días disponible desapareció para todos los usuarios del planeta — Europa, Latinoamérica, Asia, todos — porque el gobierno de EE.UU. no podía verificar nacionalidades en tiempo real y decidió cortar el acceso global en lugar de arriesgarse.

    Ese mismo día, developers de medio mundo abrieron Claude.ai y encontraron un modelo degradado. Los que habían empezado a construir pipelines con Fable 5 tuvieron que pivotar sobre la marcha. Y los que llevábamos años viendo cómo la IA maduraba como industria recibimos un recordatorio brutal: cuando un modelo tiene capacidades que un Estado considera amenaza para la seguridad nacional, el interruptor lo tiene el Estado, no Anthropic.

    Hoy, 1 de julio de 2026, Claude Fable 5 vuelve. Y la historia de cómo llegamos hasta aquí dice más sobre el futuro de la IA que cualquier benchmark.


    Lo que pasó: el jailbreak que lo cambió todo

    Investigadores de Amazon descubrieron una técnica que permitía a Fable 5 identificar vulnerabilidades en software y, en al menos un caso documentado, demostrar cómo explotarlas. El gobierno de EE.UU. reaccionó con rapidez: el mismo día 12 de junio, el Departamento de Comercio aplicó controles de exportación de emergencia que afectaron tanto a Fable 5 como a Mythos 5.

    La tensión entre ambas partes fue pública. El gobierno argumentó que el problema podría haberse corregido antes de la suspensión. Anthropic respondió que la técnica era más estrecha y específica de lo que la orden de emergencia implicaba — no una vulnerabilidad sistémica, sino un vector concreto que requerirían semanas de investigación para reproducir.

    El debate sobre la severidad real del jailbreak sigue abierto. El resultado fue inequívoco: controles de exportación de emergencia, suspensión global, y Anthropic sin poder verificar la nacionalidad de sus usuarios en tiempo real.

    No había otra salida. Apagaron todo.


    Fable 5 y Mythos 5: la diferencia que importa

    Aquí hay un matiz que mucha cobertura mediática perdió.

    Mythos 5 es la denominación interna de los modelos con capacidades cibernéticas más avanzadas que Anthropic ha construido jamás — superiores a cualquier otro modelo del mercado en ese dominio. Tras la suspensión, Anthropic decidió que Mythos 5 solo estará disponible para socios del Proyecto Glasswing, un programa de ciberseguridad defensiva con acceso controlado y supervisión directa.

    Fable 5 es diferente. Es el modelo de propósito general que se lanza hoy con los salvaguardas más fuertes que Anthropic ha implementado en ningún modelo de su historia. Anthropic afirma explícitamente que Fable 5 "no proporciona capacidades ofensivas únicas" — es decir, no hace nada que un atacante sofisticado no pudiera hacer con las herramientas que ya existen.

    Fable 5 Mythos 5
    Propósito General (razonamiento, código, escritura) Ciberseguridad avanzada
    Acceso Público (planes de pago) Solo Proyecto Glasswing
    API pública ✅ Sí ❌ No
    Capacidades ofensivas No únicas respecto a herramientas existentes Superiores a cualquier otro modelo del mercado

    La distinción es importante para cualquier developer que esté construyendo con la API. No estás usando Mythos 5. Estás usando Fable 5, que ha pasado por una revisión de seguridad que ningún modelo anterior había tenido.


    Qué cambió en Claude Fable 5: los nuevos salvaguardas

    Anthropic no volvió con el mismo modelo. Volvió con un clasificador de seguridad reentrenado específicamente para detectar y bloquear la técnica descrita en el reporte de Amazon.

    Según el anuncio oficial de Anthropic, el nuevo clasificador bloquea el comportamiento problemático en más del 99% de los casos. Cuando se activa, la solicitud no falla en silencio — se redirige automáticamente a Claude Opus 4.8. El usuario recibe respuesta, pero sin las capacidades que generaron el problema.

    El mecanismo de defensa tiene tres capas:

    1. El entrenamiento base del modelo, que ya rechaza asistencia con solicitudes peligrosas.
    2. Un clasificador específico para el patrón de jailbreak identificado por Amazon.
    3. Un margen de seguridad ampliado — Anthropic subió el umbral de bloqueo de forma deliberada, asumiendo más falsos positivos para reducir el riesgo de usos maliciosos.

    Ese tercer punto es el que más impacta a developers en producción. Más falsos positivos significa que algunas solicitudes legítimas relacionadas con ciberseguridad, análisis de código o auditoría de vulnerabilidades van a llegar a Opus 4.8 en lugar de Fable 5. No es un bug. Es una decisión consciente de arquitectura de seguridad.

    El Departamento de Comercio de EE.UU. verificó los salvaguardas y los calificó de "extraordinariamente fuertes". El 30 de junio levantó los controles de exportación. El 1 de julio, Fable 5 vuelve.


    Disponibilidad desde hoy: lo que necesitas saber

    La reactivación es global desde el 1 de julio en Claude.ai, Claude Platform, Claude Code y Claude Cowork.

    AWS, Google Cloud y Microsoft Foundry se reactivarán "lo antes posible" — sin fecha concreta confirmada.

    Hay un período de transición con límites temporales:

    • Hasta el 7 de julio: planes Pro, Max, Team y empresas seleccionadas tienen acceso a Fable 5 con hasta el 50% de sus límites de uso semanal habituales.
    • Después del 7 de julio: disponible mediante créditos de uso, sin restricción porcentual.

    Si estás en el plan gratuito, no hay cambios respecto a antes de la suspensión. Fable 5 era y sigue siendo acceso de pago.

    Para los que construimos con la API de Anthropic, el modelo vuelve a estar disponible desde hoy. Si tenías pipelines configurados con Fable 5 antes del 12 de junio, probablemente ya están activos de nuevo. Verifica tu dashboard y el comportamiento del clasificador con tus casos de uso específicos — especialmente si tienes prompts relacionados con análisis de código o seguridad.


    El nuevo marco de evaluación de jailbreaks

    Lo más interesante de lo que Anthropic publicó esta semana no son los salvaguardas. Es el marco que proponen como estándar industrial para evaluar la severidad de un jailbreak.

    Cuatro criterios:

    1. Ganancia de capacidad. ¿Cuánto supera lo que ya existe? Un jailbreak que replica lo que hace una herramienta de código abierto pesa menos que uno que desbloquea algo genuinamente nuevo.

    2. Amplitud. ¿Cuántas tareas ofensivas distintas habilita? Un jailbreak muy específico (un tipo de ataque, un vector) no es lo mismo que uno que abre la puerta a toda una clase de capacidades.

    3. Facilidad de armamento. ¿Cuánto esfuerzo humano experto requiere convertir el output en un ataque real? Hay una diferencia enorme entre "el modelo identifica una vulnerabilidad" y "el modelo produce un exploit listo para ejecutar".

    4. Descubribilidad. ¿Cómo de fácil es que un actor malicioso llegue a esta técnica? Un jailbreak que requiere semanas de ingeniería de prompts por parte de investigadores avanzados no tiene el mismo riesgo que uno que circula en un foro público.

    Este marco no es solo teoría. Anthropic lo propone como base para que gobiernos, empresas y laboratorios de IA puedan hablar de jailbreaks con criterios objetivos en lugar de reacciones políticas de emergencia.

    Si trabajas en seguridad o builds productos con IA, este marco te va a ser útil.


    Lo que esto significa para developers que construyen con IA

    Hace tres semanas, el modelo más capaz del mercado desapareció sin fecha de vuelta. Hoy está de vuelta con salvaguardas que ningún modelo anterior había tenido, respaldado por verificación gubernamental y un nuevo marco de evaluación que puede convertirse en estándar.

    ¿Qué cambia para nosotros?

    Primero, la confirmación de algo que debíamos asumir pero que muchos ignoraban: los modelos más capaces van a estar regulados. No es una posibilidad futura. Es el presente. El mismo día que Fable 5 volvió, Mythos 5 quedó restringido a socios controlados del Proyecto Glasswing. La IA de alto impacto va a tener fricción institucional. Cuanto antes lo integremos en nuestra planificación de producto, mejor.

    Segundo, la arquitectura de fallback importa más de lo que pensamos. Si tu producto dependía de Fable 5 el 12 de junio, tuviste un problema durante diecinueve días. Los mejores sistemas tienen fallback a modelos alternativos — no porque anticipen este escenario exacto, sino porque construyen con redundancia desde el principio.

    Tercero, y esto es lo más importante: la madurez del sector se mide en cómo responde a los errores, no en si los comete. Anthropic tardó diecinueve días en volver. En esas tres semanas entrenaron un nuevo clasificador, pasaron una auditoría gubernamental, propusieron un marco de evaluación de jailbreaks que puede convertirse en estándar, y redefinieron el acceso a Mythos 5. Eso no es una crisis mal gestionada. Es una empresa que aprendió en tiempo real bajo presión máxima.

    Nosotros podemos hacer lo mismo en nuestros productos.

    En el curso Construye con IA hablo de esto en profundidad: cómo construir sistemas que no colapsen cuando el modelo subyacente cambia, se actualiza o desaparece temporalmente. La resiliencia arquitectural no es un añadido. Es la condición de base para cualquier producto serio con IA.


    Preguntas frecuentes sobre Claude Fable 5

    ¿Claude Fable 5 está disponible hoy para todos los usuarios?

    Desde el 1 de julio de 2026, Fable 5 está disponible en Claude.ai, Claude Platform, Claude Code y Claude Cowork para usuarios en todos los países. AWS, Google Cloud y Microsoft Foundry se reactivarán próximamente. El acceso a Fable 5 requiere un plan de pago (Pro, Max, Team o Enterprise).

    ¿Qué es el jailbreak que causó la suspensión de Claude Fable 5?

    Investigadores de Amazon descubrieron una técnica de prompting que permitía a Fable 5 identificar vulnerabilidades en software y, en al menos un caso, demostrar cómo explotarlas. El gobierno de EE.UU. aplicó controles de exportación de emergencia el 12 de junio de 2026, lo que llevó a Anthropic a suspender el acceso global porque no podía verificar la nacionalidad de sus usuarios en tiempo real.

    ¿Cuál es la diferencia entre Claude Fable 5 y Mythos 5?

    Fable 5 es el modelo de propósito general disponible desde hoy para el público. Mythos 5 es la denominación de los modelos con capacidades cibernéticas avanzadas — superiores a cualquier otro modelo del mercado — restringido exclusivamente a socios del Proyecto Glasswing para ciberseguridad defensiva. No es accesible a través de la API pública.

    ¿Cómo afectan los nuevos salvaguardas al uso de Fable 5 en desarrollo de software?

    El nuevo clasificador bloquea el patrón de jailbreak en más del 99% de los casos, redirigiendo esas solicitudes a Claude Opus 4.8. Anthropic aumentó deliberadamente el margen de seguridad, lo que genera más falsos positivos en tareas de análisis de código, auditoría de seguridad o detección de vulnerabilidades. Si tu caso de uso incluye estas áreas, testea tu pipeline con Fable 5 para verificar el comportamiento del clasificador.

    ¿Qué límites de uso tiene Claude Fable 5 tras la vuelta?

    Hasta el 7 de julio de 2026, los planes Pro, Max, Team y empresas Enterprise seleccionadas tienen acceso a Fable 5 con hasta el 50% de sus límites de uso semanal habituales. Después del 7 de julio, el modelo estará disponible mediante créditos de uso sin restricción porcentual.

    ¿Puede volver a ocurrir una suspensión similar con otros modelos de Anthropic?

    Sí. Los controles de exportación son un instrumento legal que el gobierno de EE.UU. puede aplicar a cualquier modelo con capacidades que considere una amenaza. La colaboración reforzada entre Anthropic y el gobierno reduce la probabilidad de una suspensión de emergencia, pero no la elimina. Cualquier arquitectura de producto con IA debe contemplar escenarios de indisponibilidad del modelo principal.


    Si quieres estar al día de cómo estos eventos impactan a los developers que construyen con IA, en Dominicode Labs analizamos en tiempo real las decisiones de los grandes laboratorios y sus implicaciones para producción. Y en el canal de YouTube seguiré cubriendo la evolución de Fable 5 en las próximas semanas.


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

  • Claude Sonnet 5: el modelo que trabaja solo mientras tú duermes

    Claude Sonnet 5: el modelo que trabaja solo mientras tú duermes

    Me pasó hace unos meses revisando el output de un agente que había dejado corriendo toda la noche.

    Esperaba encontrar la tarea a medias. Un formulario sin completar. Alguna herramienta mal llamada. Lo habitual con los modelos de la generación anterior: empezaban bien, pero a mitad de camino se perdían, pedían confirmación o simplemente paraban.

    En cambio, encontré el trabajo terminado. Del principio al fin. Sin intervención.

    Ese momento cambia algo en tu cabeza como developer. No es que la IA sea "mejor". Es que ya no necesita que estés mirando.

    Claude Sonnet 5 es exactamente esa promesa hecha modelo. Anthropic lo lanzó el 30 de junio de 2026 y lo describe como "el modelo Sonnet más agéntico hasta la fecha". No es marketing vacío — la diferencia en tareas autónomas y multi-paso es medible y, para quien construye con IA, es relevante desde el primer día.


    Por qué Sonnet 5 es distinto a todo lo anterior

    Hasta ahora, la frontera estaba clara: si querías un agente que realmente terminase el trabajo, necesitabas Opus. Sonnet era el punto medio — rápido, accesible, suficientemente bueno para tareas simples. Pero en flujos complejos con múltiples pasos, herramientas y decisiones encadenadas, Sonnet se quedaba corto.

    Claude Sonnet 5 rompe esa frontera.

    Anthropic no ha simplemente subido los parámetros. Han optimizado específicamente para comportamiento agéntico: planificación de tareas, uso coordinado de herramientas (navegadores, terminales, APIs), y lo más relevante — la capacidad de verificar su propio resultado sin que se lo pidas.

    Eso último importa más de lo que parece. Un modelo que ejecuta código y luego comprueba si el output es el esperado, sin que tú se lo digas, está un paso más cerca de un colaborador que de una herramienta.


    Las capacidades agénticas en detalle

    Hay tres áreas donde el cambio es palpable:

    Tareas multi-paso sin interrupciones. Modelos anteriores tendían a pedir confirmación o detenerse cuando encontraban ambigüedad. Sonnet 5 mantiene el hilo. Algunos partners de Anthropic reportan que "terminó el trabajo de principio a fin sin intervención" — algo que antes era territorio exclusivo de Opus 4.

    Uso de herramientas coordinado. Puede combinar búsqueda web, ejecución de código y llamadas a APIs en la misma tarea sin perder el contexto de lo que estaba haciendo. No es nuevo que los modelos puedan usar herramientas — lo nuevo es que lo hacen con coherencia a lo largo de cadenas largas de razonamiento.

    Auto-verificación del resultado. Si ejecuta una query de base de datos o genera un archivo, puede evaluar si el resultado tiene sentido antes de dártelo. Esto reduce drásticamente la necesidad de loops de revisión en tus agentes.

    Si estás construyendo con la API de Claude o con Claude Code, estas tres capacidades cambian el diseño de tus flujos. No necesitas los mismos guardrails de antes. No necesitas los mismos puntos de control manual.

    En el curso de Construye con IA cubrimos exactamente este tipo de arquitectura de agentes — y con Sonnet 5 muchos de esos patrones se simplifican considerablemente.


    Benchmarks: qué dicen los números

    Los benchmarks importan, pero necesitan contexto. Aquí va la comparativa relevante para developers:

    Benchmark Claude Sonnet 5 Claude Sonnet 4.6 Claude Opus 4.8
    BrowseComp Superior Base de comparación Superior
    OSWorld-Verified Superior Base de comparación Superior
    Razonamiento general Muy cercano a Opus Inferior Referencia
    Codificación Notable mejora Base Referencia
    Esfuerzo "extra high" Iguala a Opus 4.8 Referencia

    Evaluaciones cualitativas basadas en el anuncio oficial de Anthropic (30 jun 2026).

    El dato más interesante: a nivel de esfuerzo máximo, Sonnet 5 iguala a Opus 4.8. Esto es arquitectónicamente significativo. Significa que para la mayoría de las tareas que antes justificaban pagar el precio de Opus, ahora puedes usar Sonnet 5 a un coste mucho menor.

    La excepción es ciberseguridad. Anthropic es explícito: Sonnet 5 no fue entrenado deliberadamente para tareas de seguridad ofensiva, y Opus 4.8 sigue siendo superior en ese dominio específico.


    Precios y disponibilidad

    Plan Precio hasta 31 ago 2026 Precio desde 1 sep 2026
    Input tokens $2 / M tokens $3 / M tokens
    Output tokens $10 / M tokens $15 / M tokens

    Anthropic ha aplicado un precio introductorio hasta finales de agosto. Si estás evaluando el switch en la API, este es el momento óptimo para hacerlo.

    Dónde está disponible:

    • Modelo predeterminado en los planes Free y Pro de Claude.ai
    • Disponible en Max, Team, Enterprise
    • Claude Code
    • API (model ID: claude-sonnet-5)

    Si usas Claude.ai directamente, ya lo tienes — es el modelo por defecto desde el lanzamiento.


    El tokenizador actualizado: impacto práctico

    Este punto se menciona poco y puede sorprenderte en producción.

    Sonnet 5 usa un tokenizador actualizado similar al que se introdujo con Opus 4.7. El resultado es que el mismo texto que antes ocupaba X tokens ahora puede ocupar entre 1.0× y 1.35× más tokens.

    ¿Qué significa esto en la práctica?

    Si tienes prompts largos con contexto extenso (documentos, conversaciones, sistemas de RAG), tu consumo de tokens aumentará. Anthropic compensa esto con el precio introductorio, pero necesitas tener este factor en cuenta al proyectar costes para producción.

    Una regla rápida: si venías de Sonnet 4.6 y tienes prompts de más de 5.000 tokens, haz una prueba controlada antes de cambiar el modelo en producción. Mide el consumo real, no lo estimes desde los benchmarks públicos.

    Para esto el post sobre prompt caching en Claude es directamente aplicable — con el nuevo tokenizador, el caching se vuelve aún más relevante para controlar costes.


    Cómo empezar hoy

    En Claude.ai: Ya está activo. Es el modelo por defecto. No necesitas hacer nada.

    En la API:

    El siguiente ejemplo muestra la integración mínima con el SDK oficial @anthropic-ai/sdk para TypeScript. El único cambio respecto a modelos anteriores es el model ID: claude-sonnet-5.

    import Anthropic from "@anthropic-ai/sdk";
    
    const client = new Anthropic();
    
    const response = await client.messages.create({
      model: "claude-sonnet-5",
      max_tokens: 4096,
      messages: [
        {
          role: "user",
          content: "Analiza este código y sugiere mejoras de rendimiento...",
        },
      ],
    });
    

    El cambio de model ID es inmediato. Si tienes un sistema en producción con claude-sonnet-4-6, cambiar a claude-sonnet-5 no requiere modificar nada más en la integración básica.

    Si usas Claude Code, el modelo ya está disponible y puedes seleccionarlo desde la configuración del cliente.


    Qué significa esto para developers que construyen con IA

    Voy a ser directo porque creo que es lo que necesitas saber.

    El lanzamiento de Sonnet 5 no es un update de rendimiento incremental. Es un reposicionamiento del tier medio.

    Hasta ahora, la decisión era: velocidad y coste (Haiku/Sonnet) vs. capacidad y razonamiento complejo (Opus). Con Sonnet 5, esa brecha se cierra de forma significativa. Puedes construir agentes que realmente terminen el trabajo, a un coste que tiene sentido para producción.

    Para quien está construyendo productos con IA — y no solo experimentando — esto cambia la ecuación de build vs. cost. Puedes subir la ambición de tus agentes sin subir proporcionalmente el presupuesto.

    El riesgo que veo es el de siempre: sobreestimar la autonomía del modelo en los primeros días. Sonnet 5 es notablemente mejor en tareas autónomas, pero sigue siendo un modelo de lenguaje. Sigue necesitando specs claras, herramientas bien definidas y tests que verifiquen los outputs.

    En Dominicode Labs estamos ya trabajando con Sonnet 5 en los proyectos de la comunidad — si quieres ver cómo se integra en flujos reales de producción, es donde está pasando.


    Preguntas frecuentes sobre Claude Sonnet 5

    ¿Qué diferencia hay entre Claude Sonnet 5 y Claude Sonnet 4.6?

    Claude Sonnet 5 está optimizado para comportamiento agéntico: puede planificar y ejecutar tareas multi-paso sin interrupciones, verificar sus propios resultados automáticamente y usar herramientas (navegadores, terminales, APIs) de forma coordinada en cadenas largas de razonamiento. Sonnet 4.6 era capaz, pero tendía a detenerse o pedir confirmación en tareas complejas. La mejora en benchmarks como BrowseComp y OSWorld-Verified refleja exactamente esta diferencia en tareas autónomas.

    ¿Es Claude Sonnet 5 tan bueno como Claude Opus 4.8?

    En la mayoría de tareas cotidianas de codificación, razonamiento y trabajo de conocimiento, Sonnet 5 está muy cerca de Opus 4.8 — y a nivel de esfuerzo máximo puede igualarlo. La excepción es el dominio de ciberseguridad, donde Opus 4.8 sigue siendo superior porque fue entrenado deliberadamente para esas tareas. Para el 90% de los casos de uso de desarrollo con IA, Sonnet 5 es suficientemente capaz y mucho más accesible en precio.

    ¿Cómo afecta el nuevo tokenizador a mis costes en la API?

    El tokenizador actualizado puede incrementar el consumo de tokens en un factor de 1.0× a 1.35× respecto a modelos anteriores. Esto es especialmente relevante con contextos largos: documentos, conversaciones extendidas, sistemas RAG. Anthropic compensa esto con el precio introductorio vigente hasta el 31 de agosto de 2026. La recomendación práctica es medir el consumo real con tus prompts de producción antes de estimar costes a escala.

    ¿Puedo usar Claude Sonnet 5 en Claude Code?

    Sí. Claude Sonnet 5 está disponible en Claude Code desde el lanzamiento. Dado que Claude Code es una herramienta diseñada precisamente para tareas agénticas de desarrollo — escribir, ejecutar, verificar código de forma autónoma — la combinación con Sonnet 5 es especialmente potente. Puedes seleccionar el modelo desde la configuración del cliente.

    ¿Qué precio tiene Claude Sonnet 5 y cuándo cambia?

    El precio introductorio vigente hasta el 31 de agosto de 2026 es $2/M tokens de input y $10/M tokens de output. A partir del 1 de septiembre de 2026 pasa a $3/M input y $15/M output. Si estás evaluando la migración en producción, hacerlo antes de septiembre tiene sentido económico.

    ¿Claude Sonnet 5 ya está disponible en el plan gratuito de Claude.ai?

    Sí. Desde el lanzamiento el 30 de junio de 2026, Claude Sonnet 5 es el modelo predeterminado en todos los planes de Claude.ai, incluyendo el gratuito. No necesitas hacer ningún cambio — si abres Claude.ai hoy, ya estás usando Sonnet 5.


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

  • Angular v22 + Vercel AI SDK: streaming de IA con Signals

    Angular v22 + Vercel AI SDK: streaming de IA con Signals

    ANTHROPIC_API_KEY=sk-ant-xxxxxxxx

    
    ---
    
    ## Paso 1: El servidor backend con streamText
    
    Crea un archivo `server/chat.ts` fuera del proyecto Angular (o en un monorepo aparte). Este servidor tiene un solo endpoint: recibe mensajes, llama a Claude, y hace streaming de la respuesta.
    
    ```typescript
    // server/chat.ts
    import { streamText } from 'ai';
    import { anthropic } from '@ai-sdk/anthropic';
    
    const server = Bun.serve({
      port: 3000,
      async fetch(req) {
        // CORS para desarrollo local
        if (req.method === 'OPTIONS') {
          return new Response(null, {
            headers: {
              'Access-Control-Allow-Origin': '*',
              'Access-Control-Allow-Methods': 'POST, OPTIONS',
              'Access-Control-Allow-Headers': 'Content-Type',
            },
          });
        }
    
        if (req.method === 'POST' && new URL(req.url).pathname === '/api/chat') {
          const { messages } = await req.json();
    
          const result = streamText({
            model: anthropic('claude-sonnet-4-6'),
            system: 'Eres un asistente técnico especializado en Angular y desarrollo frontend moderno. Responde en español de forma concisa y directa.',
            messages,
          });
    
          return result.toTextStreamResponse({
            headers: {
              'Access-Control-Allow-Origin': '*',
            },
          });
        }
    
        return new Response('Not found', { status: 404 });
      },
    });
    
    console.log(`Servidor corriendo en http://localhost:${server.port}`);
    

    Arrancar el servidor:

    bun run server/chat.ts
    

    streamText de la AI SDK devuelve un objeto con varios métodos. toTextStreamResponse() genera una Response HTTP estándar con Content-Type: text/plain; charset=utf-8 y Transfer-Encoding: chunked — exactamente lo que necesita el cliente para consumir el stream token a token.


    Paso 2: El modelo de datos

    Antes del componente, define la interfaz de mensaje. Simple:

    // src/app/chat/chat.types.ts
    export interface ChatMessage {
      role: 'user' | 'assistant';
      content: string;
    }
    

    Paso 3: El componente Angular v22 con Signals

    Aquí es donde la magia ocurre. No necesitas HttpClient con responseType: 'text' — eso no soporta streaming incremental. Necesitas fetch nativo con ReadableStream.

    // src/app/chat/chat.component.ts
    import {
      Component,
      signal,
      computed,
      ChangeDetectionStrategy,
    } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    import { ChatMessage } from './chat.types';
    
    @Component({
      selector: 'app-chat',
      standalone: true,
      imports: [FormsModule],
      changeDetection: ChangeDetectionStrategy.OnPush,
      templateUrl: './chat.component.html',
    })
    export class ChatComponent {
      messages = signal<ChatMessage[]>([]);
      userInput = signal('');
      isStreaming = signal(false);
    
      canSend = computed(
        () => this.userInput().trim().length > 0 && !this.isStreaming()
      );
    
      async sendMessage() {
        const content = this.userInput().trim();
        if (!content || this.isStreaming()) return;
    
        // Añadir mensaje del usuario
        this.messages.update((msgs) => [
          ...msgs,
          { role: 'user', content },
        ]);
        this.userInput.set('');
        this.isStreaming.set(true);
    
        // Capturar mensajes ANTES del placeholder — la API rechaza content vacío como último mensaje
        const messagesToSend = this.messages();
    
        // Placeholder para la respuesta del asistente
        this.messages.update((msgs) => [
          ...msgs,
          { role: 'assistant', content: '' },
        ]);
    
        try {
          const response = await fetch('http://localhost:3000/api/chat', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ messages: messagesToSend }),
          });
    
          if (!response.ok) throw new Error(`HTTP ${response.status}`);
          if (!response.body) throw new Error('No stream body');
    
          const reader = response.body.getReader();
          const decoder = new TextDecoder();
    
          while (true) {
            const { done, value } = await reader.read();
            if (done) break;
    
            const chunk = decoder.decode(value, { stream: true });
    
            // Actualiza el último mensaje (el del asistente) acumulando el chunk
            this.messages.update((msgs) => {
              const updated = [...msgs];
              const last = updated[updated.length - 1];
              updated[updated.length - 1] = {
                ...last,
                content: last.content + chunk,
              };
              return updated;
            });
          }
        } catch (error) {
          console.error('Error en streaming:', error);
          this.messages.update((msgs) => {
            const updated = [...msgs];
            updated[updated.length - 1] = {
              role: 'assistant',
              content: 'Error al conectar con el servidor. Comprueba que el backend está corriendo.',
            };
            return updated;
          });
        } finally {
          this.isStreaming.set(false);
        }
      }
    
      handleEnter(event: KeyboardEvent) {
        if (event.key === 'Enter' && !event.shiftKey) {
          event.preventDefault();
          this.sendMessage();
        }
      }
    }
    

    Tres decisiones clave en este componente:

    messages = signal<ChatMessage[]>([]) — todo el historial de la conversación vive en un signal. Cada vez que llega un chunk, actualizamos el último mensaje del array con update(). Angular detecta el cambio y re-renderiza solo ese elemento.

    ChangeDetectionStrategy.OnPush — esencial para este patrón. Sin esto, Angular ejecutaría la detección de cambios en cada tick mientras el stream está activo. Con OnPush + Signals, Angular solo actualiza cuando el signal cambia — que es exactamente cuando llega un chunk nuevo.

    fetch nativo en lugar de HttpClientHttpClient es poderoso para peticiones normales, pero para streaming necesitas acceso al ReadableStream crudo del Response. fetch te da eso directamente con response.body.getReader().


    Paso 4: El template con el nuevo control flow

    El template aprovecha el control flow de Angular v17+ (@for, @if) y lee los signals directamente — sin async pipe, sin | async, sin subscripciones.

    <!-- src/app/chat/chat.component.html -->
    <div class="chat-container">
      <div class="messages-area">
        @if (messages().length === 0) {
          <p class="empty-state">Escribe un mensaje para empezar.</p>
        }
    
        @for (msg of messages(); track $index) {
          <div class="message" [class]="msg.role">
            <span class="role-label">
              {{ msg.role === 'user' ? 'Tú' : 'Asistente' }}
            </span>
            <p class="message-content">{{ msg.content }}</p>
    
            @if (msg.role === 'assistant' && $last && isStreaming()) {
              <span class="cursor-blink">|</span>
            }
          </div>
        }
      </div>
    
      <div class="input-area">
        <textarea
          [value]="userInput()"
          (input)="userInput.set($any($event.target).value)"
          (keydown)="handleEnter($event)"
          placeholder="Escribe tu mensaje... (Enter para enviar)"
          rows="3"
          [disabled]="isStreaming()"
        ></textarea>
    
        <button
          (click)="sendMessage()"
          [disabled]="!canSend()"
        >
          @if (isStreaming()) {
            Generando...
          } @else {
            Enviar
          }
        </button>
      </div>
    </div>
    

    El cursor parpadeante | aparece solo en el último mensaje del asistente mientras isStreaming() es true. Es un detalle pequeño que hace que la experiencia se sienta viva.


    Paso 5: Estilos mínimos (opcional)

    /* src/app/chat/chat.component.css */
    .chat-container {
      display: flex;
      flex-direction: column;
      height: 100vh;
      max-width: 800px;
      margin: 0 auto;
      padding: 1rem;
      gap: 1rem;
    }
    
    .messages-area {
      flex: 1;
      overflow-y: auto;
      display: flex;
      flex-direction: column;
      gap: 1rem;
      padding: 1rem;
      border: 1px solid #e5e7eb;
      border-radius: 0.5rem;
    }
    
    .message {
      padding: 0.75rem 1rem;
      border-radius: 0.5rem;
      max-width: 80%;
    }
    
    .message.user {
      background: #e90464;
      color: white;
      align-self: flex-end;
    }
    
    .message.assistant {
      background: #f3f4f6;
      color: #111827;
      align-self: flex-start;
    }
    
    .role-label {
      font-size: 0.75rem;
      font-weight: 600;
      opacity: 0.7;
      display: block;
      margin-bottom: 0.25rem;
    }
    
    .cursor-blink {
      animation: blink 1s step-end infinite;
    }
    
    @keyframes blink {
      50% { opacity: 0; }
    }
    
    .input-area {
      display: flex;
      gap: 0.5rem;
    }
    
    textarea {
      flex: 1;
      padding: 0.75rem;
      border: 1px solid #d1d5db;
      border-radius: 0.5rem;
      resize: none;
      font-family: inherit;
    }
    
    button {
      padding: 0.75rem 1.5rem;
      background: #e90464;
      color: white;
      border: none;
      border-radius: 0.5rem;
      cursor: pointer;
      font-weight: 600;
      align-self: flex-end;
    }
    
    button:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
    

    El resultado

    Arranca los dos procesos:

    # Terminal 1: backend
    bun run server/chat.ts
    
    # Terminal 2: Angular
    ng serve
    

    Abre http://localhost:4200. Escribe cualquier pregunta técnica. Las palabras aparecen token a token mientras Claude las genera. El botón muestra "Generando…" y el cursor parpadea al final del último mensaje.

    Eso es streaming real, en Angular v22, con Signals, en menos de 20 minutos.


    Por qué este patrón funciona bien en producción

    Si quieres entender cómo se conectan estos patrones con el desarrollo de productos completos con IA, el post sobre cómo crear productos con IA para vender muestra el panorama completo.

    Lo que tienes aquí no es un prototipo. Es un patrón que escala:

    El estado es predecible. Todo vive en messages = signal<ChatMessage[]>([]). No hay subscripciones dispersas, no hay Subject de BehaviorSubject, no hay que recordar hacer unsubscribe. El signal se actualiza, Angular re-renderiza lo necesario, punto.

    El backend es stateless. Cada petición envía el historial completo de mensajes. Así funciona la API de Anthropic — no hay sesión en el servidor, lo que facilita el escalado horizontal.

    ChangeDetectionStrategy.OnPush es obligatorio aquí. Con Zone.js y la detección de cambios por defecto, Angular correría su ciclo de detección constantemente mientras el stream está activo. Con OnPush + Signals, solo actualiza cuando el signal cambia.

    Si quieres llevar esto más allá — añadir herramientas (tool calls), mantener sesiones con localStorage, o integrar el chat dentro de una app Angular más grande con routing y autenticación — el patrón es el mismo. Cambias el modelo en el servidor, añades tools a streamText, y el componente no necesita modificarse.

    Si ya tienes experiencia con Angular y quieres dominar Signals, componentes standalone y el control flow moderno que hemos usado aquí, en el Curso Angular Moderno lo cubrimos desde la arquitectura hasta producción — incluyendo patrones de integración con APIs externas como esta.

    Y si quieres ir más allá del chat básico y construir agentes reales con Claude — con herramientas, contexto persistente, y pipelines de desarrollo AI-first — eso es exactamente lo que enseñamos en Construye con IA: de la idea al producto con Claude Code.


    FAQ

    ¿Necesito Angular Universal (SSR) para que esto funcione?

    No. El streaming ocurre entre el cliente Angular (browser) y el servidor Bun que creamos. Angular SSR es irrelevante para este patrón — el componente de chat vive completamente en el cliente. Si tienes SSR activado, asegúrate de que el componente de chat solo se renderiza en el browser con isPlatformBrowser o usando @defer.

    ¿Puedo usar el mismo enfoque con OpenAI o Google Gemini en lugar de Anthropic?

    Sí. Cambia @ai-sdk/anthropic por @ai-sdk/openai o @ai-sdk/google, y sustituye anthropic('claude-sonnet-4-6') por openai('gpt-4o') o google('gemini-2.5-pro'). El resto del código — el componente Angular, el consumo del stream, los Signals — no cambia. Esa es una de las ventajas del Vercel AI SDK: abstrae el proveedor.

    ¿Qué pasa si el usuario envía el siguiente mensaje mientras el anterior aún está en streaming?

    El botón está deshabilitado mientras isStreaming() es true gracias al computed canSend. El usuario no puede enviar otro mensaje hasta que el stream termine. Si quieres cancelar el stream activo al recibir un nuevo mensaje, puedes guardar el reader como propiedad del componente y llamar a reader.cancel() antes de iniciar la nueva petición.

    ¿Cómo manejo el historial para conversaciones largas?

    La API de Anthropic tiene un límite de tokens por request. Para conversaciones largas, lo más simple es limitar el historial que envías al servidor — por ejemplo, los últimos 20 mensajes. En producción, lo correcto es implementar una ventana deslizante o resumir el historial antiguo con un llamada previa al modelo. Por ahora, con this.messages().slice(-20) en el body del fetch tienes un control básico suficiente para empezar.

    ¿Puedo usar HttpClient en lugar de fetch nativo?

    HttpClient con responseType: 'text' recibe el texto completo cuando la conexión cierra — no es streaming incremental. Para streaming real necesitas acceso al ReadableStream crudo de la Response, que solo fetch te proporciona directamente. Podrías implementar un interceptor custom o un HttpBackend alternativo, pero la complejidad no vale la pena. fetch nativo es la solución correcta aquí.


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

  • Claude Code Routines: automatiza agentes sin encender tu PC

    Claude Code Routines: automatiza agentes sin encender tu PC

    El viernes por la tarde cerré el portátil con 23 issues sin triagear en el repo, tres PRs esperando revisión de documentación y un changelog que nadie había actualizado en dos semanas.

    El lunes por la mañana, todo estaba hecho.

    No porque contraté a nadie. No porque dejé el ordenador encendido todo el fin de semana. Fue la primera vez que sentí que las Claude Code Routines no eran una feature más de Anthropic — eran la diferencia entre usar IA como herramienta y usarla como infraestructura.


    De herramienta a infraestructura: el salto que cambia todo

    Si ya usas Claude Code de forma interactiva, sabes lo que puede hacer. Le das contexto, le pides algo, revisa tu código, abre PRs. Pero todo depende de que tú estés sentado delante del teclado, iniciando cada conversación.

    Las Routines rompen esa dependencia.

    Una Routine es una configuración guardada de Claude Code: un prompt, uno o más repositorios y un conjunto de conectores (MCP), empaquetados una sola vez y ejecutados de forma automática. Lo que las hace distintas de cualquier script de bash con un cron job es que corren en la infraestructura cloud de Anthropic. Tu máquina puede estar apagada. Claude sigue trabajando.

    Están disponibles desde abril de 2026 en research preview para todos los planes de pago: Pro, Max, Team y Enterprise. Se crean desde claude.ai/code/routines — consulta la documentación oficial de Claude Code para ver los últimos límites y cambios.


    Los tres tipos de trigger

    Una Routine puede tener uno o varios triggers combinados. Esto es lo que hace que el modelo sea flexible de verdad.

    1. Schedule (cron)

    Ejecuta la Routine de forma recurrente: cada hora, diariamente, entre semana o cada semana. Si necesitas un intervalo personalizado — por ejemplo, cada dos horas o el primer día de cada mes — configuras el preset más cercano en la interfaz de claude.ai/code/routines.

    El intervalo mínimo es una hora. Expressions que corren con más frecuencia se rechazan.

    También existe el concepto de one-off run: disparas la Routine una sola vez en un timestamp futuro. Útil para recordatorios diferidos, limpiezas post-deploy o tareas que tienen que correr "cuando aterrice ese PR de upstream". Después de ejecutarse, la Routine se auto-deshabilita. Y un detalle importante: los one-off runs no cuentan contra el límite diario de Routines.

    2. GitHub event

    Dispara una sesión nueva automáticamente cuando ocurre un evento en un repositorio conectado. Los eventos soportados incluyen pull request (opened, closed, labeled, synchronized…) y release (created, published, edited…).

    Puedes añadir filtros para reducir exactamente cuándo se dispara: autor del PR, título, rama base, rama head, labels, si es draft o no, si está mergeado. Cada evento que pasa los filtros abre su propia sesión independiente — no hay reutilización de sesiones entre eventos.

    Para usar GitHub triggers hace falta instalar la Claude GitHub App en el repositorio. No basta con el acceso que configuras en /web-setup para clonar repos.

    3. Webhook (API trigger)

    Cada Routine con este trigger tiene un endpoint HTTP dedicado. Le haces POST con un bearer token y arranca una sesión nueva. El cuerpo de la request acepta un campo text opcional — puedes pasarle el cuerpo de una alerta, un stack trace o cualquier contexto que la Routine necesite para esa ejecución concreta.

    La respuesta devuelve el ID y la URL de la sesión creada, así puedes abrirla en el navegador para ver qué está haciendo Claude en tiempo real.

    curl -X POST https://api.anthropic.com/v1/claude_code/routines/trig_01ABCDEF.../fire \
      -H "Authorization: Bearer sk-ant-oat01-xxxxx" \
      -H "anthropic-beta: experimental-cc-routine-2026-04-01" \
      -H "anthropic-version: 2023-06-01" \
      -H "Content-Type: application/json" \
      -d '{"text": "Error crítico en producción: SEN-4521. Stack trace adjunto."}'
    

    Tres Routines que puedes activar esta semana

    Estos no son ejemplos de documentación. Son los casos de uso que más sentido tienen para un developer indie o un equipo pequeño.

    Triage de issues cada noche

    Un trigger de schedule que corre de lunes a viernes a las 23:00. El prompt le dice a Claude que lea todos los issues abiertos desde la última ejecución, aplique labels según el área de código referenciada, asigne propietario y publique un resumen en Slack. Llegas por la mañana con la cola de trabajo ya priorizada.

    Requiere: conector de GitHub + conector de Slack configurados como MCP connectors en tu cuenta de claude.ai.

    Code review automatizado en cada PR

    Un trigger de GitHub que reacciona a pull_request.opened con filtro is draft: false. El prompt aplica el checklist de revisión de tu equipo: seguridad, performance, style. Deja comentarios inline y un resumen para los revisores humanos. Los humanos se concentran en diseño y arquitectura — lo mecánico lo hace Claude.

    Este es el tipo de automatización que en equipos de 1-3 personas elimina el cuello de botella de revisión completamente.

    Changelog automático post-merge

    Un trigger de GitHub en pull_request.closed filtrado a is merged: true en la rama main. El prompt le pide a Claude que lea el diff del PR mergeado, extraiga el cambio relevante en lenguaje humano y lo añada al CHANGELOG.md en un PR nuevo. Sin nunca más tener que acordarte de documentar lo que acabas de subir a producción.


    Lo que paga el coste

    Las Routines consumen cuota de suscripción de la misma manera que una sesión interactiva. Además, hay un límite diario de runs por cuenta según el plan:

    • Pro: 5 runs diarios
    • Max: 15 runs diarios
    • Team / Enterprise: 25 runs diarios

    Si superas el límite o la cuota de suscripción, las ejecuciones siguientes se rechazan hasta que se resetea la ventana — salvo que tengas usage credits activados, en cuyo caso sigue corriendo en modo metered.

    Los GitHub triggers también tienen un cap por hora durante la research preview. Si un repositorio muy activo dispara demasiados eventos, los excedentes se descartan hasta que se resetea la ventana. Los límites actuales los ves en claude.ai/code/routines.

    El hecho de que sea research preview significa que los límites, la API y el comportamiento pueden cambiar. No construyas pipelines de producción críticos sobre esto todavía — pero sí es el momento perfecto para experimentar y entender cómo integrar esto en tu workflow.


    Routines vs. Managed Agents: no es lo mismo

    Anthropic también ha lanzado Claude Managed Agents con dos features que suenan parecidas pero son una capa distinta: Dreaming y Outcomes.

    La diferencia es importante para no confundirlos.

    Las Routines son un mecanismo de scheduling y ejecución. Definen cuándo y cómo corre una sesión de Claude Code. Son infraestructura de automatización.

    Dreaming es un proceso que revisa las sesiones pasadas de tus agentes y los memory stores, extrae patrones y perfecciona las memorias para que el agente mejore con el tiempo. Es un sistema de aprendizaje retrospectivo, no de ejecución de tareas.

    Outcomes es una feature de evaluación: defines un rubric de éxito y un evaluador separado (con su propio context window, para no contaminarse con el razonamiento del agente) revisa el output y le dice al agente qué corregir si no cumple el criterio. Es un loop de calidad, no de scheduling.

    Dicho de forma directa: las Routines responden a "¿cuándo y con qué trigger corre esto?". Managed Agents responde a "¿cómo mejora y cómo evalúa su propio output el agente?". Pueden usarse juntos, pero son capas con responsabilidades distintas.


    Un detalle que no está en la documentación oficial

    Cuando una Routine corre, lo hace de forma completamente autónoma. Sin permission mode, sin prompts de aprobación durante la ejecución. Claude puede ejecutar comandos de shell, usar skills del repositorio clonado y llamar a todos los conectores que hayas incluido.

    Esto es potente. Y también es la razón por la que el prompt de la Routine es el artefacto más importante del sistema. A diferencia de una sesión interactiva donde puedes corregir el rumbo, aquí el prompt tiene que ser autocontenido y explícito sobre qué hacer y qué aspecto tiene el éxito.

    Por defecto, Claude solo puede hacer push a ramas con prefijo claude/. Para permitirle escribir en ramas existentes o protegidas, tienes que habilitar explícitamente "Allow unrestricted branch pushes" en la configuración de la Routine. Una salvaguarda razonable.

    Las Routines pertenecen a tu cuenta individual de claude.ai. Los commits, los PRs y las acciones en conectores como Slack o Linear aparecen como tú — con tu identidad de GitHub, tu Slack, etc. Eso tiene implicaciones de auditoría que vale la pena tener en cuenta si trabajas en equipo.


    El shift real

    Llevo tiempo diciendo que el developer indie de 2026 puede operar con la capacidad de un equipo pequeño si usa bien las herramientas que tiene. Si llegas nuevo a Claude Code, el post sobre Effort, Models, Tools y Context te da el mapa completo antes de entrar en Routines. Y si quieres entender la capa de arquitectura detrás de los agentes, el post sobre agentic harness completa el cuadro. Las Routines son la prueba más concreta de eso que he visto hasta ahora.

    No es sobre chatear con IA. Es sobre delegar trabajo real a agentes que corren en la nube con tu identidad, contra tus repos, con tus herramientas. Y que lo hacen mientras tú duermes, estás en una reunión o simplemente tienes el portátil cerrado.

    Si llevas tiempo usando Claude Code de forma interactiva, las Routines son el siguiente paso natural. Si quieres un sistema para construir esto de forma ordenada — desde la idea hasta el producto sin caos — en el curso Construye con IA en Udemy cubrimos exactamente ese proceso: cómo estructurar el trabajo con Claude Code para que escale más allá de la sesión interactiva.

    Y si quieres ver cómo otros developers están implementando esto en proyectos reales, en Dominicode Labs estamos documentando los patrones que funcionan — incluyendo los prompts de Routines que uso en mi propio workflow.


    Preguntas frecuentes

    ¿Necesito tener mi servidor propio para usar Claude Code Routines?

    No. Las Routines corren directamente en la infraestructura cloud de Anthropic. No necesitas EC2, Railway, Fly.io ni ningún servidor propio. El único requisito es una suscripción de pago a Claude (Pro, Max, Team o Enterprise) con Claude Code on the web habilitado.

    ¿Cuál es la diferencia entre una Routine y un Desktop Scheduled Task?

    Los Desktop Scheduled Tasks corren en tu máquina local cuando el app de escritorio de Claude Code está abierto. Tienen acceso a tus archivos locales pero requieren que tu ordenador esté encendido. Las Routines corren en la nube de Anthropic independientemente de si tienes el ordenador encendido o el app abierto.

    ¿Puedo combinar varios tipos de trigger en la misma Routine?

    Sí. Una misma Routine puede tener triggers de schedule, de GitHub event y de API al mismo tiempo. Por ejemplo, una Routine de revisión de PRs puede correr de forma programada cada noche, dispararse también cuando se abre un PR nuevo en GitHub, y aceptar ejecuciones manuales vía webhook desde tu pipeline de CI/CD.

    ¿Qué pasa si una Routine falla o Claude no completa la tarea?

    El indicador de estado verde en el historial de runs solo significa que la sesión se inició y terminó sin errores de infraestructura — no que la tarea se completó con éxito. Para saber qué hizo Claude realmente tienes que abrir la sesión y revisar el transcript. Los errores de red, los conectores que faltan o los fallos a nivel de tarea aparecen en el transcript, no en el indicador de estado.

    ¿Las Routines tienen acceso a todos mis conectores MCP?

    Por defecto, cuando creas una Routine, incluye todos tus MCP connectors conectados en claude.ai. La recomendación de Anthropic es quitar los que no necesita la Routine específica para limitar el alcance de lo que Claude puede hacer durante la ejecución. Los MCP servers que hayas añadido localmente en el CLI con claude mcp add no están disponibles en Routines — tienes que añadirlos como connectors en claude.ai/customize/connectors.


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

  • SDD 2026: por qué el spec define tu ventaja competitiva

    SDD 2026: por qué el spec define tu ventaja competitiva

    Un cliente me mandó su proyecto hace tres semanas. Llevaba dos meses usando Claude Code todos los días. El repositorio tenía 340 archivos. Tenía features. Tenía tests. El código compilaba.

    Y no tenía ni idea de qué hacía el sistema.

    Me preguntó: “¿Por qué cada vez que añado algo nuevo, rompo tres cosas que ya funcionaban?” La respuesta era visible desde el primer git log: llevaba dos meses pidiéndole a la IA que generara código sin decirle nunca qué estaba construyendo realmente. Cada prompt era una instrucción táctica. Nunca había una visión. Nunca un mapa.

    Eso es Spec-Driven Development (SDD) al revés. Y en 2026, con agentes que pueden escribir mil líneas en minutos, la diferencia entre los dos modos es la diferencia entre un producto y un desastre con tests.


    La IA no necesita que seas más rápido. Necesita que seas más claro.

    La narrativa que se vende sobre el desarrollo con IA es esta: “ahora puedes construir el doble de rápido”. Es verdad. El problema es que construir el doble de rápido sin dirección no te lleva antes a destino — te lleva el doble de lejos en la dirección equivocada.

    Los agentes de IA son ejecutores extraordinariamente potentes con cero criterio arquitectónico propio. Claude Code, GitHub Copilot, Cursor, cualquiera — siguen instrucciones. Si las instrucciones son vagas, el output es coherente localmente e incoherente globalmente. Cada archivo tiene sentido en sí mismo. El sistema entero no tiene sentido como conjunto.

    El spec no es documentación. No es burocracia. Es la única forma de darle a un agente de IA el contexto suficiente para que sus decisiones locales sean coherentes con la visión global.

    Sin spec, el agente está adivinando constantemente. Y adivina bien, frase a frase. Pero adivinar bien frase a frase no produce un párrafo con sentido — produce contenido que parece correcto y no lleva a ningún lado.


    Qué es SDD y por qué no es lo que crees

    Spec-Driven Development no es escribir documentación antes de programar. Eso es lo que la mayoría imagina y por lo que lo descartan: “ya tengo suficiente trabajo sin añadir Word docs al proceso”.

    SDD es una metodología de tres artefactos que define qué construyes, cómo lo construyes y en qué orden lo construyes — antes de que un solo agente escriba una sola línea de código.

    Los tres artefactos son:

    spec.md — el qué. La especificación estructurada del sistema. Tiene seis secciones fijas: Visión, Usuarios, Funcionalidades, Flujos, Arquitectura, NFRs. En total, tres o cuatro páginas que responden a la pregunta que ningún agente puede responder por ti: qué problema resuelves exactamente, para quién, y qué significa “hecho” en este proyecto.

    plan.md — el cómo. El plan técnico por fases. No divide el trabajo en tareas sueltas — divide el trabajo en capas que tienen sentido en secuencia. Primero el dominio, después la infraestructura, después la UI. No al revés. El plan.md es el documento que evita que empieces por la pantalla de login cuando el sistema de autenticación aún no existe.

    tasks.md — el orden. La lista de tareas ordenada para TDD. Cada tarea define qué test escribes primero y qué código lo hace pasar. El tasks.md convierte el plan en commits atómicos verificables. Cuando un agente ejecuta una tarea del tasks.md, el resultado es predecible: un test verde y un incremento de funcionalidad real.

    Estos tres documentos no tardan tres días en escribirse. Con el skill /dominicode-sdd-spec-creator en Claude Code (disponible para miembros de Dominicode Labs), la estructura completa se genera en minutos a partir de una descripción del proyecto. Lo que tarda tiempo es pensar — y ese tiempo es exactamente el que te ahorra deuda técnica después.


    Antes vs después: el mismo proyecto, dos formas de empezar

    Hace unos meses construí un sistema de gestión de contenido para automatizar la publicación en múltiples canales. El proyecto tenía integraciones con tres APIs externas, lógica de colas, transformaciones de formato y un dashboard de seguimiento.

    Sin SDD (como lo hubiera hecho en 2022): Habría abierto el editor, creado una carpeta src/, y empezado por la parte que más me apetecía — probablemente el dashboard. A las dos semanas tendría un dashboard bonito conectado a datos hardcodeados, una integración con una API que funcionaba en happy path, y ninguna certeza de cómo conectar las piezas. Cada decisión técnica habría sido local, sin visión del sistema completo.

    Con SDD: Antes de escribir código, escribí el spec.md. La sección de Flujos me forzó a pensar en qué pasa cuando una API falla en mitad de una publicación — algo que no habría considerado hasta toparme con el bug en producción. La sección de NFRs me hizo definir qué latencia máxima era aceptable para el sistema de colas. La sección de Arquitectura me hizo elegir entre evento-driven y polling antes de escribir nada — no a mitad del proyecto cuando cambiar de dirección cuesta semanas.

    El spec.md tardó dos horas. El plan.md, una hora más. El tasks.md, otra hora.

    Cuatro horas de especificación que eliminaron tres semanas de refactoring posterior.

    Cuando empecé a usar Claude Code en el proyecto, el agente tenía el spec.md en el contexto. Cada decisión técnica que tomaba era coherente con la arquitectura definida. No porque el LLM sea mágicamente más inteligente con un documento — sino porque el documento le daba información que de otra forma no tenía.


    El spec como brújula del agente

    Este es el cambio de mentalidad que más cuesta hacer: el spec no es para ti. Es para el agente.

    Cuando llevas quince años programando, tu cabeza tiene el contexto del proyecto. Sabes por qué elegiste ese patrón. Sabes qué módulo toca qué. Sabes los trade-offs que hiciste en la semana dos. Ese contexto vive en tu cabeza y lo das por supuesto.

    El agente no tiene nada de eso. Sin contexto explícito, cada sesión empieza desde cero. Cada prompt es una petición descontextualizada si no le das el marco. Sin spec, el agente responde a lo que le preguntas — no a lo que necesitas construir.

    Con el spec.md en contexto, el agente puede hacer preguntas que de otra forma no haría: “esta funcionalidad que me pides entra en conflicto con el flujo de usuario número tres que está en el spec — ¿quieres cambiar el flujo o ajustar la funcionalidad?”. Esa pregunta vale más que mil líneas de código generado sin contexto.

    Esta es exactamente la lógica detrás del libro Spec-Driven Development — no es un manual de documentación, es una metodología diseñada para que el agente tenga suficiente contexto para tomar decisiones correctas sin que tú estés micromanageando cada prompt.


    Por qué el spec te protege del vibe coding

    El vibe coding no es programar con IA. Es programar con IA sin criterio. Hay developers que publican proyectos enteros generados en un fin de semana. Impresionante en superficie. Inutilizable en producción.

    El problema del vibe coding no es la velocidad — es la ausencia de coherencia acumulada. Cada prompt genera código coherente con el prompt anterior, pero nadie garantiza que el sistema resultante sea coherente con la intención original. A las cuatro horas de vibe coding, el proyecto tiene forma de algo pero no tiene diseño. Tiene features pero no tiene arquitectura.

    Lo que se acumula en silencio no es código malo — es deuda técnica agéntica. El tipo de deuda que no se ve en los tests porque los tests también los generó el agente sin un contrato claro de qué probar. El tipo de deuda que explota cuando intentas añadir la feature número veinte sobre una base que asumió implícitamente cosas que nunca se definieron.

    Para entender por qué la arquitectura de tus agentes necesita un spec detrás, te recomiendo el post sobre agentic harness: por qué la spec y la arquitectura no bastan.

    SDD es el antídoto no porque ralentice el desarrollo. Lo acelera — pero acelera el desarrollo en la dirección correcta. La spec es el contrato que el agente respeta en cada iteración. El plan es la secuencia que evita que construyas la décima planta antes de los cimientos. El tasks.md son los commits que puedes revisar, aprobar y revertir si algo no cuadra.

    Con SDD, el vibe coding se convierte en agile coding con contexto — velocidad de agente, criterio de arquitecto.


    Cómo empezar con SDD en Claude Code hoy

    Si tienes Claude Code y quieres aplicar SDD en tu próximo proyecto, el proceso es directo:

    1. Describe tu proyecto en lenguaje natural — qué construyes, para quién, qué problema resuelve.
    2. Ejecuta el skill /dominicode-sdd-creator — genera spec.md, plan.md y tasks.md en pocos minutos (disponible en Dominicode Labs).
    3. Revisa el spec antes de tocar código — es el momento de pensar, no después.
    4. Añade el spec.md al contexto de Claude Code con @spec.md al inicio de cada sesión de desarrollo — la documentación oficial de Claude Code explica cómo gestionar el contexto entre sesiones.
    5. Trabaja el tasks.md en secuencia — un task, un test, un commit.

    El skill no reemplaza tu pensamiento. Te obliga a pensar antes de que sea costoso cambiar de dirección.

    El post sobre SDD Creator, la herramienta CLI muestra exactamente cómo se genera la estructura automáticamente.

    Si quieres ver cómo se aplica esto en un proyecto real de principio a fin — desde la spec inicial hasta el deploy — es exactamente lo que trabajamos en el curso Construye con IA: no tutoriales sueltos de herramientas, sino el proceso completo de construir un producto con IA de forma que funcione en producción.


    El spec como ventaja competitiva real

    Hay algo que nadie dice sobre SDD en 2026 y que merece decirse.

    En un mundo donde cualquier developer puede generar código a gran velocidad con IA, la diferencia competitiva no está en quién genera más rápido. Está en quién sabe exactamente qué construir y por qué.

    El spec es donde vive esa ventaja. No en el prompt. No en la elección del modelo. En la claridad con la que defines el problema antes de que empiece la ejecución.

    Los developers que entienden esto ya no compiten con los que “usan IA para programar más rápido”. Son una categoría diferente: developers que combinan criterio técnico con capacidad de ejecución agéntica. El spec es la expresión concreta de ese criterio.

    Dentro de doce meses, los equipos que hayan integrado SDD en su workflow tendrán bases de código mantenibles, documentación generada como efecto colateral del proceso, y la capacidad de incorporar nuevos agentes o nuevos developers sin que el proyecto colapse. Los que sigan con vibe coding habrán reescrito el proyecto tres veces.


    FAQ

    ¿SDD no es simplemente documentación con otro nombre?

    No. La documentación describe lo que existe. El spec define lo que va a existir — antes de que exista. La diferencia no es semántica: la documentación se escribe después y siempre está desactualizada. El spec se escribe antes y guía la implementación. Si el spec y el código divergen durante el desarrollo, es señal de que hay una decisión técnica que tomar conscientemente — no de que el documento esté equivocado.

    ¿Cuánto tiempo tarda escribir el spec de un proyecto real?

    Depende del proyecto. Para un MVP de funcionalidad acotada, entre dos y cuatro horas. Para un sistema con múltiples integraciones y flujos complejos, un día. El punto de referencia útil: si el spec tarda más de un día en escribirse, es señal de que el proyecto no está suficientemente definido para empezar a construirlo — y ese es el momento exacto en que el spec te está salvando, no ralentizando.

    ¿Se puede aplicar SDD a proyectos que ya existen?

    Sí, pero el proceso es diferente. En proyectos existentes, el spec se usa para nuevas features o para refactorizaciones significativas. El ejercicio de escribir el spec de un módulo existente es también un audit implícito: si no puedes escribir el spec del módulo, es porque el módulo no tiene diseño coherente. El spec revela la deuda técnica que el código oculta.

    ¿SDD funciona con cualquier agente de IA o solo con Claude Code?

    La metodología es agnóstica al agente. Spec.md, plan.md y tasks.md son documentos markdown que cualquier LLM puede usar como contexto. El skill /dominicode-sdd-spec-creator está diseñado para Claude Code y disponible en Dominicode Labs, pero los artefactos que genera son compatibles con cualquier entorno. Lo importante no es la herramienta — es el hábito de definir antes de ejecutar.

    ¿Qué pasa cuando el spec cambia durante el desarrollo? ¿No es todo ese trabajo en vano?

    El spec cambia. Siempre cambia. Y eso es una funcionalidad, no un fallo. Cuando el spec cambia, tienes un documento que actualizar — y esa actualización fuerza una decisión consciente sobre el impacto del cambio en la arquitectura, los flujos y las tareas pendientes. Sin spec, el cambio ocurre de forma invisible: alguien pide algo diferente, el agente lo implementa, y nadie sabe qué asunciones antiguas quedan rotas. Con spec, el cambio es visible y gestionable.

    ¿Es SDD compatible con metodologías ágiles?

    Completamente. SDD no impone un ciclo de desarrollo — impone un hábito de especificación antes de ejecución. Dentro de un sprint de dos semanas, el spec de las features del sprint se escribe al inicio. El plan.md define el orden de implementación dentro del sprint. El tasks.md genera los tickets concretos. SDD convierte el backlog en artefactos ejecutables para agentes, no en listas de deseos sin criterio técnico.


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

  • Claude Code: Effort, Models, Tools y Context para developers

    Claude Code: Effort, Models, Tools y Context para developers

    La primera vez que abrí Claude Code, lo traté como un chat más inteligente. Le pegaba código, le pedía que lo arreglara, copiaba la respuesta. Funcionaba, pero lo estaba usando como una versión cara de Stack Overflow.

    Tardé tres semanas en entender que Claude Code no es un chatbot. Es un agente que ejecuta herramientas reales en tu sistema, que puede leer tu repositorio entero, que tiene niveles de razonamiento configurables y que toma decisiones en cadena sin que tú intervengas en cada paso.

    Cuando lo entendí así, cambió todo.

    Este post es lo que me hubiera gustado leer antes de empezar. No es un tutorial de instalación — asume que ya lo tienes corriendo. Es una explicación honesta de los cuatro conceptos que determinan si Claude Code trabaja para ti o contra ti: Effort, Models, Tools y Context.


    Effort — el nivel de razonamiento que decides gastar

    Cuando Claude Code procesa una tarea, no siempre piensa igual de profundo. Puedes configurar cuánto razonamiento aplica desde la UI de Claude Code o mediante la opción de esfuerzo en la configuración. Los niveles son cuatro: low, medium, high y max.

    Esto no es marketing. Es la diferencia entre gastar dos segundos y gastar dos minutos en una misma pregunta, con respuestas radicalmente distintas.

    Low — cuando la velocidad importa más que la precisión

    Con low, Claude Code responde rápido y sin profundizar demasiado. Es útil para tareas mecánicas y predecibles: renombrar variables, formatear código, generar boilerplate que ya tienes en mente pero no quieres teclear.

    Si le pides "añade un método toString() a esta clase", no necesita razonar sobre arquitectura. low es suficiente.

    Medium — el nivel por defecto para trabajo diario

    medium es lo que usas el 80% del tiempo. Hay razonamiento real, considera contexto, pero no entra en análisis profundo de consecuencias. Funciona bien para refactoring moderado, explicaciones técnicas, generación de tests unitarios para funciones simples.

    Es el equilibrio entre velocidad y calidad que necesitas en un flujo de trabajo normal.

    High — cuando el error cuesta caro

    Aquí Claude Code empieza a razonar sobre consecuencias. Evalúa múltiples opciones antes de decidir, considera casos borde, analiza impacto en el resto del sistema.

    Úsalo cuando toques código crítico: un servicio de autenticación, la lógica de pagos, una migración de base de datos, un cambio arquitectural en el core de la aplicación. El tiempo extra que tarda se justifica con la reducción de errores no detectados.

    Max — análisis exhaustivo, sin atajos

    max activa el razonamiento más profundo disponible. Claude Code descompone el problema en partes, considera múltiples estrategias, evalúa trade-offs explícitamente.

    Esto no es para trabajo diario. Es para cuando necesitas que te ayude a diseñar la arquitectura de un módulo nuevo, cuando tienes un bug imposible de reproducir que llevas días persiguiendo, o cuando vas a tomar una decisión técnica con consecuencias a largo plazo.

    El coste es tiempo y tokens. La ganancia es profundidad real.

    Regla práctica: empieza con medium. Si la respuesta no llega al nivel que necesitas, sube un nivel. No uses max por defecto — no tiene sentido pagar el coste de razonamiento exhaustivo para añadir un campo en un formulario.


    Models — cuál elegir y por qué importa

    Claude Code tiene acceso a varios modelos bajo el capó. No todos son iguales en velocidad, coste ni capacidad. Elegir mal aquí es tirar dinero o tirar tiempo.

    A junio de 2026, los modelos disponibles en Claude Code son:

    Claude Haiku 4.5 — velocidad máxima, coste mínimo

    Haiku es el modelo pequeño. Responde en segundos, cuesta muy poco por token, y es más que suficiente para tareas de bajo peso cognitivo: completar líneas de código, responder preguntas de documentación, generar snippets concretos que ya tienes pensados.

    En un workflow agentic donde Claude Code ejecuta decenas de llamadas encadenadas (leer archivos, buscar patrones, escribir logs), Haiku hace el trabajo de las subtareas sin disparar el coste.

    Claude Sonnet 4.6 — el modelo de trabajo diario

    Sonnet es el punto dulce. Más capaz que Haiku en razonamiento y contexto largo, más rápido y barato que Opus, suficientemente potente para el 90% de las tareas de un developer.

    Refactoring complejo, generación de tests con lógica no trivial, debugging asistido, implementación de features completas — Sonnet lo maneja bien. Si no sabes cuál usar, empieza aquí.

    Claude Opus 4.8 — para problemas difíciles

    Opus es el modelo grande. Más lento, más caro, y considerablemente más capaz cuando el problema requiere razonamiento profundo, comprensión de contexto muy largo o análisis de consecuencias en sistemas complejos.

    No lo uses para tareas rutinarias. Sí lo uses cuando estés diseñando una arquitectura nueva, cuando el problema tiene múltiples dependencias que hay que razonar en paralelo, o cuando los outputs de Sonnet no son suficientemente precisos para tu caso.

    Claude Fable 5 — el modelo más potente

    Fable es el frontier model de Anthropic. Capacidades extendidas de razonamiento, mejor manejo de contexto muy largo y mayor precisión en tareas de alta complejidad. En Claude Code aparece como opción para las tareas más exigentes.

    Úsalo con criterio: el coste es significativamente mayor. Tiene sentido cuando diseñas sistemas críticos, cuando necesitas que el modelo razone sobre un codebase completo de miles de archivos, o cuando el nivel de precisión que necesitas no lo alcanza Opus.

    La decisión práctica: para trabajo diario usa Sonnet. Para subtareas rápidas y repetitivas dentro de un agente, Haiku. Para decisiones técnicas importantes o problemas difíciles, Opus o Fable. El modelo correcto no es el más potente — es el que resuelve el problema con el menor coste posible.


    Tools — las herramientas built-in que hacen a Claude Code un agente real

    Aquí está la diferencia fundamental entre Claude Code y un chatbot: Claude Code tiene herramientas que ejecuta de verdad en tu sistema. No simula leer archivos — los lee. No describe cómo haría una búsqueda — la hace.

    Estas son las herramientas principales y para qué sirve cada una:

    Herramienta Qué hace
    Read Lee el contenido de un archivo del filesystem. Claude ve exactamente lo que hay en el archivo, con números de línea.
    Edit Modifica un fragmento concreto de un archivo existente. Solo envía el diff, no reescribe todo el archivo.
    Write Crea un archivo nuevo o sobreescribe uno completo. Más costoso que Edit — úsalo solo cuando el cambio afecta a todo el archivo.
    Bash Ejecuta comandos de shell reales en tu sistema. Tests, builds, git, scripts, cualquier cosa que harías en terminal.
    Glob Busca archivos por patrón (**/*.ts, src/**/*.spec.ts). Útil para que Claude Code entienda la estructura del proyecto antes de actuar.
    Grep Busca contenido dentro de archivos por expresión regular. Para localizar dónde se usa una función, qué archivos importan un módulo, qué tests cubren una clase.
    WebSearch Hace búsquedas web reales. Útil cuando necesita documentación actualizada, información sobre versiones recientes o validar datos externos.
    WebFetch Descarga y procesa el contenido de una URL concreta. Para leer documentación oficial, specs de una API, changelog de una librería.
    Agent Lanza un subagente — una instancia paralela de Claude Code que ejecuta una subtarea de forma independiente. Arquitectura agentic en acción.
    TodoRead / TodoWrite Gestiona una lista de tareas interna de la sesión. Claude Code se auto-organiza las tareas que tiene pendientes en una tarea compleja.

    Lo que hace potente a este conjunto no es ninguna herramienta por sí sola — es la combinación. Claude Code lee la estructura del proyecto con Glob, localiza el código relevante con Grep, lo lee con Read, lo modifica con Edit, y ejecuta los tests con Bash. Todo en secuencia, sin que tú intervengas en cada paso.

    Este es el flujo que hace que una instrucción como "refactoriza el módulo de autenticación para que use el nuevo interceptor HTTP" produzca cambios reales en diez archivos distintos, con los tests pasando al final.

    La referencia completa de todas las herramientas y sus parámetros está en la documentación oficial de Claude Code.

    Si quieres ver cómo encajan estas herramientas con el resto del stack IA, en Stack IA agéntica en 2026: qué usar, qué ignorar y cuál elijo analizo exactamente eso.

    Si te interesa construir workflows agenticos más avanzados con Claude Code — desde la idea hasta un producto deployado — el curso Construye con IA: De la Idea al Producto con Claude y Specs cubre exactamente eso: cómo orquestar estas herramientas para que Claude Code trabaje con autonomía real.


    Context — cómo sabe Claude Code dónde está y qué importa

    El contexto es el factor más subestimado de Claude Code. Puedes tener el modelo correcto, el nivel de esfuerzo correcto y todas las herramientas disponibles — si Claude Code no entiende el contexto de tu proyecto, los outputs serán genéricos.

    @files y @folders — lo que le pones delante

    En la interfaz de Claude Code puedes mencionar archivos o carpetas con @. Cuando escribes @src/app/auth/auth.service.ts, Claude Code lee ese archivo y lo incluye directamente en el contexto de la conversación antes de procesar tu instrucción.

    Con @src/app/auth/ incluyes toda la carpeta. Claude Code procesa los archivos relevantes y construye una comprensión del módulo antes de actuar.

    Esto no es solo "adjuntar archivos". Es darle a Claude Code el mapa del territorio antes de pedirle que navegue.

    @url — documentación externa en tiempo real

    @url le permite a Claude Code leer el contenido de una URL y usarlo como contexto. Si necesitas que siga la documentación oficial de Angular v22 antes de modificar tu código de routing, puedes darle la URL del changelog y él la procesa.

    Esto elimina el problema clásico de los LLMs con conocimiento desactualizado. Si la librería sacó una versión nueva hace dos semanas, puedes darle la fuente actualizada directamente.

    CLAUDE.md — la memoria persistente del proyecto

    El archivo CLAUDE.md en la raíz de tu proyecto es la forma de darle a Claude Code instrucciones permanentes que se cargan en cada sesión.

    Aquí defines las convenciones del proyecto: cómo nombrar archivos, qué patrones arquitecturales seguís, qué comandos son los válidos, qué herramientas externas usáis, qué NO debe tocar sin confirmación explícita. Un CLAUDE.md bien escrito hace que Claude Code se comporte como un developer que conoce las reglas del equipo desde el primer día.

    No es opcional. Es la diferencia entre un agente que trabaja contigo y uno que trabaja en paralelo a ti sin coordinación.

    Memoria entre sesiones

    Por defecto, cada sesión de Claude Code empieza sin memoria de conversaciones anteriores. El contexto no persiste automáticamente.

    La forma correcta de manejar esto es el CLAUDE.md: las decisiones técnicas importantes, las convenciones acordadas, las restricciones del proyecto — todo lo que necesita persistir va ahí. No en el historial de conversación.

    Para proyectos más complejos, puedes estructurar archivos adicionales de contexto (specs, planes, documentos de arquitectura) y referenciarlos con @ al inicio de cada sesión. Es un flujo de trabajo, no una feature automática.

    En Dominicode Labs tenemos proyectos reales donde aplicamos exactamente esta estructura — con los archivos de contexto organizados para que Claude Code mantenga coherencia a lo largo de semanas de desarrollo.


    Cuatro hábitos para usar Claude Code como un agente real

    Claude Code no es difícil. Pero usarlo bien requiere entender que no es un chatbot avanzado — es un agente con herramientas reales, niveles de razonamiento configurables, múltiples modelos con características distintas, y un sistema de contexto que tú controlas.

    Elegir el modelo correcto para cada tarea, configurar el esfuerzo según lo que está en juego, dejar que las tools hagan el trabajo sin microgestionar cada paso, y mantener un CLAUDE.md que le dé continuidad al proyecto — esos cuatro hábitos son la diferencia entre usarlo como un buscador caro y usarlo como un colaborador técnico real.

    El siguiente paso es construir algo con él. No un script de prueba — un flujo de trabajo real donde Claude Code gestione decisiones en cadena. Si quieres ver ese proceso desde el principio, el curso Construye con IA: De la Idea al Producto con Claude y Specs parte exactamente de aquí.


    FAQ — Preguntas frecuentes sobre Claude Code

    ¿Claude Code funciona con cualquier lenguaje de programación?

    Sí. Claude Code no está limitado a ningún stack. Funciona igual con TypeScript, Python, Go, Rust, Java o cualquier lenguaje que puedas ejecutar desde terminal. Las herramientas como Bash, Glob y Grep operan sobre el filesystem, no sobre el lenguaje. Lo que sí varía es la calidad del output según el lenguaje — para TypeScript y Python la precisión es especialmente alta porque son los lenguajes más representados en el entrenamiento.

    ¿Cuál es la diferencia real entre Sonnet y Opus para trabajo diario?

    En la práctica, para el 90% de las tareas cotidianas no notarás diferencia en calidad. Sí notarás diferencia en velocidad y coste. Opus tarda más y consume más tokens. La diferencia se hace evidente en problemas complejos con mucho contexto: cuando le das un módulo de 3.000 líneas y le pides que entienda las dependencias implícitas antes de refactorizar, Opus razona más profundo. Para añadir un endpoint nuevo a una API que ya funciona, Sonnet es suficiente.

    ¿Cómo evito que Claude Code modifique archivos que no debe tocar?

    Con el CLAUDE.md. Puedes definir explícitamente qué archivos o carpetas son de solo lectura, qué operaciones requieren confirmación explícita tuya antes de ejecutarse, y qué convenciones debe respetar siempre. Claude Code en modo interactivo ya solicita confirmación antes de ejecutar operaciones destructivas — y con autoApproveEdits: false en tu settings.json puedes reforzar ese control para cualquier edición de archivos.

    ¿Claude Code puede trabajar en proyectos con múltiples repositorios?

    Sí, pero con matices. Claude Code opera desde el directorio donde lo lanzas y puede leer rutas relativas o absolutas fuera de él si tienes los permisos correctos. Para proyectos monorepo o arquitecturas con múltiples repos relacionados, la práctica recomendada es lanzarlo desde la raíz del monorepo y gestionar el contexto con @carpetas específicas para cada subtarea. Si trabajas con Angular en un monorepo, el curso de Angular Moderno cubre la estructura de proyectos que mejor se integra con flujos agenticos.

    ¿Cuánto contexto puede manejar Claude Code en una sesión?

    Depende del modelo. Los modelos actuales de Claude tienen ventanas de contexto de 200.000 tokens, lo que equivale a varios cientos de miles de líneas de código. En la práctica, el límite operativo es antes: a partir de cierto volumen, la calidad del razonamiento empieza a degradarse aunque técnicamente quepa más. La buena práctica es ser selectivo con el contexto que cargas — usar @ para incluir solo los archivos relevantes para la tarea actual, no volcar el repositorio entero en cada sesión.


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

  • El Harness: por qué la spec y la arquitectura no son suficientes

    El Harness: por qué la spec y la arquitectura no son suficientes

    Mi workflow completo: de idea a producto en producción con IA

    Hace un año tardaba 2-3 semanas en tener algo desplegado desde una idea nueva.

    Hoy tardo 2-3 días.

    No porque use mejores modelos. Porque cambié el workflow.

    Acá está el proceso completo, sin omitir nada.


    Fase 1 — Captura (30 minutos)

    Antes de abrir el editor, abro un documento en blanco y respondo tres preguntas:

    1. ¿Qué problema concreto resuelve esto?
    2. ¿Quién lo va a usar y en qué contexto exacto?
    3. ¿Qué tiene que funcionar sí o sí para que sea útil desde el día uno?

    Solo eso. Sin pensar en tech stack. Sin pensar en arquitectura.

    Si no puedo responder las tres en 30 minutos, la idea no está lista para construirse.


    Fase 2 — Spec (1-2 horas)

    Con las respuestas anteriores, genero la spec técnica.

    La spec tiene 6 secciones: Visión, Usuarios, Funcionalidades, Flujos, Arquitectura y NFRs.

    No la escribo yo desde cero. La genero con un agente que toma mis respuestas de la Fase 1 como input.

    Luego la reviso y ajusto lo que el agente asumió mal.

    El output: un documento de 2-3 páginas que define qué se construye, para quién, y cómo debe comportarse.


    Fase 3 — Plan técnico (30 minutos)

    Con la spec lista, otro agente genera el plan de implementación.

    No “empieza a codear”. Define:

    • Las fases del proyecto en orden
    • Qué necesita estar listo antes de cada fase
    • Los riesgos técnicos por módulo

    Reviso el plan. Lo ajusto si algo no tiene sentido. Firma.


    Fase 4 — Implementación (el grueso)

    Aquí entra Claude Code.

    No le doy el prompt “hazme la app”. Le doy la spec + el plan + el task específico a implementar en esa sesión.

    Un task. Una sesión. Un output verificable.

    Si el task es “implementar autenticación con GitHub OAuth”, eso es todo lo que hace esa sesión.

    Al final de cada sesión, verifico que lo que se construyó cumple el criterio de aceptación de la spec.

    Si no lo cumple, corrijo antes de avanzar. No acumulo deuda de contexto.


    Fase 5 — Deploy y validación (1-2 horas)

    Deploy con el stack que use el proyecto (Railway, Vercel, Supabase).

    Luego muestro el producto a 2-3 personas del perfil objetivo y les hago una sola pregunta:

    “¿Qué haría que esto fuera indispensable para ti?”

    No “¿te gusta?” ni “¿qué mejorarías?”.

    Esa pregunta específica te da el siguiente ciclo de iteración o te dice que pivotes.


    Lo que hace que este workflow funcione no es la IA.

    Es que la IA nunca opera sin contexto estructurado.

    Cada agente recibe exactamente lo que necesita para hacer su parte. Nada más. Nada menos.

    Sin eso, la IA improvisa. Y cuando improvisa, construye lo que interpreta, no lo que necesitas.


    Si quieres ver este workflow ejecutado en vivo sobre un proyecto real — Stripe webhook receiver + Supabase, desde la spec hasta el deploy — eso es exactamente lo que hacemos el 9 de julio.

    workshop.dominicode.com

  • Crear productos con IA para vender: guía práctica para developers

    Crear productos con IA para vender: guía práctica para developers

    Hace año y medio lancé mi primer producto digital serio. No fue un curso de seis meses de producción. Fue un libro técnico que tardé tres semanas en escribir, validar y subir a Leanpub.

    La primera semana vendió doce copias. Sin ads. Sin lanzamiento masivo. Solo con un post en LinkedIn y un email a mi lista de 800 personas.

    No lo digo para presumir. Lo digo porque ese resultado me demostró algo que hasta entonces no tenía claro: crear productos con IA para vender no requiere un equipo, ni un presupuesto, ni meses de desarrollo. Requiere entender qué problema específico tienes resuelto y qué formato hace que alguien te pague por esa solución hoy.

    El developer que entiende esto en 2026 tiene una ventaja enorme. El que sigue esperando tener "el producto perfecto" antes de vender, va a seguir esperando.

    Crear productos con IA para vender significa usar modelos de lenguaje y herramientas de IA generativa para reducir el tiempo de construcción de productos digitales —libros técnicos, SaaS micro o automatizaciones— de meses a días, sin necesitar un equipo de desarrollo. No es magia: es el mismo ciclo de producto de siempre, comprimido por tecnología.


    El error que comete el 90% de los developers

    El patrón lo he visto muchas veces — en mi comunidad de Labs, en comentarios de YouTube, en DMs. Un developer con 8 o 10 años de experiencia pasa tres meses construyendo una herramienta. Le pone un nombre, le hace un landing, le añade autenticación, le conecta Stripe.

    Lanza. Cero ventas.

    El problema no fue la ejecución técnica. Fue que nunca validó si alguien quería pagar por eso. Construyó la herramienta antes de confirmar que existía un comprador.

    Esto pasa porque los developers somos buenos construyendo y malos vendiendo. Confundimos el placer de construir con la señal de que hay un mercado. No es lo mismo.

    La IA amplifica este error. Ahora puedes construir en días lo que antes tardabas meses. Eso es una ventaja brutal — pero también es una trampa si no cambias el orden de operaciones. Y antes de la herramienta, está la mentalidad: si te interesa entender qué habilidades definen al developer en la era de la IA, tengo un post donde lo desarrollo en detalle.

    Primero el comprador. Después el producto.


    Los 3 tipos de productos que puedes crear con IA para vender

    No todos los productos digitales son iguales. Hay tres categorías con dinámicas muy distintas. Cada una encaja mejor con un momento distinto de tu carrera como creator.

    1. Productos de información

    Son los más rápidos de crear y los más fáciles de validar: cursos, libros técnicos, guías, workshops.

    La IA te permite crear el primer borrador de un libro en un fin de semana. No el libro terminado — el borrador estructurado que tú refinas con tu experiencia real. Esa diferencia es importante: el valor no está en el texto que genera la IA, sino en el criterio técnico que aportas tú.

    Un libro técnico de 50 páginas a 9,99€ puede venderse a 200 personas en su primer mes si ataca un problema muy específico. Son 2.000€ sin mantenimiento, sin soporte técnico, sin servidor.

    Yo uso este formato para probar ideas antes de invertir más tiempo. El libro de Spec-Driven Development nació así: un problema concreto que resuelvo en mi trabajo diario, empaquetado en un formato que alguien puede leer en una tarde.

    2. SaaS micro

    Una herramienta que resuelve un problema específico para un segmento específico. No necesitas construir el próximo Notion. Necesitas construir la herramienta que los diseñadores de tu nicho usan cada semana y que aún no existe — o existe pero con una UX terrible.

    La IA reduce drásticamente el tiempo de desarrollo. Con Claude Code puedo ir de especificación a MVP funcional en menos de dos días. No estoy exagerando. Ese es exactamente el flujo que enseño en el curso Construye con IA: De la Idea al Producto con Claude.

    Pero el SaaS micro solo funciona si tienes una audiencia o un canal para llegar al comprador. Sin distribución, el mejor producto del mundo no vende. Por eso no recomiendo empezar aquí si estás construyendo tu primera fuente de ingresos con productos digitales.

    3. Automatizaciones y sistemas de IA

    Este es el más subestimado y el que crece más rápido en 2025-2026. Empresas pequeñas y medianas pagan entre 500€ y 5.000€ por automatizaciones que les resuelven procesos concretos: desde 500€ para flujos simples de clasificación o notificaciones, hasta 3.000-5.000€ para sistemas con múltiples integraciones o lógica de agente compleja (clasificar emails, procesar facturas, responder soporte con contexto).

    No lo venden como "IA". Lo venden como "te ahorro X horas a la semana en Y tarea".

    Un developer que sabe construir agentes con n8n o con la API de Claude puede empaquetar estas soluciones como producto repetible. Construyes una vez, vendes a varios clientes del mismo sector. Eso es escalabilidad real sin SaaS.


    El orden correcto para crear productos con IA para vender

    Si te saltas este orden, estás desperdiciando tiempo — aunque uses IA.

    1. Identifica el problema con dinero — No "qué puedo construir" sino "qué problema le duele suficiente a alguien como para pagar". La diferencia entre un problema interesante y un problema con dinero es que el segundo tiene consecuencias reales si no se resuelve: tiempo perdido, ingresos perdidos, errores en producción. Pregunta concreta que funciona: ¿en qué tarea has tardado días que otros developers también tardan días? Eso es un producto.

    2. Valida antes de construir — Para productos de información: escribe un post largo sobre el tema, publica un hilo en LinkedIn, mira si hay engagement real. Si nadie pregunta nada, no hay audiencia. Para SaaS micro: busca si hay alternativas de pago. Si existen, hay mercado. Si no existen, puede ser porque no hay mercado — no porque tú hayas encontrado un hueco.

    3. Construye el mínimo vendible, no el mínimo viable — Un MVP técnico no es lo mismo que un producto vendible. El producto vendible tiene un resultado claro para el comprador, un precio, y una forma de pagar. El resto es iteración.

    4. Distribuye antes de lanzar — El lanzamiento no es el día uno de ventas. Es la culminación de semanas de contenido que preparan al comprador. Si nadie sabe que existe tu producto el día que lo publicas, no importa lo bueno que sea.


    La ventaja real del developer que usa IA

    No es velocidad. Es iteración sin miedo.

    Antes, si una idea de producto fallaba, perdías semanas o meses. Ahora, si una idea falla, has perdido dos días. Esa diferencia cambia completamente la ecuación de riesgo.

    Puedo probar tres ideas de producto en el tiempo que antes tardaba en construir una. Y cuando una funciona — cuando alguien paga antes de que esté terminada — sé exactamente dónde poner la energía.

    Esta es la mentalidad del developer product builder: construir rápido, aprender rápido, no enamorarse de la implementación.

    La IA no te convierte en emprendedor. Pero si ya tienes la mentalidad de resolver problemas reales, la IA elimina la mayoría de los cuellos de botella técnicos que antes te frenaban.


    Un ejemplo concreto: cómo nació Markfolio

    Markfolio es una SaaS que construí para transformar ideas y artículos en libros listos para publicar en Amazon KDP. Nació de un problema mío: el proceso de dar formato a un libro para KDP es tedioso, repetitivo y propenso a errores.

    Antes de escribir una línea de código, hablé con cinco personas que publican libros técnicos. Todas tenían el mismo dolor. Eso fue suficiente señal.

    Construí el MVP en cuatro días usando Claude Code como par de programación. No cuatro días de jornada completa — cuatro días trabajando en bloques de dos horas mientras seguía con mis otros proyectos.

    Está en producción, pero no es mi foco principal ahora mismo. Y eso está bien: me ha enseñado más sobre product building en dos meses que cualquier curso de startups.

    Ese es el punto: la IA te da acceso a iterar a velocidad de startups sin el presupuesto de una startup.


    Lo que la IA no puede hacer por ti

    Esto es importante decirlo sin filtros.

    La IA no valida el mercado. Tú tienes que hablar con compradores reales.

    La IA no distribuye tu producto. Tú necesitas una audiencia o un canal.

    La IA no te da criterio sobre qué construir. Ese criterio viene de años entendiendo problemas técnicos reales.

    Por eso este tema no es para developers que llevan seis meses programando. Es para developers que tienen experiencia acumulada y no saben cómo convertirla en algo que genere ingresos fuera de una nómina.

    Si llevas años resolviendo los mismos problemas en empresas, ya tienes el activo más valioso para crear productos. Solo te falta el sistema para empaquetarlo y venderlo.


    Por dónde empezar esta semana

    No mañana. Esta semana.

    Abre un documento en blanco y responde estas tres preguntas:

    1. ¿Qué problema técnico específico he resuelto en los últimos 12 meses que otros developers también tienen?
    2. ¿Hay alguien que pagaría por resolver ese problema más rápido?
    3. ¿Cuál es el formato mínimo que me permitiría vender eso esta semana — un libro, una plantilla, una consultoría, un servicio?

    Si tienes respuestas claras a las tres, tienes un producto.

    Si quieres el sistema completo — desde la especificación hasta el producto publicado usando IA — eso es exactamente lo que construimos en Dominicode Labs: proyectos reales, metodología Spec-Driven, y una comunidad de developers que están haciendo exactamente esto.


    FAQ — Preguntas frecuentes

    ¿Necesito saber programar para crear productos con IA para vender?

    Depende del tipo de producto. Para libros, cursos y guías técnicas, no necesitas código — necesitas criterio. Para SaaS y automatizaciones, tu experiencia como developer es una ventaja directa. La IA reduce la cantidad de código que tienes que escribir, pero no elimina la necesidad de entender la arquitectura del sistema que estás construyendo.

    ¿Cuánto tiempo se tarda en crear un producto vendible con IA?

    Para un libro técnico de 40-60 páginas: entre 1 y 3 semanas si tienes claridad sobre el tema. Para un SaaS micro con funcionalidad básica: entre 3 y 10 días dependiendo de la complejidad. La IA acelera la ejecución, pero la validación del mercado y la distribución toman su propio tiempo — y no se pueden saltear.

    ¿Qué herramientas de IA se usan para construir productos?

    Las más relevantes en 2026 para developers: Claude Code para desarrollo y arquitectura, n8n para automatizaciones, Cursor como IDE con IA integrada, y la API de Anthropic para productos que necesitan razonamiento avanzado. El stack varía según el tipo de producto — tengo un análisis del stack IA agéntico de 2026 donde comparo opciones y cuándo usar cada una. Lo importante es no acumular herramientas antes de tener claridad sobre qué estás construyendo.

    ¿Cómo valido si mi idea de producto tiene mercado antes de construirla?

    Tres señales concretas: alguien ya paga por algo similar (hay mercado), el problema aparece repetidamente en foros, comunidades o Stack Overflow (hay dolor real), o alguien te ha pedido ayuda con ese problema específico en los últimos seis meses (hay demanda activa). Si no encuentras ninguna de las tres, el problema puede ser interesante pero no tiene mercado suficiente.

    ¿Puedo vender un producto construido con IA sin que "se note"?

    Mal planteada, esa pregunta lleva al producto equivocado. La IA es una herramienta de construcción, como lo es un framework o un lenguaje. Lo que el comprador paga es la solución a su problema, no el método con el que fue construida. Si el producto resuelve un problema real con calidad real, nadie pregunta cómo fue construido.


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