Bounded Execution: Preventing Runaway Agents¶
Overview¶
Resources are finite. Unbounded execution leads to runaway agents, high costs, and system crashes.
Resource Bounds¶
class BoundedAgent:
def __init__(self):
self.limits = {
'max_iterations': 10, # Max reasoning steps
'max_tool_calls': 50, # Max tools invoked
'timeout_sec': 60, # Max execution time
'max_tokens': 10000, # Max output tokens
'max_cost': 1.0 # Max cost in dollars
}
def execute(self, task):
self.iterations = 0
self.tool_calls = 0
self.start_time = time.time()
self.cost = 0
while True:
if self.iterations >= self.limits['max_iterations']:
return {"error": "Max iterations exceeded"}
if self.tool_calls >= self.limits['max_tool_calls']:
return {"error": "Max tool calls exceeded"}
elapsed = time.time() - self.start_time
if elapsed > self.limits['timeout_sec']:
return {"error": "Timeout exceeded"}
if self.cost > self.limits['max_cost']:
return {"error": "Cost limit exceeded"}
# Execute one step
self.iterations += 1
result = self.step(task)
if result.is_terminal():
return result
Timeout Patterns¶
import signal
class TimeoutHandler:
def call_with_timeout(self, func, timeout_sec):
def timeout_handler(signum, frame):
raise TimeoutError()
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout_sec)
try:
result = func()
signal.alarm(0) # Cancel alarm
return result
except TimeoutError:
return {"error": "Operation timed out"}
Cost Control¶
class CostAwareLLMCaller:
def __init__(self, max_cost_usd=1.0):
self.max_cost = max_cost_usd
self.current_cost = 0
def call(self, prompt: str) -> str:
# Estimate cost before calling
estimated_cost = self.estimate_cost(prompt)
if self.current_cost + estimated_cost > self.max_cost:
return {"error": "Cost limit exceeded"}
# Call LLM
response = self.llm.generate(prompt)
# Track actual cost
actual_cost = self.get_actual_cost(response)
self.current_cost += actual_cost
return response
3 Warnings ⚠️¶
Warning 1: Too Tight Bounds¶
# ❌ WRONG
limits = {
'max_iterations': 1, # Too few!
'timeout_sec': 5, # Too short!
}
# Most tasks can't complete
# ✅ RIGHT
limits = {
'max_iterations': 10, # Reasonable
'timeout_sec': 60, # Realistic
}
Warning 2: Not Monitoring Bounds¶
# ❌ WRONG
set_limits()
# Hope they work
# ✅ RIGHT
set_limits()
monitor_bounds() # Log when near limit
alert_on_boundary() # Warn before hitting
Warning 3: Single Point Failure¶
# ❌ WRONG: Only timeout protection
if time.time() - start > 60:
stop()
# But what if tool call hangs?
# Or infinite loop in reasoning?
# ✅ RIGHT: Multiple safeguards
timeout_handler() # Global timeout
iteration_limit() # Step-based timeout
tool_timeout() # Per-tool timeout
resource_monitor() # CPU/memory watch
Last Updated: August 9, 2026