Aller au contenu principal
Leçon 4 sur 12 · Chat Completions : compatibilité OpenAI

xAI SDK : client.chat.create

Leçon 4 sur 12 Mis à jour le 3 novembre 2026 Développeur
Sur cette page
  1. Le SDK natif xAI
  2. Installation et authentification
  3. Une conversation, pas une requête
  4. Paramètres de génération
  5. Streaming des réponses
  6. Gestion des erreurs
  7. Appel asynchrone
  8. Points clés à retenir

Leçon réécrite le 3 novembre 2026. La version précédente prêtait au SDK xai-sdk l’interface du SDK OpenAI : messages en dictionnaires, response.choices[0].message.content, paramètre stream=True et un module xai_sdk.errors qui n’existe pas. Avec le vrai SDK (version 1.21.0), ce code échoue dès le premier appel : ValueError: unknown enum label "user". La leçon suit désormais le README officiel du SDK, et chaque exemple a été exécuté contre l’API xAI (avec une clé factice, pour vérifier le chemin d’appel et les erreurs). Sources : xAI Python SDK · Best practices (xAI) · Debugging Errors (xAI).

Le SDK natif xAI

Le SDK officiel de xAI pour Python, xai-sdk, ne passe pas par l’endpoint REST Chat Completions : c’est une bibliothèque gRPC, avec un client synchrone (Client) et un client asynchrone (AsyncClient), pour Python 3.10 et plus. Il ne cherche pas à imiter le SDK OpenAI, et c’est la première chose à intégrer : ses objets, ses méthodes et ses erreurs ont leur propre forme. Pour réutiliser du code écrit pour OpenAI, la leçon suivante montre l’autre chemin, le SDK OpenAI pointé sur l’API xAI.

Installation et authentification

pip install xai-sdk

L’authentification se fait avec une clé d’API créée dans la console xAI. Placez-la dans la variable d’environnement XAI_API_KEY, que le client lit de lui-même :

export XAI_API_KEY="votre-cle-api"

Une conversation, pas une requête

Avec ce SDK, client.chat.create() n’envoie rien : il crée un objet conversation (chat), auquel vous ajoutez des messages avec append, puis vous demandez une réponse avec sample(). Les messages se construisent avec les fonctions system, user et assistant du module xai_sdk.chat, et non avec des dictionnaires.

from xai_sdk import Client
from xai_sdk.chat import system, user

client = Client()  # lit XAI_API_KEY

chat = client.chat.create(
    model="grok-4.7",
    messages=[system("Tu es un assistant utile. Réponds en français.")],
)
chat.append(user("Explique le deep learning en 3 phrases."))

response = chat.sample()
print(response.content)

La réponse expose directement son texte dans response.content, à côté de finish_reason, usage (les tokens consommés), reasoning_content pour les modèles qui l’exposent, et citations quand une recherche a été faite.

L’API reste sans état : c’est l’objet chat qui garde l’historique pour vous. Pour une conversation à plusieurs tours, ajoutez la réponse au fil avant la question suivante :

chat.append(response)
chat.append(user("Donne un exemple concret d'application."))
print(chat.sample().content)

Paramètres de génération

Les paramètres se passent à client.chat.create() et valent pour toute la conversation :

chat = client.chat.create(
    model="grok-4.7",
    messages=[system("Réponds uniquement en JSON.")],
    temperature=0.7,
    top_p=0.95,
    reasoning_effort="medium",
)
  • model : l’identifiant du modèle. xAI recommande grok-4.7 pour tout usage.
  • messages : les messages de départ, construits avec system, user et assistant.
  • temperature : l’API l’accepte de 0 à 2, mais xAI la ramène à 1 au-delà et recommande 0,7, avec top_p à 0,95.
  • max_tokens : le nombre maximal de tokens générés. Les bonnes pratiques de xAI conseillent de le fixer au-dessus de la plus longue réponse attendue, ou de laisser la valeur par défaut.
  • reasoning_effort : la profondeur de raisonnement, de none à high (et xhigh sur certains modèles). La valeur par défaut dépend du modèle : xAI recommande de la fixer explicitement à chaque requête, et de la noter avec chaque résultat.
  • response_format, tools, tool_choice : sorties structurées et appel d’outils, vus plus loin dans le cours.

stop existe aussi (jusqu’à quatre séquences), mais les bonnes pratiques de xAI précisent que les modèles de raisonnement ne l’acceptent pas, pas plus que presence_penalty et frequency_penalty.

Streaming des réponses

xAI recommande le streaming, en particulier avec les modèles de raisonnement, dont les réponses peuvent être longues à venir. Il ne passe pas par un paramètre : la conversation propose une seconde méthode, stream(), qui renvoie à chaque étape un couple (response, chunk). chunk.content contient le fragment de texte qui vient d’arriver, et response accumule la réponse complète au fil du flux.

chat = client.chat.create(model="grok-4.7")
chat.append(user("Écris un court article sur l'IA générative."))

for response, chunk in chat.stream():
    print(chunk.content, end="", flush=True)
print()

chat.append(response)  # la réponse complète rejoint l'historique

Gestion des erreurs

Comme le SDK parle gRPC, ses erreurs sont des grpc.RpcError (en asynchrone, des grpc.aio.AioRpcError, qui en héritent). On lit leur code avec .code() et le message avec .details() :

import grpc
from xai_sdk import Client
from xai_sdk.chat import user

client = Client()
chat = client.chat.create(model="grok-4.7")
chat.append(user("Bonjour"))

try:
    response = chat.sample()
    print(response.content)
except grpc.RpcError as erreur:
    if erreur.code() == grpc.StatusCode.DEADLINE_EXCEEDED:
        print("Délai dépassé : la requête a pris trop de temps.")
    else:
        print(f"Erreur {erreur.code().name} : {erreur.details()}")

Trois comportements valent d’être connus. Le SDK réessaie de lui-même les requêtes qui échouent avec UNAVAILABLE, jusqu’à cinq tentatives avec un délai croissant ; son README montre comment ajouter d’autres codes à cette liste, par exemple RESOURCE_EXHAUSTED, le code gRPC des quotas épuisés. Le délai d’attente par défaut est de 27 minutes pour toute requête et se règle à la création du client (Client(timeout=…), en secondes). Ne le réduisez pas trop : xAI conseille de prévoir au moins 900 secondes par requête avec ses modèles de raisonnement. Enfin, une clé d’API invalide se manifeste par le code INVALID_ARGUMENT et le message « Incorrect API key provided » : c’est ce que renvoie l’API aujourd’hui, vérifié le 3 novembre 2026.

Appel asynchrone

Pour une application asyncio, remplacez Client par AsyncClient. La création de la conversation reste synchrone ; ce sont sample() et stream() qui s’attendent :

import asyncio

from xai_sdk import AsyncClient
from xai_sdk.chat import user


async def main():
    client = AsyncClient()
    chat = client.chat.create(model="grok-4.7")
    chat.append(user("Bonjour"))

    response = await chat.sample()
    print(response.content)

    chat.append(response)
    chat.append(user("Résume ta réponse en une phrase."))
    async for response, chunk in chat.stream():
        print(chunk.content, end="", flush=True)


asyncio.run(main())

Points clés à retenir

  • xai-sdk est un SDK gRPC, avec sa propre interface : il ne reprend ni la forme ni les objets du SDK OpenAI
  • client.chat.create() crée une conversation ; chat.append(user(...)) ajoute un message, chat.sample() renvoie la réponse, lue dans response.content
  • Les messages se construisent avec system, user et assistant de xai_sdk.chat ; des dictionnaires font échouer l’appel
  • Le streaming passe par chat.stream(), qui renvoie des couples (response, chunk)
  • Les erreurs sont des grpc.RpcError ; UNAVAILABLE est réessayé automatiquement, le délai par défaut est de 27 minutes