Handoff Boundaries: Agent vs Code
When Should Code Decide vs. the Agent
Not everything should be left to the agent. Sometimes code should decide.
Agent Decides
Let the agent decide when:
- The decision depends on external information
- Multiple valid paths are acceptable
- The model should learn from context
- The decision is complex or subtle
Example: Routing customer support
- Customer asks: "I have a shipping question"
- Agent should decide: Is this about a specific order or general shipping info?
- Agent can understand the nuance
Code Decides
Let code decide when:
- The rule is fixed and never changes
- Speed is critical
- Safety is critical
- Cost matters
- The decision is simple and deterministic
Example: Rate limiting
- Rule: Each user gets 10 searches per hour
- Code should enforce this, not the agent
- Agent might try to bypass the limit
Examples
Good: Agent decides which tool
- User: "Find information about renewable energy"
- Agent can decide: search, then fetch, or search multiple sources, or check current date first
- Flexible and smart
Good: Code decides whether to allow the action
# Code enforces safety
if user_role != "admin" and tool_name == "delete_database":
return {"error": "Permission denied"}
result = tools[tool_name](**args)
Bad: Let agent decide everything
# Agent might ignore cost limits
while True:
result = agent.step()
# Agent keeps going even if cost is high
Good: Code enforces limits
if total_cost > max_cost:
break # Stop the agent
if iteration_count > max_iterations:
break # Stop the agent
Pattern: Guard Rails
Code proposes through the agent, code validates the action.
def guarded_agent_step():
# Agent proposes an action
tool_call = agent.propose_action()
tool_name = tool_call["name"]
tool_args = tool_call["args"]
# Code validates the action
if not is_allowed(tool_name, tool_args):
return {"error": "Action not allowed"}
if would_exceed_limits(tool_name, tool_args):
return {"error": "Would exceed limits"}
# Code executes the action
return tools[tool_name](**tool_args)
def is_allowed(tool_name, args):
# Allowlist: only certain tools allowed
if tool_name not in ["search", "fetch", "summarize"]:
return False
# Safety check: no delete operations
if "delete" in tool_name.lower():
return False
return True
def would_exceed_limits(tool_name, args):
global total_cost
global iteration_count
if total_cost > max_cost:
return True
if iteration_count >= max_iterations:
return True
return False
Handoff Boundaries
Define clear boundaries. The agent owns some decisions, code owns others.
Agent responsibilities:
- Understand the user's intent
- Decide which tool to use
- Reason through multi-step tasks
- Synthesize information
Code responsibilities:
- Enforce cost limits
- Enforce iteration limits
- Validate tool inputs
- Check permissions
- Handle errors
- Ensure safety
Example: Complete Agent With Boundaries
class BoundedAgent:
def __init__(self, max_iterations=15, max_cost=1.0):
self.max_iterations = max_iterations
self.max_cost = max_cost
self.iteration_count = 0
self.total_cost = 0.0
self.allowed_tools = ["web_search", "fetch_webpage", "summarize"]
def run(self, user_question):
conversation = []
while self.iteration_count < self.max_iterations:
# Agent thinks
response = model.think(conversation)
# Agent proposes action
if "<tool_use>" not in response:
return response # Final answer
tool_call = parse_tool_call(response)
tool_name = tool_call["name"]
# CODE: Check if allowed
if tool_name not in self.allowed_tools:
error = {"error": f"Tool {tool_name} not allowed"}
conversation.append({"role": "user", "content": str(error)})
continue
# CODE: Check cost
cost = estimate_cost(tool_name)
if self.total_cost + cost > self.max_cost:
error = {"error": "Cost limit exceeded"}
conversation.append({"role": "user", "content": str(error)})
break
# CODE: Execute
result = tools[tool_name](**tool_call["args"])
self.total_cost += cost
self.iteration_count += 1
# Agent observes
conversation.append({"role": "assistant", "content": response})
conversation.append({"role": "user", "content": str(result)})
return "Max iterations reached"
Summary
- Agent: Decides what to do based on context
- Code: Enforces rules, limits, and safety
Don't let the agent make decisions that should be made by code. Don't have code make decisions that need agent reasoning.
Discussion
Sign in to comment. Your account must be at least 1 day old.