Tired of Refreshing? Building a Smart Medical Appointment Agent with Playwright and LLM Function Calling 🏥🤖 A developer built an AI agent that combines Playwright Python with LLM function calling to automate medical appointment booking on clunky hospital portals. The agent uses a ReAct pattern to observe page state, reason with an LLM, and execute actions via Playwright, making it more resilient than traditional browser automation scripts. The system also leverages Redis for session caching and queue management in high-concurrency scenarios. We’ve all been there: waking up at 6:00 AM, frantically refreshing a hospital’s booking page, only to find that the "Expert Specialist" slots vanished in milliseconds. Traditional browser automation often fails here because hospital portals are notoriously clunky, filled with dynamic pop-ups, and inconsistent UI layouts. In this guide, we are going to build a next-generation AI Agent for intelligent task automation . By combining the raw power of Playwright Python with LLM Function Calling , we’ll create a system that doesn't just "click" but "understands" the appointment flow. This approach moves us from brittle CSS selectors to resilient, reasoning-based automation. Unlike traditional scripts that break when a button's ID changes from submit-01 to btn-confirm , our agent uses a ReAct Reason + Act pattern. It observes the page, sends the simplified HTML/Accessibility tree to the LLM, and decides which tool to use next. php graph TD A User Request: Book Dr. Smith -- B{Agent Controller} B -- C LLM Reasoning Engine C -- |Decides Tool| D Playwright Executor D -- |Interaction| E Hospital Portal E -- |Page Content/Screenshot| D D -- |Observation| B B -- |State Storage| F Redis C -- |Final Confirmation| G User Notified To follow this advanced tutorial, you'll need: We need to give our LLM "hands." We do this by defining functions that Playwright will execute. The LLM won't write code; it will output JSON matching our function signatures. python import asyncio from playwright.async api import async playwright class MedicalAgentTools: def init self, page : self.page = page async def navigate to department self, dept name: str : """Navigates to a specific hospital department link.""" links = await self.page.get by role "link" .all for link in links: text = await link.inner text if dept name in text: await link.click return f"Successfully navigated to {dept name}" return "Department not found." async def fill patient info self, name: str, id number: str : """Fills the appointment form with patient details.""" await self.page.fill 'input placeholder="Patient Name" ', name await self.page.fill 'input name="id card" ', id number return "Patient info filled successfully." The core logic involves sending the current page "state" a simplified DOM to the LLM. We use LLM Function Calling to let the model choose between navigating, filling forms, or solving a CAPTCHA. python import openai async def run agent step agent tools, user prompt : messages = {"role": "system", "content": "You are a medical booking assistant. Use tools to complete the user's request."}, {"role": "user", "content": user prompt} Define the tools for OpenAI tools = { "type": "function", "function": { "name": "navigate to department", "parameters": { "type": "object", "properties": {"dept name": {"type": "string"}} } } } ... other tools response = await openai.chat.completions.create model="gpt-4o", messages=messages, tools=tools Execute the function call via Playwright Implementation of tool execution logic goes here In high-concurrency scenarios like when a doctor’s schedule opens , you don't want to spawn 1000 browsers. We use Redis to cache session cookies and manage a queue of booking requests to prevent IP bans. python import redis r = redis.Redis host='localhost', port=6379, db=0 async def save session context : state = await context.storage state r.set "medical session user 1", str state async def load session context : state = r.get "medical session user 1" if state: await context.add cookies eval state 'cookies' While this script works for personal use, scaling AI-driven automation for enterprise healthcare or high-traffic systems requires robust error handling, proxy rotation, and advanced DOM parsing. For more production-ready patterns and deep dives into AI Agent design, I highly recommend checking out the technical deep-dives at WellAlly Blog . They cover advanced topics like "Multi-Agent Orchestration" and "Long-context DOM Processing" which were the inspiration for this architecture. 🥑 By combining Playwright 's reliability with LLM Function Calling , we've built a system that handles the unpredictability of modern web UIs. This "Agentic" approach is the future of Intelligent Task Automation , turning complex, multi-step workflows into simple natural language prompts. What's next? Did you find this helpful? Drop a comment below if you've tried building agents for web automation 🚀💻