Doing JSON structured output with Mini Me
Get JSON answers that follow a schema from a local model with Mini Me, using Go struct notation, then use them from a coordinator agent in the TUI.

So, what is structured output? It's the ability of a model to produce an output/answer in JSON while following a structure defined beforehand, usually JSON described by a JSON Schema. Of course, your model has to support this feature. You can read, for example, OpenAI's documentation on the subject: Structured model outputs.
Defining the structure
With Mini Me, you define this structure using the same notation as Golang structs (yes, I love Go, and it's easy to read), like this for example:
provider: llmman
model: hf.co/unsloth/gemma-4-E2B-it-GGUF:Q4_K_M
baseUrl: http://127.0.0.1:17434/v1
# From a Docker sandbox, the daemon runs on the host.
fallback: http://host.docker.internal:17434/v1
bashTool: false
editTools: false
planTool: false
fetchContentTool: false
askUserTool: false
acp:
name: pizza
title: π Pizza (JSON)
system: |
You are a pizzaiolo.
For the pizza the user names, list its ingredients for one 30 cm pizza.
structuredOutput: |
// One ingredient of the pizza.
type Ingredient struct {
Name string `json:"name"` // the ingredient's name, in the user's language
Quantity float64 `json:"quantity"` // amount for one pizza
Unit string `json:"unit"` // "g", "ml", "piece", "pinch" or "to taste"
Category string `json:"category"` // "base", "sauce", "cheese", "meat", "vegetable", "herb" or "other"
Optional bool `json:"optional"`
}
type Pizza struct {
Name string `json:"name"`
Vegetarian bool `json:"vegetarian"`
Ingredients []Ingredient `json:"ingredients"`
BakingTime *int `json:"bakingTime"` // minutes, null when unknown
}
var Recipe Pizza
sampling:
temperature: 0.0
chat_template_kwargs:
enable_thinking: false
So here, I want to get the ingredients needed to make a pizza, in JSON format.
Getting the ingredients of a pizza
I haven't mentioned it yet, but you can run Mini Me in "one-shot" or "headless" mode, meaning that mm runs a single prompt and then stops: mm --config agent.yaml --p "tell me something about the hawaiian pizza" or mm --p "tell me something about the hawaiian pizza" agent.yaml
So for our example, we'll use the following command:
mm -p "hawaiian pizza" agent.pizza.yaml | jq .
For a result like this:
{
"bakingTime": 12,
"ingredients": [
{
"category": "base",
"name": "Pizza Dough",
"optional": false,
"quantity": 250,
"unit": "g"
},
{
"category": "sauce",
"name": "Tomato Sauce",
"optional": false,
"quantity": 60,
"unit": "ml"
},
{
"category": "cheese",
"name": "Mozzarella Cheese",
"optional": false,
"quantity": 150,
"unit": "g"
},
{
"category": "meat",
"name": "Ham",
"optional": false,
"quantity": 100,
"unit": "g"
},
{
"category": "vegetable",
"name": "Pineapple Chunks",
"optional": false,
"quantity": 50,
"unit": "g"
},
{
"category": "herb",
"name": "Oregano",
"optional": false,
"quantity": 1,
"unit": "pinch"
}
],
"name": "Hawaiian Pizza",
"vegetarian": false
}
How to use the "pizzaiolo" agent in TUI mode?
You can ask the same thing with the TUI, but an agent in "structured output" mode can't use tools, so you won't be able to, for example, save the generated information. The trick to work around this is to use the builtin ask_agent tool. So create a new agent.yaml configuration file, which will be a coordinator agent:
provider: llmman
model: hf.co/unsloth/gemma-4-E2B-it-GGUF:Q4_K_M
baseUrl: http://127.0.0.1:17434/v1
fallback: http://host.docker.internal:17434/v1
# The agents Bob can ask with the `ask_agent` tool.
# Its answer β the JSON β comes back to him as the tool's result.
mmConfigs:
pizza:
path: agent.pizza.yaml
description: All about pizzas.
# Bob reads and writes files (read_file, write_file, edit_file); no shell.
bashTool: false
editTools: true
# planTool: false
# skillsDir: no-skills
yolo: true
acp:
name: bob
title: π€ Bob (coordinator)
system: |
Your name is Bob. You coordinate one agent that answers in JSON, through your `ask_agent` tool:
- `pizza` for pizza recipes;
When a question is about pizza, call `pizza` agent,
Call the agent, then work from its JSON.
To read a file, use `read_file`; to create one, `write_file`.
sampling:
temperature: 0.0
parallel_tool_calls: false
max_tokens: 8192
chat_template_kwargs:
enable_thinking: true
reasoning_effort: low
maxTurns: 20
watchdogTimeout: 2m
firstTokenTimeout: 3m
And now run:
mm --tui
# or mm --tui agent.yaml
And now ask Bob the agent for the ingredients to make a pineapple pizza:

Bob does trigger the ask_agent pizza tool:

And with the information it gets back, Bob can write a report:

And you can absolutely ask it to save the JSON file:

Now, you can use Mini Me to generate datasets. And thatβs it for today.
Written by
Keep reading
Mini Me release v0.3.0
What is new in Mini Me v0.3.0, the Devoxx Belgium release: approval mode, agents calling agents, request traces, JSON answers, AGENTS.md and an sbx kit.

Building a team of Mini Mes with ACP
Build a team of local Mini Me agents talking over ACP: a coordinator that routes your Go and Rust questions to two documentation specialists.

Hello Mini Me: an agent born while preparing a talk for Devoxx
Meet Mini Me, a coding agent born from a Devoxx talk on the agent loop, built for small local models with guardrails against loops and hallucinations.

No comments yet. Be the first to comment!