Building AI agents? These patterns took me 6 months and $3K in mistakes to learn. Copy-paste them now and thank me later.
1. π§ The Constraint Pattern
Problem: AI agents over-optimize without limits.
Bad:
prompt = "Create the perfect solution"
# Result: Agent creates 10-person team for simple task
Good:
prompt = f"""
Create a solution with NON-NEGOTIABLE constraints:
- Budget: MAX ${budget}
- Timeline: {days} days
- Team size: 2-4 people
- If constraints violated, proposal = REJECTED
"""
Why it works: LLMs need explicit boundaries or they'll "optimize" into absurdity.
2. π The Atomic Lock Pattern
Problem: Multiple agents grab the same task β chaos.
Bad:
task = get_pending_task()
if task:
start_work(task) # Race condition!
Good:
# Atomic task claiming
result = db.update({"status": "in_progress", "agent_id": agent.id}) \
.eq("id", task_id) \
.eq("status", "pending") \
.execute()
if len(result.data) == 1:
# Won the race - proceed
start_work(task)
else:
# Someone else got it - find another task
find_next_task()
Why it works: Database-level atomicity prevents dual assignment.
3. π° The Mock Sandwich Pattern
Problem: Testing AI systems burns through API budget.
Bad:
def test_agent():
response = openai.chat.completions.create(...) # $$$
Good:
class AIProvider:
def generate(self, prompt):
if os.getenv("TESTING"):
return self.mock_response(prompt)
return self.real_openai_call(prompt)
def mock_response(self, prompt):
if "priority" in prompt.lower():
return '{"priority": 750}'
return "Deterministic test response"
Why it works: 95% cost reduction, 10x faster tests, deterministic results.
4. β The Circuit Breaker Pattern
Problem: AI agents create infinite loops of sub-tasks.
Bad:
def create_subtask(task):
subtask = agent.decompose(task)
create_subtask(subtask) # Infinite recursion!
Good:
def create_subtask(task):
if task.depth >= MAX_DEPTH:
raise MaxDepthError("Task delegation too deep")
if workspace.tasks_last_hour > RATE_LIMIT:
workspace.pause(cooldown=300)
raise RateLimitError("Too many tasks created")
return agent.decompose(task)
Why it works: Prevents runaway automation with depth limits and rate limiting.
5. βοΈ The Hybrid Decision Pattern
Problem: AI prioritization has hidden biases.
Bad:
priority = ai.calculate_priority(task) # Black box bias
Good:
def calculate_priority(task):
# Objective factors (measurable)
base_score = (
task.blocked_dependencies * 100 +
task.age_days * 10 +
task.business_impact_score
)
# AI enhancement (subjective)
ai_modifier = ai.assess_context(task)
return min(base_score + ai_modifier, 1000)
Why it works: AI handles creativity, deterministic rules handle critical logic.
π Bonus: The Everything Pattern
Combine all patterns:
class ProductionAgent:
def execute_task(self, task_id):
# Pattern 1: Constraints
if not self.validate_constraints(task_id):
return
# Pattern 2: Atomic lock
if not self.claim_task(task_id):
return self.find_next_task()
# Pattern 3: Mock in testing
ai_response = self.ai_provider.generate(prompt)
# Pattern 4: Circuit breakers
if self.should_create_subtask(ai_response):
self.create_subtask_safely(ai_response)
# Pattern 5: Hybrid decisions
priority = self.calculate_hybrid_priority(task_id)
π‘ Implementation Tips
Start with Pattern #3 (Mock Sandwich) - it'll save you money immediately.
Pattern #1 (Constraints) is the easiest win - just add budget/time limits to your prompts.
Pattern #2 (Atomic Lock) is critical if you have >1 agent - implement early.
Patterns #4 & #5 become essential as your system grows beyond MVP.
Your Turn
Which pattern are you implementing first?
And what other AI agent patterns have you discovered the hard way?
Drop your own "sanity-saving" patterns in the comments - let's build a community knowledge base! π
Top comments (0)