Intégrer l'API OpenAI en JavaScript pour créer des applications IA avec GPT-4, le streaming et la gestion des tokens.
Installation et configuration
Le SDK officiel OpenAI est disponible pour Node.js et le navigateur.
npm install openai
Configure ton client avec ta clé API. Ne jamais exposer la clé côté client — utilise une variable d'environnement :
// openai.js
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY, // ou import.meta.env.VITE_OPENAI_API_KEY
});
export default openai;
.env et ajoute ce fichier dans .gitignore.
Premier appel Chat Completion
L'API Chat Completion est l'endpoint principal pour interagir avec GPT-4o, GPT-4 et GPT-3.5.
import openai from './openai.js';
async function chat(userMessage) {
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: 'Tu es un assistant expert en développement web.' },
{ role: 'user', content: userMessage }
],
max_tokens: 1000,
temperature: 0.7, // 0 = déterministe, 2 = très créatif
});
return response.choices[0].message.content;
}
const answer = await chat('Explique-moi les closures en JavaScript');
console.info((answer);
Pour une conversation multi-tours, accumule les messages dans un tableau :
const history = [
{ role: 'system', content: 'Tu es un assistant dev web.' }
];
async function sendMessage(userInput) {
history.push({ role: 'user', content: userInput });
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: history,
});
const reply = response.choices[0].message.content;
history.push({ role: 'assistant', content: reply });
return reply;
}
Streaming de la réponse
Le streaming affiche la réponse mot par mot dès que les tokens arrivent — indispensable pour une bonne UX.
async function streamChat(userMessage) {
const stream = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: userMessage }],
stream: true,
});
let fullResponse = '';
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content || '';
process.stdout.write(delta); // ou update le DOM en temps réel
fullResponse += delta;
}
return fullResponse;
}
Dans un contexte navigateur (React, Angular), mets à jour le state à chaque chunk :
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content || '';
setResponse(prev => prev + delta); // React useState
}
Function Calling
Le Function Calling permet au modèle de déclencher des fonctions dans ton code. Idéal pour connecter le LLM à des APIs externes.
const tools = [
{
type: 'function',
function: {
name: 'get_weather',
description: 'Obtenir la météo actuelle d\'une ville',
parameters: {
type: 'object',
properties: {
city: { type: 'string', description: 'Nom de la ville' }
},
required: ['city']
}
}
}
];
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Quel temps fait-il à Paris ?' }],
tools,
tool_choice: 'auto',
});
const toolCall = response.choices[0].message.tool_calls?.[0];
if (toolCall) {
const args = JSON.parse(toolCall.function.arguments);
const weather = await getWeather(args.city); // ta vraie fonction
console.info(weather);
}
Gestion des tokens et coûts
Chaque appel consomme des tokens (input + output). L'objet usage dans la réponse détaille la consommation.
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Bonjour' }],
});
console.info(response.usage);
// {
// prompt_tokens: 10,
// completion_tokens: 25,
// total_tokens: 35
// }
- 1 token ≈ 4 caractères en anglais / 3 en français
- GPT-4o : ~$5 / million tokens (input), ~$15 / million (output)
- GPT-4o-mini : ~$0.15 / million tokens — idéal pour les apps à fort volume
- Limite
max_tokenspour éviter les réponses trop longues
Bonnes pratiques
- Toujours valider et sanitiser les inputs utilisateur avant de les envoyer
- Implémenter un rate limiting côté serveur pour éviter les abus
- Utiliser un proxy serveur — ne jamais appeler l'API directement depuis le navigateur
- Stocker l'historique en base de données pour les conversations longues
- Gérer les erreurs (
RateLimitError,APIError) avec retry exponentiel
// Gestion des erreurs avec retry
import { APIError, RateLimitError } from 'openai';
try {
const response = await openai.chat.completions.create({ ... });
} catch (error) {
if (error instanceof RateLimitError) {
console.error('Quota atteint — attendez avant de réessayer');
} else if (error instanceof APIError) {
console.error(`Erreur API ${error.status}: ${error.message}`);
}
}