Agentic UI Patterns That Actually Convert
In October 2024 I wired an AI booking helper into the website of a dental chain with four clinics near Porto. The owner wanted fewer phone calls at reception. Patients called about insurance coverage, Friday slots, and cleaning prices. I shipped a chat box that answered all three. It read the schedule API, quoted prices from a rate table, and booked through the receptionists' endpoint. The demo looked perfect. Two weeks later the numbers told a colder story. About four hundred visitors opened the chat each week. Thirty-one booked. Everyone else closed the window mid-conversation. I pulled twenty session replays and watched people leave at the same three moments. The chat fired five questions at once. It sat silent for nine seconds while it called the calendar. It gave up with a flat error when a patient typed an insurance name with a typo. Those three exits gave me the three patterns I reuse on every agent build since.
Why most chatbots leak users
Most chatbots lose people in the gap between reading a message and acting on it. A plain chat box hides everything. The visitor types a request and stares at three bouncing dots. Nothing says what happens next or how long it takes. After four seconds the visitor assumes the page froze. I measured this on the dental build before I changed anything. Median time from question to booking confirmation ran eleven seconds. The chat showed dots the whole time. Seventy percent of visitors who waited past six seconds closed the window. They hated nothing about the answer. They never saw it.
The leak has a shape. First, the bot asks for too much upfront and the visitor feels interrogated. Second, the bot works silently and the visitor feels abandoned. Third, the bot fails flatly and the visitor blames a small typo for the dead end. Each feeling has a fix. I show one question at a time. I show each tool call as it runs. I turn every failure into a smaller offer. What follows shows each fix.
Pattern 1: progressive disclosure
My first build asked five questions in one bubble: name, phone, insurance provider, preferred doctor, preferred day. On a phone it read like a tax form. Twelve of my twenty replays ended right there. People answered one field and left.
I replaced the wall with a chain. The chat asks one question, waits, then asks the next. Each answer narrows what follows. When a patient picks cleaning, the bot skips the doctor question entirely and offers the next free hygienist slot. When a patient picks a root canal, it asks for the doctor by name. The rule I follow: never ask for facts the system already holds, and never ask two things when one answer changes the second question.
The code behind it stays simple. I keep a slot object with five keys and a next function that returns exactly one question based on filled slots. React renders a single input row plus a row of quick chips. Chips carry most taps: picking a chip takes one tap, typing takes nine. After the switch, question-step completion rose from thirty-eight percent to seventy-nine percent. Booking starts doubled in a week. Every agent flow I build now asks one thing at a time and fills the rest from context.
Pattern 2: visible tool calls
Nine seconds of silence killed the second group. The bot had to check insurance rules, then query three doctors' calendars, then hold a slot. All useful work. All invisible. Visitors saw dots and assumed nothing happened. Six replays showed the visitor typing "hello?" into the void, then closing the tab.
I made the work visible. When the bot checks coverage, the chat prints a small card: "Checking your insurance with ClinicPlus." When the calendar query starts, a second card appears: "Scanning Friday slots for Dr. Sousa." When the hold succeeds, the card flips to a checkmark with the slot time. Each card streams in over the chat, and the visitor watches progress land step by step.
The build uses server-sent events from a Next.js route. Each tool call emits a status event with a label I wrote by hand. I never show raw function names. The internal name check_calendar renders as "Scanning Friday slots." I cap visible steps at four per turn; anything deeper collapses into one card. Tool-call abandonment fell from forty-one percent to nine percent. Show the work and people wait.
Pattern 3: graceful fallback
The flat error killed the third group. A patient typed "ClinikPlus" with a K. The bot matched zero providers and answered "I don't understand. Please rephrase." The patient tried once more, got the same wall, and called the clinic. The call log showed the receptionist booked them in two minutes. The bot had the slot all along. It failed on spelling.
I replaced the wall with a ladder. Step one: fuzzy match. "ClinikPlus" matches ClinicPlus at one letter distance, so the bot asks "Did you mean ClinicPlus?" with two chips. Step two: narrow the scope. When the bot cannot parse a full request, it offers the three most common actions as chips: check insurance, find a slot, price a cleaning. Step three: name a human and a time. When both steps miss, the bot says "Marta from reception books these by hand. Leave your number and she calls back within one working hour." Every fallback ends with a chip or a callback, never a dead end.
I log each fallback with its step number in Postgres. Level-one misses resolve inside the chat eighty percent of the time. Level-three callbacks convert at fifty-five percent the same day. The bot still fails. Failure now hands the visitor something smaller that works.
Metrics I track: task completion, fallback rate, time-to-value
Three numbers tell me whether an agent interface earns its place. Task completion: share of opened chats that end in a booking. The dental chat started at eight percent and sits at twenty-four percent today. I compute it weekly from the bookings table joined to chat sessions. Anything under fifteen percent means the flow asks too much or hides too much.
Fallback rate: share of turns that hit the ladder. I track each level separately. Level one above thirty percent means my matching needs synonyms. Level three above ten percent means the flow misses a real intent and needs a new branch. After the typo fix, level-one fallback dropped from twenty-two percent to six percent.
Time-to-value: seconds from first message to booking confirmation. Median started at eleven minutes of wall time including idle pauses, and now sits near three. I read the seventy-fifth percentile too, because averages hide the slow tail where patients type with one thumb on a bus.
I review the three numbers every Monday with the clinic manager. We pick one fix, ship it by Friday, and read the numbers again. That cadence did more for conversion than any redesign I proposed. The patterns look small on a slide. On a live site they decide whether four hundred weekly visitors turn into thirty bookings or ninety.