Return structured Rust values
Request schema-backed model output and handle provider capability differences explicitly.
Define the output
Use a Rust type as the contract between the model and the rest of your
application. Derive both Deserialize and JsonSchema; keep fields concrete
and document choices that are easy to confuse.
cargo add serde --features derive
cargo add schemarsuse runifold::JsonSchema;
use serde::Deserialize;
#[derive(Debug, Deserialize, JsonSchema)]
struct Triage {
category: String,
urgent: bool,
explanation: String,
}Avoid embedding business side effects in deserialization. Validate domain rules after decoding.
Build a structured Agent
build_structured::<T>() attaches the schema to the request and returns a
typed Agent. The result preserves both the decoded value and the complete
canonical outcome.
let agent = runtime
.agent("triage")
.system("Classify the request. Keep the explanation short.")
.build_structured::<Triage>("triage_result")?;
let result = agent.run("Payment failed twice", &run).await?;
println!("{:?}", result.output);
println!("turns: {}", result.outcome.turns);Use an explicit RunContext in production so the same call also carries
budgets, authority, cancellation, and observability.
Validation and errors
There are two separate failure classes:
- the provider can reject or ignore the requested output format;
- the returned JSON can fail local deserialization or domain validation.
Treat both as data-quality failures, not as permission to silently fall back to unvalidated text. Log the response ID and model identity, but do not log sensitive payloads by default.
Provider support
Structured output is a capability contract. Some models support strict schema enforcement, others support JSON mode only, and compatible endpoints may advertise more than they enforce. Test the exact provider, model, and feature combination you deploy.
When strictness is required, configure the feature policy to fail closed. When degradation is acceptable, make the fallback visible in product behavior and metrics.