Résumer des appels de support en JSON
Sur cette page
Cette leçon construit pas à pas un prompt de résumé de transcriptions d’appels au support, avec une sortie JSON exploitable pour mesurer l’efficacité d’une équipe. Elle suit le cycle de la leçon 3 : un prompt simple, un prompt structuré, puis des cas limites qui révèlent un défaut, corrigé par des critères explicites et des exemples. Le code est mis à jour pour les sorties structurées, et la leçon se termine sur ce qui manque encore avant la production.
Le scénario et les données
Acme Corporation vend des objets connectés et traite des centaines d’appels par jour. Il faut transformer ces conversations en données structurées pour évaluer le support, en excluant les appels inexploitables : problèmes de connexion, barrière de langue, transcription inintelligible. Contraintes : des appels courts ou longs et compliqués, des sujets allant du Wi-Fi d’une ampoule à une panne système, un format précis pour l’analyse, et aucune information personnelle dans les résumés. Le cours fournit des transcriptions simulées : un appel court (une ampoule connectée qui ne s’allume pas, résolu par une réinitialisation), un appel moyen (un thermostat SmartTherm recalibré), un appel long sans résolution (une alarme SecureHome qui se déclenche la nuit, transférée à l’équipe technique). Longueurs très différentes, sujets variés, issues résolues ou non, suivis nécessaires ou non.
Du prompt simple au prompt structuré
Le premier prompt tient en deux lignes, « résume cet appel en te concentrant sur le problème, sa résolution et le suivi », suivi de la transcription. Les résumés obtenus sont corrects mais libres : titres variables, longueurs variables, aucune garantie que chaque point soit couvert, et rien n’interdit de recopier un nom ou un numéro. Le prompt structuré ajoute un prompt système (analyste du service client expert, résumés concis et exacts, ton professionnel), place la transcription en tête dans <transcript>, énumère les étapes (lire, analyser, produire le JSON), fixe des règles (confidentialité : aucun nom, téléphone ou courriel ; 100 caractères maximum par champ ; ton professionnel), et décrit la structure JSON attendue : un objet summary (problème, résolution, suivi requis, détails du suivi), un status et une liste ambiguities. Le carnet demandait en plus une analyse dans <thinking> puis le JSON dans <json> ; sur les trois appels et sur un appel volontairement ambigu (un SmartLock capricieux, un client pressé qui ne connaît pas son modèle et ne laisse pas de numéro), les sorties sont exactes, et l’appel ambigu remplit bien la liste des ambiguïtés.
Les cas limites qui cassent le prompt
Le cours soumet ensuite quatre appels qu’on ne veut pas résumer : un faux numéro, un appel incomplet (« le truc ne marche pas… je dois y aller »), une voix inintelligible, une barrière de langue. Le prompt structuré produit pour chacun un résumé complet, « statut COMPLETE », avec des problèmes clients du type « le client a composé le mauvais numéro » ou « voix inintelligible » : des données qui fausseraient l’analyse de l’équipe. Deux stratégies : les signaler pour relecture humaine, ou les catégoriser (difficulté technique, barrière de langue). Le cours choisit le signalement : si la transcription a moins de cinq échanges, si le problème du client est flou, ou si l’appel est inintelligible, incomplet ou gêné par la langue, renvoyer uniquement {"status": "INSUFFICIENT_DATA"}. Et il ajoute trois exemples couvrant trois situations : une interaction complète sans suivi, une interaction complète avec suivi et ambiguïtés (une SmartCam qui ne se connecte pas, escalade sous 24 h), une interaction aux données insuffisantes.
Avec ce prompt final, les appels normaux donnent leurs résumés, l’appel ambigu ses trois ambiguïtés, et les quatre cas limites renvoient le statut d’insuffisance ; même « blah blah blah » et une chaîne vide sont correctement rejetés.
La version 2026 : schéma garanti, réflexion native
Le carnet extrayait le JSON des balises <json> par une expression régulière. Avec les sorties structurées, le schéma est garanti par l’API, y compris la valeur du statut, et la réflexion adaptative du modèle remplace la balise <thinking> (que les modèles actuels peuvent décliner). Les consignes, les critères d’insuffisance et les exemples restent dans le prompt ; seule la forme de la sortie change.
from typing import Literal
from pydantic import BaseModel
import anthropic
client = anthropic.Anthropic()
class Summary(BaseModel):
customerIssue: str
resolution: str
followUpRequired: bool
followUpDetails: str | None
class CallSummary(BaseModel):
status: Literal["COMPLETE", "INSUFFICIENT_DATA"]
summary: Summary | None
ambiguities: list[str]
system = """
You are an expert customer service analyst, skilled at extracting key information from call transcripts and summarizing them in a structured format.
Your task is to analyze customer service call transcripts and generate concise, accurate summaries while maintaining a professional tone.
"""
prompt = """
Analyze the following customer service call transcript and generate a summary of the interaction:
<transcript>
{transcript}
</transcript>
<instructions>
1. Read the transcript carefully.
2. Analyze the transcript, focusing on the main issue, resolution, and any follow-up required.
3. Summarize the key aspects of the interaction.
Important guidelines:
- Confidentiality: omit all specific customer data like names, phone numbers, and email addresses.
- Character limit: restrict each text field to a maximum of 100 characters.
- Maintain a professional tone in your summary.
Insufficient data criteria. If any of these conditions are met:
a) the transcript has fewer than 5 total exchanges,
b) the customer's issue is unclear,
c) the call is garbled, incomplete, or is hindered by a language barrier,
then set status to INSUFFICIENT_DATA, leave summary empty and ambiguities empty.
Otherwise set status to COMPLETE.
<examples>
(les trois exemples du carnet : interaction complète, interaction avec suivi et ambiguïtés, données insuffisantes)
</examples>
</instructions>
"""
def summarize_call(transcript: str) -> CallSummary:
response = client.messages.parse(
model="claude-opus-5-5",
max_tokens=4096,
system=system,
messages=[{"role": "user", "content": prompt.format(transcript=transcript)}],
output_format=CallSummary,
)
return response.parsed_output
print(summarize_call(garbled_call).status) # INSUFFICIENT_DATA
print(summarize_call(call3).summary.followUpRequired) # True
Le cours insiste : ce prompt n’est pas prêt pour la production. Il réussit un petit jeu d’exemples jugés à l’œil, ce qui ne représente ni la diversité ni l’imprévisibilité des vrais appels. Des évaluations quantitatives sur des données représentatives sont ce qui sépare un prototype prometteur d’une solution fiable.
À vous de jouer
Compléter le jeu de test. Reprenez les transcriptions du carnet et ajoutez-en cinq de votre cru : un appel multi-sujets, un appel qui se termine sans résolution, un client en colère, un appel contenant un numéro de téléphone, un appel de deux heures résumé en dix lignes. Pour chacune, écrivez d’abord la sortie attendue, puis comparez.
Mesurer. Codez une vérification automatique : aucun chiffre à dix positions dans les champs texte, champs sous 100 caractères, statut cohérent avec le nombre d’échanges. Faites tourner les dix cas vingt fois et comptez les écarts : c’est votre première évaluation.
Sources officielles : 04_call_summarizer.ipynb (anthropics/courses, archivé) · Structured outputs (documentation Claude) · Évaluation de prompts (notre cours)
Points clés à retenir
- Les données réelles sont variées et bruitées : un prompt de production se construit sur de vraies transcriptions, longues et courtes.
- Transcription en tête, consignes numérotées, règles de confidentialité et de longueur, structure de sortie décrite : le format tient.
- Les cas limites révèlent le défaut : sans critères explicites, le modèle résume même un faux numéro.
- Des critères d’insuffisance et trois exemples couvrant les situations règlent le problème ; testez jusqu’à la chaîne vide.
- Sorties structurées et réflexion adaptative remplacent les balises
<json>et<thinking>; les évaluations restent à faire avant la production.
Crédits et licence — Adaptation française du cours « Real world prompting » du dépôt anthropics/courses (Anthropic), archivé en lecture seule le 15 septembre 2026 et publié sous licence CC BY-NC 4.0 ; cette adaptation, qui le traduit, le remanie et met son code à jour pour les modèles de novembre 2026, est diffusée sous la même licence.