DevOps Elastic Hayway
Document

SUBSCRIBE TO GET FULL ACCESS TO THE E-BOOKS FOR FREE 🎁SUBSCRIBE NOW

Professional Dropdown with Icon

SUBSCRIBE NOW TO GET FREE ACCESS TO EBOOKS

Structured outputs JSON : réponses LLM typées pour le DevOps

À la fin de ce tutoriel, vous comprendrez les structured outputs (JSON mode / JSON Schema), distinguerez function calling (arguments d’outils) et réponse finale typée, déclarerez un schéma strict, validerez avec Pydantic, et brancherez un digest d’incident sur un pipeline DevOps — sans parser du markdown « presque JSON ».

Niveau : Intermédiaire · Temps estimé : 50–65 min · Versions cibles : OpenAI Chat Completions response_format / json_schema 2026 · Anthropic Messages · Python 3.12 · Pydantic v2 · Dernière vérification : 2026-09-11

← Précédent : Function calling / tool use · → Suivant : Prompt injection & sécurité · Hub : IA pour DevOps : parcours 2026

Prérequis

Objectif : obtenir un objet JSON valide et conforme à un contrat, prêt pour CI, tickets ou webhooks.

Ce que nous allons construire

Prompt + JSON Schema (strict)
        │
        ▼
   LLM (structured outputs / JSON mode)
        │  JSON candidat
        ▼
   Validation runtime (Pydantic / jsonschema)
        │  OK / erreur contrôlée
        ▼
   Pipeline DevOps (ticket, CI, runbook)

(Schéma — alt : « Structured outputs : schéma strict, LLM, validation, pipeline DevOps ».)

Le modèle reste probabiliste ; le contrat (schéma + validation) rend le résultat actionnable. Même en mode strict, gardez une validation runtime : défense en profondeur.

Étape 1 — Pourquoi le JSON libre casse les pipelines

Sans contrainte, le modèle mélange prose, fences markdown et champs inventés. Un json.loads fragile finit en incident de parsing en CI.

Approche Fiabilité parse Contrat champs
Texte libre + regex Faible Aucun
« Réponds en JSON » (prompt seul) Moyenne Soft
JSON mode (objet JSON) Bonne Partiel
Structured outputs (json_schema strict) Forte Fort

Pour DevOps Elastic Hayway 2026 : digérer une alerte, classer une sévérité, ouvrir un ticket, alimenter un step GitHub Actions — tout exige enums et champs required.

Étape 2 — Function calling vs structured outputs

  • Function calling (leçon 46) : appels d’outils (name + arguments) exécutés par votre runtime.
  • Structured outputs : réponse finale conforme à un JSON Schema. Pas d’exécution d’outil requise.

Les deux s’empilent : tools pour lire CloudWatch / kubectl, puis structured output pour le digest typé. Les tool schemas et response schemas partagent JSON Schema — réutilisez enums et $defs.

Étape 3 — OpenAI : response_format + json_schema strict

import json
import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

INCIDENT_SCHEMA = {
    "type": "object",
    "properties": {
        "title": {"type": "string", "minLength": 5, "maxLength": 120},
        "severity": {
            "type": "string",
            "enum": ["sev1", "sev2", "sev3", "sev4"],
        },
        "service": {"type": "string"},
        "region": {
            "type": "string",
            "description": "Région AWS, ex. ca-central-1",
        },
        "summary": {"type": "string"},
        "recommended_actions": {
            "type": "array",
            "items": {"type": "string"},
            "minItems": 1,
            "maxItems": 8,
        },
        "needs_human": {"type": "boolean"},
    },
    "required": [
        "title", "severity", "service", "region",
        "summary", "recommended_actions", "needs_human",
    ],
    "additionalProperties": False,
}

resp = client.chat.completions.create(
    model="gpt-4.1-mini",
    messages=[
        {
            "role": "system",
            "content": (
                "Tu es un SRE. Produis uniquement le digest d'incident. "
                "Ne invente pas de métriques absentes du contexte."
            ),
        },
        {
            "role": "user",
            "content": (
                "Alerte: 5xx rate 12% sur api-gateway, "
                "région ca-central-1, depuis 8 min. "
                "Latency p99 2.4s. Pas de deploy récent."
            ),
        },
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "incident_digest",
            "strict": True,
            "schema": INCIDENT_SCHEMA,
        },
    },
)

digest = json.loads(resp.choices[0].message.content)
print(digest["severity"], digest["region"], digest["needs_human"])

strict: True force la conformité ; gardez le schéma petit (tokens). Pour un estate Canada, ancrez ca-central-1 dans exemples et enums région.

Étape 4 — Claude / Anthropic : même contrat

Chez Anthropic, le pattern 2026 : déclarer un schéma, obtenir du JSON contraint, parser. Selon le SDK, schéma dédié ou outil forcé emit_incident_digest (même input_schema que les tools).

# Pseudocode Anthropic — contrat conceptuel 2026
# 1) Fournir le JSON Schema (ou tool dédié)
# 2) Recevoir un JSON (texte ou tool_use forcé)
# 3) json.loads + validation Pydantic — identique à OpenAI

incident_schema = {
    "type": "object",
    "properties": {
        "title": {"type": "string"},
        "severity": {"type": "string", "enum": ["sev1", "sev2", "sev3", "sev4"]},
        "service": {"type": "string"},
        "region": {"type": "string"},
        "summary": {"type": "string"},
        "recommended_actions": {"type": "array", "items": {"type": "string"}},
        "needs_human": {"type": "boolean"},
    },
    "required": [
        "title", "severity", "service", "region",
        "summary", "recommended_actions", "needs_human",
    ],
    "additionalProperties": False,
}

Stack multi-fournisseurs (OpenAI + Claude + Vercel AI SDK) : un seul schemas/incident_digest.json. Voir Claude API : premiers appels.

Étape 5 — JSON Schema utile en DevOps

  1. Enums pour severity, env (dev/staging/prod).
  2. additionalProperties: false contre les champs fantômes.
  3. required exhaustif en mode strict OpenAI.
  4. Bornes minLength / maxItems pour éviter les pavés.
  5. Descriptions courtes ; jamais de secrets dedans.
  6. Types simples — évitez oneOf exotiques si le strict les refuse.
Objet Usage pipeline
IncidentDigest Ticket + Slack
CiFailureSummary Commentaire PR
KubectlHealthReport Gate deploy
CostAnomaly Alerte FinOps

Exemple estate multi-compte : le digest inclut region (ca-central-1) et service pour router l’alerte vers la bonne équipe on-call et le bon board. Sans ces champs typés, un bot Slack « libre » envoie le même pavé à tout le monde.

Étape 6 — Validation runtime (Pydantic v2)

from pydantic import BaseModel, Field, ValidationError
from typing import Literal

class IncidentDigest(BaseModel):
    title: str = Field(min_length=5, max_length=120)
    severity: Literal["sev1", "sev2", "sev3", "sev4"]
    service: str
    region: str
    summary: str
    recommended_actions: list[str] = Field(min_length=1, max_length=8)
    needs_human: bool

def parse_digest(raw: str) -> IncidentDigest:
    try:
        return IncidentDigest.model_validate_json(raw)
    except ValidationError as exc:
        raise RuntimeError(f"digest_invalid: {exc}") from exc

En CI : fixtures golden. En prod : métrique llm_structured_parse_fail_total.

Étape 7 — Lab : digest d’incident → ticket

But : texte d’alerte → IncidentDigest valide → ticket simulé.

  1. OPENAI_API_KEY ou stub du client en tests.
  2. Schéma Étape 3 + parse_digest.
  3. Si needs_human ou severity in {"sev1","sev2"} → ticket + page, pas d’auto-remediation. Tracez la décision dans l’audit (severity, needs_human, timestamp).
  4. Sinon, recommended_actions en commentaire CI seulement (pas de kubectl auto).
  5. Logs : model, region, severity, latence ; redactez PII.
  6. Région lab : ca-central-1.

Checklist lab :

  1. Budget API plafonné ; modèle mini.
  2. Schéma unique versionné (schemas/incident_digest.json).
  3. Afficher le JSON brut avant tout ticket réel.
  4. Contexte pauvre → needs_human: true.
  5. Stub JSON incomplet → erreur contrôlée.
  6. Publish HOLD : pas de page WordPress live.

Étape 8 — Coût, tokens et pièges

Les schémas comptent en tokens d’entrée : descriptions courtes, un seul blob (pas system + response_format en double).

Pièges : valeurs hallucinées malgré des clés contraintes ; schéma trop large ; fallback JSON mode sans validation ; secrets dans les descriptions ; confusion tools vs réponse (leçon 46).

Attaques via logs/tickets : Prompt injection & sécurité. Outils avant digest : Function calling, MCP DevOps, ChatGPT Actions.

Compléments opérationnels

Standard de brief réutilisable

Pour ai-structured-outputs, adoptez un brief unique partagé par l’équipe. Il contient toujours cinq champs : objectif mesurable, contexte borné (lab/staging), liste blanche de fichiers ou ressources, interdits explicites (secrets, réseau, prod), et definition of done exécutable (commande de test ou checklist). Sans ces champs, l’outil improvisera — parfois avec élégance, souvent hors périmètre.

Stockez les briefs gagnants sous briefs/ai-structured-outputs/ dans un dépôt de documentation interne. Chaque brief cite le commit de référence et le modèle utilisé. Au troisième succès comparable, ouvrez une PR qui transforme le brief en rule, Skill ou slash command. Voir ai-skills-concept, claude-skills-instructions et evaluer-qualite-skill.

Revue de diff comme compétence P0

La vitesse d’un agent n’a aucune valeur si personne ne sait lire un diff. Instituez une règle simple : aucun apply massif sans parcours hunk par hunk. Posez-vous trois questions : ce changement est-il demandé ? est-il testé ? est-il réversible ? Si une réponse est non, refusez ou exigez un plan plus petit.

En atelier, faites commenter un diff à voix haute pendant cinq minutes. Les juniors apprennent ainsi le vocabulaire du refus. Reliez cette pratique à ai-code-review-pr et aux workflows ai-agent-workflows.

Sécurité continue

Les surfaces ai-structured-outputs multiplient les occasions d’injection et de fuite. Traitez tickets, README upstream, logs et ressources MCP comme des données non fiables. Séparez instructions et données. Allowlist tools. Confirmation humaine avant mutation. Guide : ai-prompt-injection-securite, mcp-servers-devops, claude-code-mcp.

Secrets : variables d’environnement de session, gestionnaire d’équipe, rotation, jamais de commit. Si un secret fuit dans un chat vendor, supposez-le compromis et rotatez.

Coûts, modèles et mode dégradé

Documentez un mapping fast/strong et un soft-cap mensuel dans la stack perso. OpenRouter peut aider à basculer — openrouter-multi-modeles. Le local (ollama-llm-locaux + continue-dev) sert de mode dégradé ou de bac à sable confidentialité.

Surveillez les changements silencieux de modèle par défaut : une régression de qualité est souvent un routing vendor, pas « l’équipe qui a oublié comment prompter ».

Ancrage parcours

ai-structured-outputs n’est qu’une étape du parcours IA DevOps 2026. Tronc commun d’abord (prompts, injection, skills), puis surface spécialisée, puis industrialisation (routines, MCP, RAG). Hub de navigation : /ia/. Comparatifs utiles : claude-vs-gpt-code, codex-vs-claude-code, claude-vs-cursor-vs-copilot.

Rituals hebdomadaires

Hebdo : promouvoir un brief en Skill/rule ; archiver un échec instructif ; vérifier le budget tokens. Mensuel : revoir la stack (retirer l’inutile) ; rejouer un lab gold ; mettre à jour les versions d’outils. Ces rituals valent mieux que d’ajouter un cinquième abonnement.

Exemple de NOTES.md

# NOTES ai-structured-outputs
Date:
Modèle:
Brief (résumé):
Fichiers touchés:
Commande DoD:
Refus utiles:
Commit:
Leçon:

Sans ce journal, vous réapprendrez les mêmes leçons chaque sprint. Avec ce journal, vous construisez un avantage composé d’équipe.

FAQ

Les structured outputs remplacent-ils le function calling ?
Non. Tools = actions. Structured outputs = forme de la donnée. Les agents DevOps combinent souvent les deux.

JSON mode (json_object) suffit-il ?
Pour un prototype. En pipeline : json_schema strict + Pydantic (enums, required, pas de parasites).

Le fournisseur refuse mon schéma en strict ?
Simplifiez (pas de oneOf exotiques), alignez required / additionalProperties, ou soft mode + retry. Documentez dans le README du schéma.

Même schéma OpenAI et Claude ?
Oui pour le cœur JSON Schema ; adaptez l’enveloppe SDK. Un fichier unique consommé aussi par Vercel AI SDK.

Où en CI GitHub Actions ?
Step Python après logs d’échec → artifact CiFailureSummary → commentaire PR. Secrets via OIDC / vault, jamais dans le prompt. Échec de validation = job rouge explicite (digest_invalid), pas un silent skip.

Quiz (5 questions)

1. Structured outputs servent surtout à :
– A. Exécuter kubectl dans le cloud du LLM
– B. Contraindre la forme JSON de la réponse
– C. Remplacer IAM

2. Par rapport au function calling :
– A. C’est strictement la même API
– B. Réponse typée vs appels d’outils exécutés par votre runtime
– C. Interdit Anthropic

3. strict: True + json_schema chez OpenAI vise à :
– A. Chiffrer la réponse
– B. Forcer la conformité au schéma
– C. Désactiver les tokens de sortie

4. Après réception du JSON, la bonne posture DevOps est :
– A. eval sur la string
– B. Valider (Pydantic / jsonschema) puis brancher le pipeline
– C. Ignorer additionalProperties

5. Pour un incident sev1 avec needs_human: true :
– A. Auto-remédiation silencieuse
– B. Ticket / page humaine, pas de mutation auto
– C. Coller la clé API dans le ticket

Réponses : 1‑B · 2‑B · 3‑B · 4‑B · 5‑B

Pour aller plus loin

Maillage série IA Outils 2026 (F — Patterns)

← Précédent Function calling / tool use
→ Suivant Prompt injection & sécurité
Hub IA pour DevOps : parcours 2026
Landing Cours IA
Aussi MCP · ChatGPT Actions · Vercel AI SDK · Claude API

Conclusion

Les structured outputs JSON transforment un LLM en producteur de contrats exploitables : schéma strict, validation runtime, branchement CI/tickets, région d’exemple ca-central-1. Pattern 47/50 après function calling et avant prompt injection — socle fiable des pipelines IA sur DevOps Elastic Hayway.

Publish : HOLD — attendre le feu vert Maître avant publication WordPress.

Retour parcours IA — hub Claude, Codex, ChatGPT et Skills.