Prérequis
Avant de commencer, assurez-vous d'avoir :
- Node.js 20 ou version ultérieure
- Un projet Next.js 15 (ou créez-en un avec
npx create-next-app@latest) - Un compte Groq Cloud et une clé API depuis
console.groq.com - Des connaissances de base en TypeScript et React
Ce que vous allez construire
Vous allez créer une application de chat IA en streaming prête pour la production, utilisant l'API d'inférence de Groq avec Llama 4 Scout. À la fin, vous disposerez :
- D'une route API Next.js qui diffuse les complétions Groq vers le navigateur
- D'une interface de chat React avec streaming de tokens en temps réel et métriques de vitesse
- Du support de l'appel d'outils (Function Calling) avec validation des arguments
- De la sélection de modèle parmi les modèles disponibles sur Groq
- D'une gestion robuste des erreurs avec backoff exponentiel
Groq atteint plus de 800 tokens par seconde sur Llama 4 Scout — soit environ 10 fois plus rapide que la plupart des fournisseurs d'inférence hébergés. C'est idéal pour les applications sensibles à la latence comme les assistants de code, les Q&R en temps réel et les workflows agentiques.
Étape 1 : Configurer votre compte Groq
- Rendez-vous sur
console.groq.comet créez un compte gratuit. - Naviguez vers API Keys et cliquez sur Create API Key.
- Copiez votre clé — elle commence par
gsk_. - Ajoutez-la dans
.env.localà la racine de votre projet.
Le niveau gratuit inclut des limites généreuses pour le développement — 30 requêtes par minute sur la plupart des modèles. Les plans payants offrent des limites plus élevées et une capacité dédiée pour la production.
Étape 2 : Installer le SDK Groq
Dans votre projet Next.js, installez le SDK TypeScript officiel de Groq :
pnpm add groq-sdkAjoutez votre clé API dans .env.local :
GROQ_API_KEY=gsk_votre_clé_iciSécurité : N'exposez jamais votre GROQ_API_KEY côté client. Appelez toujours Groq depuis des routes API côté serveur ou des Server Actions. Next.js exclut automatiquement les variables d'environnement sans le préfixe NEXT_PUBLIC_ du bundle client.
Étape 3 : Initialiser le client Groq
Créez lib/groq.ts pour initialiser le client Groq en tant que singleton :
import Groq from 'groq-sdk';
export const groq = new Groq({
apiKey: process.env.GROQ_API_KEY,
});Testez une complétion simple pour confirmer que votre configuration fonctionne :
// scripts/test-groq.ts
import { groq } from '../lib/groq';
const completion = await groq.chat.completions.create({
model: 'llama-4-scout-17b-16e-instruct',
messages: [
{
role: 'user',
content: "Expliquez ce qui distingue Groq des autres fournisseurs d'inférence IA en deux phrases.",
},
],
max_tokens: 256,
});
console.log(completion.choices[0].message.content);
console.log('Utilisation :', completion.usage);Exécutez-le :
npx tsx scripts/test-groq.tsVous obtiendrez une réponse en moins de 500 millisecondes, accompagnée des métadonnées d'utilisation indiquant le nombre de tokens et le temps d'inférence.
Étape 4 : Choisir le bon modèle
Groq supporte plusieurs modèles ouverts en 2026. Choisissez selon votre cas d'usage :
| ID du modèle | Contexte | Idéal pour |
|---|---|---|
llama-4-scout-17b-16e-instruct | 131k | Chat rapide, code, Q&R |
llama-4-maverick-17b-128e-instruct | 131k | Raisonnement complexe, longs documents |
llama-3.3-70b-versatile | 128k | Tâches à haute précision |
mixtral-8x7b-32768 | 32k | Équilibre vitesse/qualité |
gemma2-9b-it | 8k | Déploiements légers ou à faible budget |
Recommandation : Pour la plupart des applications de chat et agentiques, commencez avec llama-4-scout-17b-16e-instruct. Il tourne à plus de 800 tokens par seconde avec une fenêtre de contexte de 131k tokens — suffisante pour la plupart des cas réels, et les limites du niveau gratuit sont généreuses.
Étape 5 : Implémenter le streaming dans une route API Next.js
Le streaming est essentiel pour une bonne UX de chat — les utilisateurs voient les tokens apparaître immédiatement plutôt que d'attendre la réponse complète. Créez app/api/chat/route.ts :
import { groq } from '@/lib/groq';
import { NextRequest } from 'next/server';
export const runtime = 'nodejs';
export async function POST(req: NextRequest) {
const { messages, model = 'llama-4-scout-17b-16e-instruct' } = await req.json();
const stream = await groq.chat.completions.create({
model,
messages,
stream: true,
max_tokens: 1024,
temperature: 0.7,
});
const encoder = new TextEncoder();
const readable = new ReadableStream({
async start(controller) {
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content ?? '';
if (delta) {
controller.enqueue(encoder.encode(delta));
}
}
controller.close();
},
});
return new Response(readable, {
headers: {
'Content-Type': 'text/plain; charset=utf-8',
'Transfer-Encoding': 'chunked',
'X-Content-Type-Options': 'nosniff',
},
});
}Cette route :
- Accepte une requête POST avec
messageset unmodeloptionnel - Ouvre une connexion en streaming vers Groq
- Transmet chaque token au navigateur dès que Groq le produit
- Ferme le stream proprement à la fin
Étape 6 : Créer l'interface de chat en streaming
Créez components/GroqChat.tsx avec le streaming en temps réel et les métriques de vitesse :
'use client';
import { useState, useRef } from 'react';
interface Message {
role: 'user' | 'assistant';
content: string;
}
const MODELS = [
{ value: 'llama-4-scout-17b-16e-instruct', label: 'Llama 4 Scout (le plus rapide)' },
{ value: 'llama-4-maverick-17b-128e-instruct', label: 'Llama 4 Maverick' },
{ value: 'llama-3.3-70b-versatile', label: 'Llama 3.3 70B' },
{ value: 'mixtral-8x7b-32768', label: 'Mixtral 8x7B' },
];
export function GroqChat() {
const [messages, setMessages] = useState<Message[]>([]);
const [input, setInput] = useState('');
const [model, setModel] = useState(MODELS[0].value);
const [loading, setLoading] = useState(false);
const [tokensPerSec, setTokensPerSec] = useState<number | null>(null);
const abortRef = useRef<AbortController | null>(null);
async function sendMessage() {
if (!input.trim() || loading) return;
const userMessage: Message = { role: 'user', content: input };
const newMessages = [...messages, userMessage];
setMessages(newMessages);
setInput('');
setLoading(true);
setTokensPerSec(null);
const assistantMessage: Message = { role: 'assistant', content: '' };
setMessages([...newMessages, assistantMessage]);
abortRef.current = new AbortController();
const startTime = performance.now();
let tokenCount = 0;
try {
const res = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ messages: newMessages, model }),
signal: abortRef.current.signal,
});
const reader = res.body!.getReader();
const decoder = new TextDecoder();
let accumulated = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
accumulated += chunk;
tokenCount += chunk.split(' ').length;
setMessages(prev => [
...prev.slice(0, -1),
{ role: 'assistant', content: accumulated },
]);
}
const elapsed = (performance.now() - startTime) / 1000;
setTokensPerSec(Math.round(tokenCount / elapsed));
} catch (err: unknown) {
if (err instanceof Error && err.name !== 'AbortError') {
console.error('Erreur de streaming Groq :', err);
}
} finally {
setLoading(false);
}
}
return (
<div className="max-w-2xl mx-auto p-4 flex flex-col gap-4">
<div className="flex items-center gap-2">
<select
value={model}
onChange={e => setModel(e.target.value)}
className="border rounded px-2 py-1 text-sm"
>
{MODELS.map(m => (
<option key={m.value} value={m.value}>{m.label}</option>
))}
</select>
{tokensPerSec !== null && (
<span className="text-sm text-green-600 font-mono">
{tokensPerSec} tok/s
</span>
)}
</div>
<div className="flex flex-col gap-2 min-h-64 border rounded p-3 bg-gray-50">
{messages.map((msg, i) => (
<div
key={i}
className={`rounded p-2 text-sm whitespace-pre-wrap ${
msg.role === 'user' ? 'bg-blue-100 self-end' : 'bg-white self-start'
}`}
>
{msg.content}
</div>
))}
{loading && messages.at(-1)?.content === '' && (
<div className="text-gray-400 text-sm animate-pulse">En cours de réflexion…</div>
)}
</div>
<div className="flex gap-2">
<input
value={input}
onChange={e => setInput(e.target.value)}
onKeyDown={e => e.key === 'Enter' && !e.shiftKey && sendMessage()}
placeholder="Tapez un message…"
className="flex-1 border rounded px-3 py-2 text-sm"
disabled={loading}
/>
<button
onClick={loading ? () => abortRef.current?.abort() : sendMessage}
className="px-4 py-2 bg-blue-600 text-white rounded text-sm"
>
{loading ? 'Arrêter' : 'Envoyer'}
</button>
</div>
</div>
);
}Utilisez le composant dans une page :
// app/chat/page.tsx
import { GroqChat } from '@/components/GroqChat';
export default function ChatPage() {
return (
<main className="py-12">
<h1 className="text-2xl font-bold text-center mb-8">Chat IA avec Groq</h1>
<GroqChat />
</main>
);
}Étape 7 : Ajouter l'appel d'outils
Groq supporte l'appel d'outils compatible OpenAI sur les modèles Llama 4 et Llama 3.3. Voici un exemple complet avec un outil météo :
import Groq from 'groq-sdk';
import { z } from 'zod';
import { groq } from '@/lib/groq';
const tools: Groq.Chat.Completions.ChatCompletionTool[] = [
{
type: 'function',
function: {
name: 'get_weather',
description: 'Obtenir la météo actuelle pour une ville',
parameters: {
type: 'object',
properties: {
city: { type: 'string', description: 'Nom de la ville' },
unit: { type: 'string', enum: ['celsius', 'fahrenheit'] },
},
required: ['city'],
},
},
},
];
const WeatherArgs = z.object({
city: z.string(),
unit: z.enum(['celsius', 'fahrenheit']).default('celsius'),
});
async function getWeather(city: string, unit: string) {
// Remplacez par un vrai appel API météo en production
return { city, temperature: unit === 'celsius' ? 22 : 72, condition: 'ensoleillé' };
}
export async function chatWithTools(userMessage: string) {
const messages: Groq.Chat.Completions.ChatCompletionMessageParam[] = [
{ role: 'user', content: userMessage },
];
const response = await groq.chat.completions.create({
model: 'llama-4-scout-17b-16e-instruct',
messages,
tools,
tool_choice: 'auto',
});
const toolCalls = response.choices[0].message.tool_calls;
if (!toolCalls?.length) {
return response.choices[0].message.content;
}
const toolResults = await Promise.all(
toolCalls.map(async tc => {
const args = WeatherArgs.parse(JSON.parse(tc.function.arguments));
const result = await getWeather(args.city, args.unit);
return {
tool_call_id: tc.id,
role: 'tool' as const,
content: JSON.stringify(result),
};
})
);
const finalResponse = await groq.chat.completions.create({
model: 'llama-4-scout-17b-16e-instruct',
messages: [
...messages,
response.choices[0].message,
...toolResults,
],
});
return finalResponse.choices[0].message.content;
}Conseil de validation : Parsez toujours les arguments des appels d'outils avec Zod avant de les exécuter. Le modèle peut occasionnellement produire du JSON malformé — la validation empêche ces erreurs de se propager.
Étape 8 : Prompts système pour assistants spécialisés
Les prompts système définissent le comportement et la personnalité de l'assistant. Voici une configuration pour un assistant de code :
const CODING_ASSISTANT_PROMPT = `Tu es un expert en TypeScript et React.
- Fournis toujours des exemples de code complets et fonctionnels
- Explique le raisonnement derrière les décisions architecturales
- Signale les problèmes de performance ou les failles de sécurité potentielles
- Garde les explications concises mais complètes`;
const completion = await groq.chat.completions.create({
model: 'llama-4-maverick-17b-128e-instruct',
messages: [
{ role: 'system', content: CODING_ASSISTANT_PROMPT },
{ role: 'user', content: 'Comment implémenter les mises à jour optimistes dans React Query v5 ?' },
],
max_tokens: 2048,
temperature: 0.3,
});Guide de température :
- 0.1–0.3 — réponses factuelles et cohérentes (Q&R techniques, génération de code)
- 0.5–0.7 — équilibre créativité et cohérence (chat général)
- 0.8–1.0 — réponses plus variées et créatives (brainstorming, rédaction)
Étape 9 : Gestion des erreurs avec backoff exponentiel
Le niveau gratuit a des limites de débit. Implémentez une gestion robuste des erreurs :
import Groq from 'groq-sdk';
import { groq } from '@/lib/groq';
export async function safeGroqCompletion(
messages: Groq.Chat.Completions.ChatCompletionMessageParam[],
retries = 3
): Promise<string | null> {
for (let attempt = 0; attempt < retries; attempt++) {
try {
const completion = await groq.chat.completions.create({
model: 'llama-4-scout-17b-16e-instruct',
messages,
max_tokens: 1024,
});
return completion.choices[0].message.content;
} catch (error) {
if (error instanceof Groq.RateLimitError) {
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
if (error instanceof Groq.APIError) {
console.error(`Erreur API Groq ${error.status} :`, error.message);
return null;
}
throw error;
}
}
return null;
}Conseil de production : Mettez en cache les requêtes répétées avec Upstash Redis ou un cache similaire avec TTL. De nombreux utilisateurs posent des questions similaires — le cache réduit les coûts et la pression sur les limites de débit. Un TTL de 5 minutes sur les prompts déterministes (temperature 0) est un bon point de départ.
Étape 10 : Mesurer et comparer les performances
L'un des principaux avantages de Groq est la vitesse brute. Suivez-la avec vos métriques applicatives :
export async function completionWithMetrics(prompt: string) {
const start = Date.now();
const completion = await groq.chat.completions.create({
model: 'llama-4-scout-17b-16e-instruct',
messages: [{ role: 'user', content: prompt }],
max_tokens: 512,
});
const elapsed = (Date.now() - start) / 1000;
const usage = completion.usage!;
return {
content: completion.choices[0].message.content,
metrics: {
totalTokens: usage.total_tokens,
completionTokens: usage.completion_tokens,
promptTokens: usage.prompt_tokens,
elapsedSeconds: elapsed,
tokensPerSecond: Math.round(usage.completion_tokens / elapsed),
},
};
}Groq délivre régulièrement plus de 800 tokens par seconde sur Llama 4 Scout. À titre de comparaison, la plupart des fournisseurs d'inférence hébergés délivrent 30 à 80 tokens par seconde. Cet avantage de vitesse est particulièrement notable dans les boucles agentiques où 5 à 10 appels LLM séquentiels se produisent par requête utilisateur.
Dépannage
Erreur "Invalid API Key"
Assurez-vous que votre clé commence par gsk_ et qu'elle est définie dans .env.local, pas .env. Next.js charge automatiquement .env.local uniquement en développement.
Erreurs de limite de débit en développement
Le niveau gratuit autorise 30 requêtes par minute sur la plupart des modèles. Utilisez le backoff exponentiel (Étape 9) et pensez à basculer sur gemma2-9b-it pendant le développement — il dispose d'un bucket de limite de débit séparé, moins sollicité.
Le streaming ne fonctionne pas en production
Assurez-vous que votre plateforme de déploiement supporte les réponses en streaming. Vercel, Cloudflare Workers et Railway supportent tous le streaming. Ajoutez export const runtime = 'nodejs' à votre route API si vous rencontrez des problèmes sur des environnements edge.
Erreurs de parsing des appels d'outils Parsez toujours les arguments des outils avec Zod avant de les exécuter (Étape 7). Le LLM peut occasionnellement produire du JSON malformé — la validation empêche sa propagation.
Fenêtre de contexte dépassée Llama 4 Scout dispose d'une fenêtre de contexte de 131k tokens. Si vous atteignez les limites, élaguez les messages les plus anciens de l'historique tout en conservant le prompt système et les N derniers échanges. Une fenêtre glissante de 20 messages est un bon défaut pratique.
Prochaines étapes
- Explorez les endpoints vision de Groq pour les tâches de compréhension d'images multimodales
- Essayez l'API de transcription audio de Groq (Whisper v3 Large) — elle traite l'audio à 189x la vitesse en temps réel
- Construisez un workflow multi-agents où Groq gère les décisions rapides et Claude le raisonnement complexe
- Ajoutez Langfuse pour l'observabilité LLM et la gestion des versions de prompts entre fournisseurs
- Implémentez Cloudflare Workers comme edge proxy devant Groq pour une inférence mondiale à faible latence
Conclusion
La vitesse d'inférence de Groq change fondamentalement ce qui est possible dans les applications IA. À plus de 800 tokens par seconde, vous pouvez créer des expériences IA véritablement réactives — des assistants de code qui semblent instantanés, des workflows agentiques qui se terminent en secondes plutôt qu'en minutes, et des fonctionnalités IA en temps réel qui ne compromettent pas l'UX.
La conception de l'API Groq SDK compatible OpenAI signifie que vous pouvez migrer des projets OpenAI existants avec un minimum de modifications de code. Associé à la fenêtre de contexte de 131k tokens de Llama 4 Scout, à ses solides capacités de code et de raisonnement, et à son niveau gratuit généreux, Groq est l'un des choix les plus pratiques pour les applications IA en production en 2026.