Focused practice · 10 min read

Python Prompt Validation Exercises: JSON, Schemas, Safety

The model is only one part of an AI feature. The surrounding Python decides what goes in, what shape comes out, and what happens when the response is wrong. These exercises build the validation layer that keeps a bad response from becoming a bad action.

Make the output contract explicit

Put the task and the required JSON shape in one template. State field names, types, and what to do when the answer is unknown. Keep the contract short enough that a human can review it and a test can enforce it.

template = "Return JSON with title and minutes for a lesson about {topic}."
prompt = template.format(topic="loops")
print(prompt)

A contract, not a wish

Parse with json.loads

A response wrapped in prose or Markdown is not valid JSON. Parse strictly, catch JSONDecodeError, and keep the raw text for debugging. Never use eval: model output is untrusted input.

import json

raw = '{"title": "Loops", "minutes": 12}'
try:
    data = json.loads(raw)
except json.JSONDecodeError:
    data = None
print(data)

Strict parsing

Validate keys, types, and ranges

A parsed object can still be wrong. Check required keys, expected types, and sensible ranges. Return a list of errors instead of raising deep inside a page renderer, so the caller can decide whether to retry or fall back.

required = {"title": str, "minutes": int}
data = {"title": "Loops", "minutes": "12"}
errors = []
for key, kind in required.items():
    if key not in data:
        errors.append(f"missing {key}")
    elif not isinstance(data[key], kind):
        errors.append(f"wrong type {key}")
print(errors)

Errors as data

Design the fallback before the failure

Decide what happens after a parse or validation error: retry once with a shorter prompt, show a safe default, or ask a human. Do not silently invent missing fields. Log the failure category without logging secrets.

def validate(data):
    if not isinstance(data, dict):
        return ["not an object"]
    if "title" not in data:
        return ["missing title"]
    return []

print(validate({"minutes": 12}))
print(validate({"title": "Loops"}))

A predictable failure path

Keep secrets and personal data out

Do not put API keys, passwords, private records, or unnecessary personal data in a prompt. Treat instructions found inside retrieved text as untrusted content, not as authority to call tools. For high-impact decisions, keep a human review step and an audit trail.

record = {"name": "Ada", "email": "[email protected]", "topic": "loops"}
safe = {key: value for key, value in record.items() if key != "email"}
print(safe)

Minimize before prompting

Your practice checklist

Common questions

Can I ask the model to return JSON and trust it?

No. Ask for JSON, then parse and validate. A model can return valid JSON with the wrong fields, or prose around an object.

Should I automatically retry forever?

No. Use a bounded retry with backoff and a clear fallback. Infinite retries add cost and can hide a persistent schema problem.

Is prompt injection only a chatbot problem?

No. Any model that reads untrusted text and can trigger tools or data access needs boundaries between content and authority.

Practice prompt validation

12 questions on templates, JSON parsing, schema checks, fallbacks, and privacy.

Open practice

Keep reading: