Integrez Groq en JavaScript pour une inference LLM ultra-rapide : LPU, modeles Llama et Mixtral, compatibilite SDK OpenAI, streaming, function calling et gestion des rate limits.
Pourquoi Groq est si rapide
Groq ne concoit pas de modeles : il les execute, et il le fait plus vite que quiconque. Le secret tient a son materiel dedie, le LPU (Language Processing Unit), une architecture pensee pour l'inference sequentielle des LLM la ou les GPU sont optimises pour le parallelisme massif de l'entrainement.
Concretement, la ou un GPU classique genere quelques dizaines de tokens par seconde, Groq en produit plusieurs centaines. Pour l'utilisateur, la difference est radicale : une reponse qui s'affichait progressivement apparait quasi instantanement.
Prerequis et cle API
- Compte sur la console Groq et cle API generee
- Node.js 18+ (support natif de
fetch) - Cle stockee dans
GROQ_API_KEY(variable d'environnement)
# Installer le SDK officiel Groq
npm install groq-sdk
# Stocker la cle (jamais commitee)
echo "GROQ_API_KEY=gsk_..." >> .env
Premier appel chat completions
Le SDK Groq suit le meme modele que les autres : un appel de chat completions avec une liste de messages. Mesurons la vitesse au passage.
// groq-first.js — premier appel et mesure de vitesse
import 'dotenv/config';
import Groq from 'groq-sdk';
const groq = new Groq({ apiKey: process.env.GROQ_API_KEY });
const start = Date.now();
const completion = await groq.chat.completions.create({
model: 'llama-3.3-70b-versatile', // modele Llama servi par Groq
messages: [
{ role: 'system', content: 'Tu es un assistant technique concis.' },
{ role: 'user', content: 'Explique les closures en JavaScript en 3 phrases.' },
],
temperature: 0.5,
max_tokens: 300,
});
const elapsed = Date.now() - start;
const tokens = completion.usage.completion_tokens;
console.log(completion.choices[0].message.content);
console.log(`\n${tokens} tokens en ${elapsed}ms`);
console.log(`Vitesse : ${Math.round(tokens / (elapsed / 1000))} tokens/s`);
usage est renvoye comme chez OpenAI : prompt_tokens, completion_tokens et total_tokens. Groq ajoute parfois des metriques de timing detaillees dans la reponse.
Compatibilite SDK OpenAI
Atout majeur pour la migration : l'API Groq est compatible OpenAI. Si votre code utilise deja le SDK OpenAI, il suffit de rediriger la baseURL.
// groq-via-openai.js — reutiliser le SDK OpenAI tel quel
import OpenAI from 'openai';
// Pointer le SDK OpenAI vers l'endpoint Groq
const client = new OpenAI({
apiKey: process.env.GROQ_API_KEY,
baseURL: 'https://api.groq.com/openai/v1', // seule ligne a changer
});
// Le reste du code est identique a un appel OpenAI classique
const res = await client.chat.completions.create({
model: 'llama-3.3-70b-versatile',
messages: [{ role: 'user', content: 'Resume le RAG en une phrase.' }],
});
console.log(res.choices[0].message.content);
// Selecteur de provider via configuration
const providers = {
openai: { baseURL: undefined, key: process.env.OPENAI_API_KEY, model: 'gpt-4o' },
groq: { baseURL: 'https://api.groq.com/openai/v1', key: process.env.GROQ_API_KEY, model: 'llama-3.3-70b-versatile' },
};
function makeClient(name) {
const p = providers[name];
return {
client: new OpenAI({ apiKey: p.key, baseURL: p.baseURL }),
model: p.model,
};
}
// Basculer en une ligne : 'groq' pour la vitesse, 'openai' pour le raisonnement
const { client, model } = makeClient(process.env.AI_PROVIDER ?? 'groq');
Streaming token par token
Avec Groq, le streaming devient presque superflu tant la reponse est rapide — mais il reste utile pour les longues generations et l'experience utilisateur.
// groq-stream.js — affichage en streaming
import Groq from 'groq-sdk';
const groq = new Groq({ apiKey: process.env.GROQ_API_KEY });
const stream = await groq.chat.completions.create({
model: 'llama-3.3-70b-versatile',
messages: [{ role: 'user', content: 'Ecris un court poeme sur le code.' }],
stream: true, // active le streaming SSE
});
// Chaque chunk contient un fragment de texte
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content;
if (delta) process.stdout.write(delta);
}
Streaming vers un client web (Express)
// Relayer le stream Groq vers le navigateur en SSE
app.get('/chat', async (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
const stream = await groq.chat.completions.create({
model: 'llama-3.3-70b-versatile',
messages: [{ role: 'user', content: req.query.q }],
stream: true,
});
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content ?? '';
if (delta) res.write(`data: ${JSON.stringify({ delta })}\n\n`);
}
res.write('data: [DONE]\n\n');
res.end();
});
Function calling avec Groq
Les modeles Llama servis par Groq supportent le function calling au format OpenAI, ce qui permet de construire des agents reactifs ultra-rapides.
// groq-tools.js — declarer et gerer un outil
const tools = [{
type: 'function',
function: {
name: 'get_stock_price',
description: 'Recupere le cours d\'une action',
parameters: {
type: 'object',
properties: { symbol: { type: 'string' } },
required: ['symbol'],
},
},
}];
const res = await groq.chat.completions.create({
model: 'llama-3.3-70b-versatile',
messages: [{ role: 'user', content: 'Quel est le cours de AAPL ?' }],
tools,
tool_choice: 'auto',
});
const call = res.choices[0].message.tool_calls?.[0];
if (call) {
const args = JSON.parse(call.function.arguments);
const price = await getStockPrice(args.symbol); // votre logique
// Renvoyer le resultat de l'outil au modele
const final = await groq.chat.completions.create({
model: 'llama-3.3-70b-versatile',
messages: [
{ role: 'user', content: 'Quel est le cours de AAPL ?' },
res.choices[0].message,
{ role: 'tool', tool_call_id: call.id, content: JSON.stringify(price) },
],
});
console.log(final.choices[0].message.content);
}
Rate limits et gestion des erreurs
Groq applique des limites de debit (requetes et tokens par minute). Un pattern de retry avec backoff exponentiel est indispensable en production.
// retry avec backoff exponentiel sur erreur 429
async function withRetry(fn, maxRetries = 4) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
// 429 = rate limit ; on retente avec un delai croissant
if (err.status === 429 && attempt < maxRetries) {
const delay = Math.min(1000 * 2 ** attempt, 16000);
console.warn(`Rate limit, nouvelle tentative dans ${delay}ms`);
await new Promise((r) => setTimeout(r, delay));
continue;
}
throw err; // autre erreur ou retries epuises
}
}
}
const res = await withRetry(() =>
groq.chat.completions.create({
model: 'llama-3.3-70b-versatile',
messages: [{ role: 'user', content: prompt }],
})
);
Cas d'usage ou la vitesse change tout
- Chatbots et assistants conversationnels reactifs
- Agents multi-etapes qui enchainent les appels LLM
- Classification et extraction sur de gros volumes
- Generation a la volee (suggestions, autocompletion)
- Pipelines de pre-traitement (resume, traduction batch)
- Transcription audio rapide via Whisper sur Groq
A l'inverse, pour du raisonnement de pointe (voir notre article sur les modeles de raisonnement) ou de la vision multimodale avancee, les modeles proprietaires conservent souvent l'avantage qualitatif. Une architecture hybride — Groq pour la vitesse, un modele premium pour les taches dures — est souvent le meilleur compromis.
Mesurer la vitesse : latence et debit
« Rapide » ne veut rien dire sans chiffres. Deux metriques comptent cote application : le TTFT (Time To First Token, le delai avant le premier caractere — il conditionne la sensation de reactivite) et le debit en tokens par seconde (qui determine la duree d'affichage d'une reponse longue). Voici comment les mesurer proprement en streaming.
// bench.js — mesurer TTFT et debit reel en streaming
import Groq from 'groq-sdk';
const groq = new Groq({ apiKey: process.env.GROQ_API_KEY });
async function bench(prompt) {
const t0 = Date.now();
let firstTokenAt = null;
let tokens = 0;
const stream = await groq.chat.completions.create({
model: 'llama-3.3-70b-versatile',
messages: [{ role: 'user', content: prompt }],
stream: true,
});
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content;
if (delta) {
if (firstTokenAt === null) firstTokenAt = Date.now(); // TTFT
tokens++;
}
}
const total = Date.now() - t0;
const ttft = firstTokenAt - t0;
return {
ttft, // ms avant le 1er token
debit: Math.round(tokens / ((total - ttft) / 1000)), // tokens/s
total,
};
}
const r = await bench('Explique le DOM virtuel.');
console.log(`TTFT ${r.ttft}ms | ${r.debit} tok/s | total ${r.total}ms`);
A titre indicatif, sur une application interactive, un TTFT inferieur a 200 ms est percu comme instantane. C'est precisement la ou Groq se distingue des fournisseurs GPU classiques. Le tableau ci-dessous resume les ordres de grandeur observes selon le profil de modele (les valeurs exactes evoluent avec les versions).
| Profil | TTFT typique | Debit | Ressenti utilisateur |
|---|---|---|---|
| Groq (LPU, modele 8B) | Tres faible | Tres eleve | Reponse quasi instantanee |
| Groq (LPU, modele 70B) | Faible | Eleve | Streaming tres fluide |
| GPU cloud classique 70B | Moyen | Modere | Attente perceptible |
| Modele de raisonnement | Eleve | Variable | Plusieurs secondes |
Integrer Groq dans une UI web resiliente
Cote front, deux details font la difference : permettre d'annuler une generation en cours (l'utilisateur change d'avis) et basculer sur un fournisseur de secours si Groq sature. On s'appuie sur AbortController et sur la strategie multi-provider vue plus haut.
// chat-client.ts — consommer le flux SSE avec annulation (TypeScript)
export async function streamChat(
question: string,
onToken: (t: string) => void,
signal: AbortSignal,
): Promise<void> {
const res = await fetch('/chat?q=' + encodeURIComponent(question), { signal });
if (!res.ok || !res.body) throw new Error('Flux indisponible');
const reader = res.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break;
for (const line of decoder.decode(value).split('\n\n')) {
const data = line.replace(/^data: /, '').trim();
if (!data || data === '[DONE]') continue;
onToken(JSON.parse(data).delta); // append au fur et a mesure
}
}
}
// Utilisation : un bouton "Stop" declenche controller.abort()
const controller = new AbortController();
streamChat('Resume cet article', (t) => appendToUI(t), controller.signal);
// server : fallback automatique Groq → OpenAI en cas de saturation
async function chatWithFallback(messages) {
try {
return await groq.chat.completions.create({
model: 'llama-3.3-70b-versatile', messages, stream: true,
});
} catch (err) {
// 429 / 503 cote Groq : on bascule sur un provider de secours
if ([429, 503].includes(err.status)) {
console.warn('Groq sature, bascule sur le provider de secours');
return openai.chat.completions.create({ model: 'gpt-4o-mini', messages, stream: true });
}
throw err;
}
}
Couts et choix de modele
Groq facture au token, avec des tarifs generalement competitifs sur les modeles open source. Le choix du modele equilibre vitesse, qualite et cout.
| Type de modele | Usage ideal | Compromis |
|---|---|---|
| Llama 70B versatile | Usage general, qualite/vitesse | Equilibre |
| Llama 8B instant | Classification, extraction massives | Tres rapide, moins fin |
| Mixtral | Contexte long, multilingue | Bon rapport qualite/prix |
| Gemma | Taches legeres | Compact et economique |
| Whisper | Transcription audio | Speech-to-text rapide |
Erreurs frequentes a l'integration
L'erreur numero un en passant a Groq depuis OpenAI : oublier de verifier la disponibilite du modele. Le catalogue Groq evolue (les modeles open source apparaissent et disparaissent au fil des versions), et un model code en dur peut renvoyer une 404 du jour au lendemain. Lisez l'identifiant du modele depuis votre configuration et gardez un modele de repli explicite.
Deuxieme piege, contre-intuitif : la latence reseau peut annuler le gain de vitesse du LPU. Si votre serveur appelle Groq depuis une region eloignee, le temps d'aller-retour reseau domine le temps d'inference. Placez votre backend au plus pres, et surtout streamez la reponse vers le navigateur plutot que d'attendre la generation complete cote serveur avant de relayer.
Cote front, beaucoup negligent la gestion de la deconnexion en cours de stream : si l'utilisateur ferme l'onglet ou navigue ailleurs, le flux SSE doit etre coupe proprement (via AbortController) sous peine de continuer a consommer des tokens pour rien. Enfin, ne faites jamais confiance au finish_reason implicitement : verifiez qu'il vaut bien stop et non length, signe que max_tokens a tronque la reponse au milieu d'une phrase.
Dernier point souvent sous-estime : le JSON mode et le function calling sont moins fiables sur les modeles open source que sur les modeles proprietaires de pointe. Un modele 8B « instant » peut renvoyer un JSON legerement malforme ou inventer un argument d'outil. Si votre application depend d'une sortie structuree stricte, validez systematiquement le JSON renvoye (avec Zod ou un schema JSON) et prevoyez un retry ou une escalade vers un modele plus capable en cas d'echec de parsing. La vitesse ne dispense jamais de la validation : un modele rapide qui renvoie une structure invalide une fois sur dix coute plus cher, en bugs et en retries, qu'un modele un peu plus lent mais fiable.
Conclusion
Groq resout un probleme precis et le resout brillamment : la latence de l'inference LLM. En servant des modeles open source sur son materiel LPU, il offre une vitesse qui transforme l'experience des chatbots, des agents et des pipelines de traitement. Sa compatibilite avec le SDK OpenAI rend l'adoption quasi gratuite : une baseURL a changer.
Integrez Groq la ou la reactivite compte, gardez un modele premium pour le raisonnement difficile, et abstrayez le provider derriere une configuration. Avec un retry robuste et un routage par modele, vous obtenez une stack IA a la fois rapide, economique et resiliente.
- LPU = inference LLM ultra-rapide (centaines de tokens/s)
- Modeles open source : Llama, Mixtral, Gemma, Whisper
- Compatible SDK OpenAI : changez juste la baseURL
- Ideal pour chatbots reactifs et agents multi-etapes
- Retry avec backoff sur les rate limits 429