4.1 — Reflection & Self-Critique Patterns
Reflection & Self-Critique Patterns
Yaar, ek agent jo apni galtiyon se nahi seekhta — woh ek parrot hai, agent nahi. The most significant limitation of basic AI agents is that they execute tasks without evaluating whether they executed them well. A reflection pattern breaks this cycle. It is the architecture that allows an agent to step back, critique its own output, identify errors or suboptimal decisions, and improve the result before returning it to the user or passing it to the next agent in the pipeline. This is what separates toy demos from production-grade agent systems — and it is what separates Pakistani developers building real autonomous businesses from those just following tutorials.
Section 1: Why Agents Need Reflection
Consider this scenario: You build an SEO audit agent for a Karachi digital agency. The agent scrapes a client's website, identifies technical issues, and generates a report. Without reflection, the agent might:
- Miss critical issues because its initial analysis was shallow
- Include false positives (flagging things that are not actually problems)
- Write recommendations in technical jargon the client cannot understand
- Produce a report that is 80% accurate but presented with 100% confidence
With a reflection loop, the agent generates the report, then a second pass critiques it against specific quality criteria, fixes the issues found, and only then outputs the final result. The client gets something trustworthy.
The Three Reflection Patterns:
- Self-Critique Loop: Agent generates output → Same agent critiques it → Revises → Final output
- Dual-Agent Review: Agent A generates → Agent B critiques using a different perspective or persona → Agent A revises
- Rubric-Based Evaluation: Agent generates → Output scored against a structured rubric → Items below threshold are flagged for revision
Section 2: Implementing a Self-Critique Loop
import anthropic
import os
client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
def generate_with_reflection(task: str, context: str, quality_criteria: list):
"""
Generates an output, critiques it, and returns an improved version.
This is the self-critique loop pattern.
"""
# Step 1: Initial generation
print("[Agent] Generating initial output...")
initial_response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2000,
messages=[{
"role": "user",
"content": f"Context: {context}\n\nTask: {task}\n\nGenerate a complete, high-quality response."
}]
)
initial_output = initial_response.content[0].text
# Step 2: Self-critique
criteria_text = "\n".join([f"- {c}" for c in quality_criteria])
print("[Agent] Critiquing initial output...")
critique_response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1500,
messages=[{
"role": "user",
"content": f"""You are a quality reviewer. Critique the following output against these criteria:
QUALITY CRITERIA:
{criteria_text}
OUTPUT TO REVIEW:
{initial_output}
Provide:
1. A score (1-10) for each criterion
2. Specific issues found (be precise, not general)
3. A list of improvements needed
4. Overall quality verdict: ACCEPTABLE (8+) or NEEDS_REVISION"""
}]
)
critique = critique_response.content[0].text
# Step 3: Check if revision needed
if "NEEDS_REVISION" in critique:
print("[Agent] Revising based on critique...")
final_response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2000,
messages=[{
"role": "user",
"content": f"""Improve the following output based on this critique.
ORIGINAL OUTPUT:
{initial_output}
CRITIQUE:
{critique}
Produce a revised version that addresses all issues. Do not explain the changes — just produce the improved output."""
}]
)
return final_response.content[0].text, critique
else:
print("[Agent] Output meets quality criteria.")
return initial_output, critique
# Example usage for a Pakistani SEO audit agent
if __name__ == "__main__":
result, critique = generate_with_reflection(
task="Write an SEO audit summary for a Karachi restaurant website that has no meta descriptions, slow mobile speed (LCP 4.2s), and no schema markup.",
context="The client is a restaurant owner in DHA Phase 5, Karachi. They have basic digital literacy.",
quality_criteria=[
"Technical issues explained in plain Urdu/English, no jargon",
"Each issue must include a severity rating (Critical/High/Medium/Low)",
"Each issue must include a specific action step the client can take",
"Report must include PKR cost estimates for fixes",
"Maximum 500 words — restaurant owner has limited time"
]
)
print("\nFINAL OUTPUT:")
print(result)
Section 3: The Dual-Agent Review Pattern
For high-stakes tasks — client deliverables, financial analysis, legal documents — a single agent critiquing itself has a blind spot: it cannot always see its own assumptions. The dual-agent pattern introduces a second perspective:
def dual_agent_review(task: str, content: str):
"""
Agent A writes, Agent B critiques from a different persona.
"""
# Agent B's critique persona — deliberately adversarial
critique = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1000,
messages=[{
"role": "user",
"content": f"""You are a senior quality assurance reviewer.
Your job is to find every flaw in the following content.
Be thorough, specific, and demanding.
TASK THE CONTENT WAS SUPPOSED TO ACCOMPLISH:
{task}
CONTENT TO REVIEW:
{content}
List every issue you find, ordered by severity. Be precise."""
}]
)
return critique.content[0].text
Practice Lab
Exercise 1: First Self-Critique Agent
Implement the generate_with_reflection function above. Run it on one task you normally do manually (draft an email, write a summary, generate a report). Compare the output with and without the reflection loop. Does quality improve?
Exercise 2: Calibrate Your Quality Criteria The quality criteria list is the brain of your reflection system. Try this: run the same task with 3 different criteria lists (generic vs specific vs strict). Notice how the specificity of criteria directly determines the improvement quality.
Exercise 3: Measure the Cost A reflection loop makes 2-3 API calls instead of 1. Calculate the additional cost per task. For your use case, is the quality improvement worth the extra cost? Document your answer — this is your reflection ROI analysis.
Key Takeaways
- Reflection patterns transform agents from single-pass executors into self-improving systems — the difference between 80% accuracy and 95%+ accuracy on complex tasks
- Three core patterns: self-critique loop (same agent), dual-agent review (second perspective), and rubric-based evaluation (scored against structured criteria)
- Quality criteria specificity is the most important design decision in a reflection system — vague criteria produce vague improvements
- Reflection adds 1-2 extra API calls per task: factor this into your cost model, but recognize that catching one error that would have damaged a client relationship is worth 100x the extra API cost
- Pakistani developer advantage: reflection-based agents are still rare in Pakistan's AI market — building this capability is a genuine competitive differentiator
🇵🇰 Pakistan Case Study: The SEO Report That Got Better Every Week
Bilal built an SEO audit agent for a Karachi digital marketing agency. The agent generated client reports. Without reflection, 1 in 5 reports had to be manually rewritten before sending — wrong priorities, jargon-heavy language, or incorrect recommendations.
He added a dual-agent reflection pattern: the Reporter agent generated the report, the Editor agent reviewed it against a Pakistan-specific rubric.
The Editor Agent's rubric:
SEO REPORT QUALITY CRITERIA (Pakistan Context):
1. All issues ranked by estimated monthly revenue impact (PKR)
2. Technical jargon explained in simple English (or Romanized Urdu)
3. Each recommendation must include: "How to fix" + "Time to fix" + "Cost estimate"
4. Priority issues shown first — client must know what to do Monday morning
5. No more than 5 priority issues per report (decision fatigue)
6. Positive findings must come first (builds client confidence before bad news)
Before reflection: 20% of reports needed manual rewrite. Client satisfaction: 6.5/10. After reflection: 2% needed rewrite. Client satisfaction: 8.9/10.
Sample reflection output (Editor Agent feedback on loop 1):
"Issue 5 ('fix duplicate meta descriptions') is listed as HIGH priority but has no revenue impact estimate. Issue 2 ('mobile layout broken') is listed as MEDIUM but costs the client ~PKR 45,000/month in mobile bounce traffic. Swap priorities. Also: issue 3 uses 'canonical tag conflict' without explanation — add: 'A canonical tag tells Google which version of a page to rank. Conflicts cause ranking drops.'"
After 3 reflection loops, the report was ready to send without human review.
🔧 Dual-Agent Reflection: Working Code Example
import anthropic
import os
client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
def run_dual_agent_reflection(
task: str,
context: str,
quality_criteria: list,
max_iterations: int = 3
) -> str:
"""Run a dual-agent reflection loop: Generator → Critic → Revise."""
current_output = None
for iteration in range(max_iterations):
# AGENT 1: Generator
if current_output is None:
gen_prompt = f"Task: {task}\n\nContext: {context}\n\nGenerate the output:"
else:
gen_prompt = f"Task: {task}\n\nContext: {context}\n\nPrevious version:\n{current_output}\n\nFeedback:\n{feedback}\n\nRevised version:"
gen_response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=800,
messages=[{"role": "user", "content": gen_prompt}]
)
current_output = gen_response.content[0].text
# AGENT 2: Critic
criteria_str = "\n".join(f"{i+1}. {c}" for i, c in enumerate(quality_criteria))
critic_prompt = f"""Evaluate this output against each criterion.
Be specific about what fails and why.
CRITERIA:
{criteria_str}
OUTPUT TO EVALUATE:
{current_output}
For each criterion: PASS or FAIL with specific reason.
If ALL pass, write: ALL_CRITERIA_PASSED"""
critic_response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=500,
messages=[{"role": "user", "content": critic_prompt}]
)
feedback = critic_response.content[0].text
if "ALL_CRITERIA_PASSED" in feedback:
print(f"Quality achieved in {iteration + 1} iteration(s)")
return current_output
print(f"Max iterations ({max_iterations}) reached. Returning best version.")
return current_output
# Example: SEO report for a Karachi business
result = run_dual_agent_reflection(
task="Write a 3-priority SEO report for a Karachi restaurant",
context="Website: biryanihouse.pk. Issues: LCP 8.2s, no Google Business listing, 0 backlinks.",
quality_criteria=[
"Each issue has PKR revenue impact estimate",
"No unexplained technical jargon",
"Issues ranked by priority (highest first)",
"Each issue has: how to fix + time + cost",
"Report under 300 words"
]
)
print(result)
Lesson Summary
Reflection & Self-Critique Patterns Quiz
4 questions to test your understanding. Score 60% or higher to pass.