A model is only one part of an LLM feature. The prompt controls task framing, the model controls generation, and the parser controls the boundary between natural language and software. Strong LangChain applications make that boundary explicit.
Output parsing is where many demos become real applications. If your app needs a category, score, SQL plan, support action, or JSON payload, do not hope the model returns the right format. Ask for a schema and validate it.
A good prompt states the role, task, constraints, available context, output format, and refusal conditions. For maintainability, avoid hiding business rules in scattered strings. Make them visible in the prompt template and tests.
Structured output turns a model response into a Pydantic object. This is essential for workflows that route tickets, extract fields, create plans, or trigger downstream actions.
This example classifies support tickets and returns a typed object instead of free-form text.
from typing import Literal
from pydantic import BaseModel, Field
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
class TicketClassification(BaseModel):
category: Literal["billing", "bug", "account", "feature_request", "other"]
priority: Literal["low", "medium", "high", "urgent"]
confidence: float = Field(ge=0, le=1)
short_reason: str
prompt = ChatPromptTemplate.from_messages([
("system", "Classify support tickets. Return only the requested schema."),
("human", "Ticket: {ticket}")
])
model = ChatOpenAI(model="gpt-4o-mini", temperature=0)
classifier = prompt | model.with_structured_output(TicketClassification)
result = classifier.invoke({
"ticket": "Our invoices are duplicated and customers are being charged twice."
})
print(result.category)
print(result.priority)
print(result.confidence)
import json
raw = '{"topic": "routing", "confidence": 0.82}'
payload = json.loads(raw)
required = {'topic': str, 'confidence': (int, float)}
for field, expected_type in required.items():
if field not in payload or not isinstance(payload[field], expected_type):
raise ValueError(f'invalid field: {field}')
print(payload['topic'], payload['confidence'])
routing 0.82
Use it whenever code needs to consume the result: routing, extraction, scoring, tool arguments, database writes, or workflow decisions.
No. Prompting helps, but schemas, validation, retries, evaluation, and monitoring are what make behavior dependable.
Retry with a bounded policy or return a controlled error instead of passing malformed data downstream.
Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.
Explore 500+ free tutorials across 20+ languages and frameworks.
Fresh tutorials, interview guides, and coding practice in your inbox.