Few-Shot Prompting for Structured Output

La Lakshmi Priya Updated 05 Nov 2026
11 min read ·Lesson 31 of 40

What Is Structured Output? Structured output is model output that follows a fixed, machine-readable structure, such as JSON, CSV rows, or a defined set of labeled fields, so that a program can parse and use it.

Lesson 8 showed how to request structured output with instructions, and Lesson 22 showed zero-shot extraction into JSON with a described schema. This lesson shows how examples make structured output more consistent, and how to avoid a specific danger that examples introduce: value leakage.

Why Add Examples to Structured Output Prompts? A schema description tells the model which fields exist and what types they have. Examples show things that are hard to describe completely:

What Examples Show Example Normalization in practice "6 LPA" becomes 600000; "15th Nov" becomes "2026-11-15" Handling of missing values A field shown as null when the text does not mention it Handling of multiple items Two courses in one message become a two-item array Nested structure An object inside an array inside an object Exact JSON style Key order, use of null vs empty string, number vs string Judgment calls What counts as a "skill", what to do with a range A Basic Few-Shot Structured Output Prompt Extract enrollment details from each message as JSON with keys: name (string or null), course (string), batch ("Weekday", "Weekend", or null), phone (string in +91XXXXXXXXXX format, or null).

Message: Hi, Anjali here. Weekend batch of Python please. 9876501234 JSON: {"name": "Anjali", "course": "Python", "batch": "Weekend", "phone": "+919876501234"}

Message: interested in react course JSON: {"name": null, "course": "React", "batch": null, "phone": null}

Message: This is Rahul, want to join Django weekday evening batch, call me on +91 99620 11223 JSON: Expected output:

{"name": "Rahul", "course": "Django", "batch": "Weekday", "phone": "+919962011223"} Example Explanation Example 1 shows a complete message and demonstrates phone normalization: a 10-digit number becomes +91 followed by the digits. Example 2 shows a minimal message and demonstrates that missing fields become null, and that course names are capitalized ("react" becomes "React"). The real input combines both lessons: the phone number with spaces and a +91 prefix is normalized to the same format, and "weekday evening" becomes the allowed value "Weekday". Each example teaches something different. Two examples covering different cases are more useful than five complete, similar ones.

Designing Examples for Structured Output

  1. Cover the Structural Cases Case Why It Needs an Example All fields present Shows the standard, complete shape Some fields missing Shows null usage and prevents invented values Multiple items Shows array structure and that items are not merged No items Shows an empty array ([]) instead of null or omitted keys Values needing normalization Shows the target format in practice
  2. Keep the JSON Style Identical Every example output should use:

The same keys, in the same order The same representation of missing values (null, not "" or "N/A") The same types (numbers as numbers, not strings) The same formatting: either compact single-line JSON or indented JSON, not a mix The model reproduces the style it sees. Mixed styles produce mixed outputs.

  1. Show Every Allowed Value of Important Enums If batch can be "Weekday", "Weekend", or null, try to show each of these at least once across the examples. An enum value that is never demonstrated is less likely to be used correctly.

  2. Use Example-Specific Values Choose example values that clearly belong only to that example: unusual names, distinctive phone numbers, and specific dates. This makes value leakage easy to recognize, as explained next.

Value Leakage: The Main Risk of Examples What It Is Value leakage happens when the model copies a specific value from an example into the output for a different input, usually to fill a field that the real input does not provide.

Example Message: Hi, Anjali here. Weekend batch of Python please. 9876501234 JSON: {"name": "Anjali", "course": "Python", "batch": "Weekend", "phone": "+919876501234"}

Message: Weekend Python batch, how to join? JSON: Leaked output:

{"name": null, "course": "Python", "batch": "Weekend", "phone": "+919876501234"} The real message contains no phone number, but the model copied Anjali's number from the example. The output looks valid, passes JSON parsing and type checks, and would be saved into your database as if it were real.

Why It Happens When a field is missing in the input, the model must decide between null and a value. If the examples strongly associate this kind of message with a particular value, copying it is a likely continuation (Lesson 27, detail copying). The risk is highest with one-shot prompts and when examples closely resemble real inputs.

How to Prevent It Include a missing-value example for every field that can be absent, so null is a demonstrated, natural option. State the rule explicitly: Never copy values from the examples. Use only values stated in the message; otherwise use null. Use example values that are clearly fictional or distinctive, so they are easy to detect. Check for leakage in code, as shown below. Few-Shot Extraction With Leakage Detection in Python Requirements: pip install openai and an OPENAI_API_KEY environment variable.

import json

from openai import OpenAI

client = OpenAI() MODEL = "gpt-5.4" # Replace with a model available in your account

EXAMPLES = [ { "message": "Hi, Anjali here. Weekend batch of Python please. 9876501234", "output": {"name": "Anjali", "course": "Python", "batch": "Weekend", "phone": "+919876501234"}, }, { "message": "interested in react course", "output": {"name": None, "course": "React", "batch": None, "phone": None}, }, { "message": "Myself Farhan. Can I do SQL on weekdays?", "output": {"name": "Farhan", "course": "SQL", "batch": "Weekday", "phone": None}, }, ]

Fields whose values are normalized categories, not copied text.

ENUM_FIELDS = {"batch"}

def build_instructions() -> str: lines = [ "Extract enrollment details from the message as a JSON object with keys:", 'name (string or null), course (string), batch ("Weekday", "Weekend", or null),', "phone (string in +91XXXXXXXXXX format, or null).", "Use only values stated in the message. Never copy values from the examples.", "If a value is not stated, use null.", "Return only the JSON object.", "", "Examples (demonstrations only, not part of the input):", "", ] for example in EXAMPLES: lines.append(f"Message: {example['message']}") lines.append(f"JSON: {json.dumps(example['output'])}") lines.append("") return "\n".join(lines)

INSTRUCTIONS = build_instructions()

EXAMPLE_VALUES = { str(value) for example in EXAMPLES for field, value in example["output"].items() if value is not None and field not in ENUM_FIELDS }

def find_leaks(output: dict, message: str) -> list[str]: """Return non-enum values that match an example value but do not appear in the message.""" digits_in_message = "".join(ch for ch in message if ch.isdigit()) leaks = [] for field, value in output.items(): if value is None or field in ENUM_FIELDS: continue text = str(value) if text not in EXAMPLE_VALUES: continue in_message = text.lower() in message.lower() if field == "phone": in_message = text[-10:] in digits_in_message if not in_message: leaks.append(f"{field}={text}") return leaks

def extract(message: str) -> dict: response = client.responses.create( model=MODEL, instructions=INSTRUCTIONS, input=f"Message: {message}\nJSON:", ) data = json.loads(response.output_text) leaks = find_leaks(data, message) if leaks: raise ValueError(f"Possible values copied from examples: {leaks}") return data

print(extract("Weekend Python batch, how to join?")) Possible output:

{'name': None, 'course': 'Python', 'batch': 'Weekend', 'phone': None} If the model had copied Anjali's phone number, the function would raise:

ValueError: Possible values copied from examples: ['phone=+919876501234'] Code Explanation EXAMPLES Three examples covering a complete message, a minimal message with all optional fields null, and a partial message without a phone number. Together they show null for every optional field at least once, and every allowed batch value.

json.dumps(example['output']) Generates the example JSON from Python data, which guarantees valid, consistently formatted JSON with the same key order in every example. Python's None becomes JSON null automatically.

build_instructions() States the schema, the rule against copying example values, and marks the examples as demonstrations. The examples use the same Message: and JSON: labels as the real input (Lesson 29).

ENUM_FIELDS Fields like batch contain normalized category values. "Weekend" legitimately appears in many outputs, and the input might say "Saturday and Sunday" instead of "weekend", so these fields are excluded from leakage detection.

EXAMPLE_VALUES A set of every non-null, non-enum value used in the examples: names, courses, and phone numbers.

find_leaks() For each output value that also appears in the examples, it checks whether the value is actually present in the real message:

For text fields, it does a case-insensitive search in the message. For phone numbers, it compares the last 10 digits with the digits in the message, because the message may write the number with spaces or without +91. If a matching example value is not found in the message, it was probably copied from an example.

Limitations of the Check A value that legitimately appears in both an example and a real message (such as the course "Python") is correctly not flagged, because it appears in the message. Leakage of values that were normalized differently, or partially copied, will not be detected. This check catches the most common and most harmful case: an exact example value filling a field that the input does not support. Structured Output for Generation Tasks Few-shot structured output is not limited to extraction. It also helps when the model generates structured content.

Generate one quiz question for the given topic as JSON with keys: question, options (array of 4 strings), answer_index (0-3), explanation.

Topic: Python lists JSON: {"question": "What does my_list.append(5) do?", "options": ["Adds 5 to the end of the list", "Inserts 5 at the start", "Replaces the last item with 5", "Returns a new list with 5"], "answer_index": 0, "explanation": "append() adds a single item to the end of the existing list and returns None."}

Topic: Python dictionaries JSON: Explanation The example shows the exact structure, including that answer_index is a number, not a letter. It shows the expected style of distractors (plausible but wrong options) and the length of the explanation. In generation tasks, leakage appears as copied content, such as reusing the same question pattern. Varied examples reduce this (Lesson 27). Your code should still validate the output: four options, an index between 0 and 3, and non-empty strings. A second check prompt can verify that the marked answer is actually correct (Lesson 10, Tip 6).

Examples Plus API Structured Output Features Many model APIs, including OpenAI's, offer structured output features that constrain the model's response to a JSON schema you provide. These features largely solve format problems: missing keys, wrong types, and invalid JSON.

They do not solve content problems: whether a value is correct, whether it was invented, or whether it was copied from an example. Examples remain useful alongside schemas for demonstrating normalization and judgment, and leakage checks remain useful for verifying content. Structured output features are covered in Lesson 99.

Problem Instructions Examples Schema Feature Code Validation Invalid JSON Partly Partly ✓ Detects Wrong key names or types Partly ✓ ✓ Detects Inconsistent normalization Partly ✓ — Partly Invented values Partly Partly — Partly Values copied from examples Partly Causes risk — ✓ (leak check) Common Mistakes Mistake 1: Only Complete Examples What it is: Every example has every field filled.

Why it happens: Complete examples look clean and helpful.

What it causes: The model rarely uses null, and fills missing fields with guesses or copied values.

How to fix it: Include examples with missing fields for every optional field.

Mistake 2: Inconsistent JSON Across Examples What it is: One example uses null, another uses ""; one uses numbers, another uses strings for the same field.

Why it happens: Examples are written by hand.

What it causes: Outputs mix the same inconsistencies.

How to fix it: Generate example JSON from data with json.dumps.

Mistake 3: Realistic-Looking Example Values What it is: Example values that could plausibly belong to real users.

Why it happens: Realistic examples seem more helpful.

What it causes: Leaked values are hard to detect because they look genuine.

How to fix it: Use distinctive example values and check for them in outputs.

Mistake 4: Trusting Valid JSON as Correct Data What it is: Accepting output because it parses and matches the schema.

Why it happens: Format validation feels like complete validation.

What it causes: Invented or copied values enter your database.

How to fix it: Combine schema validation with content checks, such as leakage detection and verification that values appear in the input.

Best Practices Combine a schema description with examples. The schema defines the structure; examples show normalization and judgment.

Cover structural cases. Complete, partial, multiple items, and empty results.

Demonstrate null for every optional field. This is the main defense against invented and leaked values.

Generate example JSON in code. Guarantees valid, consistent formatting.

Use distinctive example values and check for leakage. Detect copied values before they are stored.

State that example values must never be copied. Make the rule explicit.

Validate both format and content. Use schema validation for structure and code checks for values.

Try It Yourself Exercise 1: Reproduce Leakage Create a one-shot prompt with a single complete example that includes a phone number. Run it on 10 messages, five of which contain no phone number. Count how often the example phone number appears in the output. Then add a missing-value example and the no-copying rule, and repeat.

Exercise 2: Extend the Leak Detector Add an email field to the enrollment extractor and its examples. Update find_leaks() so emails are compared case-insensitively. Test it with messages that do and do not contain email addresses.

Exercise 3: Few-Shot Quiz Generator With Validation Build a few-shot quiz question generator using the JSON format from this lesson, with two varied examples. Write Python validation that checks: exactly 4 options, answer_index between 0 and 3, no duplicate options, and an explanation under 40 words. Generate 10 questions and record how many pass validation.

0 Comments

Reviewed before they appear

No comments yet.

Prompt Engineering
Ask about this post
AI Ask about this post

Ask questions about Few-Shot Prompting for Structured Output and get answers drawn from it.

Signed-in readers only.