How to Validate LLM Output in Python
A beginner-friendly DataValidator class that checks required fields and type constraints on LLM-generated or user JSON data.
Python code
47 linesimport json
from typing import Any, Dict, List, Optional
class DataValidator:
"""Simple helper for validating LLM-generated or user data."""
def __init__(self, required_fields: List[str], schema: Optional[Dict[str, str]] = None):
self.required_fields = required_fields
self.schema = schema or {}
def validate(self, data: Dict[str, Any]) -> Dict[str, Any]:
"""Validate data and return normalized result with status."""
errors = []
for field in self.required_fields:
if field not in data or data[field] in (None, ""):
errors.append(f"Missing required field: {field}")
for field, expected_type in self.schema.items():
if field in data and data[field] is not None:
if not isinstance(data[field], eval(expected_type)):
errors.append(
f"Field '{field}' should be {expected_type}, got {type(data[field]).__name__}"
)
return {
"is_valid": len(errors) == 0,
"errors": errors,
"data": self._clean(data),
}
def _clean(self, data: Dict[str, Any]) -> Dict[str, Any]:
return {k: v for k, v in data.items() if v is not None}
if __name__ == "__main__":
# Example: validating LLM response for a user profile
validator = DataValidator(
required_fields=["name", "email"],
schema={"age": "int", "active": "bool"},
)
raw_llm_output = json.loads('{"name": "Alice", "email": "alice@example.com", "age": "30"}')
result = validator.validate(raw_llm_output)
print(json.dumps(result, indent=2))
Output
{
"is_valid": false,
"errors": [
"Field 'age' should be int, got str"
],
"data": {
"name": "Alice",
"email": "alice@example.com",
"age": "30"
}
}
How it works
This validator checks two things: required fields exist and aren't empty, and optional fields match the expected type from a schema. It uses isinstance with eval to map string type names like int or bool to actual classes. The _clean method strips None values so downstream code gets predictable data. The result bundles validity status, error messages, and cleaned data into one dictionary—easy to consume in AI pipelines.
Common mistakes
- Using `eval` on untrusted schema values could execute arbitrary code—keep schemas internal
- Confusing `required_fields` with schema fields—required fields bypass type checks
- Forgetting that `isinstance(True, int)` is True, so booleans pass int validation
Variations
- Use `pydantic` models with `BaseModel` and type hints for more robust validation
- Replace schema dict with a validator function per field for custom logic
Real-world use cases
- Validating structured responses from an OpenAI API call before storing in a database.
- Checking that user-submitted form data from a webhook matches an expected contract.
- Normalizing LLM-generated JSON from different models into a uniform internal format.
Sponsored
More from AI & LLM integration patterns
- Cache LLM Completions by Hashing the Prompt in Python easy
- Chain of Thought Prompting in Python: Step-by-Step Reasoning Demo easy
- Circuit Breaker Pattern in Python for LLM API Calls medium
- Cosine Similarity to Retrieve Top K Chunks in Python easy
- Demonstrate Prompt Injection Bypass in Python easy
- How to Accumulate Streamed Tokens into a Final String in Python easy
Keep learning
Related tutorials and quizzes for this topic.