Les éléments d'une requête
- Leçon 3
- 50 min
- Module 1 : Commencer par une seule requête au modèle
Leçon 3 sur 19 · Créer des applications fiables avec les API de LLMLes éléments d'une requête
1. Commencer par une seule requête au modèle
2. La rédaction de requêtes, une tâche d'ingénierie
3. Sorties structurées et validation
4. Appeler des outils en toute sécurité
5. Conversations et diffusion en continu
6. Contrôles de fiabilité et de coût
Ce que vous saurez faire
Lisez chaque partie d’une vraie requête à un modèle de langage et de sa réponse. Comprenez le rôle de chacune. Ainsi, un paramètre refusé par le modèle ou une réponse interrompue ne prendra pas votre code au dépourvu.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Les parties d’une requête HTTP (méthode, chemin, en-têtes, corps) et les codes d’état. Vous les avez vus dans Les bases de HTTP, dans Créer et déployer votre première API.
- La température, dans Prédire la suite : température, et les jetons de raisonnement cachés, dans Raisonnement et multimodalité : l’idée. Les deux font partie de Les LLM : comment ils fonctionnent et comment en choisir un.
Ce qu’il vous faut sur votre ordinateur
- Le projet
ticket-assistanttel que vous l’avez laissé dans Un premier essai sans compte, avec.venvactif :python -m pytestaffiche2 passed(2 tests réussis). Sinon, réinitialisez le projet comme dans cette leçon.
Vous n’avez besoin ni de compte ni de clé. La dernière section propose un appel réel facultatif. Avec Ollama, il est gratuit. Avec votre propre clé, il coûte une fraction de cent.
Le formulaire au comptoir du service de messagerie
Section intitulée « Le formulaire au comptoir du service de messagerie »Pour envoyer un colis, vous remplissez un formulaire. Il contient des cases fixes : l’adresse, votre numéro de compte, le service (standard ou express), le contenu et votre prix maximal. Le reçu contient aussi des cases fixes : un numéro de suivi, le poids, le prix et, plus tard, un état. Par exemple, « livré » ou « retourné : adresse incomplète ».
Vous n’avez pas besoin de savoir comment fonctionnent les camions du service de messagerie. Mais vous devez comprendre chaque case du formulaire. Une erreur dans une case envoie le colis à la mauvaise adresse, ou l’empêche de partir.
Le problème : un champ mal compris peut échouer sans bruit
Section intitulée « Le problème : un champ mal compris peut échouer sans bruit »TermeAmiraLa développeuse de Larkfield. Elle écrit le code des outils du service d’assistance dans les cours. voulait que l’assistant donne toujours la même réponse au même billet de soutien. Dans le cours sur les modèles de langage, une TermeTempératureUn paramètre qui contrôle à quel point un modèle varie son choix du jeton suivant. À 0, il prend presque toujours le jeton le plus probable. Des valeurs plus hautes donnent des réponses plus variées.En savoir plus Prédire la suiteLes LLM : comment ils fonctionnent et comment en choisir un de 0 permettait cela. Elle a donc ajouté "temperature": 0 à la requête. Le fournisseur a répondu par une erreur, HTTP 400 :
Unsupported value: 'temperature' does not support 0 with this model. Only the default (1) value is supported.Ensuite, elle a voulu économiser et a fixé la limite de sortie à 40 jetons. Cette fois, aucune erreur. La réponse avait le code d’état 200, mais son texte était vide : "". Ce sont deux vraies réponses de Termechat-smallLe nom que le code de Larkfield donne à un petit modèle hébergé peu coûteux : gpt-6-luna sur Azure. Le code utilise ce nom, donc le modèle peut changer sans modifier le code.En savoir plus Ce qu'est une API de LLMCréer des applications fiables avec les API de LLM.
Le premier échec est visible : le code reçoit une erreur. Le second est silencieux : le code qui lit seulement le texte de la réponse ne reçoit rien, sans savoir pourquoi. Pour éviter les deux, vous devez lire la requête et la réponse champ par champ.
L’idée : chaque champ a un rôle
Section intitulée « L’idée : chaque champ a un rôle »L’anatomie d’une requête décrit ses parties et leurs rôles, comme l’anatomie d’un corps décrit ses organes. Voici les parties d’une requête Chat Completions :
- Le point de terminaison : l’adresse du fournisseur et le chemin d’une opération, ici
/chat/completions. - L’identifiant d’accès : la clé d’API, dans l’en-tête
Authorization(autorisation). - L’identifiant du modèle : le modèle qui doit répondre.
- Les messages, chacun avec un rôle.
system(système) contient les instructions de l’application.user(utilisateur) contient le texte à traiter.assistantcontient une réponse précédente du modèle dans une conversation (module 5). Certains fournisseurs nomment le rôle systèmedeveloper(développeur). - Les paramètres de génération : par exemple
max_completion_tokens, la limite de sortie, ettemperature(température).
La réponse a ses propres parties : un code d’état HTTP, des en-têtes, un identifiant et le modèle qui a répondu. Elle contient aussi la réponse sous forme de message avec le rôle assistant, la raison d’arrêt et l’utilisation. La raison d’arrêt indique pourquoi le modèle s’est arrêté : "stop" (arrêt) lorsqu’il a terminé, "length" (longueur) lorsqu’il a atteint la limite de sortie.
Petit exemple détaillé : la vraie requête pour T-80008
Section intitulée « Petit exemple détaillé : la vraie requête pour T-80008 »Voici la vraie requête, en HTTP simple. Elle a été enregistrée pour le billet T-80008, la requête v1 et chat-small. La clé et le nom de la ressource sont masqués. Le message système contient 4 407 caractères. La majeure partie est donc coupée ici.
POST https://<your-resource>.cognitiveservices.azure.com/openai/v1/chat/completionsAuthorization: Bearer [REDACTED]Content-Type: application/json
{ "model": "chat-small", "messages": [ {"role": "system", "content": "You are Larkfield's support assistant. Read the support policy and the customer's ticket. … Policy: …"}, {"role": "user", "content": "Ticket:\nHello, where is my order LK-581106? The confirmation email said the garden shed shipped on Monday, but I have no delivery date yet."} ], "max_completion_tokens": 1000}Et voici la réponse, 3,44 secondes plus tard. Azure envoie aussi des rapports de filtrage du contenu et des détails de durée. Ils sont omis ici.
HTTP/1.1 200 OKx-request-id: 62aebed5-b92d-497b-9460-65b9c49be4e8x-ratelimit-limit-tokens: 100000x-ratelimit-remaining-tokens: 98968
{ "id": "chatcmpl-EWuZQpxY7DZbRE4aO70zlg2uVrBCj", "model": "gpt-6-luna-2026-09-22", "choices": [{ "message": {"role": "assistant", "content": "{\"language\":\"en\",\"team\":\"delivery\", … }", "refusal": null}, "finish_reason": "stop" }], "usage": { "prompt_tokens": 1032, "prompt_tokens_details": {"cached_tokens": 1029}, "completion_tokens": 308, "completion_tokens_details": {"reasoning_tokens": 187}, "total_tokens": 1340 }}Lisez les nombres. L’entrée comptait 1 032 jetons. Le cache du fournisseur en contenait déjà 1 029. En effet, les mêmes instructions figuraient au début de nombreuses requêtes précédentes. La sortie comptait 308 jetons, dont 187 de raisonnement caché : chat-small est un TermeModèle de raisonnementUn modèle qui écrit des jetons de raisonnement cachés avant sa réponse. chat-small en est un. Un tel modèle accepte souvent seulement sa température par défaut, et ses jetons cachés comptent dans la limite de sortie.En savoir plus Raisonnement et multimodalitéLes LLM : comment ils fonctionnent et comment en choisir un. Vous les payez comme des jetons de sortie, mais vous ne les voyez jamais. L’en-tête de TermeLimite de débitLe maximum qu’un client peut envoyer à un fournisseur pendant une période, par exemple 100 000 jetons et 100 requêtes par minute. Au-delà, le fournisseur répond HTTP 429 (Too Many Requests) et ne fait aucun travail.En savoir plus Gérer les limites du fournisseurCréer des applications fiables avec les API de LLM indique le budget de la fenêtre actuelle : 100 000 − 1 032 = 98 968 jetons restants.
Le diagramme suit le même appel dans le code du projet, de l’application de soutien au fournisseur, puis au retour.
Description textuelle du diagramme
Quatre participants, de gauche à droite : l’application de soutien, l’assistant, l’adaptateur et le fournisseur. L’assistant correspond aux fichiers main.py et context.py, l’adaptateur à providers.py, et le fournisseur à chat-small sur Azure. L’application donne le billet T-80008 à l’assistant. L’assistant construit la requête : modèle chat-small, un message système, un message utilisateur et max_completion_tokens 1000. Il demande à l’adaptateur de traiter la requête. L’adaptateur envoie POST /openai/v1/chat/completions au fournisseur, avec la clé dans l’en-tête Authorization. Le modèle écrit 308 jetons, dont 187 de raisonnement caché. Le fournisseur répond HTTP 200 après 3,44 secondes, avec l’identifiant de requête 62aebed5…. La réponse contient le contenu, finish_reason « stop » et l’utilisation : 1 032 jetons en entrée et 308 en sortie. L’adaptateur transforme cela en objet Completion : le texte, la raison d’arrêt et les nombres de jetons. L’assistant donne à l’application l’équipe (delivery), needs_human (false) et un brouillon de réponse. Un agent lit le brouillon avant tout envoi.
Explorez un champ à la fois
Section intitulée « Explorez un champ à la fois »L’explorateur contient la même requête et la même réponse. Choisissez un champ : l’explorateur marque ses lignes, explique son rôle et montre une vraie variante. Chaque variante reprend la même requête avec un seul champ modifié. Elles ont été envoyées le même soir et montrent la vraie réponse du fournisseur.
Explorer
Une vraie requête et sa réponse, champ par champ
Prédisez d’abord : La requête n'envoie aucune température. Amira ajoute "temperature": 0 pour rendre les réponses reproductibles. À quoi vous attendez-vous : toujours la même réponse, une réponse différente ou autre chose?
- Champ
- model
- Où
- La requête
- Variantes réelles
- 1
L’identifiant du modèle : quel modèle doit répondre. Sur Azure, c’est le nom d’un déploiement (chat-small), qui pointe vers une version de modèle. La plupart des autres fournisseurs prennent le nom du modèle lui-même.
La requête enregistrée (T-80008). Les lignes marquées sont model.
POST https://<your-resource>.cognitiveservices.azure.com/openai/v1/chat/completions
Authorization: Bearer [REDACTED]
Content-Type: application/json
{
"model": "chat-small",
"messages": [
{
"role": "system",
"content": "You are Larkfield's support assistant. Read the support policy and the customer's ticket. … (4,318 more characters: the seven fields to return and Grace's policy)"
},
{
"role": "user",
"content": "Ticket:\nHello, where is my order LK-581106? The confirmation email said the garden shed shipped on Monday, but I have no delivery date yet."
}
],
"max_completion_tokens": 1000
}
(not sent: temperature, so the model uses its default)Une variante réelle : un changement
Changement : "model": "chat-strong" (a larger model, gpt-6.1-sol)
- Statut : 200
- finish_reason : stop
- Jetons : 1 032 en entrée (0 en cache), 150 en sortie (0 de raisonnement)
- Modèle : gpt-6.1-sol-2026-09-29, 3,45 s
Le contenu :
{
"language": "en",
"team": "delivery",
"needs_human": false,
"reason": "The customer is asking for a delivery update on their own shipped order, with no concerns requiring human handling.",
"confidence": "high",
"order": {
"order_id": "LK-581106",
"status": null
},
"reply": "Hello, standard delivery in Canada takes 3 to 5 business days. Please check your shipping confirmation email for a tracking link, which may show an estimated delivery date once the courier updates it. If no tracking link is available, let us know so the delivery team can check order LK-581106."
}chat-strong (gpt-6.1-sol) a donné la même équipe et le même needs_human avec 150 jetons de sortie et aucun jeton de raisonnement. Son prix est de 2 $ US / 10 $ US par million de jetons, donc cet appel a coûté environ 14 fois plus que chat-small.
Appels réels à gpt-6-luna sur Azure (chat-small), sauf la variante du point de terminaison (Gemma 3 4B avec Ollama). La clé et le nom de la ressource sont cachés. Azure renvoie aussi des rapports de filtre de contenu et des détails de durée ; ils sont omis ici.
Description textuelle de l’explorateur
L’explorateur a deux groupes de boutons. Dans la requête : endpoint, Authorization, model, role system, role user, temperature, max_completion_tokens. Dans la réponse : status and headers, id, model (returned), role assistant, finish_reason, usage. Pour le champ choisi, il marque les lignes du champ dans la requête ou la réponse. Il explique le champ et montre ses vraies variantes.
Toutes les variantes :
- Point de terminaison : les mêmes messages envoyés à TermeOllamaUn programme gratuit qui télécharge des modèles ouverts et les fait fonctionner sur votre ordinateur. Votre code l’appelle à une adresse locale, comme une API hébergée.En savoir plus Modèle hébergé ou autohébergéLes LLM : comment ils fonctionnent et comment en choisir un sur un portable avec TermeGemma 3 4BUn petit modèle ouvert de Google, avec 4 milliards de paramètres. Il peut fonctionner sur un portable avec Ollama, sans compte ni coût par appel.En savoir plus Modèle hébergé ou autohébergéLes LLM : comment ils fonctionnent et comment en choisir un. HTTP 200; la réponse est du JSON dans un bloc TermeMarkdownUne façon de noter la mise en forme en texte simple, par exemple **gras** ou # pour un titre. Les modèles l’ajoutent souvent : un programme qui attend du JSON simple doit l’enlever ou refuser la réponse., avec needs_human true; 1 092 jetons en entrée, 189 en sortie.
- Authorization : une mauvaise clé. HTTP 401, « Accès refusé en raison d’une clé d’abonnement invalide ou d’un mauvais point de terminaison d’API. » Aucun jeton utilisé.
- Modèle : chat-strong (gpt-6.1-sol). HTTP 200, les mêmes valeurs pour l’équipe et needs_human, 1 032 jetons en entrée, 150 en sortie, aucun jeton de raisonnement. Le coût était d’environ 0,0036 $ US, soit environ 14 fois celui de chat-small.
- Rôle système : le message système retiré. HTTP 200, finish_reason stop, une réponse en texte brut qui dit au client de contacter « le détaillant »; aucun JSON; 38 jetons en entrée, 257 en sortie.
- Température : 0 ajouté. HTTP 400, « Valeur non prise en charge : ‘temperature’ ne prend pas en charge 0 avec ce modèle. Seule la valeur par défaut (1) est prise en charge. »
- max_completion_tokens : 40. HTTP 200, finish_reason length, contenu vide; les 40 jetons de sortie étaient tous du raisonnement. Et 60 avec le raisonnement désactivé : finish_reason length, le JSON coupé après le champ order, donc du JSON invalide.
- id et rôle assistant : la même requête envoyée de nouveau. Un nouvel identifiant et une réponse différente, avec les mêmes valeurs pour l’équipe et needs_human; 238 jetons en sortie.
- finish_reason : la limite de 40 jetons donne « length ».
- Utilisation : chat-strong a utilisé 150 jetons de sortie et aucun jeton de raisonnement.
- Le rôle utilisateur, le code d’état et les en-têtes, ainsi que le modèle retourné n’ont aucune variante.
Les paramètres ne se transfèrent pas d’un modèle à l’autre
Section intitulée « Les paramètres ne se transfèrent pas d’un modèle à l’autre »L’erreur de température enseigne la leçon la plus générale de cette page. Une requête qui fonctionne avec un modèle peut échouer avec un autre. chat-small est un modèle de raisonnement et accepte seulement sa température par défaut. Le cours sur les modèles de langage utilisait Gemma 3 4B avec des températures de 0 et 0,8 sans problème. Le nom de la limite de sortie diffère aussi. Le nom actuel est max_completion_tokens; l’ancien est max_tokens. Lors d’un test, Ollama a ignoré max_completion_tokens : avec une limite de 30, Gemma 3 4B a quand même écrit 172 jetons. Il a respecté max_tokens. Le projet envoie max_completion_tokens. Avec le modèle local, la limite n’a donc aucun effet.
Pour chaque modèle utilisé, lisez donc la documentation du fournisseur sur les paramètres. Testez une vraie requête avant de construire votre application autour. Le module 4 présente une différence plus importante : l’un des deux TermeModèle hébergéUn modèle qui fonctionne sur les ordinateurs d’un fournisseur. Votre code lui envoie des requêtes par Internet, et vous payez chaque appel.En savoir plus Modèle hébergé ou autohébergéLes LLM : comment ils fonctionnent et comment en choisir un ne peut utiliser aucun outil.
Étape 1 : voir la requête envoyée par le projet
Section intitulée « Étape 1 : voir la requête envoyée par le projet »Vous ajoutez maintenant un petit outil au projet : assistant/raw.py. Il affiche le corps exact de la requête que l’assistant enverrait. Avec --send, il envoie ce corps avec httpx, une bibliothèque HTTP simple, et affiche la réponse brute. Il permet de voir ce que le projet transmet sur le réseau.
-
Créez le fichier
assistant/raw.pyavec ce contenu :assistant/raw.py """See one request as JSON, and (optionally) send it with plain HTTP, without the SDK.python -m assistant.raw T-80008 print the request body that the assistant would sendpython -m assistant.raw T-80008 --send send it to ASSISTANT_BASE_URL with httpx and print the response--send needs a live provider (for example Ollama: ASSISTANT_BASE_URL=http://localhost:11434/v1 andASSISTANT_MODEL=gemma3:4b). The key is sent in a header and never printed."""import jsonimport osimport sysimport httpxfrom .context import build_requestfrom .data import load_ticketdef main(argv: list[str]) -> int:model = os.environ.get("ASSISTANT_MODEL", "chat-small")base_url = os.environ.get("ASSISTANT_BASE_URL", "")api_key = os.environ.get("ASSISTANT_API_KEY", "")ticket = load_ticket(argv[0] if argv else "T-80008")body = build_request(ticket, model, "v1")print(json.dumps(body, indent=2, ensure_ascii=False))if "--send" not in argv:return 0if not base_url:print("Set ASSISTANT_BASE_URL first, for example http://localhost:11434/v1 for Ollama.", file=sys.stderr)return 2headers = {"Content-Type": "application/json"}if api_key:headers["Authorization"] = f"Bearer {api_key}"response = httpx.post(base_url.rstrip("/") + "/chat/completions", json=body, headers=headers,timeout=30)print(f"\nHTTP {response.status_code}")for name in ("content-type", "date", "x-request-id"):if name in response.headers:print(f"{name}: {response.headers[name]}")print(json.dumps(response.json(), indent=2, ensure_ascii=False))return 0 if response.is_success else 1if __name__ == "__main__":sys.exit(main(sys.argv[1:])) -
Affichez la requête pour T-80008 :
Fenêtre de terminal python -m assistant.raw T-80008La sortie commence et se termine ainsi. Le long message système est coupé ici :
{"model": "chat-small","messages": [{"role": "system","content": "You are Larkfield's support assistant. Read the support policy and the customer's ticket.\n\nAnswer with one JSON object and nothing else, …"},{"role": "user","content": "Ticket:\nHello, where is my order LK-581106? The confirmation email said the garden shed shipped on Monday, but I have no delivery date yet."}],"max_completion_tokens": 1000} -
Lisez le message système dans votre terminal. Trouvez les sept champs qu’il demande et le début de la politique de TermeGraceLa responsable du service d’assistance de Larkfield. Elle écrit la politique de support et décide ce qu’est une bonne réponse à un client..
raw.py lit trois variables d’environnement : des valeurs nommées que l’interpréteur de commandes transmet à chaque programme qu’il lance. Vous les avez vues dans Configuration et secrets, dans le cours Python pour l’ingénierie de l’IA en pratique. Elles contiennent le nom du modèle, l’adresse du fournisseur et la clé. Elles sont vides pour le moment. Le modèle est donc chat-small et rien n’est envoyé. La prochaine leçon explique pourquoi les paramètres et les clés appartiennent aux variables d’environnement, pas au code.
Étape 2 : ce que le SDK ajoute
Section intitulée « Étape 2 : ce que le SDK ajoute »raw.py construit la requête HTTP à la main. Le paquet Python officiel openai, le SDK (trousse de développement logiciel), fait le même travail pour vous. Il transforme aussi le JSON de la réponse en objets Python avec des champs nommés. De nombreux fournisseurs et serveurs locaux utilisent le même format Chat Completions. Le même SDK fonctionne donc avec tous.
Description textuelle du diagramme
La fonction build_request du projet crée un dictionnaire Python avec le modèle, les messages et max_completion_tokens. Le SDK openai le reçoit dans client.chat.completions.create(**request). Sous le SDK, la bibliothèque httpx envoie un POST par HTTPS au point de terminaison du fournisseur. Le POST contient le corps JSON et les en-têtes, avec la clé. raw.py contourne le SDK : il appelle directement httpx.post avec l’URL et le corps. Les deux chemins envoient la même requête.
Vous pouvez voir ce que fait le SDK sans appel réel : donnez-lui une réponse enregistrée. Lancez Python dans le dossier du projet avec python, puis tapez ces lignes :
import jsonfrom openai.types.chat import ChatCompletionlines = open("recordings/eval_text.jsonl", encoding="utf-8").read().splitlines()entry = [json.loads(x) for x in lines if '"3b337102809abc06"' in x][0]response = ChatCompletion.model_validate(entry["response"])response.modelresponse.choices[0].finish_reasonresponse.usage.prompt_tokens, response.usage.completion_tokensresponse.usage.completion_tokens_details.reasoning_tokensLa sortie :
'gpt-6-luna-2026-09-22''stop'(1032, 241)1153b337102809abc06 est la clé de requête de T-80008 dans la dernière leçon. Le SDK a vérifié le JSON selon son propre modèle de réponse et a donné un nom à chaque champ. Cet enregistrement utilisait 241 jetons de sortie, dont 115 de raisonnement. C’est un autre appel que celui de l’explorateur. Tapez exit() pour quitter Python. La prochaine leçon place le SDK derrière une seule classe dans le projet.
Quand utiliser chacun : le SDK pour l’application, car il gère les détails de HTTP et fournit des objets typés. HTTP simple pour apprendre, déboguer et voir exactement ce qui est transmis.
Exercice guidé : lire l’explorateur
Section intitulée « Exercice guidé : lire l’explorateur »- Faites votre prédiction dans l’explorateur, puis sélectionnez I have made my prediction (j’ai fait ma prédiction).
- Sélectionnez temperature (température). Vous devriez voir HTTP 400 et « Seule la valeur par défaut (1) est prise en charge ».
- Sélectionnez max_completion_tokens (limite de jetons de sortie). Dans la première variante, trouvez
finish_reason(raison d’arrêt) et le nombre de TermeJetons de raisonnementDes jetons que certains modèles écrivent avant la réponse pour travailler le problème. Vous ne les voyez pas, mais ils comptent dans la limite de sortie et vous les payez.En savoir plus Raisonnement et multimodalitéLes LLM : comment ils fonctionnent et comment en choisir un. - Sélectionnez role : system (rôle : système). Lisez la réponse. Que manque-t-il par rapport à la réponse originale?
- Sélectionnez usage (utilisation). Calculez le coût de l’appel original et de l’appel à chat-strong. Utilisez 0,10 / 0,50 $ US par million de jetons pour chat-small et 2 / 10 $ US pour chat-strong.
Afficher les réponses
- Le fournisseur a refusé la requête avant l’exécution du modèle. chat-small est un modèle de raisonnement et accepte seulement sa température par défaut. Amira ne peut pas rendre ses réponses reproductibles avec ce paramètre.
finish_reason: "length", et les 40 jetons de sortie étaient tous des jetons de raisonnement : le contenu est vide.- Tout ce dont l’application a besoin : aucun JSON, aucune équipe, aucun
needs_human(intervention humaine requise). Le modèle a répondu directement au client et l’a dirigé vers « le détaillant ». Il ne savait pas qu’il travaillait pour TermeLarkfieldUne boutique en ligne d’articles pour la maison. Ce n’est pas une vraie entreprise. Tous les cours Nextia utilisent son service d’assistance et ses données comme exemple.En savoir plus L'IA dans les produits de tous les joursBases d'une carrière en IA : rôles, compétences et feuilles de route. - Pour chat-small : 1 032 × 0,10 + 308 × 0,50 = 257 millionièmes de dollar, soit environ 0,00026 $ US. Pour chat-strong : 1 032 × 2 + 150 × 10 = 3 564 millionièmes, soit environ 0,0036 $ US. chat-strong coûte donc environ 14 fois plus pour ce billet facile.
À vous de jouer : un changement, une prédiction
Section intitulée « À vous de jouer : un changement, une prédiction »Le billet T-80001 concerne la commande d’un voisin. Affichez sa requête avec python -m assistant.raw T-80001. Avant de lancer la commande, faites une prédiction : quels champs diffèrent de T-80008, et lesquels restent identiques?
Afficher la réponse
Seul le contenu du message utilisateur change : il contient plutôt le billet de Tom. Le modèle, le message système (les mêmes instructions et la même politique) et max_completion_tokens restent identiques. Les quelque 1 000 premiers jetons de chaque requête sont donc identiques. C’est pourquoi le cache du fournisseur pouvait contenir 1 029 des 1 032 jetons d’entrée. La réponse pour T-80001 dans les enregistrements utilisait 1 054 jetons d’entrée, car le billet de Tom est plus long.
Facultatif : un appel réel
Section intitulée « Facultatif : un appel réel »Tout ce qui précède fonctionne avec des enregistrements. Pour voir une réponse en direct, vous avez deux options. Passez cette section si vous n’avez accès à aucune des deux : aucune leçon suivante n’en dépend.
Option 1 : un modèle local gratuit avec Ollama. Ollama exécute des modèles ouverts sur votre ordinateur et offre le même point de terminaison Chat Completions. Gemma 3 4B nécessite environ 3,3 Go d’espace disque. Le cours l’a exécuté avec Ollama 0.40.1 sur un Mac mini doté de 16 Go de mémoire.
-
Installez Ollama à partir de son site Web, puis démarrez-le.
-
Téléchargez le modèle, une seule fois :
Fenêtre de terminal ollama pull gemma3:4b -
Envoyez la requête :
Fenêtre de terminal ASSISTANT_BASE_URL=http://localhost:11434/v1 ASSISTANT_MODEL=gemma3:4b python -m assistant.raw T-80008 --sendFenêtre de terminal $env:ASSISTANT_BASE_URL = "http://localhost:11434/v1"$env:ASSISTANT_MODEL = "gemma3:4b"python -m assistant.raw T-80008 --sendFenêtre de terminal ASSISTANT_BASE_URL=http://localhost:11434/v1 ASSISTANT_MODEL=gemma3:4b python -m assistant.raw T-80008 --sendSur macOS et Linux, les variables s’appliquent seulement à cette commande. Dans PowerShell, elles restent définies jusqu’à la fermeture de la fenêtre.
Après la requête, la sortie affiche la réponse. Voici la fin d’une exécution réelle (gemma3:4b, Ollama 0.40.1). Le contenu est tronqué ici :
HTTP 200content-type: application/jsondate: Fri, 09 Oct 2026 02:52:58 GMT{ "id": "chatcmpl-244", "object": "chat.completion", "created": 1791514378, "model": "gemma3:4b", "system_fingerprint": "fp_ollama", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "```json\n{\n \"language\": \"en\",\n \"team\": \"delivery\",\n \"needs_human\": true, … \"reply\": \"Hello, I understand you're checking on the status of order LK-581106, which was shipped on Monday. I’ve checked the tracking information and it currently shows as ‘In Transit’ with an estimated delivery date of Wednesday. …\"\n}\n```" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 1092, "prompt_tokens_details": { "cached_tokens": 1091 }, "completion_tokens": 191, "total_tokens": 1283 }}Les mêmes champs, mais d’un autre fournisseur. Deux différences comptent. L’utilisation ne contient aucun jeton de raisonnement : Gemma 3 4B ne raisonne pas. Et la réponse dit « J’ai vérifié les renseignements de suivi… date de livraison prévue mercredi ». Le modèle n’a aucune donnée de suivi : il a inventé ces renseignements. Votre exécution donnera une réponse différente.
Option 2 : votre propre clé chez un fournisseur hébergé. Tout fournisseur offrant un point de terminaison Chat Completions compatible avec OpenAI convient. Définissez trois variables : ASSISTANT_BASE_URL (pour OpenAI, https://api.openai.com/v1), ASSISTANT_MODEL (un nom de modèle dans la liste de votre fournisseur) et ASSISTANT_API_KEY (votre clé). Une requête pour T-80008 envoie environ 1 000 jetons d’entrée et reçoit quelques centaines de jetons en retour. Avec un petit modèle, cela coûte une fraction de cent. Le cours a testé cette option avec le point de terminaison compatible avec OpenAI d’Azure, et non avec OpenAI directement.
Saisissez la clé uniquement dans votre terminal, jamais dans un fichier du projet. La prochaine leçon montre où la conserver en toute sécurité.
Erreur courante
Une réponse vide, sans erreur
Symptôme : Amira réduit la limite de sortie à 40 jetons pour économiser. Le fournisseur répond avec le statut 200, et l’assistant affiche une réponse vide. Rien dans les journaux (logs) n’indique un problème.
Cause : chat-small raisonne avant d’écrire. Les 40 jetons ont tous servi au raisonnement caché, donc le texte de la réponse est vide. La réponse l’indiquait avec finish_reason: "length" et reasoning_tokens: 40. Le code lisait seulement le contenu.
Solution : lisez finish_reason dans chaque réponse. "length" signifie que la réponse est tronquée ou absente : ne l’utilisez jamais comme une réponse complète. Donnez de la marge à un modèle de raisonnement : le projet utilise 1 000 jetons. Avec cette requête, chat-small a utilisé jusqu’à 600 jetons de raisonnement pour un des billets de soutien du cours. Le module 3 traduit cette vérification en code.
Ce que cela signifie pour un vrai service d’IA : un statut 200 signifie que le fournisseur a fait son travail. Cela ne signifie pas que vous avez une réponse utilisable. La raison de fin et l’utilisation vous permettent de le savoir.
Vérification des connaissances
Section intitulée « Vérification des connaissances »Vérifiez votre compréhension
Nommez le rôle de chaque partie : le point de terminaison, l'en-tête Authorization, le message système, le message utilisateur et max_completion_tokens.
Afficher la réponse
Le point de terminaison est l’adresse du fournisseur et de l’opération (POST /chat/completions). L’en-tête Authorization contient la clé d’API : le fournisseur sait ainsi qui envoie la requête et qui paie. Le message système contient les instructions de l’application. Le message utilisateur contient le texte à traiter, ici le billet. max_completion_tokens est le nombre maximal de jetons que le modèle peut produire, y compris le raisonnement caché. Il limite le coût et le temps.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Faites une prédiction : vous envoyez la requête T-80008 avec max_completion_tokens fixé à 250. À quoi peut ressembler la réponse, et comment votre code le sait-il?
Afficher la réponse
chat-small utilise d’abord des jetons de sortie pour le raisonnement caché. Pour ce billet, il en a utilisé de 115 à 187 dans les exécutions enregistrées. Avec 250 jetons, la réponse peut être complète, tronquée en plein milieu ou vide si le raisonnement utilise les 250 jetons. Lors d’un test réel, les 250 jetons ont tous servi au raisonnement, et le contenu était vide. Le code le sait grâce à la raison de fin, « length », et aux jetons de raisonnement dans l’utilisation. Il ne le sait pas grâce au statut, qui est 200.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Tomás dit : « On a testé une température de 0 avec Gemma sur Ollama, donc on peut aussi l'utiliser avec chat-small. » Que répondez-vous?
Afficher la réponse
Un réglage qui fonctionne avec un modèle peut échouer avec un autre. chat-small est un modèle de raisonnement et accepte uniquement sa température par défaut. La requête réelle avec une température de 0 a reçu HTTP 400. Consultez la documentation de chaque modèle et envoyez une requête réelle avec les réglages exacts avant de vous y fier. Cela vaut aussi pour le nom de la limite de sortie : Ollama a ignoré max_completion_tokens.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Une requête contient un point de terminaison, un identifiant d’accès (la clé d’API dans l’en-tête
Authorization), un identifiant de modèle, des messages avec des rôles (system,user,assistant) et des réglages de génération commemax_completion_tokensettemperature. - Une réponse contient un statut et des en-têtes, un identifiant, le modèle qui a répondu, la réponse sous forme de message
assistant, la raison de fin et l’utilisation. finish_reason: "length"signifie que la réponse est tronquée ou vide, même avec un statut 200. Pour T-80008 avec une limite de 40, les 40 jetons ont tous servi au raisonnement caché.- Les réglages diffèrent selon les modèles : chat-small rejette
temperature: 0avec HTTP 400, et Ollama ignoremax_completion_tokens. Testez d’abord une requête réelle. python -m assistant.raw T-80008affiche le corps exact. Le SDK envoie le même JSON et fournit des objets typés.
Ensuite, vous placerez tout le code du fournisseur derrière une seule frontière. Vous garderez la clé hors du code et rendrez les échecs clairs.
Leçon suivante : La frontière de l'application