CloudflareMódulo III · Procesos y servicios · Capítulo 10 de 15Nivel: BásicoEn desarrollo

10. IA en tu aplicación

Cómo añadir IA a una app en Cloudflare: modelos con Workers AI, control y caché con AI Gateway, y búsqueda semántica sobre tus datos con Vectorize.

En desarrollo. La publico antes de terminarla porque ya puede servirte; la iré completando y anotaré los cambios al final.

Víctor Rodríguez5 min de lectura
Un robot lee tus notas y responde con una idea.

Qué vas a aprender

  • Añadir IA a tu aplicación: resúmenes, respuestas y búsqueda por significado.
  • Hacer preguntas sobre tus propios datos.
  • Vigilar y limitar lo que gasta la IA.

Conocimientos iniciales

Si alguna de estas preguntas no te suena, ábrela: está explicada desde cero.

  • ¿Qué es un modelo de IA?

    El programa entrenado que genera texto, imágenes o resúmenes (como los que hay detrás de ChatGPT o Claude). Se usa enviándole una petición y recibiendo la respuesta, y se paga por uso.

  • ¿Qué es un token?

    La unidad en la que un modelo de IA cuenta el texto: más o menos tres cuartos de palabra. Los precios de la IA se dan por millón de tokens de entrada (lo que envías) y de salida (lo que responde).

  • ¿Qué es un embedding?

    Una lista de números que representa el significado de un texto. Textos parecidos dan listas parecidas, y eso permite buscar por significado y no solo por palabras exactas.

  • ¿Qué es RAG?

    Responder con IA usando tus propios datos: primero se buscan los documentos relevantes y después se le pasan al modelo para que conteste solo con ellos.

En los proyectos de I+D, la IA suele ser la parte que se quiere probar y la infraestructura, lo que estorba. En Cloudflare, llamar a un modelo es un binding más, y la búsqueda semántica sobre tus datos son dos servicios conectados. En este capítulo añado a la aplicación de notas un buscador que entiende lo que preguntas.

Para quién es y qué necesitas

Para quien quiere añadir IA a su aplicación (resúmenes, preguntas sobre sus datos, agentes) sin montar infraestructura aparte.

Antes de empezar:

  • El proyecto de los capítulos anteriores, con notas en D1.
  • Para pasar de las 10.000 neuronas diarias de Workers AI: el plan de pago.
  • Un límite de gasto pensado antes de escribir la primera llamada. Lo explico en AI Gateway.

Al terminar tendrás resúmenes con un modelo abierto, preguntas sobre tus notas con búsqueda semántica (RAG) y las llamadas vigiladas y limitadas con AI Gateway.

Las piezas de IA en Cloudflare

flowchart LR
    W[Worker] -->|env.AI.run| GW[AI Gateway<br/>registro · caché · límites]
    GW --> WAI[Workers AI<br/>modelos abiertos]
    GW --> EXT[OpenAI · Anthropic<br/>otros proveedores]
    W --> V[(Vectorize<br/>embeddings)]
    W --> AS[AI Search<br/>RAG gestionado]
Pieza Para qué Cuándo la uso
Workers AI Ejecutar modelos (texto, embeddings, imagen, voz) Prototipos, tareas de volumen alto y coste bajo, embeddings
AI Gateway Observar y controlar llamadas a modelos, de Cloudflare o externos Yo lo pongo siempre que hay IA en producción
Vectorize Base de datos de vectores para búsqueda semántica RAG a medida, recomendaciones, deduplicar
AI Search RAG gestionado: indexa tus documentos y responde Cuando no quieres montar el pipeline
Agents SDK Agentes con estado, herramientas y tareas programadas Asistentes que recuerdan y actúan

Llamar a un modelo con Workers AI

wrangler.jsonc (extracto)
{
"ai": { "binding": "AI", "remote": true }
}
src/summarize.ts
const MODEL = "@cf/meta/llama-3.1-8b-instruct-fp8-fast";
export async function summarize(env: Env, text: string) {
const response = await env.AI.run(
MODEL,
{
messages: [
{
role: "system",
content: "Summarize in two sentences, in the text's language. No fluff.",
},
{ role: "user", content: text.slice(0, 8000) },
],
max_tokens: 200,
},
{ gateway: { id: "notes" } },
);
return response.response;
}
Modelo (noviembre de 2026) Tipo Entrada / salida por millón de tokens
@cf/meta/llama-3.1-8b-instruct-fp8-fast Texto, rápido 0,045 $ / 0,384 $
@cf/openai/gpt-oss-20b Texto, razonamiento 0,200 $ / 0,300 $
@cf/meta/llama-3.3-70b-instruct-fp8-fast Texto, más capaz 0,293 $ / 2,253 $
@cf/baai/bge-m3 Embeddings multilingüe 0,012 $

AI Gateway: ver, cachear y limitar

AI Gateway se crea en el panel (AI › AI Gateway) y se usa añadiendo { gateway: { id } } a la llamada, como en el ejemplo anterior. A cambio tienes:

Función Para qué
Registro de peticiones, tokens y coste Saber qué gasta cada función de tu app
Caché de respuestas idénticas No pagar dos veces la misma pregunta
Limitación de peticiones Que un usuario o un error en bucle no dispare la factura
Reintentos y modelo de respaldo Si un proveedor falla, probar con otro
Proveedores externos OpenAI, Anthropic, Google y otros con la misma URL de gateway

Para usar un proveedor externo a través del gateway, cambias la URL base de su SDK por la del gateway y guardas la clave del proveedor como secreto.

Búsqueda semántica con Vectorize

Un embedding convierte un texto en una lista de números (un vector) de forma que textos parecidos dan vectores cercanos. Guardando los vectores de cada nota en Vectorize, puedo buscar por significado (“mis notas sobre facturas”) y no solo por palabras exactas.

Antes del código, el recorrido completo de una pregunta (RAG):

sequenceDiagram
    participant U as Usuario
    participant W as Tu Worker
    participant AI as Workers AI
    participant V as Vectorize
    participant DB as D1
    U->>W: Pregunta
    W->>AI: Vector de la pregunta
    W->>V: Las 5 notas más parecidas, solo de este usuario
    W->>DB: Texto de esas notas
    W->>AI: Responde usando solo estas notas
    AI-->>U: Respuesta
Terminal
npx wrangler vectorize create notes-vectors --dimensions=1024 --metric=cosine
wrangler.jsonc (extracto)
{
"vectorize": [{ "binding": "VECTORS", "index_name": "notes-vectors" }]
}

Indexar una nota (lo hago en el consumidor de la cola, al crearla o editarla):

src/indexing.ts
const EMBEDDINGS = "@cf/baai/bge-m3";
export async function embed(env: Env, text: string) {
const r = await env.AI.run(EMBEDDINGS, { text: [text] });
// bge-m3 has several response shapes; with `text` it returns `data`.
const vector = "data" in r ? r.data?.[0] : undefined;
if (!vector) throw new Error("The model returned no vector");
return vector;
}
export async function indexNote(
env: Env,
note: { id: number; userId: string; title: string; content: string },
) {
const vector = await embed(env, `${note.title}\n${note.content}`);
await env.VECTORS.upsert([
{
id: String(note.id),
values: vector,
metadata: { userId: note.userId },
},
]);
}

Buscar y responder con las notas encontradas (RAG):

src/ask.ts
import { embed } from "./indexing";
export async function ask(env: Env, userId: string, question: string) {
const vector = await embed(env, question);
const { matches } = await env.VECTORS.query(vector, {
topK: 5,
filter: { userId },
});
const ids = matches.map((m) => Number(m.id));
if (ids.length === 0) return "I couldn't find any notes about that.";
const placeholders = ids.map(() => "?").join(",");
const { results } = await env.DB
.prepare(`SELECT title, content FROM notes WHERE id IN (${placeholders})`)
.bind(...ids)
.all<{ title: string; content: string }>();
const context = results
.map((n) => `## ${n.title}\n${n.content}`)
.join("\n\n");
const r = await env.AI.run(
"@cf/meta/llama-3.1-8b-instruct-fp8-fast",
{
messages: [
{
role: "system",
content:
"Answer in the user's language using only these notes. " +
"If the answer isn't in them, say so.\n\n" + context,
},
{ role: "user", content: question },
],
max_tokens: 400,
},
{ gateway: { id: "notes" } },
);
return r.response;
}

AI Search: el RAG ya montado

Si no necesitas controlar cada paso, AI Search indexa los documentos de un bucket de R2 (o de una web), calcula los embeddings, los guarda y responde preguntas con un modelo, todo gestionado. Para un prototipo de “pregunta a tus documentos” es lo más rápido; si luego necesitas control fino, pasas a Vectorize.

Agentes

Para asistentes que mantienen una conversación, recuerdan y usan herramientas (consultar la base de datos, programar un recordatorio), el Agents SDK construye cada agente sobre un Durable Object, con estado propio y tareas programadas. Es otra guía en sí misma; lo menciono para que sepas que existe.

Cuánto cuesta

Cuánto cuesta al mes

Supuestos: 1.000 usuarios: 30.000 notas indexadas y 20.000 preguntas al mes con el modelo de 8B

ConceptoImporte
Embeddings (bge-m3)Unos 9 M de tokens (30.000 notas de ~300 tokens y las preguntas)0,11 $
Respuestas (Llama 3.1 8B)30 M de tokens de entrada (1,35 $) y 6 M de salida (2,30 $), sin descontar lo gratuito3,65 $
Vectorize30.000 vectores de 1.024 dimensiones: dentro de lo incluido0,00 $
AI GatewaySin coste en el uso básico0,00 $
Total al mes3,76 $

Precios consultados el 3 de noviembre de 2026. Pueden cambiar.

Producto Gratuito Pago
Workers AI 10.000 neuronas al día 0,011 $ por 1.000 neuronas (cada modelo publica su equivalencia en tokens)
Vectorize: dimensiones consultadas 30 M al mes 50 M incluidas; 0,01 $ por millón
Vectorize: dimensiones guardadas 5 M 10 M incluidas; 0,05 $ por cada 100 M

Resumen

  • Workers AI para modelos abiertos y embeddings; AI Gateway delante de todo, con límites.
  • Vectorize + D1 para un RAG a medida; AI Search si lo quieres gestionado.
  • Filtra siempre por usuario en las búsquedas y pon max_tokens.
  • Siguiente capítulo: seguridad.

Recursos

¿Te ha servido? Esto forma parte de un libro que estoy escribiendo: Cloudflare de cero a producción. Ver el índice provisional →