Environment Boundaries and Constraints › Types of Environment Constraints

Michael BrenndoerferJuly 17, 20254 min read
AI Agent HandbookAll chapters
Part 8 of 15Environment and Interaction - The Agent's World
Chapter 23Environment Boundaries and Constraints › Types of Environment Constraints
Reading section 3 of 11 · Types of Environment Constraints · 4 minSection 3 of 11 · 4 min

Book contents

Section 3 of 11 · 4 min read

Environment Boundaries and Constraints › Types of Environment ConstraintsOne section · Sections in this chapter3 / 11 ↓

When designing your agent's environment, you'll typically work with several categories of constraints. Each serves a different purpose in keeping your agent safe and effective.

Access Constraints

Access constraints define what data and resources your agent can reach. These are your first line of defense.

For our personal assistant, you might specify:

  • Read access: Calendar events, contact list, recent emails
  • Write access: Calendar events, draft emails (but not sent emails)
  • No access: File system, browser history, system settings

The following class implements this permission model:

In[3]:
Code
## Example (Claude Sonnet 4.5)
## Using Claude Sonnet 4.5 for its superior reasoning about permissions


class AgentEnvironment:
    def __init__(self, allowed_resources):
        self.allowed_resources = set(allowed_resources)
        self.access_log = []

    def check_access(self, resource_type, operation):
        """Verify if the agent can perform this operation"""
        permission = f"{resource_type}:{operation}"

        if permission in self.allowed_resources:
            self.access_log.append(
                {
                    "resource": resource_type,
                    "operation": operation,
                    "allowed": True,
                }
            )
            return True
        else:
            self.access_log.append(
                {
                    "resource": resource_type,
                    "operation": operation,
                    "allowed": False,
                }
            )
            return False


## Set up environment with specific permissions
env = AgentEnvironment(
    allowed_resources=[
        "calendar:read",
        "calendar:write",
        "email:read",
        "email:draft",  # Note: not email:send
    ]
)

## Agent tries to access calendar
if env.check_access("calendar", "write"):
    print("Agent can modify calendar")

## Agent tries to send email
if not env.check_access("email", "send"):
    print("Agent cannot send emails without approval")
Out[3]:
Console
Agent can modify calendar
Agent cannot send emails without approval

This simple permission system ensures your agent can only touch what you've explicitly allowed. Notice how we separate read and write operations. This granularity matters because reading data is generally safer than modifying it.

Action Constraints

Beyond what your agent can access, you need to control what actions it can take. Some operations are inherently more risky than others.

Consider these action tiers:

Safe actions (can happen automatically):

  • Reading information
  • Generating text or summaries
  • Performing calculations
  • Searching within allowed data

Moderate actions (might need confirmation):

  • Creating calendar events
  • Drafting emails
  • Saving notes or files
  • Making API calls to external services

High-risk actions (always need confirmation):

  • Sending emails or messages
  • Deleting data
  • Making purchases
  • Changing system settings

The following class implements these action constraints:

In[4]:
Code
## Example (Claude Sonnet 4.5)
## Using Claude Sonnet 4.5 for its ability to reason about action safety


class ActionPolicy:
    def __init__(self):
        self.safe_actions = {"read", "search", "calculate", "summarize"}
        self.confirm_actions = {"create", "draft", "save"}
        self.restricted_actions = {"send", "delete", "purchase"}

    def requires_confirmation(self, action):
        """Check if this action needs user approval"""
        if action in self.safe_actions:
            return False
        elif action in self.confirm_actions:
            return "optional"  # Could be configured per user
        elif action in self.restricted_actions:
            return True
        else:
            return True  # Unknown actions require confirmation by default


policy = ActionPolicy()

## Agent wants to send an email
action = "send"
if policy.requires_confirmation(action):
    print(f"Action '{action}' requires user confirmation")
    # In a real system, you'd prompt the user here
    user_approved = input("Approve this action? (yes/no): ")
    if user_approved.lower() == "yes":
        print("Proceeding with send...")
    else:
        print("Action cancelled")

Notice the three-tier system. This gives you flexibility. A power user might configure their agent to automatically create calendar events, while a cautious user might want to review every action.

Rate and Resource Constraints

Even for allowed actions, you might want to limit how often or how much your agent can do something. This prevents runaway behavior and controls costs.

In[4]:
Code
## Example (GPT-5)
## Using GPT-5 for this straightforward rate limiting example

from datetime import datetime, timedelta


class RateLimiter:
    def __init__(self, max_calls, time_window):
        self.max_calls = max_calls
        self.time_window = time_window  # in seconds
        self.calls = []

    def can_proceed(self, action):
        """Check if we're within rate limits"""
        now = datetime.now()

        # Remove old calls outside the time window
        cutoff = now - timedelta(seconds=self.time_window)
        self.calls = [call for call in self.calls if call > cutoff]

        # Check if we're under the limit
        if len(self.calls) < self.max_calls:
            self.calls.append(now)
            return True
        else:
            return False


## Limit API calls to 10 per minute
api_limiter = RateLimiter(max_calls=10, time_window=60)

## Agent tries to make an API call
if api_limiter.can_proceed("api_call"):
    print("Making API call...")
else:
    print("Rate limit exceeded. Please wait.")
Out[4]:
Console
Making API call...

Rate limiting is especially important for actions that cost money (like API calls) or could annoy users (like sending notifications). It's a safety net that prevents your agent from going haywire.