Workers AI: LLM odvození a modely vidění přímo na okraji
Workers AI zaznamenala 4000% meziroční nárůst požadavků na odvození do Q1 2026. Naučte se přímo spouštět textové, vizuální a řečové modely ve vašich Workerech bez vyhrazeného GPU s latencí pod 200 ms.
Inference AI přesunuta na okraj
Až do roku 2023 bylo provozování velkého jazykového modelu téměř povinné komunikovat s externím API (OpenAI, Anthropic, Google) nebo nasazovat drahé GPU na vyhrazené infrastruktuře. Latence sítě k těmto centralizovaným koncovým bodům ke každému požadavku přidal 200–800 ms a náklady na GPU byly příliš vysoké nízkoobjemové aplikace.
Dělníci AI změnil tento scénář. Cloudflare se rozšířil AI inferenční hardware (specializované GPU) v desítkách datových center po celém světě. Modely běží na stejném hardwaru, na kterém běží váš Worker, což eliminuje zpáteční síť k externím poskytovatelům. Výsledkem je odvození latence snížené, účtované za spotřebu bez správy infrastruktury.
Co se naučíte
- Šablony dostupné v Workers AI: LLM, vize, řeč, vkládání
- Generování textu pomocí Llama 3.1 a streamování odpovědí
- Modely vidění: analýza obrazu pomocí LLaVA
- Převod řeči na text pomocí funkce Whisper
- Vložení textu pro sémantické vyhledávání
- AI Gateway: ukládání do mezipaměti, omezení rychlosti a pozorovatelnost požadavků AI
- Limity, náklady a optimalizační strategie
Přehled dostupných modelů
Workers AI nabízí výběr open-source modelů optimalizovaných pro odvození
na hardwaru Cloudflare. Modely jsou označeny předponou
@cf/ o @hf/ (Hostováno objímání obličeje):
| Kategorie | Hlavní modely | Případ použití |
|---|---|---|
| Generování textu | @cf/meta/llama-3.1-8b-instruct, @cf/mistral/mistral-7b-instruct-v0.2 | Chatbot, shrnutí, otázky a odpovědi, generování kódu |
| Generování textu (velké) | @cf/meta/llama-3.3-70b-instruct-fp8-fast | Komplexní uvažování, pokročilá analýza |
| Vidění | @cf/llava-hf/llava-1.5-7b-hf, @cf/unum/uform-gen2-qwen-500m | Popisky obrázků, vizuální otázky a odpovědi |
| Převod řeči na text | @cf/openai/whisper, @cf/openai/whisper-large-v3-turbo | Zvukový přepis |
| Vložení textu | @cf/baai/bge-base-en-v1.5, @cf/baai/bge-large-en-v1.5 | Sémantické vyhledávání, podobnost, RAG |
| Klasifikace obrázků | @cf/microsoft/resnet-50 | Klasifikace obrázků |
| Překlad | @cf/meta/m2m100-1,2b | Překlad více než 100 jazyků |
| Generování obrazu | @cf/stabilityai/stable-diffusion-xl-base-1.0 | Převod textu na obrázek |
Konfigurace: AI Binding v wrangler.toml
Chcete-li použít Workers AI, stačí přidat vazbu [ai] v konfiguraci:
# wrangler.toml
name = "ai-worker"
main = "src/worker.ts"
compatibility_date = "2024-09-23"
# Binding per Workers AI
[ai]
binding = "AI"
Typ TypeScript vazby musí být deklarován v rozhraní Env:
// types.ts - dichiarazione del binding AI
interface Env {
AI: Ai; // Tipo fornito da @cloudflare/workers-types
}
Generování textu s lamou 3.1
Nejčastějším případem použití je generování textu pomocí šablony instrukce-odpověď. Podívejme se, jak implementovat koncový bod chatu:
// src/worker.ts - endpoint di chat con Llama 3.1
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.method !== 'POST' || new URL(request.url).pathname !== '/chat') {
return new Response('POST /chat required', { status: 400 });
}
const { messages, stream = false } = await request.json<ChatRequest>();
// Valida l'input
if (!Array.isArray(messages) || messages.length === 0) {
return Response.json({ error: 'messages array required' }, { status: 400 });
}
if (stream) {
// Streaming response: il modello restituisce token man mano
const aiStream = await env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
messages,
stream: true,
max_tokens: 1024,
temperature: 0.7,
});
// Trasforma lo stream AI in Server-Sent Events
return new Response(aiStream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
},
});
}
// Risposta sincrona: attende il completion completo
const result = await env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
messages,
max_tokens: 1024,
temperature: 0.7,
});
return Response.json({
response: (result as AiTextGenerationOutput).response,
usage: {
// Workers AI non espone ancora i token counts nella risposta base
model: '@cf/meta/llama-3.1-8b-instruct',
},
});
},
};
interface ChatRequest {
messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>;
stream?: boolean;
}
interface Env {
AI: Ai;
}
Úplnější příklad, který implementuje systémového asistenta a robustní zpracování chyb:
// src/assistant-worker.ts
const SYSTEM_PROMPT = `Sei un assistente tecnico esperto in cloud computing e edge computing.
Rispondi in modo conciso e tecnico. Se non conosci la risposta, dillo chiaramente.
Non inventare informazioni. Rispondi sempre in italiano a meno che l'utente non scriva in un'altra lingua.`;
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.method !== 'POST') {
return new Response('Method Not Allowed', { status: 405 });
}
let body: AssistantRequest;
try {
body = await request.json<AssistantRequest>();
} catch {
return Response.json({ error: 'Invalid JSON body' }, { status: 400 });
}
if (!body.question?.trim()) {
return Response.json({ error: 'question field is required' }, { status: 400 });
}
try {
const result = await env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
messages: [
{ role: 'system', content: SYSTEM_PROMPT },
{ role: 'user', content: body.question },
],
max_tokens: 2048,
temperature: 0.3, // Bassa temperatura per risposte piu deterministiche
}) as AiTextGenerationOutput;
return Response.json({
answer: result.response,
model: '@cf/meta/llama-3.1-8b-instruct',
timestamp: new Date().toISOString(),
});
} catch (err) {
console.error('AI inference error:', err);
return Response.json(
{ error: 'AI inference failed', details: (err as Error).message },
{ status: 500 }
);
}
},
};
interface AssistantRequest {
question: string;
}
interface Env {
AI: Ai;
}
Modely vidění: Analýza obrazu
Modely vidění umožňují analyzovat vstupní obrázky spolu s otázkou textové. To je užitečné pro moderování obsahu, extrakci informací z naskenovaných dokumentů a funkcí usnadnění:
// src/vision-worker.ts - analisi immagini con LLaVA
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.method !== 'POST') {
return new Response('Method Not Allowed', { status: 405 });
}
// Accetta immagine come Base64 o URL
const body = await request.json<VisionRequest>();
let imageData: number[];
if (body.imageUrl) {
// Scarica l'immagine e converti in array di byte
const imgResponse = await fetch(body.imageUrl);
if (!imgResponse.ok) {
return Response.json({ error: 'Failed to fetch image' }, { status: 400 });
}
const buffer = await imgResponse.arrayBuffer();
imageData = Array.from(new Uint8Array(buffer));
} else if (body.imageBase64) {
// Decodifica Base64
const binaryString = atob(body.imageBase64);
imageData = Array.from({ length: binaryString.length }, (_, i) =>
binaryString.charCodeAt(i)
);
} else {
return Response.json({ error: 'imageUrl or imageBase64 required' }, { status: 400 });
}
const prompt = body.prompt ?? 'Descrivi questa immagine in dettaglio in italiano.';
const result = await env.AI.run('@cf/llava-hf/llava-1.5-7b-hf', {
image: imageData,
prompt,
max_tokens: 512,
}) as AiTextGenerationOutput;
return Response.json({
description: result.response,
prompt,
model: '@cf/llava-hf/llava-1.5-7b-hf',
});
},
};
interface VisionRequest {
imageUrl?: string;
imageBase64?: string;
prompt?: string;
}
interface Env {
AI: Ai;
}
Převod řeči na text s šepotem
Workers AI obsahuje Whisper pro přepis zvuku. Model přijímá zvuk
ve formátu ArrayBuffer a vrátí přepis s časovým razítkem
volitelné:
// src/transcribe-worker.ts - Speech-to-text con Whisper
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.method !== 'POST') {
return new Response('Method Not Allowed', { status: 405 });
}
const contentType = request.headers.get('Content-Type') ?? '';
// Accetta audio come multipart/form-data o application/octet-stream
let audioBuffer: ArrayBuffer;
if (contentType.includes('multipart/form-data')) {
const formData = await request.formData();
const audioFile = formData.get('audio') as File | null;
if (!audioFile) {
return Response.json({ error: 'audio field required in form data' }, { status: 400 });
}
audioBuffer = await audioFile.arrayBuffer();
} else {
// Raw binary audio
audioBuffer = await request.arrayBuffer();
}
if (audioBuffer.byteLength === 0) {
return Response.json({ error: 'Empty audio data' }, { status: 400 });
}
// Limita a 25MB (limite Whisper)
if (audioBuffer.byteLength > 25 * 1024 * 1024) {
return Response.json({ error: 'Audio file too large (max 25MB)' }, { status: 413 });
}
const result = await env.AI.run('@cf/openai/whisper', {
audio: Array.from(new Uint8Array(audioBuffer)),
}) as AiSpeechRecognitionOutput;
return Response.json({
text: result.text,
wordCount: result.text.split(/\s+/).filter(Boolean).length,
model: '@cf/openai/whisper',
});
},
};
interface Env {
AI: Ai;
}
Vložení textu pro sémantické vyhledávání
Vložení jsou číselné vektory, které představují sémantický význam textu. Workers AI obsahuje modely BGE optimalizované pro sémantické vyhledávání. V kombinaci s Vectorize (vektorová databáze Cloudflare) vám umožňují stavět RAG potrubí zcela na okraji:
// src/embedding-worker.ts - generazione embeddings + ricerca semantica
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === '/embed' && request.method === 'POST') {
const { texts } = await request.json<EmbedRequest>();
if (!Array.isArray(texts) || texts.length === 0) {
return Response.json({ error: 'texts array required' }, { status: 400 });
}
// BGE genera embedding di 768 dimensioni (base) o 1024 (large)
const result = await env.AI.run('@cf/baai/bge-base-en-v1.5', {
text: texts,
}) as AiTextEmbeddingsOutput;
return Response.json({
embeddings: result.data,
dimensions: result.data[0]?.length ?? 0,
count: result.data.length,
model: '@cf/baai/bge-base-en-v1.5',
});
}
if (url.pathname === '/search' && request.method === 'POST') {
const { query, topK = 5 } = await request.json<SearchRequest>();
// 1. Genera l'embedding per la query
const queryEmbed = await env.AI.run('@cf/baai/bge-base-en-v1.5', {
text: [query],
}) as AiTextEmbeddingsOutput;
// 2. Ricerca semantica su Vectorize
const results = await env.VECTORIZE.query(queryEmbed.data[0], {
topK,
returnMetadata: 'all',
});
return Response.json({
query,
results: results.matches.map((match) => ({
id: match.id,
score: match.score,
metadata: match.metadata,
})),
});
}
return new Response('Not Found', { status: 404 });
},
};
interface EmbedRequest {
texts: string[];
}
interface SearchRequest {
query: string;
topK?: number;
}
interface Env {
AI: Ai;
VECTORIZE: VectorizeIndex;
}
AI Gateway: Pozorovatelnost a ukládání do mezipaměti
Brána umělé inteligence Cloudflare je to transparentní proxy, že ano pozice před voláními AI (jak Workers AI, tak externí poskytovatelé, jako je OpenAI). Přidává sémantické ukládání do mezipaměti, omezení rychlosti, protokolování a automatický přechod:
// src/worker-with-gateway.ts - Workers AI via AI Gateway
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const { prompt } = await request.json<{ prompt: string }>();
// Usa il gateway invece del binding diretto
// Il gateway aggiunge: caching, retry, logging, rate limiting
const response = await fetch(
`https://gateway.ai.cloudflare.com/v1/${env.CF_ACCOUNT_ID}/${env.AI_GATEWAY_ID}/workers-ai/@cf/meta/llama-3.1-8b-instruct`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${env.CF_API_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
messages: [{ role: 'user', content: prompt }],
max_tokens: 512,
}),
}
);
if (!response.ok) {
const error = await response.text();
return Response.json({ error }, { status: response.status });
}
const result = await response.json();
return Response.json(result);
},
};
interface Env {
AI: Ai;
CF_ACCOUNT_ID: string;
CF_API_TOKEN: string;
AI_GATEWAY_ID: string;
}
Případně můžete bránu nakonfigurovat přímo ve vazbě AI na wrangler.toml:
# wrangler.toml con AI Gateway
[ai]
binding = "AI"
# Il gateway viene usato automaticamente per tutte le chiamate
# Configurato nella dashboard Cloudflare
Omezení a úvahy o nákladech
| Model | Zdarma (neuronové jednotky) | Placené ($ za 1 000 neuronů) | Typická latence |
|---|---|---|---|
| Lama 3.1 8B | 10 000 NU/den zdarma | 0,011 $ / 1 000 NU | ~500 ms-2s (závisí na tokenech) |
| Lama 3.3 70B FP8 | Zahrnuto v placeném plánu | 0,050 $ / 1 000 NU | ~1-5s |
| Šepot | 10 000 NU/den zdarma | 0,011 $ / 1 000 NU | ~1-3s za minutu zvuku |
| vložení BGE | 10 000 NU/den zdarma | 0,011 $ / 1 000 NU | ~50-200 ms |
| Stabilní difúze XL | 10 000 NU/den zdarma | 0,020 $ / obrázek | ~3-10s |
Časové limity a limity CPU
Workers AI funguje mimo běžný rozpočet CPU pracovníka (placený plán 30 s). U velkých modelů, jako je Llama 70B, to však může trvat 5–15 sekund reagovat. V těchto případech nezapomeňte použít streamování vracet tokeny za pochodu a nepřekračovat časový limit HTTP klienta. Pro dlouhé závěry zvažte použití fronty (Workers Queues) a upozorněte klienta po dokončení.
Výrobní vzor: RAG at the Edge
Stále častějším vzorem je RAG (generace rozšířeného vyhledávání) zcela na okraji: Vektorizace pro získávání, Workers AI pro vkládání a generování.
// src/rag-worker.ts - RAG completo all'edge
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.method !== 'POST') return new Response('POST only', { status: 405 });
const { question } = await request.json<{ question: string }>();
// Step 1: Genera l'embedding della domanda
const queryEmbedding = await env.AI.run('@cf/baai/bge-base-en-v1.5', {
text: [question],
}) as AiTextEmbeddingsOutput;
// Step 2: Recupera i chunk rilevanti dal vector store
const relevant = await env.DOCS.query(queryEmbedding.data[0], {
topK: 3,
returnMetadata: 'all',
});
// Step 3: Costruisce il contesto dai chunk recuperati
const context = relevant.matches
.map((m) => m.metadata?.['text'] as string ?? '')
.filter(Boolean)
.join('\n\n---\n\n');
// Step 4: Genera la risposta con il contesto
const answer = await env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
messages: [
{
role: 'system',
content: `Rispondi alla domanda basandoti SOLO sul contesto fornito.
Se il contesto non contiene informazioni sufficienti, dillo esplicitamente.
Contesto:
${context}`,
},
{ role: 'user', content: question },
],
max_tokens: 1024,
temperature: 0.1,
}) as AiTextGenerationOutput;
return Response.json({
question,
answer: answer.response,
sources: relevant.matches.map((m) => ({
id: m.id,
score: m.score,
title: m.metadata?.['title'],
})),
});
},
};
interface Env {
AI: Ai;
DOCS: VectorizeIndex;
}
Závěry a další kroky
Umělá inteligence pracovníků představuje změnu paradigmatu v přístupu k vyvozování AI: žádná GPU ke správě, žádní externí poskytovatelé k integraci, fakturace pro spotřebu s velkorysou bezplatnou úrovní. Odráží 4000% meziroční růst do 1. čtvrtletí 2026 rychlé přijetí vývojáři, kteří hledají jednodušší cestu vůči AI ve svých produktech.
Kombinace Workers AI + Vectorize + Durable Objects (pro správu historie konverzací) vám umožňuje vytvořit kompletní asistenty AI na platformě Cloudflare, bez externích závislostí.
Další články v seriálu
- Článek 6: Vercel Edge Runtime — pokročilý middleware, Geolokace a A/B testování: Jak Vercel používá edge runtime s Next.js pro přizpůsobení a příznaky funkcí.
- Článek 7: Geografické směrování na okraji — Personalizace Obsah a soulad s GDPR: Vytvářejte geografickou logiku, aniž byste se dotkli hlavního serveru.
- Článek 8: Cache API a strategie zneplatnění v Cloudflare Pracovníci: Programovatelné CDN s TTL, zatuchlý-běh-obnovení platnosti a čištění podle klíče.







