C.W.K.
Stream
Lesson 05 of 05 · published

Structured Outputs & PDF Understanding

~22 min · structured-outputs, pdf, input_file

Level 0Tokenizer
0 XP0/54 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

Structured outputs guarantee the model's response conforms to a specific JSON schema. Combined with vision, you can extract structured data from PDFs and documents.

Pydantic with Responses API

Structured output schema limits: max 5,000 properties, 10 nesting levels, 1,000 enum values, and 120,000 characters total.

One pipeline replaces three

The pre-input_file pattern was: pdfplumber → text extraction → chunking → embedding → vector search → prompt assembly → JSON parsing. input_file + response_format collapses that into one API call. Pass the PDF; get back a typed Pydantic instance.

Caveat: input_file processes the whole PDF in one pass, so very long documents (100+ pages) hit context-window limits. For those, you still want chunking. For invoices, reports, contracts, single-page forms — input_file is the canonical shape.

Code

Sending a PDF via input_file·python
completion = client.chat.completions.create(
    model="gpt-5.4",
    messages=[{"role": "user", "content": "Return a JSON with name and age for 'Alice, 30'"}],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                },
                "required": ["name", "age"],
                "additionalProperties": False,
            }
        }
    }
)
import json
person = json.loads(completion.choices[0].message.content)
Structured extraction with response_format·python
from pydantic import BaseModel

class InvoiceData(BaseModel):
    vendor: str
    total: float
    items: list[str]
    date: str

response = client.responses.parse(
    model="gpt-5.4",
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text", "text": "Extract invoice data from this PDF:"},
            {"type": "input_file", "file_id": "file-abc123"},
        ]
    }],
    text_format=InvoiceData,
)
invoice = response.output_parsed  # typed InvoiceData object

External links

Exercise

Pick a PDF invoice (or generate one). Extract {vendor, invoice_number, total, currency, line_items[]} via input_file + response_format. Run on 5 different PDFs and measure which fields fail most.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.