L’API OpenAI est devenue la référence pour intégrer des capacités d’intelligence artificielle dans les applications. Que vous construisiez un assistant client, un générateur de contenu, un système de classification ou un agent autonome, comprendre comment consommer cette API correctement fait la différence entre un prototype fragile et un système robuste en production. Ce guide vous accompagne de l’installation jusqu’aux patterns avancés, avec du code Python fonctionnel à chaque étape.

Installation et configuration de l’environnement

Commencez par créer un environnement virtuel Python dédié pour isoler vos dépendances. Utilisez `python -m venv .venv` puis `source .venv/bin/activate` (Linux/macOS) ou `.venvScriptsactivate` (Windows). Installez ensuite le SDK officiel OpenAI avec `pip install openai`. En 2026, la version 1.x du SDK est stable et apporte des améliorations significatives sur la gestion des erreurs et le support async par rapport aux versions 0.x.

La gestion de la clé API est critique pour la sécurité. Ne jamais coder la clé en dur dans votre code source — elle finirait inévitablement dans un dépôt Git public. Utilisez les variables d’environnement : créez un fichier `.env` à la racine de votre projet avec `OPENAI_API_KEY=sk-…`, ajoutez `.env` à votre `.gitignore`, et chargez-le avec la bibliothèque `python-dotenv` : `from dotenv import load_dotenv; load_dotenv()`. Le SDK OpenAI lit automatiquement la variable `OPENAI_API_KEY` de l’environnement.

Vérifiez votre installation avec un test minimal :
« `python
from openai import OpenAI
client = OpenAI() # Lit OPENAI_API_KEY automatiquement
response = client.chat.completions.create(
model=’gpt-4o-mini’,
messages=[{‘role’: ‘user’, ‘content’: ‘Dis bonjour en français’}]
)
print(response.choices[0].message.content)
« `
Si vous obtenez une réponse, votre setup est fonctionnel. Si vous recevez une `AuthenticationError`, vérifiez que votre clé est bien définie et n’a pas de guillemets superflus dans le fichier `.env`.

Chat Completions : le cœur de l’API

L’endpoint `chat.completions.create` est le plus utilisé. Il prend une liste de messages avec des rôles (`system`, `user`, `assistant`) et retourne la réponse du modèle. Le message `system` définit le comportement global du modèle : ton, domaine de compétence, contraintes. C’est votre ‘prompt de personnalité’. Les messages `user` sont les entrées de l’utilisateur, et les messages `assistant` représentent les réponses précédentes du modèle dans une conversation multi-tours.

Pour une conversation multi-tours, maintenez une liste de messages que vous enrichissez à chaque échange :
« `python
history = [{‘role’: ‘system’, ‘content’: ‘Tu es un assistant expert WordPress.’}]
while True:
user_input = input(‘Vous : ‘)
history.append({‘role’: ‘user’, ‘content’: user_input})
resp = client.chat.completions.create(model=’gpt-4o’, messages=history)
answer = resp.choices[0].message.content
history.append({‘role’: ‘assistant’, ‘content’: answer})
print(f’Assistant : {answer}’)
« `
Attention à la croissance de l’historique : chaque token dans `messages` est facturé. Pour les conversations longues, implémentez une stratégie de fenêtrage (sliding window) ou un résumé automatique des messages anciens.

Les paramètres les plus importants de `chat.completions.create` : `temperature` (0 à 2, contrôle la créativité — 0 pour des réponses déterministes, 0.7 pour un équilibre créativité/cohérence), `max_tokens` (limite la longueur de la réponse, attention à ne pas tronquer), `top_p` (alternative à temperature, recommandé de ne pas modifier les deux simultanément), et `response_format` qui accepte `{‘type’: ‘json_object’}` pour forcer une réponse JSON valide — indispensable pour les applications qui parsent la réponse.

Streaming : afficher les réponses en temps réel

Le streaming permet d’afficher la réponse token par token au lieu d’attendre la génération complète. C’est indispensable pour les interfaces utilisateur : personne n’attend 10 secondes une réponse complète alors qu’on pourrait voir les premiers mots apparaître en 500 ms. Activez le streaming avec `stream=True` :
« `python
stream = client.chat.completions.create(
model=’gpt-4o’,
messages=[{‘role’: ‘user’, ‘content’: ‘Explique le machine learning’}],
stream=True
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end= », flush=True)
print() # Saut de ligne final
« `

Dans une application web Flask ou FastAPI, le streaming se fait via les Server-Sent Events (SSE) ou les WebSockets. FastAPI supporte nativement le streaming avec `StreamingResponse` et un générateur asynchrone. Le pattern est toujours le même : itérer sur les chunks du stream OpenAI et les pousser immédiatement vers le client HTTP. Cette architecture réduit la latence perçue de 70 à 90 % par rapport à une réponse bloquante.

Attention à la gestion des erreurs en mode streaming. Une fois le flux ouvert, les erreurs réseau ou API se produisent au milieu du stream, pas avant. Encadrez votre boucle d’itération dans un bloc `try/except` qui capture `openai.APIError`, `openai.APIConnectionError` et `openai.RateLimitError`. Implémentez une logique de retry avec backoff exponentiel pour les erreurs temporaires (429 Rate Limit, 503 Service Unavailable).

Gestion des tokens et contrôle des coûts

Chaque appel API est facturé en tokens — des unités textuelles correspondant approximativement à 0,75 mot en anglais (légèrement plus en français à cause des accents et de la morphologie). En 2026, GPT-4o facture 2,5 $ pour 1M tokens d’entrée et 10 $ pour 1M tokens de sortie. GPT-4o-mini est 15× moins cher : 0,15 $/1M en entrée, 0,6 $/1M en sortie. Pour estimer vos coûts, utilisez la bibliothèque `tiktoken` : `import tiktoken; enc = tiktoken.encoding_for_model(‘gpt-4o’); len(enc.encode(text))`.

Les stratégies de réduction de coûts : premièrement, choisissez le bon modèle. GPT-4o-mini est suffisant pour la classification, la structuration de données, les résumés simples et les réponses FAQ. Réservez GPT-4o ou o3 pour les tâches complexes nécessitant un raisonnement multi-étapes. Deuxièmement, compressez vos prompts système. Un prompt système verbeux de 2000 tokens est facturé à chaque appel — compressez-le sans en sacrifier la précision.

Troisièmement, utilisez le caching de prompts d’OpenAI pour les contextes répétitifs. Depuis fin 2024, OpenAI applique automatiquement un cache sur les préfixes de prompts identiques de plus de 1024 tokens, réduisant leur coût de 50 %. Si votre système prompt est long et stable, il sera automatiquement mis en cache après quelques appels. Quatrièmement, paginez vos batches : l’API Batch permet de traiter des dizaines de milliers de requêtes de manière asynchrone avec 50 % de réduction tarifaire pour un délai de réponse de 24 heures.

Fonctions et outils : faire agir le modèle

L’API Function Calling (rebrandé ‘Tools’ en 2024) permet au modèle de décider d’appeler des fonctions externes et de structurer ses paramètres. C’est la base des agents IA : le modèle peut chercher des informations en temps réel, exécuter des actions dans votre système ou interroger une base de données selon le contexte. Vous définissez les outils disponibles dans le paramètre `tools` de la requête :
« `python
tools = [{‘type’: ‘function’, ‘function’: {
‘name’: ‘get_weather’,
‘description’: ‘Retourne la météo pour une ville’,
‘parameters’: {‘type’: ‘object’, ‘properties’: {
‘city’: {‘type’: ‘string’, ‘description’: ‘Nom de la ville’}
}, ‘required’: [‘city’]}
}}]
« `

Le flux de traitement est le suivant : le modèle retourne `finish_reason=’tool_calls’` avec les paramètres de la fonction à appeler. Votre code exécute réellement la fonction, puis renvoie le résultat dans un nouveau message de rôle `tool`. Le modèle intègre ce résultat et génère sa réponse finale. Ce cycle peut se répéter plusieurs fois si le modèle doit utiliser plusieurs outils en séquence — c’est le principe des agents ReAct (Reason + Act).

Pour les applications de production, utilisez le paramètre `tool_choice: ‘required’` lorsque vous voulez forcer l’usage d’un outil spécifique, ou `tool_choice: {‘type’: ‘function’, ‘function’: {‘name’: ‘X’}}` pour imposer une fonction précise. Le paramètre `parallel_tool_calls: True` (activé par défaut) permet au modèle d’appeler plusieurs outils simultanément — particulièrement utile pour les requêtes d’enrichissement parallèle.

Gestion des erreurs et bonnes pratiques de production

En production, les erreurs API sont inévitables. Les plus courantes : `RateLimitError` (429 — vous avez dépassé votre quota de tokens par minute), `APIConnectionError` (problème réseau transitoire), `APITimeoutError` (le modèle met trop longtemps à répondre), et `BadRequestError` (prompt invalide, contexte trop long). Implémentez un décorateur de retry avec backoff exponentiel en utilisant la bibliothèque `tenacity` : `@retry(wait=wait_exponential(min=1, max=60), stop=stop_after_attempt(3), retry=retry_if_exception_type(RateLimitError))`.

Logguez systématiquement vos appels API : model utilisé, nombre de tokens d’entrée/sortie (`response.usage.prompt_tokens`, `response.usage.completion_tokens`), latence, et un identifiant de session. Ces métriques vous permettront d’optimiser vos coûts, de détecter les dérives de qualité et de debugger les cas limites. En production, utilisez un système de logging structuré (structlog ou loguru) plutôt que des `print()`.

Enfin, ne jamais exposer votre clé API côté client (JavaScript frontend). Toutes les requêtes OpenAI doivent transiter par votre backend. Implémentez une authentification utilisateur sur votre API backend et un rate limiting par utilisateur pour éviter les abus. En 2026, les applications qui exposent leur clé OpenAI côté client sont régulièrement détectées et drainées de leurs crédits en quelques heures par des bots automatisés.

Structured Outputs : garantir la structure JSON des réponses

Depuis fin 2024, OpenAI propose les Structured Outputs — une évolution du mode JSON qui garantit que la réponse respecte un schéma JSON Schema précis. Contrairement à `response_format: {‘type’: ‘json_object’}` qui garantit seulement du JSON valide (mais sans garantie de structure), les Structured Outputs garantissent que tous les champs requis sont présents avec les bons types. Pour les utiliser, définissez votre schéma Pydantic et passez-le via `response_format` :

« `python
from pydantic import BaseModel
from openai import OpenAI

client = OpenAI()

class ArticleAnalysis(BaseModel):
titre: str
mots_cles: list[str]
score_qualite: int
resume: str

result = client.beta.chat.completions.parse(
model=’gpt-4o-2024-11-20′,
messages=[{‘role’: ‘user’, ‘content’: ‘Analyse cet article : …’}],
response_format=ArticleAnalysis
)
analysis = result.choices[0].message.parsed
print(analysis.mots_cles) # Toujours une liste de strings
« `
Le modèle retourne directement un objet Python typé — plus de parsing manuel, plus de KeyError surprise. Cette approche est indispensable pour les pipelines de traitement de données où la cohérence des sorties conditionne les étapes suivantes.

Les Structured Outputs supportent les types JSON Schema standards : string, number, boolean, array, object, enum, et les types optionnels (anyOf avec null). Les types Pydantic complexes (Union, Optional, Literal, nested models) sont automatiquement convertis en JSON Schema par le SDK. Attention : certains modèles plus anciens ne supportent pas les Structured Outputs — vérifiez la documentation OpenAI pour la liste des modèles compatibles.

Embeddings et recherche sémantique : aller plus loin avec l’API

Au-delà du chat, l’API OpenAI expose l’endpoint `embeddings` qui convertit du texte en vecteurs numériques (embeddings). Ces vecteurs capturent le sens sémantique du texte : deux phrases sémantiquement proches auront des vecteurs proches (distance cosinus faible). C’est la base des systèmes RAG (Retrieval-Augmented Generation) qui permettent à un LLM de répondre à des questions sur votre base de données privée.

Exemple d’utilisation : `response = client.embeddings.create(input=’votre texte’, model=’text-embedding-3-small’)`. Le modèle `text-embedding-3-small` génère des vecteurs de 1536 dimensions et est 5× moins cher que `text-embedding-ada-002` pour des performances similaires. Stockez ces vecteurs dans une base de données vectorielle (pgvector pour PostgreSQL, Chroma, Pinecone, Qdrant) et effectuez des recherches par similarité cosinus pour retrouver les passages les plus pertinents par rapport à une question utilisateur.

Le pipeline RAG complet : indexation (découper vos documents en chunks, générer les embeddings, stocker en base vectorielle), puis au moment de la requête utilisateur (convertir la question en embedding, rechercher les N chunks les plus similaires, passer ces chunks dans le contexte du LLM avec la question). Ce pattern permet à GPT-4o de répondre sur vos données internes sans fine-tuning et avec une fenêtre de contexte quasi illimitée (via l’indexation). Des frameworks comme LangChain et LlamaIndex automatisent ce pipeline.

Sources et références

G
WP Admin Lab

Architecte web full-stack. WordPress, performance, data et sécurité. Notes de terrain, tests reproductibles et retours d'expérience.