Structured Outputs¶
Get provider‑enforced typed results in ~6 minutes. Requires Python 3.10+ and pip install alloy-ai
.
Alloy enforces outputs using provider structured outputs. A JSON Schema is sent to the model, and responses are parsed into your requested type.
How it works (strict mode)¶
- Primitives (str, int, float, bool):
- Providers require an object root. Alloy wraps primitives as
{ "value": <primitive> }
and unwrapsvalue
before parsing. - Dataclasses (objects):
- A JSON Schema is generated from the dataclass. All fields are required and
additionalProperties: false
is set. - Arrays:
list[T]
is supported whenT
maps to a concrete schema as above.
There is no prompt shaping. Output shape is enforced only via structured outputs.
Return Contracts¶
- Default
@command
: returnsstr
. If the model produces no final output, Alloy raisesCommandError
. @command(output=None)
: side-effect only. The wrapper always returnsNone
.@command(output=T)
: strict typed return. ReturnsT
or raises on empty/mismatch.
Authoring guideline: the decorated function always returns a prompt str
. The actual return type of the command is controlled by the decorator’s output
parameter.
Strict-mode limitations¶
Some types cannot produce a strict JSON Schema under provider constraints:
- Open-ended objects (
dict
ordict[...]
) andlist[dict]
are not supported. - Strict mode requires
additionalProperties: false
. Accepting arbitrary keys would violate this, so Alloy raises a clear configuration error. - Optional/Union types are not supported yet.
Use a concrete schema instead, such as a @dataclass
or TypedDict
with known fields.
Planned - TypedDict outputs with strict schemas (equivalent to dataclasses).
Errors and diagnostics¶
- If an unsupported output type is used in strict mode, Alloy raises
ConfigurationError
with guidance to use a concrete schema. - If the model returns an unparsable payload or no final output, Alloy raises
CommandError
with the expected type and a snippet of the model output.
Example parse error:
CommandError: Failed to parse model output as float: 'Please provide the text…'
Example¶
from alloy import command
@command(output=float)
def extract_price(text: str) -> str:
return f"Extract the price (number only) from: {text}"
print(extract_price("This item costs $49.99.")) # -> 49.99
Provider notes¶
- OpenAI: Uses Responses
text={"format": {"type": "json_schema", ...}}
and unwraps primitives from{"value": ...}
. When tool calls complete but no final structured output is present, Alloy may issue one follow‑up turn (no tools) using the same schema to request the final answer. This is controlled byauto_finalize_missing_output
(envALLOY_AUTO_FINALIZE_MISSING_OUTPUT
, default on). If still missing, the command raises. - Anthropic/Gemini: Use their respective structured-output mechanisms with a JSON Schema.
- Some providers may require a final follow‑up turn to produce a structured response when tools are used. When
auto_finalize_missing_output
is enabled (default), Alloy performs a single follow‑up turn without tools to request the final structured answer. - Ollama: No native structured outputs; strict mode not applied.