Aller au contenu

Sortie structurée

Deux approches selon le niveau de contrainte voulu :

ModeGarantieQuand l’utiliser
json_objectJSON valide, structure libreExtraction simple, schéma décrit en prompt
json_schemaTypes et champs exacts garantisIntégration base de données, workflow strict

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.

Fenêtre de terminal
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"
}
from openai import OpenAI
import 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"}
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!);

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 OpenAI
import 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!);

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}]

  1. System message : décrivez le schéma JSON attendu (voir ci-dessus)
  2. Dans les options avancées du nœud OpenAI → Response FormatJSON Object
  3. Branchez un nœud JSON Parse ou Set pour extraire les champs

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
}