Build Your Own AI Agent Like Claude Code: A Python & Gemini Security Deep-Dive + Video

Listen to this Post

Featured Image

Introduction:

AI agents that can navigate multi-directory projects, execute code, and interact with LLMs are revolutionizing developer workflows—but they also introduce new attack surfaces. This handbook-inspired guide teaches you to build a custom AI agent using Python and Google’s Gemini, while embedding cybersecurity best practices like API key isolation, prompt injection defenses, and functional programming for predictable, auditable behavior.

Learning Objectives:

  • Architect a multi‑directory AI agent that safely integrates with the Gemini API
  • Implement functional programming patterns to reduce side‑effects and improve agent security
  • Harden your agent against common vulnerabilities (API leaks, malicious prompts, privilege escalation)

You Should Know:

1. Secure Environment Setup for AI Agent Development

Start by isolating your agent in a virtual environment and securely managing API credentials. This prevents dependency conflicts and accidental credential exposure.

Step‑by‑step guide (Linux/macOS & Windows):

 Linux/macOS
python -m venv agent_env
source agent_env/bin/activate
pip install google-generativeai python-dotenv

Windows (PowerShell)
python -m venv agent_env
.\agent_env\Scripts\Activate
pip install google-generativeai python-dotenv

Create a `.env` file (never commit it) to store your Gemini API key:

GEMINI_API_KEY=your_key_here
AGENT_MAX_TOKENS=1024

Load it securely in Python:

from dotenv import load_dotenv
import os
load_dotenv()
api_key = os.getenv("GEMINI_API_KEY")

Security tip: On Linux, restrict `.env` permissions with chmod 600 .env. On Windows, use icacls .env /inheritance:r /grant:r "%USERNAME%:(R)".

2. Integrating Google Gemini API with Zero‑Trust Principles

Treat the Gemini API as an untrusted external service—validate all outputs and never pass unsanitized user input directly to the model.

Step‑by‑step guide:

import google.generativeai as genai
genai.configure(api_key=api_key)
model = genai.GenerativeModel('gemini-1.5-pro')

def safe_query(user_prompt: str) -> str:
 Sanitize input – strip control characters and limit length
sanitized = ''.join(ch for ch in user_prompt if ch.isprintable())[:500]
 Add system guardrails
guarded_prompt = f"Reply only with safe, non‑executable text. User: {sanitized}"
response = model.generate_content(guarded_prompt)
 Validate response (e.g., no shell metacharacters)
if any(c in response.text for c in ';&|$`'):
return "Blocked: potential command injection"
return response.text

Tool configuration: Enable request logging and set timeouts to prevent DoS:

genai.configure(timeout=30, retry_config={'max_retries': 3})

3. Multi‑Directory Project Structure for Agent Isolation

Organize your agent into separate directories for input, output, and code execution. This containment reduces the blast radius of a compromised agent.

Step‑by‑step guide (Linux/Windows):

ai_agent/
├── .env
├── src/
│ ├── core/  agent logic (no file writes)
│ ├── io/  strictly controlled read/write modules
│ └── sandbox/  executed code outputs
├── logs/
└── tests/

Create the structure and set restrictive permissions:

 Linux
mkdir -p ai_agent/{src/{core,io,sandbox},logs,tests}
chmod 750 ai_agent
chmod 700 ai_agent/sandbox  only agent can write here

Windows (PowerShell)
New-Item -Path ai_agent -ItemType Directory -Force
New-Item -Path ai_agent\src\core, ai_agent\src\io, ai_agent\src\sandbox, ai_agent\logs, ai_agent\tests -ItemType Directory
icacls ai_agent\sandbox /deny "Everyone:(W)"

4. Functional Programming for Predictable, Testable Agents

Avoid shared state and side‑effects—use pure functions and immutable data structures. This makes your agent’s behavior reproducible and easier to audit for malicious deviations.

Step‑by‑step guide with examples:

from functools import reduce
from typing import List, Dict

Pure function: same input → same output, no external state
def sanitize_messages(messages: List[bash]) -> List[bash]:
return [{msg, 'content': msg['content'].strip()[:2000]} 
for msg in messages]

Use map instead of mutating loops
def apply_filters(text: str, filters: List[bash]) -> str:
return reduce(lambda acc, f: f(acc), filters, text)

Example usage – chaining security filters
filters = [str.lower, lambda s: s.replace('DROP TABLE', 'BLOCKED')]
clean_input = apply_filters("DROP TABLE users;", filters)

This functional approach prevents the agent from accidentally modifying global variables or accumulating dangerous state across turns.

5. Defending Against Prompt Injection and Malicious Queries

Attackers may try to override your agent’s system instructions or trick it into executing harmful commands. Implement layered defenses.

Step‑by‑step mitigation:

  1. Pre‑prompt delimiter: Wrap user input in unique markers so the model cannot confuse it with system instructions.
    USER_INPUT_DELIMITER = "<<<USER_INPUT>>>"
    system_prompt = f"You are a safe assistant. Never ignore delimiters. User said: {USER_INPUT_DELIMITER}{user_input}{USER_INPUT_DELIMITER}"
    

  2. Output sanitization: Use regex to block JavaScript, SQL, or shell commands.

    import re
    dangerous_patterns = [
    r'\b(exec|eval|system|subprocess)\b',
    r'<code>.</code>',  backticks for command substitution
    r'\$(.)'  $() command substitution
    ]
    if any(re.search(p, response.text) for p in dangerous_patterns):
    return "Response blocked: detected executable pattern"
    

  3. Rate limiting and quota management: Prevent abuse via rapid iteration.

    from time import time
    last_call = {}
    def rate_limit(user_id: str, interval_sec=5):
    now = time()
    if user_id in last_call and now - last_call[bash] < interval_sec:
    raise Exception("Rate limit exceeded")
    last_call[bash] = now
    

6. Hardening Agent Execution with Containers or Sandboxes

For true isolation, run your agent’s code‑execution component inside a Docker container (Linux) or Windows Sandbox. This contains any malicious output from the AI.

Step‑by‑step guide (Docker on Linux/macOS/WSL2):

Create a `Dockerfile`:

FROM python:3.11-slim
RUN useradd -m agent_user
USER agent_user
WORKDIR /home/agent_user
COPY --chown=agent_user:agent_user sandbox_script.py .
CMD ["python", "sandbox_script.py"]

Build and run with restricted capabilities:

docker build -t agent_sandbox .
docker run --rm --read-only --cap-drop=ALL --network none agent_sandbox

On Windows without Docker, use `Sandboxie` or configure a PowerShell constrained language mode:

$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"

7. Monitoring, Logging, and Anomaly Detection

Log every interaction between your agent and the Gemini API, plus any file system or network calls. Use structured JSON logs for easy analysis.

Step‑by‑step logging setup:

import logging
import json
from datetime import datetime

logging.basicConfig(
filename='agent_audit.log',
level=logging.INFO,
format='%(asctime)s - %(message)s'
)

def audit_log(event_type, details):
log_entry = {
"timestamp": datetime.utcnow().isoformat(),
"event": event_type,
"details": details
}
logging.info(json.dumps(log_entry))

Example usage
audit_log("api_call", {"prompt_hash": hash(user_input), "token_usage": 150})

Anomaly detection rule: If the agent requests >10 file reads in a minute or attempts to write outside ./sandbox, trigger an alert:

 Linux – watch log for spikes
tail -f agent_audit.log | grep -E '"event":"file_read"' | wc -l

Use Windows `Get-Content -Wait` and `Select-String` similarly.

What Undercode Say:

  • Key Takeaway 1: Building your own AI agent is as much about security architecture as it is about prompt engineering—every API key, directory, and function call becomes a potential attack vector.
  • Key Takeaway 2: Functional programming patterns (pure functions, immutability) are not just academic; they drastically reduce the unpredictable “side‑effect surface” that makes AI agents dangerous in production.

Analysis (10 lines):

The freeCodeCamp tutorial and Terrell Potts’ GitHub branch provide an excellent hands‑on foundation for agent development. However, most public examples overlook runtime security. By adding environment isolation, input validation, and functional rigor, you transform a prototype into a deployable‑grade agent. The Gemini API’s flexibility is a double‑edged sword—without rate limiting and output filtering, an attacker could exhaust quotas or inject malicious payloads. Multi‑directory projects prevent a single compromised module from accessing your entire file system. Sandboxing with Docker or Windows Sandbox is non‑negotiable if your agent ever executes code it generates. Monitoring logs for anomalous API usage patterns (e.g., sudden token spikes) can reveal prompt injection attempts. Finally, treat the agent as a semi‑trusted “intern” – always verify its outputs before acting on them.

Prediction:

By 2027, most enterprise AI agents will ship with built‑in “guardian” layers—functional sandboxes, automated prompt audit trails, and real‑time anomaly detection—turning today’s hobbyist Python projects into standardized DevSecOps components. The line between an AI assistant and an intrusion vector will blur, forcing organizations to adopt zero‑trust agent architectures where every API call is authenticated, every log is tamper‑evident, and every code execution happens inside ephemeral containers. Those who master secure agent development now will define the next generation of cybersecurity automation.

▶️ Related Video (80% Match):

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: What Better – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky