Notes on how I built a web-browsing AI agent to book tennis courts for me.
I connected the agent to a Telegram Chatbot so that I can book tennis courts from anywhere via text message.
For example, I can say: “hey are there any courts free tmrw 6-7 pm?” and the agent would go and check. Then I’d follow-up with “book a court for me and Joe Doe” and the agent would book it.
The agent was built when vision models where good, but not perfect. It required a few hacks to get it to navigate websites reliably. For example, when the agent (say, Claude) wants to click on a button, I would give different LLM (say, Gemini) a zoomed-in picture of that button for a second opinion.
Here is a sketch of the architecture of the AI agent:
┌─────────────────────────────────────────────────────────────────────────────────┐
│ WEB BROWSING AGENT SYSTEM │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────┐
│ USER INTERFACE │
│ │
│ • Telegram Bot │
│ • Direct API │
└─────────┬───────┘
│
│ Task Request
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ AGENT CONTROLLER │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ MAIN AGENT LOOP │ │
│ │ │ │
│ │ • System & Task Prompts (src/prompts.py) │ │
│ │ • Message Management │ │
│ │ • Tool Orchestration │ │
│ │ • Response Parsing │ │
│ │ • Self-reflection & Validation │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────┬───────────────────────────────────────────────────────────┘
│
│ LLM Calls
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ MULTI-MODEL LLM LAYER │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Claude 3.5 │ │ GPT-4o │ │ Gemini 1.5 │ │
│ │ Sonnet │ │ │ │ Pro/Flash │ │
│ │ (Primary) │ │ (Fallback) │ │(Images + Tables)│ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ │
│ • Vision + Text Processing │
│ • Tool Function Calling │
│ • Overload Handling & Retry Logic │
└─────────────────┬───────────────────────────────────────────────────────────┘
│
│ Tool Calls
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ BROWSER TOOLS LAYER │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ CLICK │ │ TYPE_TEXT │ │ SCROLL │ │
│ │ │ │ │ │ │ │
│ │ • Click on UI │ │ • Input text │ │ • Scroll up/ │ │
│ │ elements │ │ into fields │ │ down pages │ │
│ │ • Use element │ │ • Focus & type │ │ • Navigate │ │
│ │ coordinates │ │ │ │ content │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ MAKE_SCREENSHOT│ │ GO_BACK │ │ ANALYZE_BOOKING │ │
│ │ │ │ │ │ _TABLE │ │
│ │ • Full page │ │ • Browser back │ │ │ │
│ │ screenshots │ │ navigation │ │ • Parse table │ │
│ │ • Visual │ │ • History │ │ data with LLM │ │
│ │ observation │ │ management │ │ • Extract │ │
│ └─────────────────┘ └─────────────────┘ │ availability │ │
│ └─────────────────┘ │
└─────────────────┬───────────────────────────────────────────────────────────┘
│
│ Browser Control
▼
┌────────────────────────────────────────────────────────────────────────────┐
│ BROWSER AUTOMATION LAYER │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ PLAYWRIGHT ENGINE │ │
│ │ │ │
│ │ • Chromium Browser Control │ │
│ │ • Page Navigation & Interaction │ │
│ │ • Clickable Element Detection & Annotation │ │
│ │ • Screenshot Capture │ │
│ │ • JavaScript Execution │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ WEB ELEMENT ANNOTATOR │ │
│ │ │ │
│ │ • JavaScript for clickable element detection (mark_page.js) │ │
│ │ • UI element labeling with numbers │ │
│ │ • Coordinates (x,y) extraction for CLICK tool │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────┬──────────────────────────────────────────────────────────┘
│
│ Web Requests
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ TARGET WEBSITE │
│ │
│ • Tennis Court Booking Systems │
│ • Dynamic Web Applications │
│ • Complex UI Interactions │
│ │
└─────────────────────────────────────────────────────────────────────────────┘