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.

Easy Python 3.9+ Aug 9, 2026 AI & LLM integration patterns 14 views 0 copies

Python code

47 lines
Python 3.9+
import 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

stdout
{
  "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

  1. Use `pydantic` models with `BaseModel` and type hints for more robust validation
  2. 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

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from AI & LLM integration patterns

Related tutorials and quizzes for this topic.