Prompt engineering at scale
Reuse prompts while checking both output format and meaning.
In this lesson · 04 of 10
All lessons in this track →Saved in this browser. View your learning.
Start with the idea
Reuse prompts while checking both output format and meaning.
Reusable instructions need reusable tests. A response can have the right format and still contain invented facts. Treat refusal and cut-off output separately from success.
Structured output: An answer in a specified format, such as fields in a JSON object.
See the example and check your understanding
A made-up teaching example
The résumé input says only that someone led a team. The output invents 47 staff and a 96 percent success rate. Valid JSON does not make either number true.
Ask yourself
Does passing a format check prove that the content is supported?
Show the explanation
No. Check claims against the input. Ask for missing figures instead of inventing them.
Start with these checks
- Validate the format.
- Check factual support separately.
- Handle refusals and incomplete outputs explicitly.
Use the different practice case below and check every requirement in its full instructions.
The video explains the main idea. Use the sources, instructions and checks below to complete the practice.
Captions appear here during playback.
Prompt engineering at scale
Reuse prompts while checking both output format and meaning.
Video playback is unavailable. Read the descriptive transcript below, go directly to practice, or open the video file.
Source-based teaching example · Fictional data · Reviewed 2026-10-03. Microsoft Mark · locally synthesized. On a small screen, use fullscreen for diagram details or read the transcript.
Read the descriptive transcript
0:00 · What you will learn
Reuse prompts while checking both output format and meaning.
What appears on screen
Reuse prompts while checking both output format and meaning.
0:06 · The idea
Reusable instructions need reusable tests. A response can have the right format and still contain invented facts. Treat refusal and cut-off output separately from success.
What appears on screen
Reusable instructions need reusable tests. A response can have the right format and still contain invented facts. Treat refusal and cut-off output separately from success.
0:21 · One useful term
Structured output. An answer in a specified format, such as fields in a JSON object.
What appears on screen
An answer in a specified format, such as fields in a JSON object.
0:30 · A worked example
The résumé input says only that someone led a team. The output invents 47 staff and a 96 percent success rate. Valid JSON does not make either number true.
What appears on screen
The résumé input says only that someone led a team. The output invents 47 staff and a 96 percent success rate. Valid JSON does not make either number true.
0:45 · Your turn to think
Does passing a format check prove that the content is supported? Pause and decide before continuing.
What appears on screen
Does passing a format check prove that the content is supported? Pause the video if you need more time.
1:02 · Why this answer works
No. Check claims against the input. Ask for missing figures instead of inventing them.
What appears on screen
No. Check claims against the input. Ask for missing figures instead of inventing them.
1:11 · Check 1
Validate the format.
What appears on screen
Validate the format.
1:16 · Check 2
Check factual support separately.
What appears on screen
Check factual support separately.
1:21 · Check 3
Handle refusals and incomplete outputs explicitly.
What appears on screen
Handle refusals and incomplete outputs explicitly.
1:27 · Now try a different case
Open the lesson and try its different practice case. Use every check in the full task. Watching alone does not mark the lesson complete.
What appears on screen
Open the lesson Try the new case Check and revise The full task and its requirements are in the linked lesson.
Watching explains the example. Complete the lesson practice to check what you can do. Explore all visual lessons →
Lesson preparation and outcomes
Prerequisites: Functions, named arguments and JSON parsing.
By the end, you can: Version prompt templates, validate structured results and preserve source facts.
Worked scenario and practice feedback
A resume input says only led a team. A fluent output invents 47 staff and 96% success. Even perfectly valid JSON fails semantic evidence checks. Revise examples to preserve supplied facts and request missing metrics rather than quantify from imagination.
Guided and independent practice: Run the offline dispatcher, then independently add a schema-valid unsupported metric, a refusal and truncated JSON. Keep the same cases when comparing template versions.
Answer criteria: Refusal and truncation bypass successful parsing; unsupported claims fail; no low-temperature or schema setting is treated as truth. If the local pack or interpreter is unavailable, trace the synthetic input, expected output and failure guard on paper; label execution unverified. Required practice uses no paid API calls, accounts, purchase, operational data or actual deployment.
When a prompt is in a chat window, you write it once. When a prompt is in production code, you write it once and run it ten thousand times. The latter demands more discipline. This lesson covers the patterns that hold up at scale.
Part 1 Prompt templates with variables.
Hardcoding prompts inside f-strings works until you want to change them. Then you’re hunting through code. Better: keep prompts separate from the call site.
RESUME_BULLET_TEMPLATE = """\
CONTEXT: I was a {role}, {rank} in the {branch}, for {years} years.
My main responsibilities were {responsibilities}.
TASK: Rewrite the resume bullet below for a civilian audience.
STANDARDS: Active voice. Under 25 words. Preserve only supplied facts; ask for missing metrics. No
military jargon. Target audience: civilian hiring manager for
{target_role}.
BULLET: {bullet}
"""
def build_resume_prompt(**kwargs):
return RESUME_BULLET_TEMPLATE.format(**kwargs)
prompt = build_resume_prompt(
role="transportation operations NCO",
rank="E-7",
branch="Army",
years="12",
responsibilities="vehicle fleet management and personnel oversight",
target_role="supply chain manager",
bullet="Led team in successful execution of mission objectives.",
)A few habits that pay off:
- Keep templates in their own module (
prompts.py) once you have more than two. - Use named parameters, not positional. They’re self-documenting and resilient to template edits.
- Validate inputs when the prompt is user-facing. A missing field becomes a clearly-broken prompt fast.
Part 2 Structured output: JSON instead of prose.
For programmatic consumers, you don’t want prose. You want a parseable object.
Both Anthropic and OpenAI support structured output. Two ways to get there:
Method A: ask for JSON in the prompt and parse it
SCHEMA = """\
Return JSON exactly matching this schema:
{
"summary": "string, one sentence",
"key_points": ["string", "string", "string"],
"recommendation": "string, under 20 words"
}
"""
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=1024,
system=SCHEMA,
messages=[{"role": "user", "content": "Summarize: " + long_text}],
)
import json
if response.stop_reason != "end_turn":
raise ValueError("generation_not_complete_or_refused")
if not response.content or any(block.type != "text" for block in response.content):
raise ValueError("unsupported_content")
parsed = json.loads("".join(block.text for block in response.content))
# Next validate the application schema and source support; parsing alone is insufficient.Prompt-only JSON has no schema guarantee. It fails the day the model adds a chatty preamble before the JSON and json.loads chokes.
Method B: use the provider’s structured-output mode
OpenAI:
response = client.chat.completions.create(
model="gpt-5-mini",
response_format={
"type": "json_schema",
"json_schema": {
"name": "summary",
"schema": {
"type": "object",
"additionalProperties": False,
"properties": {
"summary": {"type": "string"},
"key_points": {"type": "array", "items": {"type": "string"}},
"recommendation": {"type": "string"},
},
"required": ["summary", "key_points", "recommendation"],
},
"strict": True,
},
},
messages=[{"role": "user", "content": "Summarize: " + long_text}],
)
import json
if not response.choices or response.choices[0].finish_reason != "stop":
raise ValueError("generation_not_complete")
message = response.choices[0].message
if message.refusal or not isinstance(message.content, str):
raise ValueError("refused_or_missing_content")
parsed = json.loads(message.content)
# Next validate the application schema and source support; parsing alone is insufficient.Anthropic supports native structured outputs on supported models/APIs: set output_config={"format": {...}} with a supported JSON schema, or mark a supported tool strict: True. These features constrain output formatting; plain tool use alone is not a schema guarantee. Refusal, truncated output, unsupported constraints and provider-specific limitations still require explicit handling. Always validate the received object independently; current provider documentation includes limitations such as enum casing and constraints enforced by SDK-side validation. Apply application rules and source verification after format validation. These SDK snippets are reference shapes, not live calls required by this lesson. Check the current OpenAI structured-output guide and Claude structured-output guide before an approved integration.
For this summary contract, an offline application check could be:
def validate_summary(value):
if not isinstance(value, dict) or set(value) != {"summary", "key_points", "recommendation"}:
return False
if any(not isinstance(value[k], str) or not value[k].strip() for k in ("summary", "recommendation")):
return False
points = value["key_points"]
return (isinstance(points, list) and len(points) == 3
and all(isinstance(p, str) and p.strip() for p in points)
and len(value["recommendation"].split()) < 20)
assert validate_summary({"summary": "Fictional draft.", "key_points": ["A", "B", "C"], "recommendation": "Verify the sources."})
assert not validate_summary({"summary": "Draft.", "key_points": ["A"], "recommendation": "Verify."})This checks fields and bounded formatting only. It cannot establish that a point is true, a recommendation is sensible or a sentence accurately summarizes the supplied evidence.
Part 3 Few-shot examples in code.
Foundations Lesson 03 taught the “show, don’t tell” move. Here’s how to do it programmatically.
EXAMPLES = [
{
"input": "Led team in successful execution of mission objectives.",
"output": "Led a team to carry out operational objectives; ask the author for team size and verified results."
},
{
"input": "Responsible for maintenance operations.",
"output": "Coordinated maintenance operations; ask the author for verified asset counts and outcomes."
},
]
example_block = "\n\n".join(
f"BAD: {e['input']}\nGOOD: {e['output']}"
for e in EXAMPLES
)
prompt = f"""\
Rewrite the resume bullet below in the style shown by the examples.
{example_block}
NOW REWRITE THIS:
BAD: {user_bullet}
GOOD:
"""Two or three sharp examples beat ten paragraphs of instructions. If quality slips, look at the examples before you look at the instructions.
Part 4 Chains: when one prompt isn't enough.
Some tasks naturally have multiple steps. Resist the urge to chain immediately. Try a single, well-structured prompt first. Evaluate the simplest candidate against task cases. Add stages when their separate responsibilities and validation boundaries are justified.
A clean chain pattern:
def process(text):
# Step 1: classify
category = classify_input(text)
if category == "resume_bullet":
return rewrite_bullet(text)
elif category == "cover_letter":
return rewrite_cover_letter(text)
elif category == "job_description":
return decode_jd(text)
return textThree principles:
- Each step has a single responsibility. Easier to test, easier to swap.
- Pass structured data between steps. Not free-form prose if you can help it.
- Verify between steps. If step 1’s output is junk, step 2 will be junk too. Fail loud.
This fixed dispatcher is a workflow. Agentic selection would let a model choose among allowed transitions; either design needs validation and bounded failure.
Interface/reference limits
Use the workflow reference to distinguish model capability, deployment and harness controls. Provider snippets in this lesson are illustrative, have not been executed against an actual provider in this revision, and require current SDK/model capability verification before separately authorized use.
Primary source checked October 2, 2026: OpenAI Structured Outputs.
Related primary source checked October 2, 2026: Claude structured outputs and supported constraints. Strict tool arguments and final response JSON are distinct features; application semantic checks remain necessary.