PRODUCT

Connected CMMS icon Connected CMMS

Connected Buildings icon Connected Buildings

Connected Refrigeration icon Connected Refrigeration

Connected CMMS
Connected Buildings
Connected Refrigeration
How we built an AI agent that runs an entire helpdesk
Engineering blog

How we built an AI agent that runs an entire helpdesk

Engineering Team, Facilio Engineering Team, Facilio
13 min read
K
Written by Kamal
Solutions Engineer, Facilio engineering team · LinkedIn
Engineering series

Every great AI product is built in the details. Over the past few months, our team built an AI agent that now runs the entire tenant helpdesk for a leading facilities management company in the UAE. Every call and WhatsApp message is answered by the agent, in English and Arabic, day and night.

Getting there wasn't about one clever model. It was about obsessing over every second of every conversation. This note walks through how we approached the problem, how we built and fine-tuned the agent, how it performs on live calls, and where Helpdesk AI goes next.

In short
  1. The problem: a busy tenant helpdesk where every call needs the right decision in seconds, in English or Arabic.
  2. We connected the agent to the client's existing phone system, so tenants kept their numbers and changed nothing.
  3. We engineered every layer for speed, because on a live call a pause sounds like a dropped line.
  4. Fine-tuning against real call scenarios gave us specialist agents and a resolver that matches property names by sound.
  5. Today the agent handles almost every conversation end to end, and we keep improving it on live traffic.

The problem: a helpdesk with no room for error

A tenant calls about a leak, or to chase something they reported last week. To the tenant, that is one call. To the agent, it is a chain of decisions made in seconds: is this an emergency, which property is it, is a request already open, and what should happen next.

Our client manages a large portfolio, with thousands of individual spaces across its sites, buildings and floors. Tenants reach the helpdesk by phone and on WhatsApp, in English and Arabic, at every hour. In that setting, a wrong decision isn't an awkward reply. It is a request logged against the wrong building, or an emergency left waiting.

Accuracy here isn't a nice-to-have; it's the difference between resolving an issue and creating a new one.

Kamal · Facilio engineering team

Our approach: design every decision around the requestor

Before building anything, we set the bar. A natural-sounding conversation was not the goal. The goal was the right request, on the right space, with the right priority, and a tenant who never noticed that anything had changed.

That bar gave us three non-negotiables. The phone line had to stay exactly as it was. The agent had to respond as quickly as a person would. And it had to be accurate where it matters most: emergencies, and identifying the right property. Every engineering decision that followed traces back to one of them.

Building the agent

Connecting to the phone system tenants already use

The client runs its phones on 3CX, and tenants already know the numbers. A new number would have meant a new habit, and every new habit is a reason not to call.

So we built a SIP softphone server, hosted in the UAE, and connected it directly to the client's 3CX. To the phone system, the agent is simply another endpoint it can route calls to. WhatsApp messages reach the same agent. No one had to learn anything new, and from day one the experience felt continuous and familiar.

TenantEnglish · ArabicCALLExisting numbersClient's 3CXVoice serverHosted in the UAEWHATSAPPWhatsApp messagesAGENTIC FLOWEmergenciesLeaks · fire · gasExisting requestsFollow-upsNew ticketsFresh requestsRequest loggedTenant kept postedTenantEnglish · ArabicCALLExisting numbersClient's 3CXWHATSAPPMessagesVoice serverIn the UAEAGENTIC FLOWEmergenciesLeaks · fire · gasExisting requestsFollow-upsNew ticketsFresh requestsRequest loggedTenant kept posted
The path of a call or message. Calls come in through the client's existing 3CX and our voice server in the UAE. WhatsApp reaches the same agent. A specialist takes it from there.

Engineering for speed on a live call

On a phone call, silence carries meaning. Even a short pause feels like a dropped line, and the requestor starts saying "Hello? Hello?". Once that happens, the conversation is already on the back foot.

So we designed the agent to start answering within a fraction of a second, and tuned every layer to hold that standard, from end-of-speech detection to model choice. The voice server runs in the UAE, close to the requestors. End-of-speech detection decides sooner that the requestor has finished. And the live conversation runs on a fast model, because the largest models, capable as they are, cannot respond inside that window.

Latency and flow matter as much as the words themselves. Choosing speed, though, came with a trade-off we then engineered around.

Fine-tuning the agent against real call scenarios

We didn't want tenants to be the ones finding our mistakes. Before go-live, we built a scored eval suite from real call scenarios and ran the agent through it. Every failure was traced to its root, fixed and re-tested against the full suite, so a fix in one place could never quietly break another. Two improvements defined this phase.

Splitting one prompt into specialist agents

A fast model is less capable, and it shows when one set of instructions tries to cover everything. Our first design gave the agent one long prompt for every scenario: emergencies, follow-ups, new requests and every rule in between. Across the full range of scenarios, it began skipping rules and mixing up steps.

Making the model bigger would have given back the latency we had engineered for. So we made its job smaller. Using Agentic Flow, our framework for orchestrating agents, we split the work across specialists: one for emergencies, one for existing requests, one for new tickets. Each carries only the instructions it needs, so it stays fast and gets it right. Specialization beat generalization.

First design · one long prompt
Emergencies
Existing requests
New tickets
Every rule, every step
Skipped rules, mixed-up steps
What we shipped · Agentic Flow
EmergenciesOwn instructions only
Existing requestsOwn instructions only
New ticketsOwn instructions only
Fast, and follows its rules
Same fast model, smaller jobs. The single agent holding every rule kept slipping. Specialists holding only what they need did not.

The split also made our most important rule simple to enforce. Leaks, fires and gas issues skip every question and go straight to same-day priority, because safety and urgency come before process, as any plan for emergency maintenance demands. With emergencies in their own agent, that rule never competes with anything else.

agentic_flowIllustration, not production code
# every conversation goes to exactly one specialist
if conversation.is_emergency:        # leak, fire, gas
    route(emergency_agent)           # skips every question → same-day priority
elif conversation.is_existing_request:
    route(existing_request_agent)
else:
    route(new_ticket_agent)

# each agent loads only the instructions it needs

Matching property names by how they sound

Property names get mangled over a phone line, in every accent. Speech-to-text handles common words well and struggles with names, many of them Arabic, stored in a spelling the transcript rarely matches. Across thousands of spaces, a misheard name doesn't just fail to match. It can match the wrong building.

We built a Phonetic Property Resolver that matches what the requestor said by how it sounds, including Arabic transliteration. Requestors land on the right property even when speech-to-text gets the name wrong, which is what keeps every request tied to the right space.

Progress in this phase came from rigorous measurement and relentless iteration, not intuition.

Testing it in the real world

Go-live was the real test, and the agent held up. Tenants kept calling the numbers they knew, and nobody had to learn anything new. The agent finds the property, logs the request and keeps the tenant posted, across calls and WhatsApp messages in roughly equal measure.

Today it handles almost every conversation end to end, including the meaningful share that arrives after hours, exactly when a helpdesk is hardest to staff. Only a small share comes back to the helpdesk team for a callback.

Improving it after go-live

Go-live didn't freeze the agent. It is traced in production the same way it was evaluated before launch, so we can see exactly how each conversation unfolded. The conversations that still need a callback show us precisely where to improve next, and every change goes through the same eval suite before it reaches a live call.

What's next for Helpdesk AI

The next stage of the journey builds on what is already working: closing the remaining gaps that callbacks reveal, and carrying the same building blocks into the next helpdesks we take on. A voice channel on an existing phone system, phonetic property matching, specialist flows and the evals behind them now form a tested foundation for every deployment that follows.

Conclusion

The challenge was never to build an agent that could hold a conversation. It was to build one that could hold a helpdesk: on the client's own phone lines, inside the time a requestor is willing to wait, across thousands of properties, with emergencies handled first.

Most of that work sat around the model rather than in it: the phone line, the timing, the split into specialists, the way names are matched, and the evals behind every change. Each one is small on its own. Together, they are why the agent now carries almost every conversation from first word to logged request, at any hour of the day.

None of this is visible to the requestors. They simply get the help they asked for. And that, in the end, is the whole point.

Written by Kamal, with the Facilio engineering team.