Guide du formateur â Niveau AvancĂ©, Session 1
« Claude API : plongée en profondeur »
Programme : Applied AI â Yann Isola
Public : Architectes solutions préparant la certification Claude Certified Architect
Durée : 2 h 00 (+ 10 min de pause recommandée à mi-parcours)
Prérequis : Python intermédiaire, notions HTTP/REST (REST = Representational State Transfer), avoir déjà appelé une API (API = Application Programming Interface, interface de programmation applicative) quelconque.
Matériel : clé API Anthropic de démonstration, terminal avec curl et Python 3.10+, SDK (SDK = Software Development Kit, kit de développement logiciel) anthropic installé, page web interactive de la session (webpage/index.html).
Objectifs pédagogiques
Ă la fin de la session, chaque participant sait :
- Construire une requĂȘte API Claude complĂšte et justifier chaque paramĂštre (
model,max_tokens,messages,system,temperature,stop_sequences). - Interpréter chaque valeur de
stop_reasonet concevoir la logique applicative correspondante. - Raisonner sur la fenĂȘtre de contexte comme une mĂ©moire de travail : coĂ»t linĂ©aire, effet « lost in the middle », stratĂ©gies de placement.
- Mettre en Ćuvre le prompt caching avec
cache_controlet calculer le retour sur investissement (ROI = Return On Investment). - ImplĂ©menter le streaming SSE (SSE = Server-Sent Events, Ă©vĂ©nements envoyĂ©s par le serveur) et nommer les Ă©vĂ©nements du cycle de vie dâun message.
- Choisir entre appel synchrone, streaming et Batches API selon le cas dâusage, avec les arguments coĂ»t/latence/SLA (SLA = Service Level Agreement, engagement de niveau de service).
- Concevoir une stratĂ©gie de gestion dâerreurs robuste : 429, backoff exponentiel, en-tĂȘtes
retry-after.
Plan minuté
| Bloc | Durée | Contenu |
|---|---|---|
| 0. Ouverture | 5 min | Cadrage certification, tour de table express |
| 1. Anatomie dâune requĂȘte | 20 min | model, max_tokens, messages, system â dĂ©mo curl + Python |
| 2. RÎles & prefilling | 15 min | user/assistant/system, prefilling de réponse |
| 3. stop_reason | 10 min | Les 4 valeurs, logique applicative |
| 4. FenĂȘtre de contexte | 15 min | MĂ©moire de travail, coĂ»t linĂ©aire, lost in the middle |
| Pause | 10 min | |
| 5. Prompt caching | 20 min | cache_control, économie 90 %, surcoût 25 %, calculs ROI |
| 6. Comptage de tokens | 10 min | Endpoint count_tokens, tokenizers par famille |
| 7. Streaming SSE | 15 min | Cycle dâĂ©vĂ©nements, dĂ©mo live |
| 8. Batches API | 10 min | Async, â50 %, SLA 24 h, 100k requĂȘtes |
| 9. Gestion dâerreurs | 10 min | 429, backoff exponentiel, retry-after |
| 10. ClĂŽture | 5 min | Exit tickets, annonce des exercices |
Bloc 0 â Ouverture (5 min)
Message dâaccroche : « Aujourdâhui on ne parle pas de prompting. On parle de ce qui distingue un dĂ©veloppeur qui appelle Claude dâun architecte qui conçoit un systĂšme autour de Claude : le contrat dâAPI, lâĂ©conomie des tokens, et les modes de dĂ©faillance. »
Question flash au groupe : « Qui a dĂ©jĂ reçu une erreur 429 en production ? Quâavez-vous fait ? » â collecter 2-3 rĂ©ponses, y revenir au bloc 9.
Bloc 1 â Anatomie dâune requĂȘte API (20 min)
1.1 Le contrat minimal
Trois champs sont obligatoires : model, max_tokens, messages.
Démo curl (à taper en live) :
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Explique le protocole FIX en une phrase."}
]
}'
â Le nom de modĂšle (claude-sonnet-4-5) est volatil : vĂ©rifier la documentation officielle avant tout support de cours ou dĂ©ploiement.
Points Ă marteler :
anthropic-version: en-tĂȘte dâĂ©pinglage de version dâAPI. Sans lui â erreur. Câest un contrat : le comportement nâĂ©voluera pas sous vos pieds.max_tokensest un plafond de gĂ©nĂ©ration, pas une cible. Le modĂšle peut sâarrĂȘter avant. Mais sâil lâatteint, la rĂ©ponse est tronquĂ©e (voirstop_reason: "max_tokens"au bloc 3).- La facturation porte sur tokens dâentrĂ©e + tokens de sortie, Ă des tarifs diffĂ©rents (la sortie coĂ»te typiquement ~5Ă lâentrĂ©e â selon le modĂšle).
1.2 Ăquivalent Python (SDK officiel)
import anthropic
client = anthropic.Anthropic() # lit ANTHROPIC_API_KEY dans l'environnement
response = client.messages.create(
model="claude-sonnet-4-5", # â volatil
max_tokens=1024,
temperature=0.2, # déterminisme relatif pour tùches techniques
stop_sequences=["FIN_RAPPORT"], # arrĂȘt personnalisĂ©
system="Tu es un analyste financier. Réponds en français, style concis.",
messages=[
{"role": "user", "content": "Résume les risques d'un stablecoin adossé à des matiÚres premiÚres."}
],
)
print(response.content[0].text)
print(response.usage) # input_tokens / output_tokens â pilotage des coĂ»ts
print(response.stop_reason) # toujours l'inspecter en production
Décryptage de la réponse :
{
"id": "msg_01XFDUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"content": [{"type": "text", "text": "..."}],
"model": "claude-sonnet-4-5",
"stop_reason": "end_turn",
"usage": {"input_tokens": 58, "output_tokens": 212}
}
contentest un tableau de blocs (pas une simple chaĂźne) : blocstext,tool_use, etc. Habitude dâarchitecte : toujours itĂ©rer sur les blocs, jamais supposercontent[0]unique.usage: câest votre compteur de facturation. En production, on le logge systĂ©matiquement (observabilitĂ© des coĂ»ts).
1.3 Les paramĂštres dâĂ©chantillonnage
| ParamĂštre | RĂŽle | Recommandation architecte |
|---|---|---|
temperature (0â1) |
AlĂ©a de lâĂ©chantillonnage | 0â0.3 pour extraction/classification, 0.7â1 pour crĂ©ativitĂ© |
top_p |
Nucleus sampling (Ă©chantillonnage par noyau de probabilitĂ©) | Ne pas combiner avec temperature â choisir lâun des deux |
top_k |
Restreint aux k tokens les plus probables | Rarement nécessaire, cas avancés |
stop_sequences |
ChaĂźnes dâarrĂȘt personnalisĂ©es | Utile pour dĂ©limiter des sorties structurĂ©es |
PiÚge certification : temperature: 0 ne garantit pas un déterminisme parfait (non-déterminisme numérique résiduel possible). Formulation correcte : « réduit fortement la variabilité ».
Bloc 2 â RĂŽles de messages & prefilling (15 min)
2.1 Trois canaux, trois niveaux de privilĂšge
systemâ canal privilĂ©giĂ©. Ce nâest PAS « un premier message user dĂ©guisĂ© ». Il est traitĂ© avec une prioritĂ© particuliĂšre par le modĂšle. Usages : persona, rĂšgles de sĂ©curitĂ©, politique de sortie (format, langue, refus), contexte mĂ©tier stable.userâ le tour de lâappelant. Contenu : question, documents, rĂ©sultats dâoutils (tool_result).assistantâ les tours du modĂšle. Mais aussi : le prefilling.
RĂšgle structurelle : le tableau messages doit alterner user/assistant et commencer par user. Deux messages consĂ©cutifs de mĂȘme rĂŽle â erreur 400.
2.2 Prefilling : mettre des mots dans la bouche du modĂšle
Le dernier message peut ĂȘtre un assistant partiel : le modĂšle continue Ă partir de lĂ .
response = client.messages.create(
model="claude-sonnet-4-5", # â
max_tokens=500,
messages=[
{"role": "user", "content": "Liste 3 risques de contrepartie en JSON."},
{"role": "assistant", "content": "{"} # prefill : force l'ouverture JSON
],
)
# La rĂ©ponse commence directement aprĂšs "{" â pas de prĂ©ambule "Voici le JSON :"
Cas dâusage architecte :
- Forcer un format de sortie (JSON â JavaScript Object Notation, XML â eXtensible Markup Language).
- Supprimer les préambules (« Bien sûr ! Voici⊠»).
- Contraindre un choix : prefill
"La réponse est ("pour un QCM (QCM = Questionnaire à Choix Multiples).
Attention : le texte du prefill ne fait pas partie de la rĂ©ponse retournĂ©e â pensez Ă le re-prĂ©fixer cĂŽtĂ© client ("{" + response.content[0].text).
DĂ©mo live suggĂ©rĂ©e : mĂȘme question avec et sans prefill, comparer les sorties. Effet immĂ©diat, trĂšs parlant.
Bloc 3 â stop_reason : les 4 signaux (10 min)
Chaque rĂ©ponse indique pourquoi le modĂšle sâest arrĂȘtĂ©. Un architecte Ă©crit une branche de code pour chacun.
stop_reason |
Signification | Réaction applicative |
|---|---|---|
end_turn |
Fin naturelle du tour | Cas nominal â traiter la rĂ©ponse |
max_tokens |
Plafond atteint â rĂ©ponse tronquĂ©e | Alerter/relancer avec plafond plus haut, ou continuer la gĂ©nĂ©ration |
stop_sequence |
Une stop_sequences a été rencontrée |
Lire response.stop_sequence pour savoir laquelle ; parser la sortie délimitée |
tool_use |
Le modĂšle demande lâexĂ©cution dâun outil | ExĂ©cuter lâoutil, renvoyer un tool_result, reboucler |
Code de garde canonique (à faire écrire aux participants) :
match response.stop_reason:
case "end_turn":
return extract_text(response)
case "max_tokens":
logger.warning("RĂ©ponse tronquĂ©e â usage=%s", response.usage)
raise TruncatedResponseError(partial=extract_text(response))
case "stop_sequence":
return parse_delimited(extract_text(response), response.stop_sequence)
case "tool_use":
return handle_tool_loop(response)
case _:
raise UnexpectedStopReason(response.stop_reason)
PiĂšge certification : max_tokens nâest pas une erreur HTTP â la requĂȘte retourne 200. Câest un Ă©tat mĂ©tier Ă dĂ©tecter soi-mĂȘme. Beaucoup de systĂšmes en production livrent silencieusement des JSON tronquĂ©s parce que personne ne teste stop_reason.
Bloc 4 â La fenĂȘtre de contexte comme mĂ©moire de travail (15 min)
4.1 Changer de mental model
La fenĂȘtre de contexte (â 200 000 tokens sur la plupart des modĂšles Claude actuels, certains modĂšles proposent 1M en bĂȘta) nâest pas « une limite Ă ne pas dĂ©passer ». Câest la mĂ©moire de travail du modĂšle : tout ce quâil « sait » pour cette requĂȘte sây trouve â system prompt, historique, documents, dĂ©finitions dâoutils, rĂ©sultats dâoutils.
Trois consĂ©quences dâarchitecture :
- CoĂ»t linĂ©aire. Chaque token dâentrĂ©e est facturĂ© Ă chaque appel. Une conversation qui accumule 150k tokens dâhistorique coĂ»te 150k tokens dâentrĂ©e par tour. Sans stratĂ©gie (rĂ©sumĂ©, troncature, caching), le coĂ»t dâune conversation croĂźt quadratiquement avec sa longueur (somme des longueurs de prĂ©fixes).
- Effet « lost in the middle ». Les modĂšles rappellent mieux lâinformation placĂ©e en dĂ©but et en fin de contexte quâau milieu. Placement stratĂ©gique : instructions critiques et question au plus prĂšs de la fin ; documents volumineux en tĂȘte ; ne jamais enterrer une consigne clĂ© au milieu de 80k tokens de logs.
- Latence. Le temps jusquâau premier token (TTFT = Time To First Token) croĂźt avec la taille de lâentrĂ©e.
4.2 Exercice mental (2 min, Ă lâoral)
« Un assistant RAG (RAG = Retrieval-Augmented Generation, gĂ©nĂ©ration augmentĂ©e par rĂ©cupĂ©ration) injecte 40 chunks de 1 000 tokens. OĂč placez-vous la question de lâutilisateur ? » â RĂ©ponse attendue : aprĂšs les documents, en fin de prompt, Ă©ventuellement rĂ©pĂ©tĂ©e si les documents sont trĂšs longs.
4.3 Calcul de coût en direct
# Ordre de grandeur â tarifs â volatils, vĂ©rifier la grille officielle
PRIX_INPUT_PAR_MTOK = 3.00 # $ / million de tokens d'entrĂ©e â
PRIX_OUTPUT_PAR_MTOK = 15.00 # $ / million de tokens de sortie â
def cout_appel(input_tokens: int, output_tokens: int) -> float:
return (input_tokens * PRIX_INPUT_PAR_MTOK
+ output_tokens * PRIX_OUTPUT_PAR_MTOK) / 1_000_000
# Conversation de 20 tours, historique moyen 30k tokens, réponses 500 tokens
total = sum(cout_appel(30_000, 500) for _ in range(20))
print(f"{total:.2f} $") # â 1.95 $ pour UNE conversation
Multiplier par 10 000 utilisateurs/jour â lâĂ©conomie du contexte devient un sujet de direction technique, pas un dĂ©tail.
Bloc 5 â Prompt caching (20 min)
5.1 Le principe
Le prompt caching permet de rĂ©utiliser le prĂ©fixe dâun prompt dĂ©jĂ traitĂ©. On pose des points de rupture cache_control ; tout ce qui prĂ©cĂšde (et correspond exactement) est servi depuis le cache.
Ăconomie : â
- Lecture cache (cache hit) : ~10 % du prix normal â 90 % dâĂ©conomie sur la portion cachĂ©e.
- Ăcriture cache (cache write) : surcoĂ»t de ~25 % sur la portion Ă©crite.
- TTL (TTL = Time To Live, durĂ©e de vie) de base : ~5 minutes â , rafraĂźchi Ă chaque hit ; option 1 h â disponible avec surcoĂ»t supĂ©rieur.
5.2 Syntaxe
response = client.messages.create(
model="claude-sonnet-4-5", # â
max_tokens=1024,
system=[
{
"type": "text",
"text": GROS_CONTEXTE_METIER, # ex. 50k tokens de documentation
"cache_control": {"type": "ephemeral"} # â point de rupture
}
],
messages=[{"role": "user", "content": question_utilisateur}],
)
u = response.usage
print(u.cache_creation_input_tokens) # tokens Ă©crits au cache (surcoĂ»t 25 % â )
print(u.cache_read_input_tokens) # tokens lus du cache (â90 % â )
print(u.input_tokens) # tokens non cachés, plein tarif
RĂšgles Ă connaĂźtre (certification) :
- Le cache fonctionne sur prĂ©fixe exact : le moindre octet modifiĂ© en amont du breakpoint invalide le cache. â Mettre le contenu stable en premier (system, outils, documents), le contenu variable en dernier (question).
- Ordre dans le préfixe :
toolsâsystemâmessages. Un changement de dĂ©finition dâoutils invalide tout. - Minimum cachable : â 1 024 tokens sur la plupart des modĂšles (2 048 sur certains). En dessous, le breakpoint est ignorĂ© silencieusement.
- JusquâĂ 4 breakpoints â par requĂȘte.
5.3 Calcul de rentabilité (à faire faire)
« System prompt + docs = 60k tokens, question = 300 tokens, 500 requĂȘtes/heure. »
- Sans cache : 500 Ă 60 300 tokens plein tarif.
- Avec cache : 1 écriture (60k à 1,25) + 499 lectures (60k à 0,10) + 500 à 300 plein tarif.
- â Ă©conomie â 88 % sur lâentrĂ©e. Le cache est rentable dĂšs 2 requĂȘtes dans la fenĂȘtre TTL (1,25 + 0,10 = 1,35 < 2,00).
Anti-pattern Ă citer : placer un horodatage ou un identifiant de session au dĂ©but du system prompt â 0 % de cache hit, surcoĂ»t de 25 % Ă chaque appel. On paie plus cher quâen dĂ©sactivant le cache.
Bloc 6 â Comptage de tokens (10 min)
6.1 Pourquoi compter avant dâenvoyer
- Valider quâon tient dans la fenĂȘtre avant de payer.
- Dimensionner
max_tokensintelligemment. - Pré-calculer un budget / faire du chargeback interne.
6.2 Lâendpoint dĂ©diĂ©
count = client.messages.count_tokens(
model="claude-sonnet-4-5", # â le comptage dĂ©pend du modĂšle
system="Tu es un assistant juridique.",
messages=[{"role": "user", "content": contrat_complet}],
)
print(count.input_tokens) # gratuit, pas de gĂ©nĂ©ration â (soumis Ă rate limit dĂ©diĂ©)
Points clés :
- Chaque famille de modĂšles a son tokenizer : le mĂȘme texte ne fait pas le mĂȘme nombre de tokens sur Claude et sur un modĂšle GPT (GPT = Generative Pre-trained Transformer), ni forcĂ©ment entre gĂ©nĂ©rations de Claude. â Ne jamais rĂ©utiliser un comptage tiktoken (tokenizer OpenAI) pour dimensionner un appel Claude.
- Ordres de grandeur pour lâestimation mentale : ~3,5â4 caractĂšres/token en anglais, un peu plus de tokens/mot en français (accents, morphologie). Le code et le JSON tokenisent plus densĂ©ment quâon ne croit.
- Le comptage inclut system + messages + tools : passer la requĂȘte complĂšte Ă
count_tokens.
Bloc 7 â Streaming SSE (15 min)
7.1 Pourquoi streamer
- UX (UX = User eXperience, expĂ©rience utilisateur) : TTFT perçu de ~1 s au lieu dâattendre 30 s une rĂ©ponse complĂšte.
- Obligatoire en pratique pour les longues générations (les timeouts HTTP guettent les réponses > 10 min).
7.2 Le cycle dâĂ©vĂ©nements SSE
SSE = Server-Sent Events : flux HTTP unidirectionnel text/event-stream, événements event: + data: séparés par des lignes vides.
Séquence pour un message simple :
message_start â enveloppe du message (id, model, usage d'entrĂ©e)
content_block_start â ouverture du bloc n°0 (type: text)
content_block_delta â {"delta": {"type": "text_delta", "text": "Le"}}
content_block_delta â {"delta": {"type": "text_delta", "text": " protocole"}}
... (des dizaines/centaines de deltas)
content_block_stop â fermeture du bloc n°0
message_delta â stop_reason + usage de sortie finaux
message_stop â fin du flux
(+ événements ping de keep-alive à ignorer, + error possible en cours de flux.)
PiÚge certification : stop_reason et le compte final de tokens de sortie arrivent dans message_delta, pas dans message_start. Un client qui ne lit pas message_delta ne saura jamais si la réponse a été tronquée.
7.3 Implémentation
# Version haut niveau (SDK)
with client.messages.stream(
model="claude-sonnet-4-5", # â
max_tokens=1024,
messages=[{"role": "user", "content": "Explique le netting bilatéral."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final = stream.get_final_message()
print("\nâ", final.stop_reason, final.usage)
# Version bas niveau (Ă©vĂ©nements bruts) â celle qu'il faut connaĂźtre pour la certif
stream = client.messages.create(..., stream=True)
for event in stream:
match event.type:
case "message_start":
msg_id = event.message.id
case "content_block_delta":
if event.delta.type == "text_delta":
buffer += event.delta.text
case "message_delta":
stop_reason = event.delta.stop_reason
output_tokens = event.usage.output_tokens
case "message_stop":
break
DĂ©mo : ouvrir le visualiseur de streaming de la page web de session (webpage/index.html) â chaque Ă©vĂ©nement sâaffiche avec son type colorĂ©. TrĂšs efficace pour ancrer la sĂ©quence.
Bloc 8 â Batches API (10 min)
8.1 Le troisiĂšme mode dâexĂ©cution
| Mode | Latence | CoĂ»t | Cas dâusage |
|---|---|---|---|
| Synchrone | secondes | plein tarif | interactif |
| Streaming | premier token en ~1 s | plein tarif | interactif, longues sorties |
| Batch | jusquâĂ 24 h (SLA) â | â50 % â | traitement de masse, non urgent |
- JusquâĂ 100 000 requĂȘtes â (ou ~256 Mo â ) par batch.
- La plupart des batches terminent en moins dâune heure en pratique ; 24 h est lâengagement contractuel.
- Chaque requĂȘte du batch est indĂ©pendante (pas de partage dâĂ©tat).
- RĂ©sultats disponibles 29 jours â , non garantis dans lâordre â toujours corrĂ©ler par
custom_id.
8.2 Code
batch = client.messages.batches.create(
requests=[
{
"custom_id": f"doc-{i}", # clĂ© de corrĂ©lation â OBLIGATOIRE
"params": {
"model": "claude-haiku-4-5", # â petit modĂšle pour la masse
"max_tokens": 512,
"messages": [{"role": "user", "content": f"Classifie : {doc}"}],
},
}
for i, doc in enumerate(documents)
]
)
# Polling de l'état
status = client.messages.batches.retrieve(batch.id)
print(status.processing_status) # in_progress â ended
print(status.request_counts) # succeeded / errored / canceled / expired
# RĂ©cupĂ©ration (JSONL â JSON Lines, un objet JSON par ligne)
for result in client.messages.batches.results(batch.id):
if result.result.type == "succeeded":
traiter(result.custom_id, result.result.message)
else:
rejouer(result.custom_id, result.result) # errored / expired / canceled
Cas dâusage Ă faire trouver au groupe : classification nocturne de tickets, enrichissement de CRM (CRM = Customer Relationship Management), Ă©valuation massive de prompts, gĂ©nĂ©ration de mĂ©tadonnĂ©es documentaires, backtesting de prompts sur historiques.
PiĂšge certification : batch + prompt caching se combinent â les requĂȘtes partageant un long prĂ©fixe dans le mĂȘme batch peuvent bĂ©nĂ©ficier du cache, cumulant les remises (les hits de cache ne sont pas garantis en batch).
Bloc 9 â Gestion dâerreurs (10 min)
9.1 Taxonomie
| Code | Nom | Cause | Retry ? |
|---|---|---|---|
| 400 | invalid_request_error | RequĂȘte malformĂ©e (rĂŽles, JSONâŠ) | â corriger le code |
| 401 | authentication_error | ClĂ© invalide | â |
| 403 | permission_error | ClĂ© sans accĂšs Ă la ressource | â |
| 404 | not_found_error | ModĂšle/ressource inexistant | â |
| 413 | request_too_large | RequĂȘte trop grosse | â rĂ©duire |
| 429 | rate_limit_error | RPM/ITPM/OTPM dépassés | backoff |
| 500 | api_error | Erreur interne | backoff |
| 529 | overloaded_error | Surcharge du service | backoff |
(RPM = Requests Per Minute ; ITPM/OTPM = Input/Output Tokens Per Minute â les trois compteurs de rate limit.)
9.2 Backoff exponentiel avec jitter
import random, time
import anthropic
def appel_robuste(client, max_retries=5, **kwargs):
for tentative in range(max_retries):
try:
return client.messages.create(**kwargs)
except anthropic.RateLimitError as e:
# Priorité au serveur : respecter retry-after s'il est fourni
retry_after = e.response.headers.get("retry-after")
if retry_after is not None:
delai = float(retry_after)
else:
delai = min(60, (2 ** tentative)) * random.uniform(0.5, 1.5) # jitter
time.sleep(delai)
except anthropic.APIStatusError as e:
if e.status_code in (500, 529):
time.sleep(min(60, 2 ** tentative) * random.uniform(0.5, 1.5))
else:
raise # 4xx â 429 : inutile de rĂ©essayer
raise ExhaustedRetriesError()
Trois points dâarchitecte :
retry-afterprime sur votre formule â le serveur sait mieux que vous quand rĂ©essayer.- Jitter obligatoire â sans alĂ©a, tous vos workers rĂ©essaient au mĂȘme instant (« thundering herd », effet troupeau).
- Le SDK officiel fait dĂ©jĂ 2 retries par dĂ©faut â connaĂźtre ce comportement avant dâempiler votre propre couche (risque de retries multiplicatifs).
Mentionner aussi : surveiller les en-tĂȘtes anthropic-ratelimit-*-remaining pour du throttling proactif plutĂŽt que rĂ©actif.
Bloc 10 â ClĂŽture (5 min)
- Rappel du fil rouge : paramĂštres â signaux (stop_reason) â Ă©conomie (contexte, cache, batch) â robustesse (erreurs).
- Annoncer les 3 exercices (constructeur de requĂȘte, streaming, conception batch) et le QCM.
- Distribuer les exit tickets.
Exit tickets (5)
à remplir en 3 minutes, ramassés à la sortie :
- stop_reason : votre application reçoit
stop_reason: "max_tokens"sur une extraction JSON. Que sâest-il passĂ© et que fait votre code ? (2 phrases) - Caching : pourquoi placer un horodatage au dĂ©but du system prompt ruine-t-il le prompt caching, et combien cela coĂ»te-t-il en plus (%) ?
- Streaming : dans quel événement SSE trouve-t-on le
stop_reasonfinal ? (nom exact) - Batch : citez deux conditions qui rendent la Batches API préférable à des appels synchrones, et la remise associée.
- Erreurs : on reçoit un 429 avec en-tĂȘte
retry-after: 12. Quel délai appliquer et pourquoi ne pas utiliser sa propre formule de backoff dans ce cas ?
CorrigĂ© express : 1) plafond max_tokens atteint, JSON tronquĂ© â dĂ©tecter et relancer avec plafond supĂ©rieur ou continuation. 2) Le cache exige un prĂ©fixe exact ; lâhorodatage change Ă chaque appel â 0 hit, mais on paie le surcoĂ»t dâĂ©criture ~25 % â . 3) message_delta. 4) Volume massif + pas dâexigence de latence (SLA 24 h â ) â â50 % â . 5) 12 s : lâen-tĂȘte serveur prime sur toute heuristique client.
Annexes formateur
- Risques de dĂ©mo live : prĂ©voir des rĂ©ponses enregistrĂ©es (fixtures) au cas oĂč le rĂ©seau/la clĂ© API lĂąche. Le visualiseur SSE de la page web fonctionne hors ligne (simulation).
- DiffĂ©renciation : participants rapides â leur faire implĂ©menter la continuation aprĂšs
max_tokens(re-prompt avec la sortie partielle en prefill assistant). - Toutes les valeurs â (tarifs, TTL, limites, noms de modĂšles) doivent ĂȘtre revalidĂ©es sur https://docs.anthropic.com avant chaque session.