Volver al Blog
engineering||11 min de lectura

Los agentes de IA no deberían controlar tus apps; deberían ser la app

AR
Aral Roca

Creador de Kitmul

Kitmul empezó como algo mucho más modesto de lo que es ahora. Mantengo dos librerías open source: NextTranslate y Teaful. Necesitaba un proyecto real en Next.js donde iterar sobre ellas. No demos artificiales ni repositorios de ejemplo; un producto vivo donde los bugs aparecen solos y las limitaciones se hacen evidentes.

Ese era el único objetivo.

Página principal de Kitmul: 304 herramientas gratuitas, sin registro, sin subida de archivos
Página principal de Kitmul: 304 herramientas gratuitas, sin registro, sin subida de archivos

El efecto multiplicador de la IA

Para acelerar el desarrollo empecé a usar agentes de IA para programar: Claude Code, Gemini y Codex. No solo por productividad. Quería entender de primera mano cómo se comportan estos agentes en un workflow de desarrollo real. En qué son buenos, dónde fallan y cómo cambian la forma en que piensas sobre construir software.

Lo que no esperaba es el efecto que tendría en el alcance del proyecto. Cuando puedes implementar una idea en minutos en vez de horas, dejas de hacer triaje de ideas. Simplemente las construyes. Pasé de "voy a mantener estas dos librerías" a "voy a construir 300+ herramientas" en apenas 3 semanas.

Actualmente estoy en Claude Code 20x. La combinación de un agente que entiende tu codebase en profundidad y puede ejecutar tareas multi-paso de forma autónoma ha sido el mayor multiplicador de velocidad de desarrollo que he experimentado.

De herramientas para devs a herramientas para todo el mundo

Como desarrollador open source, siempre he construido para otros desarrolladores. Librerías, herramientas CLI, utilidades de build. Público limitado, impacto limitado.

Con Kitmul cambié la pregunta. En vez de "qué herramienta necesita un dev", me pregunté: "qué herramienta busca la gente en Google y acaba en una web que le cobra o le sube los archivos a un servidor".

La respuesta: cientos de herramientas. Eliminar fondos de imágenes, separar pistas de audio, convertir formatos, comprimir PDFs, generar QRs. Herramientas que la gente usa a diario y por las que muchos sitios cobran 10-20€ al mes.

Hoy Kitmul tiene más de 300. Y no son wrappers triviales.

La arquitectura: todo en el dispositivo del usuario

La decisión técnica fundamental de Kitmul es que todo se ejecuta en el cliente. Sin excepciones siempre que sea posible.

El stack es directo: si JavaScript nativo alcanza, se usa JavaScript. Si la operación es intensiva (procesamiento de audio, manipulación de imágenes pesada, separación de pistas) se compila a WebAssembly. Para las partes donde el rendimiento es crítico, Rust compilado a WASM.

Por ejemplo, así fusionamos PDFs completamente en el navegador:

import { PDFDocument } from 'pdf-lib';

export async function mergePDFs(files) {
  const merged = await PDFDocument.create();

  for (const file of files) {
    const bytes = await file.arrayBuffer();
    const pdf = await PDFDocument.load(bytes);
    const pages = await merged.copyPages(pdf, pdf.getPageIndices());
    pages.forEach((page) => merged.addPage(page));
  }

  return merged.save(); // Devuelve Uint8Array, nunca sale del navegador
}

Cero llamadas de red. El archivo va de File API → pdf-lib → descarga.

Por qué Rust + WASM: el verificador de números primos

Para cómputo más pesado, JavaScript se queda corto. Un ejemplo real de Kitmul: nuestro Verificador de Números Primos. JavaScript puede verificar primalidad para números pequeños, pero intenta probar un número con más de 1.200 dígitos y el navegador se congela. BigInt simplemente no puede con ello.

Aquí el enfoque con JavaScript, que funciona bien para números de hasta ~13 dígitos:

function isPrime(n) {
  if (n <= 1) return false;
  if (n <= 3) return true;
  if (n % 2 === 0 || n % 3 === 0) return false;
  for (let i = 5; i * i <= n; i += 6) {
    if (n % i === 0 || n % (i + 2) === 0) return false;
  }
  return true;
}

// Funciona para números pequeños, pero ¿para uno de 1200+ dígitos?
// La aritmética de BigInt se vuelve tan lenta que la pestaña se congela.

La solución: compilamos un crate de Rust que usa num-bigint con un test de primalidad Miller-Rabin a WASM. El lado de Rust recibe el número como string (porque puede tener miles de dígitos) y devuelve si es primo:

use num_bigint::BigUint;
use num_traits::{One, Zero};

#[no_mangle]
pub extern "C" fn is_number_prime(ptr: *const u8, len: usize) -> i32 {
    let bytes = unsafe { std::slice::from_raw_parts(ptr, len) };
    let num_str = std::str::from_utf8(bytes).unwrap_or("0");
    let n = num_str.parse::<BigUint>().unwrap_or_else(|_| BigUint::zero());

    if n <= BigUint::one() { return 0; }

    if miller_rabin(&n) { 1 } else { 0 }
}

Luego desde JavaScript, cargamos el módulo WASM y pasamos el número como bytes:

// Cargar WASM y verificar un número de 1200+ dígitos
const { instance } = await WebAssembly.instantiate(wasmBuffer, {});
const exports = instance.exports;

const numStr = "12345..."; // Número de 1200+ dígitos
const bytes = new TextEncoder().encode(numStr);
const ptr = exports.wasm_alloc(bytes.length);
new Uint8Array(exports.memory.buffer).set(bytes, ptr);

const result = exports.is_number_prime(ptr, bytes.length);
exports.wasm_dealloc(ptr, bytes.length);
// result: 1 = primo, 0 = no primo

JavaScript con BigInt no puede manejar números por encima de ~1.200 dígitos. El módulo Rust WASM maneja números de cualquier tamaño; lo hemos probado con números de más de 3.000 dígitos. Mismo navegador, mismo dispositivo, pero el crate num-bigint de Rust usa aritmética de limbs optimizada que JavaScript simplemente no puede igualar.

Las implicaciones de esta arquitectura:

  • Coste de infraestructura prácticamente cero: no hay servidores procesando archivos.
  • Privacidad real, no prometida: los datos literalmente no salen del dispositivo.
  • Escalabilidad sin aprovisionar máquinas: cada usuario trae su propio compute.

La tesis: los agentes de IA no deberían controlar tus apps. Deberían SER la app.

Aquí es donde creo que la industria se está equivocando.

OpenAI con Operator, Anthropic con Computer Use, Google con Project Mariner: los grandes están construyendo agentes de IA que controlan aplicaciones existentes. Hacen capturas de pantalla, mueven el ratón, hacen clic en botones, rellenan formularios. Básicamente están construyendo bots de RPA muy sofisticados.

Creo que este enfoque es fundamentalmente erróneo. Por varias razones:

1. Estás construyendo sobre interfaces diseñadas para humanos, no para máquinas. Cuando un agente de IA navega por una web, está luchando contra dropdowns, modales, banners de cookies, CAPTCHAs y cambios de diseño. Cada rediseño de una web puede romper el agente. Es frágil por diseño.

2. Sigues dependiendo de servicios de terceros. El agente puede ser inteligente, pero sigue subiendo tu PDF a iLovePDF, sigue enviando tus imágenes a los servidores de Canva, sigue dando tus datos a alguien. El problema de privacidad no desaparece solo porque un robot esté haciendo los clics.

3. Es lento. Captura de pantalla → analizar → clic → esperar carga → captura de nuevo. Este loop lleva segundos por acción. Mientras tanto, una llamada directa a una función lleva milisegundos.

La alternativa, lo que estoy construyendo con Kitmul, es radicalmente diferente:

El agente de IA no controla apps. El agente de IA ES la app.

En vez de navegar a SmallPDF para fusionar archivos, el agente llama a mergePDFs() directamente. En vez de abrir Canva para eliminar un fondo, ejecuta un modelo WASM en el navegador. Sin capturas de pantalla, sin movimientos de ratón, sin esperar cargas de página. Llamadas directas a funciones, resultados directos.

// El enfoque de "captura y clic" (Operator, Computer Use):
// 1. Navegar a smallpdf.com          (~3s)
// 2. Encontrar botón de subida        (~1s)
// 3. Subir archivo                    (~5s)
// 4. Esperar procesamiento            (~3s)
// 5. Clic en descargar                (~2s)
// 6. Esperar descarga                 (~3s)
// Total: ~17 segundos + tus archivos en el servidor de otro

// El enfoque de Kitmul:
const merged = await mergePDFs(files);  // ~300ms, nunca sale de tu dispositivo

Es una diferencia de velocidad de 30-50x, con el beneficio añadido de que tus archivos nunca tocan un servidor remoto.

La orquestación en práctica

Kitmul ya tiene un chat integrado donde la IA actúa como orquestador. El usuario describe lo que quiere en lenguaje natural. La IA selecciona herramientas del catálogo, las ejecuta en secuencia y encadena outputs.

Un ejemplo concreto: subes un audio. La IA lo separa en pistas usando un modelo WASM de separación de fuentes. Luego aplica reducción de ruido a la pista vocal. Convierte el resultado a MP3. Todo encadenado, todo en el navegador, todo sin que el archivo salga de tu dispositivo.

El orquestador usa un registro de herramientas que mapea intenciones en lenguaje natural a funciones concretas:

// Versión simplificada de cómo funciona el orquestador
const toolRegistry = {
  'merge_pdf': { fn: mergePDFs, input: 'file[]', output: 'file' },
  'split_audio': { fn: splitAudio, input: 'file', output: 'file[]' },
  'compress_image': { fn: compressImage, input: 'file', output: 'file' },
  // ... 300+ herramientas más
};

// La IA decide el plan de ejecución, y luego lo ejecuta:
const plan = await ai.plan("Separa esta canción y elimina el ruido de las voces");
// → [{ tool: 'split_audio', input: userFile },
//    { tool: 'noise_reduction', input: '$prev.vocals' },
//    { tool: 'convert_to_mp3', input: '$prev' }]

for (const step of plan) {
  step.result = await toolRegistry[step.tool].fn(resolve(step.input));
}

No es un concepto. Funciona hoy.

La parte realmente interesante: herramientas que se auto-construyen

Aquí es donde Kitmul diverge de todo lo demás.

Con 300+ herramientas, cubrimos muchos casos de uso. Pero cuando un usuario pide algo que no tenemos, en vez de decir "lo sentimos, no podemos hacer eso", el sistema debería ser capaz de crear la herramienta al vuelo con IA; y entonces, crucialmente, tener un human-in-the-loop que verifique que la herramienta generada funciona correctamente antes de que pase a formar parte del catálogo permanente.

Piénsalo:

  1. Un usuario pide: "Necesito una herramienta que convierta archivos MIDI a partitura."
  2. La IA genera la herramienta: una implementación client-side usando WebAssembly.
  3. Un revisor humano (yo, o eventualmente una comunidad de contribuidores) verifica que la herramienta funciona, maneja edge cases y cumple los estándares de calidad de Kitmul.
  4. Una vez aprobada, la herramienta se añade permanentemente al catálogo.
  5. El siguiente usuario que pida lo mismo obtiene la herramienta verificada, de calidad producción, al instante.

El sistema literalmente se construye a sí mismo basándose en lo que los usuarios necesitan. Cada petición sin respuesta se convierte en una señal. Cada herramienta verificada hace la plataforma más capaz. Es un flywheel donde la IA genera, los humanos verifican, y el catálogo crece orgánicamente.

Esto es fundamentalmente diferente del enfoque de "generar código en runtime" que algunas empresas de IA están persiguiendo. Código generado ejecutándose sin verificación es un riesgo: puede tener bugs, agujeros de seguridad, o simplemente no funcionar en edge cases. El paso de human-in-the-loop no es una limitación; es una feature. Asegura que cada herramienta del catálogo sea de calidad producción.

Míralo en acción

Aquí tienes una demo rápida de cómo funciona Kitmul:

El objetivo: 4.000 herramientas en un año

Tengo un backlog con más de 4.000 ideas de herramientas. No es un número arbitrario: es el tamaño real de la lista después de analizar qué busca la gente y qué actualmente requiere subir archivos a un servidor o pagar una suscripción.

Con Claude Code 20x y el enfoque de auto-construcción, esto no es una utopía. Muchas herramientas se construyen en una sola sesión. Las más complejas (las que requieren WASM personalizado o procesamiento de señal) llevan más, pero siguen siendo órdenes de magnitud más rápidas que sin IA.

Lo que viene

La orquestación funciona para flujos simples, pero los workflows complejos con bifurcaciones, condicionales y feedback loops aún necesitan trabajo. El pipeline de auto-construcción se está diseñando ahora mismo.

La visión a largo plazo: un sistema donde cualquier tarea que hoy haces con software fragmentado (subiendo archivos aquí, pagando una suscripción allá, instalando una app para esto otro) pueda resolverse dentro de una única interfaz, ejecutada localmente, orquestada por IA, y en constante expansión según lo que los usuarios realmente necesitan.

La pregunta con la que quiero cerrar: ¿De verdad necesitamos agentes de IA que controlen nuestras apps actuales? ¿O necesitamos repensar qué debería ser la app en sí?

Creo que la respuesta es lo segundo. Y creo que el navegador es el runtime correcto para demostrarlo.

Comparte este artículo

Boletín

Recibe Consejos de Productividad y Nuevas Herramientas Primero

Únete a miles de creadores y desarrolladores. En cada edición: nuevas herramientas, trucos de productividad y novedades — sin spam.

Acceso prioritario a nuevas herramientas
Cancela en cualquier momento, sin preguntas