Sortie structurée
Deux approches selon le niveau de contrainte voulu :
| Mode | Garantie | Quand l’utiliser |
|---|---|---|
json_object | JSON valide, structure libre | Extraction simple, schéma décrit en prompt |
json_schema | Types et champs exacts garantis | Intégration base de données, workflow strict |
Mode JSON (json_object)
Section intitulée « Mode JSON (json_object) »Active la contrainte JSON côté serveur : la réponse est garantie valide en JSON. Décrivez la structure attendue dans le system message — le modèle s’y conforme.
Exemple — extraction de subvention
Section intitulée « Exemple — extraction de subvention »curl https://api.astrolabe.chat/v1/chat/completions \ -H "Authorization: Bearer $ASTROLABE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "mistral-small", "messages": [ { "role": "system", "content": "Extrais les informations suivantes et réponds UNIQUEMENT avec ce JSON, sans markdown ni texte autour :\n{\"nom_structure\": string, \"montant\": number, \"objet\": string}" }, { "role": "user", "content": "L'\''association Les Colibris demande 8 500 € pour financer son programme d'\''éducation à l'\''environnement." } ], "response_format": { "type": "json_object" }, "max_tokens": 500 }'Réponse :
{ "nom_structure": "Les Colibris", "montant": 8500, "objet": "programme d'éducation à l'environnement"}Exemple Python
Section intitulée « Exemple Python »from openai import OpenAIimport json
client = OpenAI( base_url="https://api.astrolabe.chat/v1", api_key="sk-...",)
resp = client.chat.completions.create( model="mistral-small", messages=[ { "role": "system", "content": ( 'Extrais les informations et réponds UNIQUEMENT avec ce JSON :\n' '{"nom_structure": string, "montant": number, "objet": string, ' '"type_structure": "association"|"SCOP"|"SCIC"|"fondation"|"autre"}' ), }, { "role": "user", "content": "La SCOP Textile Libre demande 15 000 € pour l'achat de machines éco-responsables.", }, ], response_format={"type": "json_object"}, max_tokens=500,)
data = json.loads(resp.choices[0].message.content)# {"nom_structure": "Textile Libre", "montant": 15000,# "objet": "achat de machines éco-responsables", "type_structure": "SCOP"}Exemple TypeScript
Section intitulée « Exemple TypeScript »import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.astrolabe.chat/v1", apiKey: process.env.ASTROLABE_API_KEY,});
const resp = await client.chat.completions.create({ model: "mistral-small", messages: [ { role: "system", content: 'Extrais les informations et réponds UNIQUEMENT avec ce JSON :\n' + '{"nom_structure": string, "montant": number, "objet": string}', }, { role: "user", content: "Les Colibris demande 8 500 € pour l'éducation à l'environnement.", }, ], response_format: { type: "json_object" }, max_tokens: 500,});
const data = JSON.parse(resp.choices[0].message.content!);Mode JSON Schema (json_schema)
Section intitulée « Mode JSON Schema (json_schema) »Contraint la réponse token par token au schéma défini — chaque champ, type et enum est garanti. À préférer quand la structure doit être stable pour une base de données ou un webhook.
from openai import OpenAIimport json
client = OpenAI( base_url="https://api.astrolabe.chat/v1", api_key="sk-...",)
schema = { "type": "object", "properties": { "nom_structure": { "type": "string" }, "montant_demande": { "type": "number" }, "objet": { "type": "string" }, "type_structure": { "type": "string", "enum": ["association", "fondation", "SCOP", "SCIC", "autre"] }, "eligible": { "type": "boolean" } }, "required": ["nom_structure", "montant_demande", "objet", "type_structure", "eligible"], "additionalProperties": False,}
resp = client.chat.completions.create( model="mistral-small", messages=[ { "role": "system", "content": "Tu analyses des dossiers de subvention ESS.", }, { "role": "user", "content": "Analyse : 'La SCOP Textile Libre demande 15 000 € pour l'achat de machines éco-responsables.'", }, ], response_format={ "type": "json_schema", "json_schema": { "name": "analyse_subvention", "strict": True, "schema": schema, }, }, max_tokens=500,)
data = json.loads(resp.choices[0].message.content)# {# "nom_structure": "Textile Libre",# "montant_demande": 15000,# "objet": "achat de machines éco-responsables",# "type_structure": "SCOP",# "eligible": true# }const schema = { type: "object", properties: { nom_structure: { type: "string" }, montant_demande: { type: "number" }, objet: { type: "string" }, type_structure: { type: "string", enum: ["association", "fondation", "SCOP", "SCIC", "autre"] }, eligible: { type: "boolean" }, }, required: ["nom_structure", "montant_demande", "objet", "type_structure", "eligible"], additionalProperties: false,} as const;
const resp = await client.chat.completions.create({ model: "mistral-small", messages: [ { role: "system", content: "Tu analyses des dossiers de subvention ESS.", }, { role: "user", content: "Analyse : 'La SCOP Textile Libre demande 15 000 € pour des machines éco-responsables.'", }, ], response_format: { type: "json_schema", json_schema: { name: "analyse_subvention", strict: true, schema, }, }, max_tokens: 500,});
const data = JSON.parse(resp.choices[0].message.content!);Bonnes pratiques pour le system message
Section intitulée « Bonnes pratiques pour le system message »Le modèle suit fidèlement la structure si le system message est précis :
Décrire le schéma inline :
Réponds UNIQUEMENT avec ce JSON, sans markdown ni texte autour :{"champ1": string, "champ2": number, "champ3": boolean}Contraindre les valeurs possibles :
Le champ "statut" doit être exactement l'une de ces valeurs : "urgent", "normal", "faible".Pour les tableaux :
Réponds avec un tableau JSON d'objets : [{"nom": string, "montant": number}]Dans n8n
Section intitulée « Dans n8n »- System message : décrivez le schéma JSON attendu (voir ci-dessus)
- Dans les options avancées du nœud OpenAI → Response Format →
JSON Object - Branchez un nœud JSON Parse ou Set pour extraire les champs
Dans Make
Section intitulée « Dans Make »Dans le body HTTP, ajoutez "response_format": {"type": "json_object"} et récupérez
choices[0].message.content → branchez un module Parse JSON.
{ "model": "mistral-small", "messages": [ { "role": "system", "content": "Réponds UNIQUEMENT avec ce JSON : {\"nom\": string, \"montant\": number}" }, { "role": "user", "content": "{{texte}}" } ], "response_format": { "type": "json_object" }, "max_tokens": 500}