If you are building an AI application, chances are you need the LLM to output data in a format your code can actually read—like a JSON object.
Historically, developers would add “Return ONLY valid JSON and nothing else” to their prompt. And half the time, the LLM would still reply with: Here is the JSON you requested: { ... }, breaking the JSON parser.
Here is how modern AI Engineers guarantee reliable JSON extraction using Pydantic and Tool Calling.
The Solution: Tool Calling (Function Calling)
Instead of begging the LLM to format its text response as JSON, we give the LLM a “tool” (or “function”). A tool is essentially a JSON Schema that defines exactly what fields and data types we expect.
We then tell the LLM: “You must use this tool to answer the user.” Because the LLM is trained on API calls, it will naturally populate the arguments of the tool, guaranteeing that the output matches your schema.
Step 1: Define Your Schema with Pydantic
In Python, we use Pydantic to define the exact structure we want. Let’s say we want to extract user information from an email.
`from pydantic import BaseModel, Field
class UserProfile(BaseModel): first_name: str = Field(description=“The user’s first name”) last_name: str = Field(description=“The user’s last name”) age: int = Field(description=“The user’s age, if mentioned. Otherwise 0.”) is_premium: bool = Field(description=“True if the user mentions upgrading or premium.”)`
Step 2: Use LangChain’s with_structured_output
LangChain makes this incredibly easy. We bind the Pydantic schema directly to the model. The model is now forced to return an instance of `UserProfile`.
`from langchain_openai import ChatOpenAI
Initialize the model
llm = ChatOpenAI(model=“gpt-4o-mini”)
Bind the schema
structured_llm = llm.with_structured_output(UserProfile)
Invoke the model
result = structured_llm.invoke(“Hi, my name is John Doe. I am 32 years old and I want to cancel my premium subscription.”)
print(result.first_name) # Output: John print(result.is_premium) # Output: True`
Why This is Bulletproof
When you use `with_structured_output`, the LLM provider (like OpenAI or Anthropic) enforces the JSON schema at the API level. You do not need to write regular expressions, you do not need to strip out markdown backticks, and you get native Python objects back immediately.
This pattern is the foundation for extracting entities, classifying documents, and building reliable AI workflows.
