Comment obtenir des réponses en JSON (structuredOutput)
Ce guide montre comment faire répondre un agent uniquement en JSON, selon une forme que vous déclarez, pour qu'un script, jq ou un autre agent puisse exploiter la réponse. Il suppose que vous lancez déjà mm avec un fichier de configuration, sur un serveur qui accepte response_format: json_schema (llama.cpp, donc dmr, llamacpp, llmman ; Ollama ; l'API OpenAI). Le dossier demos/structured-output/ contient les fichiers utilisés ci-dessous.
Étapes
-
Écrivez un fichier de configuration pour un agent qui ne répond qu'en JSON, tous ses outils désactivés : une réponse contrainte par un schéma ne laisse aucune place à un appel d'outil, et mm refuse de démarrer sinon :
bashTool: false editTools: false planTool: false skillsDir: no-skills # un dossier qui n'existe pas : pas d'outil read_skillN'ajoutez ni
mmConfigs, nilsp, nimcp. -
Déclarez la forme de la réponse sous
structuredOutput, en types Go et unevarqui nomme la racine :structuredOutput: | type Language struct { Name string `json:"name"` // the language's name, in English Official bool `json:"official"` // true when it has an official status at the national level } type Country struct { Name string `json:"name"` // the country's common name, in English Capital *string `json:"capital"` // the capital CITY (not the country), in English; null when unknown Languages []Language `json:"languages"` // the main languages only, at most 4, most spoken first, each once } // One entry per country named in the question, in the order asked. var Countries = []Country{}Les tags
jsondonnent les clés. Les commentaires sont ce que le modèle lit pour remplir chaque champ : écrivez-les comme des consignes. -
Posez une question avec
-pet envoyez la réponse dans un pipe :mm agent.countries.yaml -p "donne moi les langages parlés de la France, le Canada, le Vietnam et les US" | jq -c '.[] | {name, capital}'{"name":"France","capital":"Paris"} {"name":"Canada","capital":"Ottawa"} {"name":"Vietnam","capital":"Hanoi"} {"name":"United States","capital":"Washington, D.C."}stdout ne porte que le JSON ; le code de sortie vaut 1 quand la réponse manque ou est invalide.
Variantes
- Faire exploiter le JSON par un autre agent. Déclarez l'agent JSON dans les
mmConfigsd'un coordinateur — un agent qui a des outils — ; il l'appelle avecask_agentet reçoit le JSON comme résultat de l'outil. Voir Comment laisser votre agent appeler d'autres agents etdemos/structured-output/agent.coordinator.yaml. Le coordinateur, lui, ne peut pas avoir destructuredOutput: il a des outils. - Interroger l'agent JSON par la config du coordinateur, depuis un shell :
mm agent.coordinator.yaml --ask countries -p "capitale du Vietnam" | jq .(voir Comment interroger un autre agent depuis un skill ou un script). - Dans le terminal ou la fenêtre, l'agent répond à chaque question en JSON, affiché comme n'importe quelle réponse.
- Pour l'API hébergée d'OpenAI, faites de la racine une struct (
var Answer = Triage{}) : son mode strict exige un objet au sommet. llama.cpp et Ollama acceptent un tableau. - Champs facultatifs : un pointeur (
*string) oujson:",omitempty"autorise la valeurnull; la clé est toujours présente.
En cas de problème
the answer was cut off by max_tokens before its JSON was complete— un petit modèle peut répéter les éléments d'une liste jusqu'à la limite. Bornez les listes dans leurs commentaires (at most 4,each once), ou augmentezsampling.max_tokens.- Un champ contient la mauvaise chose (le nom du pays dans
capital) — précisez son commentaire. Avec llama.cpp, le modèle écrit les clés dans l'ordre alphabétique quel que soit l'ordre de déclaration : un champ peut être rempli avant celui dont il dépend, rendez donc chaque commentaire autosuffisant. structuredOutput cannot be used with tools — this agent declares: …— désactivez les outils listés.structuredOutput:<ligne>:<col>: …— la déclaration à cette ligne du bloc n'est pas prise en charge ; voir la référence destructuredOutput.- Un modèle qui raisonne met du temps à répondre : coupez son raisonnement pour un agent de consultation (Comment couper le raisonnement d'un modèle).
Voir aussi
- Référence de
structuredOutput— la correspondance des types, les erreurs - Spécificités du mode invite — ce qu'imprime
-p - Sortie structurée — explication — pourquoi des déclarations Go, pourquoi pas d'outils
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
|