Aller au contenu

Structured Outputs

Les structured outputs transforment les réponses des modèles, passant de texte libre à du JSON strictement formaté. RouteAPI prend en charge deux modes de structured outputs : JSON mode (nécessite un JSON valide) et JSON Schema (garantit la conformité à un schéma spécifique).

Les structured outputs sont un mécanisme permettant de contrôler le format des réponses des modèles. Contrairement aux conversations ordinaires où les modèles génèrent librement du texte, les structured outputs forcent le modèle à générer des données JSON selon le format que vous avez défini. Ceci est crucial pour les scénarios nécessitant un traitement programmatique des sorties du modèle (extraction de données, génération de formulaires, analyse de réponses API).

RouteAPI propose deux modes de structured outputs :

ComparaisonJSON modeJSON Schema
GarantieLa sortie est un JSON valideLa sortie est conforme au schéma spécifié
Paramètreresponse_format: { type: "json_object" }response_format: { type: "json_schema", json_schema: {...} }
Définition du schémaNon requise, mais le format doit être décrit dans le promptJSON Schema complet requis
RigueurGarantit uniquement l’analysabilité, pas la structureGarantit que les champs, types et éléments requis correspondent exactement
Cas d’usageFormats simples, le modèle peut comprendre la structure depuis le promptStructures imbriquées complexes, validation de type stricte nécessaire

Explication simple : JSON mode garantit uniquement « peut être analysé avec succès par JSON.parse » mais ne se soucie pas des champs ; JSON Schema garantit non seulement la validité mais aussi que la structure, les noms de champs, les types et les éléments requis sont tous conformes à votre définition.

ScénarioDescriptionMode recommandé
Extraction de donnéesExtraire des informations structurées de texte non structuré (nom, adresse, date)JSON Schema
Génération de formulairesFaire générer au modèle des valeurs initiales de formulaire ou des objets de configurationJSON Schema
Analyse de réponses APILa sortie du modèle doit s’interfacer avec des API système en avalJSON Schema
Paires clé-valeur simplesBesoin de quelques champs seulement, structure simple et claireJSON mode
Tâches de classificationSortie de valeurs enum fixes (ex : sentiment : positif/négatif/neutre)JSON Schema + enum

JSON mode est la méthode de structured output la plus simple : vous définissez response_format.type à "json_object" dans votre requête, et le modèle générera un JSON valide au lieu de texte brut.

{
"model": "gpt-5.5",
"messages": [
{
"role": "system",
"content": "You are a data extraction assistant. Extract name, age, and city fields from user input and return in JSON format."
},
{
"role": "user",
"content": "My name is Li Ming, I'm 28 years old, and I live in Shanghai."
}
],
"response_format": { "type": "json_object" }
}
  1. Le format JSON doit être décrit dans le prompt : Le modèle ne sait pas quels champs vous voulez ; vous devez lui indiquer explicitement via le message système ou le message utilisateur quels champs générer et leurs types. Dans l’exemple ci-dessus, "Extract name, age, and city fields from user input and return in JSON format" est la description du format.

  2. Ne garantit pas la conformité au schéma : Le modèle pourrait générer {"name": "Li Ming", "age": 28, "city": "Shanghai"}, ou {"姓名": "Li Ming", "年龄": 28}, ou même {"person": {"name": "Li Ming"}}. Tant que c’est un JSON valide, c’est acceptable.

  3. Comment l’utiliser : Convient aux scénarios avec des formats simples, peu de champs, et où le modèle peut comprendre la structure depuis le langage naturel. Si une validation stricte des noms de champs ou des types est nécessaire, utilisez JSON Schema.

Requête (curl) :

Fenêtre de terminal
curl https://api.routeapi.ai/v1/chat/completions \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.5",
"messages": [
{
"role": "system",
"content": "You are a data extraction assistant. Extract name, age, and city fields from user input and return in JSON format."
},
{
"role": "user",
"content": "My name is Li Ming, I am 28 years old, and I live in Shanghai."
}
],
"response_format": { "type": "json_object" }
}'

Réponse :

{
"id": "chatcmpl_xxx",
"object": "chat.completion",
"created": 1730000000,
"model": "gpt-5.5",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"name\": \"Li Ming\", \"age\": 28, \"city\": \"Shanghai\"}"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 58,
"completion_tokens": 18,
"total_tokens": 76
}
}

Notez que message.content est une chaîne JSON, vous devez l’analyser vous-même avec JSON.parse / json.loads.

Le mode JSON Schema vous permet de définir précisément la structure de sortie, et le modèle garantit que le JSON généré est entièrement conforme à votre définition de schéma.

{
"model": "gpt-5.5",
"messages": [
{
"role": "user",
"content": "My name is Li Ming, I'm 28 years old, and I live in Shanghai."
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "person_extraction",
"strict": true,
"schema": {
"type": "object",
"properties": {
"name": { "type": "string", "description": "Name" },
"age": { "type": "integer", "description": "Age" },
"city": { "type": "string", "description": "City" }
},
"required": ["name", "age", "city"],
"additionalProperties": false
}
}
}
}
ChampTypeRequisDescription
typestringOuiFixé à "json_schema"
json_schema.namestringOuiNom du schéma pour identification, lettres, chiffres, underscores, tirets
json_schema.strictbooleanNonActive le mode strict, défaut false
json_schema.schemaobjectOuiDéfinition JSON Schema standard
ModestrictComportement
Mode stricttrueLe modèle doit générer exactement selon le schéma, noms de champs, types, éléments requis, additionalProperties tous strictement respectés
Mode non-strictfalseLe modèle essaie de se conformer au schéma, mais ne garantit pas une cohérence complète, peut omettre des champs ou en ajouter d’autres

Recommandation : Utilisez strict: true en production ; c’est la valeur principale du mode JSON Schema. Le comportement du mode non-strict est similaire à JSON mode + description dans le prompt, l’intérêt est limité.

Le champ schema suit la spécification standard JSON Schema (Draft 2020-12), champs courants :

ChampDescription
typeType de données : "object", "array", "string", "number", "integer", "boolean", "null"
propertiesDéfinitions de champs pour les objets (utilisé quand type est "object")
requiredTableau des noms de champs requis
additionalPropertiesAutorise ou non des champs supplémentaires non définis (recommandé false en mode strict)
itemsSchéma pour les éléments du tableau (utilisé quand type est "array")
enumListe de valeurs enum, restreint la plage de valeurs
descriptionDescription du champ, aide le modèle à comprendre la sémantique
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" },
"score": { "type": "number" },
"is_active": { "type": "boolean" },
"notes": { "type": ["string", "null"] }
}
}

Descriptions de types :

  • "string" : Chaîne de caractères
  • "integer" : Entier
  • "number" : Nombre (incluant entiers et décimaux)
  • "boolean" : Booléen
  • "null" : Valeur nulle
  • ["string", "null"] : Autorise chaîne ou null (champ optionnel)
{
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" }
},
"required": ["name"]
},
"tags": {
"type": "array",
"items": { "type": "string" }
},
"scores": {
"type": "array",
"items": { "type": "number" }
}
}
}
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" },
"city": { "type": "string" }
},
"required": ["name", "age"]
}

Le tableau required liste les champs qui doivent exister. Dans l’exemple ci-dessus, name et age sont requis, city est optionnel.

{
"type": "object",
"properties": {
"sentiment": {
"type": "string",
"enum": ["positive", "negative", "neutral"],
"description": "Sentiment classification result"
},
"priority": {
"type": "integer",
"enum": [1, 2, 3],
"description": "Priority: 1-low, 2-medium, 3-high"
}
},
"required": ["sentiment"]
}

enum restreint le champ aux seules valeurs de la liste ; le modèle ne générera pas d’autres valeurs.

{
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"name": { "type": "string" },
"address": {
"type": "object",
"properties": {
"city": { "type": "string" },
"street": { "type": "string" }
},
"required": ["city"]
}
},
"required": ["name", "address"]
}
},
"required": ["user"]
}

Les objets peuvent être imbriqués indéfiniment, mais une imbrication excessive peut affecter la qualité de génération et les performances du modèle.

{
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Date, format YYYY-MM-DD"
},
"amount": {
"type": "number",
"description": "Amount in CNY"
}
}
}

description n’est pas requis, mais fortement recommandé. Il aide le modèle à comprendre la sémantique du champ, les plages de valeurs et les conventions de format, améliorant significativement la précision de génération.

Extraire les informations utilisateur depuis du texte non structuré :

{
"name": "user_info_extraction",
"strict": true,
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "User name"
},
"age": {
"type": "integer",
"description": "Age"
},
"email": {
"type": ["string", "null"],
"description": "Email address, null if not in text"
},
"phone": {
"type": ["string", "null"],
"description": "Phone number, null if not in text"
},
"city": {
"type": "string",
"description": "City"
}
},
"required": ["name", "age", "city"],
"additionalProperties": false
}
}

Faire générer au modèle un tableau de produits :

{
"name": "product_list",
"strict": true,
"schema": {
"type": "object",
"properties": {
"products": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Product name"
},
"price": {
"type": "number",
"description": "Price in CNY"
},
"category": {
"type": "string",
"enum": ["electronics", "clothing", "food", "other"],
"description": "Product category"
},
"in_stock": {
"type": "boolean",
"description": "Whether in stock"
}
},
"required": ["name", "price", "category", "in_stock"],
"additionalProperties": false
}
},
"total_count": {
"type": "integer",
"description": "Total product count"
}
},
"required": ["products", "total_count"],
"additionalProperties": false
}
}

Extraction d’informations de commande avec imbrication multi-niveaux :

{
"name": "order_extraction",
"strict": true,
"schema": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "Order ID"
},
"customer": {
"type": "object",
"properties": {
"name": { "type": "string" },
"phone": { "type": "string" },
"address": {
"type": "object",
"properties": {
"province": { "type": "string" },
"city": { "type": "string" },
"street": { "type": "string" }
},
"required": ["province", "city", "street"],
"additionalProperties": false
}
},
"required": ["name", "phone", "address"],
"additionalProperties": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"product_name": { "type": "string" },
"quantity": { "type": "integer" },
"unit_price": { "type": "number" }
},
"required": ["product_name", "quantity", "unit_price"],
"additionalProperties": false
}
},
"total_amount": {
"type": "number",
"description": "Order total amount"
}
},
"required": ["order_id", "customer", "items", "total_amount"],
"additionalProperties": false
}
}

La plupart des modèles mainstream agrégés par RouteAPI supportent JSON mode (response_format: { type: "json_object" }), incluant :

  • Série OpenAI GPT (gpt-4o, gpt-4-turbo, gpt-3.5-turbo, etc.)
  • Série Claude (claude-3.5-sonnet, claude-3-opus, claude-3-haiku, etc.)
  • Série Gemini (gemini-2.0-flash, gemini-1.5-pro, etc.)
  • Autres modèles supportant le format OpenAI

JSON Schema (response_format: { type: "json_schema" }) nécessite des capacités de modèle plus élevées ; modèles actuellement supportés :

  • OpenAI : séries gpt-4o, gpt-4-turbo (version 2024-08-06 et ultérieures)
  • Claude : séries claude-3.5-sonnet, claude-3-opus
  • Gemini : gemini-2.0-flash-exp, séries gemini-1.5-pro
  • Autres : certains modèles de nouvelle génération

Comment confirmer : Interrogez les capacités du modèle via l’API Models avant d’appeler, vérifiez le champ supports_response_format.

CapacitéJSON modeJSON SchemaNotes
Plage de support des modèlesLarge (presque tous les modèles mainstream)Limitée (modèles de nouvelle génération)JSON mode a un support plus élevé
Complexité du schémaN/ARecommandé pas plus de 3 niveaux d’imbricationProfondeur excessive affecte la qualité de génération
Nombre max de champsN/ARecommandé pas plus de 50 champs de niveau supérieurTrop de champs affecte les performances
Garantie stricteGarantit uniquement JSON valideGarantit conformité au schémaConformité à 100% en mode strict
PerformanceRapideRelativement plus lentValidation du schéma a un coût supplémentaire
Consommation de tokensFaibleLégèrement plus élevéeDéfinition du schéma occupe des tokens de prompt
  1. Limite de taille de schéma : Une définition de schéma unique ne devrait pas dépasser 10KB ; des schémas excessivement larges peuvent être tronqués ou rejetés.

  2. Limite de profondeur d’imbrication : Recommandé que les niveaux d’imbrication ne dépassent pas 3-4 niveaux ; une imbrication excessive réduit la qualité et la vitesse de génération du modèle.

  3. Impact sur les performances : Le temps de réponse du mode JSON Schema est généralement 10%-30% plus lent que les requêtes régulières car le modèle doit valider la structure en temps réel pendant la génération.

  4. Fonctionnalités de schéma non supportées : Certaines fonctionnalités avancées de JSON Schema (comme $ref, allOf, anyOf, oneOf, regex) peuvent ne pas être supportées par tous les modèles.

  5. Sortie en streaming : Le mode JSON Schema supporte la sortie en streaming (stream: true), mais content est retourné en fragments ; le JSON complet doit être concaténé avant analyse.

Exemple 1 : Extraire des informations structurées depuis du texte non structuré

Section intitulée « Exemple 1 : Extraire des informations structurées depuis du texte non structuré »

Scénario : Extraire les informations client et la classification des problèmes depuis une conversation de service client.

curl :

Fenêtre de terminal
curl https://api.routeapi.ai/v1/chat/completions \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{
"role": "user",
"content": "Customer Li Ming (phone 13800138000) reported that order ORD-2024-001 in Chaoyang District, Beijing has not been shipped and is quite urgent."
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "customer_inquiry",
"strict": true,
"schema": {
"type": "object",
"properties": {
"customer_name": { "type": "string", "description": "Customer name" },
"phone": { "type": ["string", "null"], "description": "Customer phone" },
"location": { "type": ["string", "null"], "description": "Customer location" },
"order_id": { "type": ["string", "null"], "description": "Order ID" },
"issue_category": {
"type": "string",
"enum": ["delivery", "quality", "refund", "other"],
"description": "Issue category: delivery-logistics, quality-quality, refund-refund, other-other"
},
"urgency": {
"type": "string",
"enum": ["low", "medium", "high"],
"description": "Urgency level"
}
},
"required": ["customer_name", "issue_category", "urgency"],
"additionalProperties": false
}
}
}
}'

Réponse :

{
"choices": [
{
"message": {
"role": "assistant",
"content": "{\"customer_name\":\"Li Ming\",\"phone\":\"13800138000\",\"location\":\"Chaoyang District, Beijing\",\"order_id\":\"ORD-2024-001\",\"issue_category\":\"delivery\",\"urgency\":\"high\"}"
},
"finish_reason": "stop"
}
]
}

Python :

import os
import json
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ROUTEAPI_KEY"],
base_url="https://api.routeapi.ai/v1",
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": "Customer Li Ming (phone 13800138000) reported that order ORD-2024-001 in Chaoyang District, Beijing has not been shipped and is quite urgent.",
}
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "customer_inquiry",
"strict": True,
"schema": {
"type": "object",
"properties": {
"customer_name": {"type": "string", "description": "Customer name"},
"phone": {"type": ["string", "null"], "description": "Customer phone"},
"location": {"type": ["string", "null"], "description": "Customer location"},
"order_id": {"type": ["string", "null"], "description": "Order ID"},
"issue_category": {
"type": "string",
"enum": ["delivery", "quality", "refund", "other"],
"description": "Issue category",
},
"urgency": {
"type": "string",
"enum": ["low", "medium", "high"],
"description": "Urgency level",
},
},
"required": ["customer_name", "issue_category", "urgency"],
"additionalProperties": False,
},
},
},
)
data = json.loads(response.choices[0].message.content)
print(f"Customer: {data['customer_name']}")
print(f"Issue type: {data['issue_category']}")
print(f"Urgency: {data['urgency']}")

Node.js :

import OpenAI from 'openai';
const client = new OpenAI({
apiKey: process.env.ROUTEAPI_KEY,
baseURL: 'https://api.routeapi.ai/v1',
});
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'user',
content: 'Customer Li Ming (phone 13800138000) reported that order ORD-2024-001 in Chaoyang District, Beijing has not been shipped and is quite urgent.',
},
],
response_format: {
type: 'json_schema',
json_schema: {
name: 'customer_inquiry',
strict: true,
schema: {
type: 'object',
properties: {
customer_name: { type: 'string', description: 'Customer name' },
phone: { type: ['string', 'null'], description: 'Customer phone' },
location: { type: ['string', 'null'], description: 'Customer location' },
order_id: { type: ['string', 'null'], description: 'Order ID' },
issue_category: {
type: 'string',
enum: ['delivery', 'quality', 'refund', 'other'],
description: 'Issue category',
},
urgency: {
type: 'string',
enum: ['low', 'medium', 'high'],
description: 'Urgency level',
},
},
required: ['customer_name', 'issue_category', 'urgency'],
additionalProperties: false,
},
},
},
});
const data = JSON.parse(response.choices[0].message.content);
console.log(`Customer: ${data.customer_name}`);
console.log(`Issue type: ${data.issue_category}`);
console.log(`Urgency: ${data.urgency}`);

Scénario : Faire générer au modèle des valeurs initiales de formulaire basées sur une description en langage naturel.

Python :

response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": "You are a form filling assistant. Generate form data based on user description.",
},
{
"role": "user",
"content": "Create a new employee onboarding form: Zhang Wei, male, born in 1995, bachelor's degree, software engineer position, monthly salary 15000.",
},
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "employee_form",
"strict": True,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"gender": {"type": "string", "enum": ["male", "female"]},
"birth_year": {"type": "integer"},
"education": {
"type": "string",
"enum": ["high_school", "bachelor", "master", "phd"],
},
"position": {"type": "string"},
"salary": {"type": "number", "description": "Monthly salary in CNY"},
},
"required": ["name", "gender", "birth_year", "education", "position", "salary"],
"additionalProperties": False,
},
},
},
)
form_data = json.loads(response.choices[0].message.content)
print(json.dumps(form_data, ensure_ascii=False, indent=2))

Sortie :

{
"name": "Zhang Wei",
"gender": "male",
"birth_year": 1995,
"education": "bachelor",
"position": "Software Engineer",
"salary": 15000
}

Scénario : Faire extraire au modèle les informations clés depuis une réponse API tierce non structurée.

Node.js :

const apiResponse = `
Order status: Shipped
Logistics company: SF Express
Tracking number: SF1234567890
Estimated delivery: January 20, 2024
Current location: Beijing Distribution Center
`;
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'user',
content: `Extract structured data from the following logistics information:\n${apiResponse}`,
},
],
response_format: {
type: 'json_schema',
json_schema: {
name: 'logistics_info',
strict: true,
schema: {
type: 'object',
properties: {
status: {
type: 'string',
enum: ['pending', 'shipped', 'in_transit', 'delivered'],
},
carrier: { type: 'string', description: 'Logistics company' },
tracking_number: { type: 'string', description: 'Tracking number' },
estimated_delivery: {
type: ['string', 'null'],
description: 'Estimated delivery date, format YYYY-MM-DD',
},
current_location: { type: ['string', 'null'], description: 'Current location' },
},
required: ['status', 'carrier', 'tracking_number'],
additionalProperties: false,
},
},
},
});
const data = JSON.parse(response.choices[0].message.content);
console.log(data);
// Output: { status: 'shipped', carrier: 'SF Express', tracking_number: 'SF1234567890', estimated_delivery: '2024-01-20', current_location: 'Beijing Distribution Center' }

Si votre définition de schéma elle-même a des problèmes (erreurs de syntaxe, fonctionnalités non supportées), la requête retournera directement une erreur 400 :

{
"error": {
"message": "Invalid JSON schema: ...",
"type": "invalid_request_error",
"param": "response_format.json_schema.schema",
"code": "invalid_json_schema"
}
}

Solution :

  • Vérifiez si la syntaxe du schéma est conforme à la spécification JSON Schema
  • Supprimez les fonctionnalités avancées non supportées (comme $ref, allOf)
  • Simplifiez les structures excessivement imbriquées

Le modèle ne peut pas générer une sortie conforme au schéma

Section intitulée « Le modèle ne peut pas générer une sortie conforme au schéma »

Dans de rares cas, le modèle peut être incapable de générer du contenu conforme au schéma (par exemple, l’entrée utilisateur est complètement en conflit avec les exigences du schéma) ; dans ce cas, une erreur sera retournée ou il reviendra à une sortie en texte brut. Exemple d’erreur :

{
"error": {
"message": "Failed to generate valid output matching the provided schema after maximum retries.",
"type": "model_error",
"code": "schema_generation_failed"
}
}

Solution :

  • Vérifiez si le prompt est cohérent avec les exigences du schéma
  • Simplifiez le schéma, supprimez les contraintes trop strictes
  • Indiquez explicitement les exigences de sortie dans le prompt
  • Pour les champs optionnels, utilisez le type ["string", "null"] au lieu de juste "string"

Pour les échecs de génération occasionnels, vous pouvez implémenter un réessai automatique :

import time
def call_with_retry(client, **kwargs):
max_retries = 3
for attempt in range(max_retries):
try:
response = client.chat.completions.create(**kwargs)
content = response.choices[0].message.content
data = json.loads(content) # Verify it can be parsed
return data
except (json.JSONDecodeError, Exception) as e:
if attempt == max_retries - 1:
raise
time.sleep(2 ** attempt) # Exponential backoff
  1. Commencer simple : Vérifiez d’abord la faisabilité avec JSON mode, puis passez à JSON Schema après avoir confirmé qu’une validation stricte est nécessaire.

  2. Clarifier requis et optionnel : Mettez les champs requis dans le tableau required, utilisez ["type", "null"] pour les champs optionnels ou ne les mettez simplement pas dans required.

  3. Utiliser enum pour restreindre les énumérations : Pour les champs avec des valeurs limitées (statut, classification, priorité), listez-les explicitement avec enum ; cela peut grandement réduire les taux d’erreur.

  4. Ajouter description : Ajoutez description à chaque champ, expliquant la signification, le format, la plage de valeurs ; le modèle génère plus précisément en se basant sur cela.

  5. Définir additionalProperties: false : En mode strict, ajouter cela empêche le modèle de générer des champs supplémentaires non définis.

ProblèmeDescriptionSuggestion
Trop profondément imbriquéPlus de 4 niveaux d’imbrication réduit la qualité de générationDiviser en plusieurs objets plats, ou extraire en étapes avec des conversations multi-tours
Trop de champsUn seul objet dépasse 50 champsGrouper par logique métier, diviser en plusieurs sous-objets
Sur-contraintTous les champs sont requis, pas de flexibilitéMarquer uniquement les champs essentiels comme requis, autoriser null pour les autres champs
Pas de descriptionLe modèle ne comprend pas la sémantique des champsAjouter description à chaque champ, expliquer clairement
  1. Réduire la taille du schéma : La définition du schéma occupe des tokens de prompt ; des schémas excessivement larges augmentent la latence et le coût.

  2. Mettre en cache les définitions de schéma : Lorsque le même schéma est utilisé de manière répétée, définissez-le comme une constante dans le code pour éviter de le reconstruire à chaque requête.

  3. Choisir le modèle approprié : Toutes les tâches n’ont pas besoin du modèle le plus puissant ; une extraction structurée simple peut utiliser gpt-3.5-turbo + JSON mode.

  4. Traitement par lots : S’il y a plusieurs tâches similaires, concevez un schéma de tableau pour faire traiter plusieurs éléments de données au modèle en une fois.

FacteurImpactSuggestion d’optimisation
Taille du schémaLa définition du schéma occupe des tokens de promptRationaliser la description, supprimer les champs redondants
Choix du modèleJSON Schema nécessite généralement des modèles plus puissantsUtiliser JSON mode + modèle plus faible pour les tâches simples
Longueur de réponseLa sortie JSON est généralement plus longue que le texte (noms de clés, guillemets, crochets)Raccourcir les noms de champs, utiliser des enums au lieu de longues chaînes
Nombre de réessaisLes réessais d’échec de génération doublent la facturationOptimiser le schéma et le prompt pour réduire le taux d’échec

Conseil pratique : Pour les scénarios d’appels à haute fréquence, testez d’abord avec JSON mode ; après avoir confirmé que le modèle peut générer de manière stable le format correct, passez à JSON Schema. JSON mode a généralement 10%-20% de consommation de tokens et de coût inférieure à JSON Schema.

  • Le support de JSON mode et JSON Schema dépend du modèle sélectionné ; veuillez interroger le champ supports_response_format via l’API Models pour confirmer.
  • response_format est mutuellement exclusif avec tools (appel d’outils) : la même requête ne peut pas utiliser à la fois structured outputs et appel d’outils.
  • Dans la sortie en streaming (stream: true), content est retourné en fragments et doit être entièrement concaténé avant JSON.parse.
  • Les paramètres optionnels explicitement passés 0 ou false sont traités comme définis explicitement par l’utilisateur et ne seront pas traités comme des omissions par défaut.
  • Enregistrez l’ID de requête, l’ID de modèle, le code d’état et l’utilisation des tokens de chaque requête pour le dépannage. Les détails de la structure d’erreur sont disponibles dans Errors and Debugging.