Session 5· 18· 10 min

Parse Math Reasoning

What you'll learn
  • Use Pydantic for structured chain-of-thought output
  • Nest a Step model inside a MathReasoning model
  • See how structured reasoning makes answers inspectable

A richer Pydantic schema: a math-tutor model returns a list of Step objects (each with explanation and output) plus a final_answer. Same pattern as lesson 17 with nested models.

18_responses_parse_math_reasoning.py
class Step(BaseModel):                                         ①
    explanation: str
    output: str

class MathReasoning(BaseModel):
    steps: list[Step]                                            ②
    final_answer: str

response = client.responses.parse(
    model="gpt-4o-2024-08-06",
    input=[...],
    text_format=MathReasoning,
)
math = response.output_parsed
for s in math.steps:                                             ③
    print(s.explanation, "->", s.output)
print("Final:", math.final_answer)
Nested Pydantic class — Step is a separate model.
list[Step] tells Pydantic "a list of these".
math.steps is a list of Step instances, each with typed attributes.
$ python 18_responses_parse_math_reasoning.py
Make reasoning inspectable
Asking for a list of steps plus a final answer gives you chain-of-thought you can display, log, or validate. Much better than a wall of text.
Recap — what you just learned
  • Pydantic models nest naturally — list[Step], Optional[User], etc.
  • Structured chain-of-thought is more inspectable than free-form text
  • Same pattern as lesson 17, just deeper
Next up: 19 — Parse Research Paper