Enforce a JSON Schema¶
Pass a schema and result.structured comes back already validated against it, whichever
mechanism the target supports:
import anyinfer as ai
REVIEW = {
"type": "object",
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "neutral", "negative"]},
"score": {"type": "integer", "minimum": 1, "maximum": 5},
"themes": {"type": "array", "items": {"type": "string"}},
},
"required": ["sentiment", "score", "themes"],
"additionalProperties": False,
}
result = client.generate(
"Analyze this review:\n" + review_text,
target="medium",
schema=REVIEW,
repair=ai.Repair(max_attempts=1),
)
analysis = result.structured # already validated against REVIEW
print(analysis["sentiment"], analysis["score"])
repair=ai.Repair(max_attempts=1) allows one corrective round trip against the same
model before the call fails; see repair for
what that costs and why it never falls back to another provider.
Handling Failure¶
try:
result = client.generate(prompt, target="medium", schema=REVIEW)
except ai.SchemaViolationError as error:
log.warning("model produced: %s", error.raw_text)
for message in error.errors:
log.warning(" %s", message)
You get the bounded raw output, specific validation errors, and any delimiter-confirmed
complete top-level members in error.partial, so your application can inspect the
response or tighten the prompt. Fallback never fires here: the model
answered, just in the wrong shape.
Pydantic Models Work¶
No pydantic dependency is added; the model is duck-typed through model_json_schema():
from pydantic import BaseModel
class Review(BaseModel):
sentiment: str
score: int
result = client.generate(prompt, target="medium", schema=Review)
parsed = Review.model_validate(result.structured)
Knowing What Happened¶
result.structured_mechanism # "grammar" | "json_schema" | "json_mode" | "prompt"
result.repair_attempts # 0 if the model got it right first time
Both are worth logging in aggregate. A model that frequently needs repair is usually a
prompt problem; a target that unexpectedly reports "prompt" may not be the model you
thought you configured.
Key Takeaways
result.structuredis validated client-side against your original schema, whatever mechanism the provider used to produce it.- A
SchemaViolationErrorcarries the raw text, the specific validation errors, and any recoverable partial members (enough to debug the prompt, not just the failure). - Repair is opt-in and costs an extra request per attempt; budget for it on latency-sensitive paths.
- Pydantic models are accepted directly, with no pydantic dependency in the library.