Answering in a shape
By default an agent’s answer is the model’s text. Passoutput - a JSON Schema, the same raw-schema
form step.ai.generate takes - and two things change: the model is constrained to that shape, and
the answer comes back parsed, so final is the object rather than a string you have to parse
yourself.
agent<Invoice> is your assertion about the schema you passed - nothing
checks the parsed value against the schema, exactly as with step.ai.generate. What output
guarantees is that the answer is valid JSON and that the model was constrained while producing it.
Two ways this fails, both loudly rather than by handing you the wrong thing:
Without
output, agent() behaves exactly as it always has and final is the model’s text. The
option changes nothing for an agent that does not use it.