Reflection & Self-Critique: Agent Self-Awareness¶
Overview¶
Humans catch their own mistakes by reviewing their work. Agents can do the same.
Self-critique is one of the most effective ways to improve agent quality—simple to implement and powerful in practice.
How Reflection Works¶
Basic Reflection Loop¶
class ReflectiveAgent:
"""Agent that critiques its own work"""
def solve_with_reflection(self, task):
"""Generate solution, then critique it"""
# Step 1: Initial solution
solution = self.generate_solution(task)
# Step 2: Self-critique
critique = self.self_critique(task, solution)
# Step 3: Evaluate critique
if critique.has_errors:
# Step 4: Revise based on critique
revised = self.revise_solution(
task,
solution,
critique
)
return revised
return solution
def generate_solution(self, task):
"""Generate initial attempt"""
prompt = f"""Solve this task: {task}
Provide your solution."""
return self.llm.call(prompt)
def self_critique(self, task, solution):
"""Critique the solution"""
prompt = f"""
Task: {task}
Proposed solution: {solution}
Critique this solution. What's wrong with it?
What could be improved?
"""
critique_text = self.llm.call(prompt)
return self.parse_critique(critique_text)
def revise_solution(self, task, solution, critique):
"""Improve solution based on critique"""
prompt = f"""
Task: {task}
Original solution: {solution}
Critique: {critique.text}
Provide a revised solution that addresses the critique.
"""
return self.llm.call(prompt)
Chain-of-Criticism Pattern¶
Multi-Round Reflection¶
class ChainOfCriticism:
"""Multiple rounds of critique"""
def solve_with_iterations(self, task, max_iterations=3):
"""Iteratively improve through critique"""
solution = self.generate_solution(task)
for iteration in range(max_iterations):
# Critique
critique = self.critique(task, solution)
# Analyze
score = self.score_solution(task, solution, critique)
# Check stopping criterion
if score > 0.9: # Good enough
break
if critique.is_unsalvageable:
break
# Improve
solution = self.improve(task, solution, critique)
return solution
def score_solution(self, task, solution, critique):
"""Rate solution quality"""
scoring_prompt = f"""
Task: {task}
Solution: {solution}
Critique: {critique}
Rate solution quality 0-1. Be harsh, not generous.
"""
score_text = self.llm.call(scoring_prompt)
return float(score_text.strip())
When to Use: - Complex problems requiring multiple passes - High-stakes decisions - When initial attempts are often wrong
Cost: 3-4x tokens for 3 iterations
Quality Improvement: +20-35% accuracy
Specific Critique Prompts¶
Code Review Critique¶
class CodeReviewCritique:
"""Critique code for common issues"""
def critique_code(self, code, language):
"""Comprehensive code critique"""
critique_areas = [
"correctness", # Does it work?
"efficiency", # Is it efficient?
"readability", # Is it understandable?
"security", # Are there vulnerabilities?
"maintainability", # Is it maintainable?
"edge_cases" # Does it handle edge cases?
]
critiques = {}
for area in critique_areas:
prompt = f"""
Review this {language} code for {area} issues:
{code}
List specific {area} problems. Be thorough.
"""
critique = self.llm.call(prompt)
critiques[area] = critique
return critiques
def suggest_improvements(self, code, critiques):
"""Generate improved version"""
prompt = f"""
Original code:
{code}
Issues found:
{format_critiques(critiques)}
Provide improved code that addresses all issues.
"""
return self.llm.call(prompt)
Feedback-Driven Reflection¶
Learning from External Critique¶
class FeedbackReflection:
"""Agent learns from human feedback"""
def solve_and_get_feedback(self, task):
"""Solve, get feedback, improve"""
solution = self.generate_solution(task)
# Ask human for feedback
feedback = self.request_human_feedback(task, solution)
if feedback.approved:
# Good! Learn from this
self.learn_from_success(task, solution, feedback)
return solution
else:
# Not good. Learn from error
self.learn_from_failure(
task,
solution,
feedback.critique
)
# Improve and retry
improved = self.improve_from_feedback(
task,
solution,
feedback.critique
)
return improved
def learn_from_failure(self, task, solution, feedback):
"""Record what went wrong"""
learning_record = {
'task': task,
'failed_solution': solution,
'feedback': feedback,
'category': self.categorize_error(feedback)
}
self.memory.add_learning(learning_record)
def improve_from_feedback(self, task, solution, feedback):
"""Generate improved version"""
prompt = f"""
Task: {task}
Failed attempt: {solution}
Human feedback: {feedback}
Generate an improved solution that addresses the feedback.
"""
return self.llm.call(prompt)
Avoiding Over-Critique¶
When NOT to Critique¶
class SmartCritique:
"""Only critique when needed"""
def should_critique(self, task, solution):
"""Decide if critique is worth it"""
factors = {
'confidence': solution.confidence,
'task_difficulty': self.estimate_difficulty(task),
'expected_error_rate': self.base_error_rate(task),
'critique_cost': 0.3 # Roughly 30% token cost
}
# Only critique if:
# - Low confidence AND
# - High difficulty AND
# - Worth the token cost
if factors['confidence'] > 0.85:
return False # Already confident
if factors['task_difficulty'] < 0.3:
return False # Too easy, not worth it
if factors['critique_cost'] > self.token_budget:
return False # Can't afford
return True # Critique is worthwhile
3 Warnings ⚠️¶
Warning 1: Critique Blindness¶
# ❌ WRONG
# Agent critiques own work and misses obvious errors
solution = agent.generate()
critique = agent.self_critique(solution)
# Agent doesn't see its own mistakes
# ✅ RIGHT
# Use external critic (different model)
solution = agent.generate()
critic_model = different_model() # GPT-4 critiques Claude output
critique = critic_model.critique(solution)
# Different perspective catches errors
Warning 2: Infinite Refinement¶
# ❌ WRONG
while True:
solution = generate()
critique = self_critique(solution)
if critique.perfect:
break
solution = improve(critique)
# Never good enough, loops forever
# Wastes tokens
# ✅ RIGHT
for iteration in range(max_iterations):
solution = generate()
critique = self_critique(solution)
score = score_solution(critique)
if score > 0.9 or iteration == max_iterations - 1:
break
solution = improve(critique)
Warning 3: Critiquing Wrong Things¶
# ❌ WRONG
# Critique code for security in simple script
code = "print('hello')"
security_critique = critique_for_security(code)
# Wastes tokens on non-issue
# ✅ RIGHT
# Critique only relevant aspects
if is_production_code(code):
security_critique = critique_for_security(code)
elif is_performance_critical(code):
efficiency_critique = critique_for_efficiency(code)
else:
readability_critique = critique_for_readability(code)
# Focused critique
Last Updated: August 9, 2026