> ## Content Index
> Fetch the complete content index at: https://blog.devutilites.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Cloudflare Workers AI a fondo: modelos de IA a una llamada de tu Worker
- URL: https://blog.devutilites.com/cloudflare-workers-ai-a-fondo/
- Published: 2026-10-03T03:13:59.000Z
- Updated: 2026-10-03T03:13:59.000Z
- Description: Qué es Workers AI y cómo funciona: un catálogo de modelos abiertos (texto, embeddings, imagen, voz) en GPUs de Cloudflare, con un binding en tu Worker o por API REST. Cómo se factura en neuronas, límites por tipo de modelo, streaming y un Worker de chat con tests.
- Author: Luis Collantes
- Tags: Cloudflare, IA

Usar un modelo de lenguaje desde tu aplicación suele significar elegir entre dos males: pagar una API externa por token y mandarle tus datos, o montar tus propias GPUs. **Workers AI** es una tercera vía: un catálogo de **modelos abiertos** (Llama, Qwen, Mistral, gpt-oss, Gemma, Kimi y compañía, además de modelos de embeddings, imagen y voz) que Cloudflare ejecuta en GPUs de su red y que llamas con una línea desde un Worker.

No hay que desplegar nada, ni reservar máquinas, ni pagar por horas: pagas por uso, en una unidad propia llamada **neurona**, y tienes una cantidad gratis cada día incluso en el plan Free.

En este artículo vemos cómo funciona, cómo se factura (con cuentas reales), los límites, cómo hacer streaming y un Worker de chat con su manejo de errores.

🧪

**Este artículo NO incluye inferencias reales.** Workers AI **no tiene simulación local**: incluso con `wrangler dev`, cada llamada va a tu cuenta de Cloudflare y gasta neuronas, y no he usado una cuenta para estas pruebas. Lo que sí está comprobado, el 3 de octubre de 2026, con **Wrangler 4.147.0**, **TypeScript 7.0.2** y **Vitest 5.0.3**: el código **compila contra los tipos oficiales** que genera `wrangler types` y su lógica pasa **tests con un doble de `env.AI`** (un objeto falso que imita la forma de las respuestas). Las respuestas de los modelos que verás son de ese doble, no de un modelo. Precios y límites comprobados en la documentación oficial ese mismo día.

## Cómo funciona

![Esquema de Workers AI: tu código llama a env.AI.run con un modelo, una entrada y opciones, o usa la API REST; opcionalmente la petición pasa por AI Gateway; Cloudflare la ejecuta en sus GPUs con un modelo del catálogo de texto, embeddings, imagen o voz; la respuesta vuelve completa en JSON o en streaming](https://blog.devutilites.com/content/images/2026/10/cf-workers-ai-esquema.png)

Un binding, un nombre de modelo y una entrada. Cloudflare elige la GPU. Diagrama: devutilites.

1. **Añades el binding `ai`** a tu configuración. En el Worker aparece `env.AI`.
2. **Llamas a `env.AI.run(modelo, entrada, opciones)`**. El modelo se identifica con un nombre del tipo `@cf/<autor>/<modelo>`, por ejemplo `@cf/meta/llama-3.3-70b-instruct-fp8-fast`. La entrada depende del tipo de modelo: `messages` o `prompt` para generar texto, `text` para embeddings, una imagen para clasificación…
3. **Cloudflare ejecuta el modelo** en una GPU de su red y te devuelve el resultado: un objeto JSON o, con `stream: true`, un flujo de eventos SSE que puedes reenviar tal cual al navegador.

También se puede llamar **sin Worker**, por la API REST de Cloudflare (`/accounts/<cuenta>/ai/run/...` o el endpoint compatible con OpenAI `/ai/v1/chat/completions`), con un token de API que tenga permiso de Workers AI.

### El catálogo

El catálogo de Workers AI tenía **69 modelos** el día que escribí esto, de estos tipos:

| Tipo                                 | Para qué                             | Ejemplos                                                     |
| ------------------------------------ | ------------------------------------ | ------------------------------------------------------------ |
| Generación de texto                  | Chat, resúmenes, extracción, agentes | Llama 3.x, Qwen, gpt-oss, Mistral, Kimi                      |
| Embeddings                           | Búsqueda semántica y RAG             | bge-m3 (multilingüe), bge-base-en-v1.5, qwen3-embedding-0.6b |
| Texto a imagen                       | Generar imágenes                     | FLUX, Stable Diffusion                                       |
| Voz                                  | Transcribir (ASR) y sintetizar (TTS) | Whisper, Deepgram                                            |
| Clasificación, detección, traducción | Moderación, etiquetas, idiomas       | Llama Guard, m2m100                                          |

Algunos modelos de texto admiten **llamadas a funciones** (*function calling*), **LoRA** (adaptadores ajustados por ti) o la **API de lotes**, que encola muchas peticiones y te devuelve un `request_id` para recoger los resultados después, sin errores por límite de velocidad. Cada ficha del catálogo indica qué admite el modelo, su ventana de contexto y su precio.

💡

**Un mismo modelo puede tener varias versiones.** `llama-3.1-8b-instruct`, `-awq`, `-fp8` y `-fp8-fast` son variantes cuantizadas u optimizadas del mismo modelo, con precios distintos. Mira la ficha de cada una antes de elegir, porque algunas aparecen en la tabla de precios y su página ya no existe.

## Precios: neuronas

Workers AI se factura en **neuronas**, una unidad que mide el cómputo en GPU. Cada modelo tiene un precio en neuronas por millón de tokens (o por imagen, por minuto de audio…), y la documentación muestra también su equivalencia en dólares.

| Plan         | Gratis                 | Después                         |
| ------------ | ---------------------- | ------------------------------- |
| Workers Free | 10.000 neuronas al día | Nada: hay que pasar a Paid      |
| Workers Paid | 10.000 neuronas al día | 0,011 $ por cada 1.000 neuronas |

El contador se pone a cero cada día a las **00:00 UTC** (las 02:00 en la España peninsular en verano). Algunos modelos grandes exigen un método de pago aunque estés dentro de la cuota.

Para hacerse una idea, con los precios de la documentación y una pregunta típica de un RAG (1.500 tokens de entrada, con el contexto, y 300 de salida):

| Modelo                                   | Neuronas por millón (entrada / salida) | Neuronas por pregunta  | Preguntas gratis al día |
| ---------------------------------------- | -------------------------------------- | ---------------------- | ----------------------- |
| @cf/meta/llama-3.2-3b-instruct           | 4.625 / 30.475                         | ≈ 16                   | ≈ 625                   |
| @cf/meta/llama-3.3-70b-instruct-fp8-fast | 26.668 / 204.805                       | ≈ 101                  | ≈ 99                    |
| @cf/baai/bge-m3 (embeddings)             | 1.075                                  | ≈ 1,6 por 1.500 tokens | —                       |

Pasada la cuota, la pregunta al modelo de 70B sale por unos 0,0011 $ y la del de 3B, por unos 0,00018 $. Indexar un millón de tokens de texto con `bge-m3` cuesta 1.075 neuronas, ni 2 céntimos. **Los tokens de salida son lo caro**: limita `max_tokens`.

## Límites

Los límites de velocidad son **por tipo de tarea** (y algunos por modelo), por cuenta:

| Tipo                                                    | Peticiones por minuto                                                  |
| ------------------------------------------------------- | ---------------------------------------------------------------------- |
| Generación de texto                                     | 300 (los modelos que exigen Paid: 20, o 50 con créditos de AI Gateway) |
| Embeddings                                              | 3.000 (bge-large-en-v1.5: 1.500)                                       |
| Clasificación de texto                                  | 2.000                                                                  |
| Resumen                                                 | 1.500                                                                  |
| Texto a imagen, voz a texto, imagen a texto, traducción | 720                                                                    |
| Clasificación de imágenes, detección de objetos         | 3.000                                                                  |

⚠️

**Las inferencias en local cuentan.** La documentación lo dice claro: las llamadas desde `wrangler dev` van a tu cuenta, gastan neuronas y cuentan para los límites. No dejes un bucle de pruebas lanzando peticiones.

## El código

La configuración solo necesita el binding:

```json
{
  "ai": { "binding": "AI" }
}
```

Y un Worker de chat que responde de una vez o en streaming. Uso un modelo pequeño, porque para respuestas cortas sobra, y le pongo una etiqueta (`tags`) para agrupar las peticiones en el panel:

```typescript
// Worker mínimo de chat con Workers AI: respuesta en streaming (SSE) o de una vez
export interface EntornoChat {
  AI: Ai;
}

const MODELO = "@cf/meta/llama-3.2-3b-instruct"; // pequeño y barato: ~16 neuronas por pregunta típica

export default {
  async fetch(request, env): Promise<Response> {
    if (request.method !== "POST") return new Response("POST { pregunta, stream? }\n", { status: 405 });
    const { pregunta, stream = false } = (await request.json()) as { pregunta?: string; stream?: boolean };
    if (!pregunta) return Response.json({ error: "falta pregunta" }, { status: 400 });

    const messages = [
      { role: "system", content: "Responde en español de España, en tres frases como máximo." },
      { role: "user", content: pregunta },
    ];

    try {
      if (stream) {
        // con stream: true, run() devuelve un ReadableStream de eventos SSE
        const flujo = await env.AI.run(MODELO, { messages, stream: true, max_tokens: 256 }, { tags: ["chat"] });
        return new Response(flujo as ReadableStream, { headers: { "content-type": "text/event-stream" } });
      }
      const salida = await env.AI.run(MODELO, { messages, max_tokens: 256 }, { tags: ["chat"] });
      const texto = typeof salida === "string" ? salida : "response" in salida ? salida.response : null;
      return Response.json({ respuesta: texto, uso: typeof salida === "object" && "usage" in salida ? salida.usage : undefined });
    } catch (e) {
      // límite de neuronas agotado, rate limit, modelo inexistente…: no devuelvas el error crudo
      console.error("Workers AI:", e);
      return Response.json({ error: "el modelo no está disponible ahora" }, { status: 503 });
    }
  },
} satisfies ExportedHandler<EntornoChat>;
```

Tres detalles que salen de los tipos oficiales, no de la intuición:

- **La salida de `run()` es una unión.** Para este modelo, `wrangler types` la declara como objeto con `response`, como `string` o como respuesta de lote asíncrono. Si accedes a `salida.response` sin comprobarlo, TypeScript no compila.
- **Con `stream: true` recibes un `ReadableStream`** de eventos SSE. Lo devuelves con `content-type: text/event-stream` y el navegador lo lee con `EventSource` o `fetch`.
- **Captura los errores.** Si se acaba la cuota diaria, se supera el límite de velocidad o el modelo no existe, `run()` lanza una excepción. No devuelvas el mensaje tal cual al cliente.

### Los tests

Como no hay simulación local, la lógica se prueba con un **doble**: un objeto con un método `run` que devuelve lo que devolvería el modelo. No dice nada de la calidad de las respuestas, pero comprueba que el Worker construye bien la petición, reenvía el stream y no filtra errores:

```text
 ✓ test/chat.test.ts > chat > sin stream devuelve JSON con la respuesta y el uso
 ✓ test/chat.test.ts > chat > con stream reenvía el ReadableStream como text/event-stream
 ✓ test/chat.test.ts > chat > si el modelo falla responde 503 sin filtrar el error
```

Para probarlo de verdad: `npx wrangler login`, `npx wrangler dev` y un `curl -X POST localhost:8787 -d '{"pregunta":"¿Qué es un Worker?"}'`. Ese paso sí gasta neuronas.

## Errores comunes (y cómo evitarlos)

- **No limitar `max_tokens`.** La salida es lo más caro y lo más lento. Ponle un tope.
- **Elegir el modelo más grande por defecto.** Un 3B o un 8B resuelve muchas tareas (clasificar, extraer, resumir textos cortos) por una fracción del precio. Sube solo si la calidad no llega.
- **Usar un modelo de embeddings en inglés para textos en español.** `bge-base-en-v1.5` está pensado para inglés; para español, `bge-m3` u otro multilingüe.
- **Probar en local como si fuera gratis.** Las llamadas en `wrangler dev` cuentan.
- **Suponer la forma de la respuesta.** Cada modelo tiene su esquema de entrada y salida, documentado en su ficha. Genera los tipos con `wrangler types` y deja que el compilador te avise.
- **Lanzar miles de peticiones en paralelo.** Para trabajos por lotes (indexar un archivo entero, resumir miles de textos), usa la API de lotes o una [cola](https://blog.devutilites.com/cloudflare-queues-a-fondo/).
- **No tener visibilidad.** Sin logs no sabes qué preguntas se hacen ni cuánto cuestan. Pasa las peticiones por [AI Gateway](https://blog.devutilites.com/cloudflare-ai-gateway-a-fondo/).

## Cuándo usar Workers AI (y cuándo no)

**Úsalo** para añadir IA a una aplicación que ya vive en Cloudflare sin gestionar GPUs ni otra cuenta: chat y asistentes, resúmenes, clasificación y moderación, embeddings para búsqueda semántica con [Vectorize](https://blog.devutilites.com/cloudflare-vectorize-a-fondo/), transcripción de audio o generación de imágenes. La cuota diaria gratuita da para prototipos y proyectos pequeños.

**No es la mejor opción** si necesitas el modelo más potente del mercado para una tarea difícil (los modelos cerrados de OpenAI, Anthropic o Google siguen por delante en muchas; puedes llamarlos igualmente a través de AI Gateway), si necesitas un modelo propio entero (no solo un LoRA) o si tienes GPUs propias infrautilizadas.

## Sigue leyendo

- [Cloudflare a fondo](https://blog.devutilites.com/cloudflare-a-fondo/): la visión general de la plataforma.
- [Cloudflare Vectorize a fondo](https://blog.devutilites.com/cloudflare-vectorize-a-fondo/): guarda los embeddings y monta un RAG.
- [Cloudflare AI Gateway a fondo](https://blog.devutilites.com/cloudflare-ai-gateway-a-fondo/): logs, caché y límites para tus llamadas a modelos.
- [Cloudflare Browser Run a fondo](https://blog.devutilites.com/cloudflare-browser-run-a-fondo/): convierte páginas web a Markdown para dárselas a un modelo.
- [Planes de Cloudflare Workers: Free frente a Paid](https://blog.devutilites.com/cloudflare-workers-free-vs-paid/): qué cambia en cada plan.