Le di 50 dólares a cinco IAs para que hicieran la misma web: el prompt y los resultados
La plataforma donde corrí los cinco modelos es Fast Inference. Ahí están los cinco, con la misma API, que es lo que hace que esta comparación sea justa.
Casi todas las comparativas de modelos que circulan miden lo mismo: tokens por segundo y puntuaciones de exámenes. Ninguna de las dos cosas te dice lo que quieres saber de verdad, que es esta: si el modelo caro cuesta trescientas veces más, ¿te da trescientas veces más?
Así que le puse a cinco un encargo difícil, medí lo que tardaba y lo que gastaba cada uno, y después ejecuté lo que me entregaron. Aquí tienes el prompt entero, el script y los números.
El encargo
La clave de que esto sirva para algo es que la tarea sea difícil de verdad. Pedir "una landing page" no separa a un modelo de otro: todos la hacen. Hay que pedir algo que se pueda romper.
Este es el prompt exacto, listo para copiar:
Construye la web COMPLETA de "Raíz Verde", un vivero enorme a las afueras que
vende plantas y árboles y además va a casa del cliente a plantarlos.
No quiero una maqueta ni un solo archivo: quiero un PROYECTO QUE FUNCIONE de
principio a fin.
REQUISITOS OBLIGATORIOS
Backend
- Node.js usando SOLO módulos nativos (node:http, node:fs, node:path,
node:sqlite). Cero dependencias externas, cero npm install.
- Arranca con `node server.js` y sirve en el puerto 3000.
- API REST de verdad: GET /api/plantas (catálogo), GET /api/plantas/:id (ficha),
POST /api/pedidos (guarda el pedido), POST /api/contacto (guarda el mensaje).
- Los pedidos y los mensajes se PERSISTEN en disco (JSON o SQLite). Si reinicias
el servidor, siguen ahí.
- Al menos 12 plantas en el catálogo, cada una con nombre, tipo, precio,
descripción y si admite plantación a domicilio.
Frontend
- Portada, catálogo con filtro por tipo, ficha de planta, sección del servicio de
plantación a domicilio, tres planes de precios, opiniones de clientes, carrito
y formulario de contacto.
- El catálogo se carga LLAMANDO A LA API, no escrito a mano en el HTML.
- El carrito suma, resta y calcula el total. Al confirmar, hace POST /api/pedidos
y enseña la confirmación.
- Responsive: se ve bien en móvil y en escritorio.
Ilustraciones e iconos
- TODAS las ilustraciones y todos los iconos son SVG inline dibujados por ti.
- PROHIBIDO usar emojis. Ni uno.
- PROHIBIDO enlazar imágenes, fuentes, iconos o CSS de internet.
Calidad
- Diseño cuidado y con personalidad, no una plantilla gris.
- Sin frameworks ni CDNs. HTML, CSS y JavaScript a mano.
FORMATO DE ENTREGA
Devuelve cada archivo exactamente así, uno detrás de otro, sin texto entre
medias y sin explicaciones:
=== ARCHIVO: server.js ===
(contenido completo del archivo)
=== FIN ===
Usa tantos archivos como necesites. No resumas, no pongas "resto del código
igual", no dejes nada a medias.
Tres detalles de ese prompt que no son adorno:
El formato de entrega. Sin unos separadores claros no puedes trocear la respuesta en archivos de forma automática. Con ellos, un matchAll te deja el proyecto en disco.
La prohibición de emojis. Parece una tontería y es la columna más reveladora de toda la comparativa: mide si el modelo obedece una instrucción explícita, que es lo que de verdad importa cuando le encargas trabajo.
"Sin dependencias externas". Obliga al modelo a usar la librería estándar de Node de verdad, y ahí es donde se ve quién la conoce y quién se inventa funciones.
Los resultados
Medición del 9 de septiembre de 2026, uno detrás de otro (no en paralelo, que contamina los tiempos), de más barato a más caro y sin límite de presupuesto.
| modelo | rondas | 1ª letra | total | archivos | peso | coste | |---|---|---|---|---|---|---| | DeepSeek V4 Flash | 2 | 4,9 s | 115 s | 4 | 43 KB | 0,0107 $ | | GLM-5.2 Fast | 1 | 45,1 s | 92 s | 4 | 44 KB | 0,1851 $ | | GPT-6 Astra | 3 | 370,3 s | 1.522 s | 6 | 122 KB | 2,0746 $ | | Kimi K3 Fast | 3 | 573,6 s | 856 s | 6 | 96 KB | 2,1505 $ | | Claude Opus 5 | 4 | 253,2 s | 1.373 s | 8 | 179 KB | 3,6401 $ |
Total de todo el experimento: 8,06 $.
Lo que sale de ahí:
- Opus entrega cuatro veces más proyecto que DeepSeek y cobra trescientas cuarenta veces más. Ese es el número que importa, y no lo verás en ningún benchmark de tokens por segundo.
- GPT-6 Astra fue el más lento de los cinco: veinticinco minutos. En esta prueba y por esta pasarela, que es una precisión importante — por su API directa el resultado puede ser otro.
- Cuatro de los cinco servidores arrancan y sirven la web. El que no arranca es DeepSeek: llama a
sqlite3.open(), que no existe ennode:sqlite. Se inventó la función. - A GLM y a Kimi se les colaron quince emojis a cada uno, con el encargo prohibiéndolos expresamente. DeepSeek, Astra y Opus, ninguno.
La conclusión práctica
El modelo caro no te da trescientas cuarenta veces más. Te da más: más archivos, más superficie, más detalle. Pero no en esa proporción.
Lo que yo me llevo, y te sirve uses la herramienta que uses: tira del modelo barato para el trabajo normal y guarda el caro para lo que se atasque. Si lo aplicas a tu día a día en Cursor, en Claude Code o eligiendo modelo en cualquier interfaz, la diferencia a final de mes es real.
Y el matiz honesto: el barato te escribió el proyecto por un céntimo, pero su backend no arrancaba. Descubrirlo también cuesta tiempo. Barato no es gratis.
Las dos trampas que me costaron horas
Si vas a montar tu propia comparación, esto te ahorra la tarde.
1. Pide la respuesta en streaming, siempre. Sin stream: true, los modelos lentos devuelven un error HTTP 524 antes de terminar. No es que fallen: es que la pasarela corta la conexión mientras esperan.
2. La conexión se corta a los 600 segundos. Pase lo que pase. Un modelo que escriba a 28 tokens por segundo nunca termina un proyecto largo de una sola vez. La solución es continuar: le devuelves lo que llevaba escrito y le pides que siga desde ahí. Cada ronda estrena reloj.
Y un aviso de la segunda: cuando el modelo retoma, muchas veces vuelve a abrir un bloque de código con ```. Si pegas ese trozo tal cual, te corrompe el archivo justo por la costura. Hay que quitarlo antes de concatenar. A mí me rompió un JSON y tardé un rato en entender por qué.
El script
Esto es el esqueleto de lo que usé. Manda el mismo prompt a cada modelo, mide, trocea la respuesta en archivos y saca la tabla.
const BASE = 'https://api.inference.net/v1'
const MODELOS = [
{ id: 'deepseek-v4-flash', tope: 8192 },
{ id: 'glm-5.2-fast', tope: 32000 },
{ id: 'kimi-k3-fast', tope: 32000 },
{ id: 'gpt-6-astra', tope: 32000 },
]
async function pedir(modelo, mensajes) {
const res = await fetch(`${BASE}/chat/completions`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.INFERENCE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: modelo.id,
messages: mensajes,
max_tokens: modelo.tope,
stream: true, // trampa 1
stream_options: { include_usage: true },
}),
})
const lector = res.body.getReader()
const dec = new TextDecoder()
let texto = '', resto = '', cortado = false, entrada = 0, salida = 0
while (true) {
const { done, value } = await lector.read()
if (done) break
resto += dec.decode(value, { stream: true })
const lineas = resto.split('\n')
resto = lineas.pop() ?? ''
for (const l of lineas) {
if (!l.startsWith('data:')) continue
const carga = l.slice(5).trim()
if (carga === '[DONE]') break
try {
const ev = JSON.parse(carga)
texto += ev.choices?.[0]?.delta?.content ?? ''
if (ev.choices?.[0]?.finish_reason === 'length') cortado = true
if (ev.usage) {
entrada = ev.usage.prompt_tokens
salida = ev.usage.completion_tokens
}
} catch {}
}
}
return { texto, cortado, entrada, salida }
}
// Trampa 2: si se corta, se le devuelve lo escrito y se le pide que siga.
async function correr(modelo, prompt) {
const mensajes = [{ role: 'user', content: prompt }]
let todo = ''
for (let ronda = 1; ronda <= 20; ronda++) {
const r = await pedir(modelo, mensajes)
// quita la valla de markdown que abren al continuar: corrompe el archivo
const trozo = ronda === 1 ? r.texto : r.texto.replace(/^\s*```[a-zA-Z]*\s*\n?/, '')
todo += trozo
if (!r.cortado) break
mensajes.push({ role: 'assistant', content: trozo })
mensajes.push({
role: 'user',
content:
'Continúa EXACTAMENTE donde lo dejaste, sin repetir nada y sin explicar nada. ' +
'Mantén el formato === ARCHIVO: ruta === … === FIN ===',
})
}
return todo
}
// Trocear la respuesta en archivos de verdad
const RE = /===\s*ARCHIVO:\s*(.+?)\s*===\r?\n([\s\S]*?)(?:\r?\n===\s*FIN\s*===|$)/g
for (const m of todo.matchAll(RE)) {
const ruta = m[1].trim()
if (ruta.includes('..')) continue // que no se salga de la carpeta
// fs.writeFileSync(ruta, m[2])
}
El coste se calcula con los precios que la propia API publica en GET /v1/models, así que no hay que fiarse de ninguna tabla de marketing: (tokens_entrada × precio_entrada + tokens_salida × precio_salida) / 1.000.000.
Por qué esto se puede hacer en una tarde
Para comparar cinco modelos de cinco empresas distintas normalmente necesitas cinco cuentas, meter la tarjeta cinco veces y cuadrar cinco facturas a final de mes. Y cada API con sus manías.
Yo lo hice con Fast Inference: una sola clave para cincuenta y nueve modelos, el mismo endpoint y el mismo formato para todos, y cambias de modelo escribiendo su nombre. Sirven los modelos abiertos optimizados para ir rápido y los de pago, como Opus, por esa misma API.
Este artículo acompaña a un vídeo patrocinado por ellos. Los números son míos, están medidos el mismo día y los tienes todos arriba para que los reproduzcas.
Un aviso último sobre los tiempos: varían según el momento. DeepSeek me hizo la misma tarea en 52 segundos, en 427 y otra vez en 52, en tres pasadas del mismo día. Los precios sí son estables. Si montas tu comparación, mide tú y el mismo día.