pip install mellea, Ollama running locally.
Mellea provides two paths to structured output. Choose based on how the call fits
into your code:
| Pattern | When to use |
|---|---|
@generative with return type | You want a named, reusable function. The return type is declared in the signature. |
instruct(format=...) | You are building the prompt dynamically or combining structured output with grounding_context or user_variables. |
Pattern 1: @generative with typed returns
Classification with Literal
Simple Pydantic extraction
List returns
Return a list of typed values or Pydantic models:Nested models
Complex structured extraction works naturally with nested Pydantic models:Pattern 2: instruct(format=...)
When you need structured output alongside dynamic prompts, grounding context, or
user variables, use the format parameter on instruct():
format parameter triggers constrained decoding. The result is a
ModelOutputThunk whose .value is a JSON string matching the schema. Parse it
with PydanticModel.model_validate_json(str(result)).
Validating structured output content
Constrained decoding enforces schema validity — the output is always parseable JSON matching your model. To enforce semantic constraints (e.g., “the list must contain at least 2 names”), combineformat with a custom validation function:
check(None, ...) idiom creates a validation-only requirement that is never
embedded in the prompt. This avoids biasing the model while still gating the output
on your semantic constraint.
Requirements on @generative output
You can also apply requirements to @generative output. When the return type is a
Pydantic model, the requirements operate on the JSON string representation:
@generative, the output is parsed into the Pydantic model automatically.
You receive a Summary instance, not a JSON string.
Choosing between the two patterns
Use@generative when:
- The function is reusable and called from multiple places.
- The input and output types are stable.
- You want a clean function signature with IDE type-checking.
- You prefer direct attribute access (
person.name) over manual JSON parsing.
instruct(format=...) when:
- The prompt is built dynamically with
user_variablesorgrounding_context. - You are retrofitting structured output onto an existing
instruct()call. - You need fine-grained control over requirements and sampling alongside formatting.
SamplingResult inspection.
See also: Generative Functions | The Requirements System