Citations automatiques et bonnes pratiques
Des réponses sourcées et fiables
Quand le modèle utilise la recherche web ou la recherche X, la Responses API inclut automatiquement des citations dans la réponse. Ces citations permettent à vos utilisateurs de vérifier les sources et renforcent la confiance dans les réponses générées.
Fonctionnement des citations
Les citations apparaissent dans le tableau annotations de chaque élément de contenu :
{
"output": [{
"type": "message",
"content": [{
"type": "output_text",
"text": "Selon les dernières données, le marché de l'IA...",
"annotations": [
{
"type": "url_citation",
"url": "https://example.com/article",
"title": "Analyse du marché de l'IA en 2026",
"start_index": 35,
"end_index": 68
}
]
}]
}]
}
Champs d’une citation
| Champ | Description |
|---|---|
type | Toujours url_citation |
url | URL source |
title | Titre de la page source |
start_index | Position de début dans le texte |
end_index | Position de fin dans le texte |
Afficher les citations dans votre application
response = client.responses.create(
model="grok-4.20-reasoning",
input="Quelles sont les dernières avancées en IA ?",
tools=[{"type": "web_search"}]
)
text = response.output[0].content[0].text
annotations = response.output[0].content[0].annotations
# Construire le texte avec notes de bas de page
footnotes = []
for i, ann in enumerate(annotations, 1):
footnotes.append(f"[{i}] {ann.title} — {ann.url}")
print(text)
print("\n--- Sources ---")
for fn in footnotes:
print(fn)
En HTML
def render_with_citations(text, annotations):
# Trier par position (de la fin au début pour ne pas décaler les indices)
sorted_anns = sorted(annotations, key=lambda a: a.start_index, reverse=True)
html = text
for i, ann in enumerate(sorted_anns):
ref_num = len(sorted_anns) - i
link = f'<a href="{ann.url}" title="{ann.title}" target="_blank">[{ref_num}]</a>'
html = html[:ann.end_index] + link + html[ann.end_index:]
return html
Bonnes pratiques pour la production
1. Validez toujours le statut
response = client.responses.create(...)
if response.status != "completed":
handle_error(response)
return
2. Gérez les réponses vides
if not response.output or not response.output[0].content:
return "Le modèle n'a pas généré de réponse."
text = response.output[0].content[0].text
3. Loguez les métriques
Pour chaque requête en production, enregistrez :
response.idpour la traçabilitéusage.total_tokenspour la consommationusage.cost_in_nano_usdpour les coûts- Le temps de réponse côté client
- Le statut de la réponse
4. Sécurisez votre clé API
- Stockez-la dans une variable d’environnement, jamais dans le code
- Utilisez un gestionnaire de secrets en production (Vault, AWS Secrets Manager)
- Tournez vos clés régulièrement
- Ne les exposez jamais côté client (navigateur)
5. Gérez le contenu généré
Les réponses du modèle peuvent contenir du contenu inapproprié malgré les filtres. Implémentez une couche de modération si vous affichez les réponses publiquement.
6. Planifiez la scalabilité
- Utilisez le streaming pour réduire le temps d’attente perçu
- Implémentez un système de queue pour les requêtes lourdes
- Mettez en cache les réponses fréquentes
- Surveillez vos quotas de rate limiting
Checklist de mise en production
- Configuration du timeout à 3600 secondes
- Retry avec backoff exponentiel
- Rate limiting côté client
- Logging des métriques (tokens, coûts, latence)
- Gestion des erreurs (401, 429, 500, timeout)
- Sécurisation de la clé API
- Modération du contenu si nécessaire
- Monitoring et alertes de coût
- Circuit breaker pour la résilience
Points clés à retenir
- Les citations sont automatiques quand le modèle utilise
web_searchoux_search - Elles contiennent l’URL, le titre et la position dans le texte
- Validez toujours le statut et gérez les réponses vides
- Sécurisez votre clé API — jamais dans le code source ou côté client
- Implémentez logging, retry, rate limiting et monitoring avant de passer en production