Building Automatic Repair Prompts: Retry Strategies
An automatic repair prompt is a carefully crafted message that tells the LLM exactly what went wrong and how to fix it. Unlike generic "try again" messages, effective repair prompts provide context, examples, and a clear success criterion. Teams using well-designed repair prompts reduce invalid outputs requiring manual intervention by 70% (Anthropic, 2025).
This article teaches you the anatomy of repair prompts, template patterns, and optimization techniques for building robust auto-correction systems.
The Anatomy of a Repair Prompt
An effective repair prompt has five components:
- Context reminder: Remind the LLM of the original task.
- Error identification: State what validation failed.
- Explanation: Why this matters or what went wrong.
- Correction guidance: Specific instructions to fix it.
- Success criterion: Clear definition of correct output.
Here's a template:
Original task: {ORIGINAL_TASK}
Your previous output had the following validation error(s):
{ERROR_LIST}
Why this matters: {EXPLANATION}
To fix this, ensure:
- {SPECIFIC_FIX_1}
- {SPECIFIC_FIX_2}
Correct output should:
- {SUCCESS_CRITERION_1}
- {SUCCESS_CRITERION_2}
Please try again and return only valid {FORMAT}.
Repair Prompt Examples
Example 1: Missing Required Field
Original task: Extract customer email from support ticket.
LLM output:
{"name": "Alice Chen"} // Missing email
Generic repair (weak):
Your output was invalid. Try again.
Effective repair (strong):
Your previous output was missing the required field "email".
The validation schema requires:
- "name": string (provided: "Alice Chen")
- "email": string (required, not provided)
Please extract the customer email from the ticket text and include it in the JSON.
Correct output format:
{"name": "Alice Chen", "email": "[email protected]"}
Try again with both fields:
The strong version:
- Identifies the exact missing field
- Shows the schema requirement
- Provides an example of correct format
- Repeats the original text so the LLM can find the email
Example 2: Invalid Type
LLM output:
{"age": "forty-two"} // Should be integer, not string
Effective repair:
Your "age" field was a string "forty-two", but the schema requires an integer.
Correct output should be:
{"age": 42}
Extract the age as a NUMBER, not text. Try again:
Example 3: Value Out of Range
LLM output:
{"rating": 15} // Must be 1–10
Effective repair:
Your rating was 15, but the schema requires a number between 1 and 10 (inclusive).
Rule: 1 <= rating <= 10
Correct output example:
{"rating": 8}
Please rate between 1 and 10 only. Try again:
Repair Prompt Templates in Code
Build a library of repair templates:
REPAIR_TEMPLATES = {
"missing_field": """Your output is missing the required field "{field}".
The schema requires: {schema_snippet}
Include the {field} field in your response. Try again:""",
"wrong_type": """Your "{field}" field is {actual_type}, but should be {expected_type}.
Example of correct format:
{example}
Try again with the correct type:""",
"out_of_range": """Your {field} value "{value}" is outside the allowed range: {constraint}.
Allowed: {allowed_values}
Choose a valid value and try again:""",
"invalid_format": """Your {field} value doesn't match the required format: {format}.
Valid examples:
- {example_1}
- {example_2}
Format your {field} correctly and try again:""",
"invalid_choice": """Your {field} value "{value}" is not in the allowed choices: {choices}.
Pick one of: {choices_list}
Try again with a valid choice:"""
}
def generate_repair_prompt(error_type: str, **kwargs) -> str:
"""Generate a repair prompt based on error type and context."""
template = REPAIR_TEMPLATES.get(error_type, REPAIR_TEMPLATES["missing_field"])
return template.format(**kwargs)
# Usage
error = generate_repair_prompt(
"wrong_type",
field="age",
actual_type="string",
expected_type="integer",
example='{"age": 42}'
)
Repair Chains: Multi-Step Correction
For complex tasks, use a repair chain where each retry targets a specific aspect:
def repair_chain(
text: str,
schema: dict,
max_retries: int = 3
) -> Optional[dict]:
"""Multi-step repair chain for extraction."""
client = anthropic.Anthropic()
repair_strategies = [
{
"name": "syntax",
"check": lambda p: json.loads(p), # Valid JSON?
"feedback": "Your output is not valid JSON. Ensure it's properly formatted with correct quotes and brackets."
},
{
"name": "schema",
"check": lambda p: jsonschema.validate(p, schema), # Valid schema?
"feedback": "Your output doesn't match the required schema. Check field names and types."
},
{
"name": "constraints",
"check": lambda p: check_business_rules(p), # Valid business logic?
"feedback": "Your values don't satisfy business constraints. Check ranges and allowed values."
}
]
output = None
for attempt in range(max_retries):
# Generate or repair
if attempt == 0:
prompt = f"Extract data from: {text}\nReturn JSON: {json.dumps(schema)}"
else:
strategy = repair_strategies[min(attempt - 1, len(repair_strategies) - 1)]
prompt = f"""Previous attempt failed: {strategy['feedback']}
Text: {text}
Schema: {json.dumps(schema)}
Try again with careful attention to {strategy['name']}. Return valid JSON only:"""
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=500,
messages=[{"role": "user", "content": prompt}]
)
output = response.content[0].text
# Validate through each repair strategy
success = True
for strategy in repair_strategies:
try:
parsed = json.loads(output)
strategy["check"](parsed)
except Exception:
success = False
break
if success:
return json.loads(output)
return None
This approach prioritizes fixes: first syntax, then schema, then business logic. Each failure triggers a targeted repair.
Comparing Repair Strategies
| Strategy | Success Rate | Cost | Complexity | Use Case |
|---|---|---|---|---|
| Generic retry | 10–15% | Low | Very low | Testing/exploration |
| Single repair prompt | 25–35% | Low | Low | Most production systems |
| Template-based repairs | 40–50% | Low | Medium | Validation-heavy systems |
| Repair chain | 50–60% | Medium | High | Critical/complex extractions |
| Repair + prompt optimization | 60–70% | Medium | High | High-reliability systems |
Key Takeaways
- Effective repair prompts include context, specific error identification, and clear correction guidance.
- Template-based repairs are 2–3x more effective than generic "try again" messages.
- Repair chains (syntax -> schema -> constraints) improve success rates by 50–60%.
- Always include the original task context in repair prompts so the LLM can locate source information.
- Log all repair attempts to identify patterns in failure modes.
Frequently Asked Questions
Should I increase model temperature when repairing?
No, keep temperature consistent (typically 0.0–0.5 for structured output). Higher temperature increases variability; stick with what worked.
How do I know if a repair prompt is good?
A/B test it. Run 100 failures through a generic repair message vs. your template. If the template improves fix rate by 15–25%, it's good.
What if the LLM can't find the information to repair?
That's a data problem, not a prompt problem. If the email isn't in the ticket, no repair prompt will help. Log these as "data insufficient" and escalate.
Can I chain repairs indefinitely?
No. After 3–5 repairs, the LLM is likely stuck. If it fails that many times, change the approach: use a different model, revise the schema, or fall back to a cached response.