Session 6· 09· 10 min

Structured Output with a JSON Schema

What you'll learn
  • Pass a raw JSON schema dict to with_structured_output()
  • See when a schema is preferable to a Pydantic class
  • Wrap up Session 6 and prep for the projects

Sometimes you do not want a Pydantic class — maybe the schema is loaded from a config file at runtime, or it comes from a user. LangChain accepts a plain dict schema too. Same return shape, different input type.

scripts/09_structured_output_json_schema.py
schema = {                                                  ①
    "title": "Weather",
    "description": "Weather info for a city",
    "type": "object",
    "properties": {
        "city": {"type": "string"},
        "temp_c": {"type": "number"},
        "condition": {"type": "string"},
    },
    "required": ["city", "temp_c", "condition"],
}

structured = model.with_structured_output(schema)            ②
result = structured.invoke("What is the weather in Madrid?")   ③
print(result)                                                  ④
A plain Python dict — standard JSON Schema, same rules you learned in Session 5 Phase 1.
Pass the dict instead of a Pydantic class.
invoke returns a dict (not a Pydantic instance) since you passed a dict schema.
You index the result with dict keys: result["city"], result["temp_c"].
$ python scripts/09_structured_output_json_schema.py
When to use a dict schema
Dict schemas are the right choice when the shape is dynamic — loaded from YAML, user-supplied, or assembled at runtime. Use Pydantic for everything static. The conventional wisdom is "Pydantic by default, dict when you have to".
Code Check
When you pass a JSON schema dict to with_structured_output, what type does invoke return?
Session 6 complete
You can now init, invoke, stream, batch, call tools in a loop, parallelise, and produce structured output with Pydantic or JSON schemas — across three providers with one interface. You are ready for the capstone projects.
Recap — what you just learned
  • with_structured_output accepts both Pydantic classes AND plain dict schemas
  • Dict schema → dict result, Pydantic class → typed instance
  • Use Pydantic by default, dicts when the schema is dynamic
Next up: Session 6 Troubleshooting