XML et Markdown dans l'API
Mis à jour le 29 juillet 2026
Structurer vos instructions pour le modèle
Tant qu’un prompt tient en trois phrases, le texte brut suffit. Le problème arrive quand il grossit : plusieurs blocs de contexte, des règles conditionnelles, des données utilisateur à traiter, un schéma de sortie. Tout se mélange, le modèle confond ce qu’il doit lire et ce qu’il doit appliquer, et votre équipe ne sait plus quelle ligne modifier. Les tags XML et la syntaxe Markdown répondent à ce double besoin : lisible pour le modèle, maintenable pour l’humain. Mistral recommande explicitement leur usage dans les prompts de production.
La raison de leur efficacité est simple. Les modèles de langage ont été entraînés sur des milliards de documents contenant du HTML, du XML et du Markdown ; ces formats leur sont familiers parce qu’ils sont massivement présents dans les données d’entraînement. Le modèle identifie donc clairement les sections et leur rôle, tandis que vous obtenez un prompt qu’un collègue peut auditer d’un coup d’œil.
Tags XML pour délimiter les sections
L’usage le plus rentable des tags XML consiste à isoler les données des instructions. Dans l’exemple qui suit, le system prompt porte les règles et le schéma attendu ; le message utilisateur enveloppe le document dans un <document>, ce qui empêche le modèle de prendre le contenu du rapport pour une consigne.
from mistralai import Mistral
import os
client = Mistral(api_key=os.getenv("MISTRAL_API_KEY"))
system_prompt = """Vous êtes un assistant d'analyse de documents.
<instructions>
Analysez le document fourni et extrayez les informations demandées.
Répondez uniquement en JSON.
Si une information est absente, utilisez null.
</instructions>
<output_schema>
{
"titre": "string",
"auteur": "string",
"date": "string (YYYY-MM-DD)",
"resume": "string (max 100 mots)",
"mots_cles": ["string"]
}
</output_schema>"""
user_prompt = """<document>
Rapport trimestriel Q1 2026 — Mistral AI
Rédigé par Arthur Mensch, CEO
Date de publication : 1er avril 2026
Ce rapport présente les résultats du premier trimestre 2026. L'entreprise a connu une croissance significative de son activité API avec une augmentation de 300% du nombre de requêtes quotidiennes.
</document>
Extrayez les métadonnées de ce document."""
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
temperature=0.0
)
print(response.choices[0].message.content)
En production, un petit vocabulaire de tags revient constamment et gagne à être standardisé dans toute votre base de prompts :
<instructions>...</instructions> <!-- Règles pour le modèle -->
<context>...</context> <!-- Informations de fond -->
<document>...</document> <!-- Texte à analyser -->
<examples>...</examples> <!-- Exemples few-shot -->
<constraints>...</constraints> <!-- Limites et interdits -->
<output_format>...</output_format> <!-- Format de sortie attendu -->
<user_data>...</user_data> <!-- Données utilisateur -->
Markdown pour les instructions lisibles
Le Markdown répond à un autre besoin : hiérarchiser des règles. Là où le XML découpe le prompt en zones, les titres, les listes et le gras du Markdown organisent le contenu d’une zone. Ce prompt de rédaction technique met ainsi sur le même plan visuel un rôle, des règles d’écriture, une structure obligatoire numérotée et une liste d’interdits — un rédacteur humain saurait travailler avec, ce qui est le bon test.
system_prompt = """# Assistant de rédaction technique
## Votre rôle
Vous rédigez de la documentation technique pour des APIs REST.
## Règles de rédaction
- **Vouvoiement** dans tout le texte
- Phrases courtes (max 25 mots)
- Un concept par paragraphe
- Code inline entre backticks : `GET /api/v1/users`
## Structure obligatoire
1. **Introduction** — Contexte et objectif de l'endpoint
2. **Requête** — Méthode, URL, headers, paramètres
3. **Réponse** — Codes HTTP, corps JSON, exemples
4. **Erreurs** — Codes d'erreur possibles et résolution
## Interdits
- Pas de jargon non défini
- Pas de "simplement" ou "facilement"
- Pas d'exemples avec des données fictives non réalistes"""
Combiner les deux formats
Pour les prompts complexes, la pratique la plus efficace consiste à emboîter les deux : le XML délimite les grandes zones, le Markdown structure l’intérieur de chacune. L’agent de support multilingue ci-dessous utilise <persona> pour l’identité, <rules> pour le comportement — avec, à l’intérieur, deux sous-sections Markdown dont une règle d’escalade conditionnelle — et <knowledge_base> pour les faits périssables, qui sont ainsi la seule partie à mettre à jour quand la version du logiciel change.
system_prompt = """# Agent de support multilingue
<persona>
Vous êtes l'assistant de la société DataFlow, éditeur de logiciels ETL.
Vous parlez français, anglais et espagnol.
</persona>
<rules>
## Règles de comportement
- Répondez dans la langue de l'utilisateur
- Identifiez la catégorie du problème : **bug**, **question**, **demande de fonctionnalité**
- Pour les bugs : collectez version du logiciel, OS, message d'erreur exact
## Escalade
- Si le problème persiste après 3 échanges → proposer un ticket support
- Si le client mentionne une perte de données → escalade immédiate (priorité haute)
</rules>
<knowledge_base>
- Version actuelle : DataFlow 4.2.1 (avril 2026)
- OS supportés : Windows 11, Ubuntu 22.04+, macOS 14+
- Documentation : docs.dataflow.io
</knowledge_base>"""
Un template de prompt réutilisable
Le pas suivant consiste à ne plus écrire les prompts à la main mais à les fabriquer. La fonction ci-dessous prend un document et une liste de questions, et produit les messages complets. Deux détails méritent votre attention : les instructions imposent une citation justificative pour chaque réponse et une formule de repli explicite quand l’information est absente, ce qui réduit fortement les hallucinations sur les documents contractuels ; et la temperature à 0.1 laisse juste assez de souplesse pour formuler, sans autoriser d’interprétation.
def build_analysis_prompt(document: str, questions: list[str]) -> list:
"""Construit un prompt d'analyse structuré avec XML."""
system = """# Analyste de documents
<instructions>
Lisez le document fourni et répondez aux questions posées.
Chaque réponse doit citer la partie du document qui la justifie.
Si la réponse n'est pas dans le document, répondez "Non mentionné dans le document."
</instructions>
<output_format>
Pour chaque question, répondez au format :
**Q{n}** : [votre réponse]
> Citation : "[extrait du document]"
</output_format>"""
questions_formatted = "\n".join(
f"{i+1}. {q}" for i, q in enumerate(questions)
)
user = f"""<document>
{document}
</document>
<questions>
{questions_formatted}
</questions>"""
return [
{"role": "system", "content": system},
{"role": "user", "content": user}
]
# Utilisation
messages = build_analysis_prompt(
document="Contrat de prestation de services entre...",
questions=[
"Quelle est la durée du contrat ?",
"Quelles sont les pénalités de retard ?",
"Y a-t-il une clause de non-concurrence ?"
]
)
response = client.chat.complete(
model="mistral-large-latest",
messages=messages,
temperature=0.1
)
Quelques habitudes rendent ces prompts durables. Nommez vos tags de façon descriptive — <document> dit ce qu’il contient, <data> ne dit rien et vous perdrez cinq minutes à chaque relecture. Fermez-les systématiquement : un tag ouvert sans fermeture brouille la frontière entre deux sections et le modèle peut alors lire vos instructions comme du contenu à analyser. Indentez enfin pour la lisibilité humaine ; le modèle s’en passe très bien, mais la personne qui reprendra le prompt dans six mois, non.
Points clés à retenir
- Les tags XML isolent les données des instructions dans le prompt
- Le Markdown structure les règles et les listes de manière lisible
- Combinez les deux pour les prompts complexes de production
- Nommez vos tags de manière descriptive et fermez-les systématiquement
- Les prompts structurés sont plus faciles à maintenir, tester et versionner