An email signature block from a new co-author. You want to extract name and email and add them to your contacts sheet. In your current workflow, how do you get those two fields?
Copy the signature, open the spreadsheet, paste each field manually. Thirty seconds per contact, two hundred contacts in a conference season.
class Contact(BaseModel): name: str; email: str — now the model must return exactly those two fields. Add result_type=Contact and call .model_dump() to get a plain dict:
from pydantic import BaseModel
class Contact(BaseModel):
name: str
email: str
result = Agent(model, result_type=Contact).run_sync(text)
return result.output.model_dump()Why define the class inside the function file? Can't the model return a JSON string I parse myself?
You could parse a JSON string manually — but you'd write the validation logic yourself. Pydantic validates types, catches missing fields, and gives you a clean dict. The model knows it must fill in name and email exactly — it can't return "full_name" or add a "phone" field you didn't ask for. That's reproducible extraction.
So the LLM literally has to return this exact shape. Like a structured extraction form the model fills in. No extra fields, no renamed keys.
That's exactly what it is. A codebook-compliant extraction form the model has to fill in. Structured output is how you make AI reproducible.
And the dict goes straight to append_row from the automation track. Extract → append — one pipeline, no spreadsheet open.
The bridge between tracks looks like this:
contact = extract_contact(text)
row = [contact["name"], contact["email"]]
# append_row(sheet_id, row) <- automation track functionFor now: define the model, run the agent, call .model_dump(), return the dict. That's the Week 4 capstone direction. For now: define the model, run the agent, call .model_dump(), return the dict.
from pydantic import BaseModel
class Contact(BaseModel):
name: str
email: str
result = Agent(model, result_type=Contact).run_sync(text)
return result.output.model_dump()Pydantic validates types and required fields automatically. The model knows the schema and fills it exactly — no extra fields, no renamed keys. .model_dump() returns a plain dict you can append to a sheet or pass to the next step.
model_dump() returns a plain dict — {"name": "...", "email": "..."}. That dict maps directly to a Sheet row via GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND. The structured extraction pattern is the bridge between AI output and your data pipeline.
An email signature block from a new co-author. You want to extract name and email and add them to your contacts sheet. In your current workflow, how do you get those two fields?
Copy the signature, open the spreadsheet, paste each field manually. Thirty seconds per contact, two hundred contacts in a conference season.
class Contact(BaseModel): name: str; email: str — now the model must return exactly those two fields. Add result_type=Contact and call .model_dump() to get a plain dict:
from pydantic import BaseModel
class Contact(BaseModel):
name: str
email: str
result = Agent(model, result_type=Contact).run_sync(text)
return result.output.model_dump()Why define the class inside the function file? Can't the model return a JSON string I parse myself?
You could parse a JSON string manually — but you'd write the validation logic yourself. Pydantic validates types, catches missing fields, and gives you a clean dict. The model knows it must fill in name and email exactly — it can't return "full_name" or add a "phone" field you didn't ask for. That's reproducible extraction.
So the LLM literally has to return this exact shape. Like a structured extraction form the model fills in. No extra fields, no renamed keys.
That's exactly what it is. A codebook-compliant extraction form the model has to fill in. Structured output is how you make AI reproducible.
And the dict goes straight to append_row from the automation track. Extract → append — one pipeline, no spreadsheet open.
The bridge between tracks looks like this:
contact = extract_contact(text)
row = [contact["name"], contact["email"]]
# append_row(sheet_id, row) <- automation track functionFor now: define the model, run the agent, call .model_dump(), return the dict. That's the Week 4 capstone direction. For now: define the model, run the agent, call .model_dump(), return the dict.
from pydantic import BaseModel
class Contact(BaseModel):
name: str
email: str
result = Agent(model, result_type=Contact).run_sync(text)
return result.output.model_dump()Pydantic validates types and required fields automatically. The model knows the schema and fills it exactly — no extra fields, no renamed keys. .model_dump() returns a plain dict you can append to a sheet or pass to the next step.
model_dump() returns a plain dict — {"name": "...", "email": "..."}. That dict maps directly to a Sheet row via GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND. The structured extraction pattern is the bridge between AI output and your data pipeline.
Create a free account to get started. Paid plans unlock all tracks.