SoftPartners logoSoftPartners
Guide9 min read

Building an AI agent that turns inbound messages into scheduled jobs

Inbound requests arrive on five channels and only become a job after a person retypes them. Here is how we scope an AI agent for that gap — and the four things we never let it decide.

  • The agent proposes, the system commits
  • Emergency detection fails open to a human
  • Measured by jobs booked without retyping

For a service business — plumbing, electrical, HVAC, anything dispatched — inbound requests arrive by phone, text, web form, email, and whatever marketplace sends leads this year. Each one is a person describing a problem in their own words, at their own level of detail. None of them are a job yet. Somebody has to read it, work out what is actually wrong, check whether this is an existing customer, ask the two questions that were missing, find a slot, and type it into the system.

That gap between "a message arrived" and "a job exists" is where the agent belongs. Not answering the phone like a person, and not running the business — just closing that specific gap, with a human still owning the commitments.

Decide what the agent owns before you build it

The agent ownsThe system or a human owns
Reading the message and extracting a structured requestWhether the job is accepted
Asking the missing clarifying questionsThe price, the quote, and any discount
Matching against existing customers and addressesConfirming the customer identity when the match is uncertain
Proposing appointment windows that the calendar can actually holdCommitting the slot and dispatching the technician
Drafting the replyAnything an unhappy customer is escalating
The split we start from

The pattern behind that split is the same one that governs every automation we ship: the model proposes, deterministic code decides and records. An agent that can commit a slot is an agent that can double-book a Saturday morning. An agent that proposes a slot the scheduler then holds cannot.

FIG. 01INBOUND REQUEST FLOWMessage arrivestext, form, emailRead the intentAI proposesCheck rulescalendar, coverageBook or draftdeterministicHuman onexceptionsanything unclearTHE AGENT OWNS THE ROUTINE PATH. PEOPLE OWN THE REST.

The anatomy of the flow

01

Channel intake

Every channel — SMS, web form, email, voice transcript — normalizes into one inbound message object with the raw text, the sender, the channel, and a timestamp. Building the rest against a single shape is what stops you writing the same logic five times.

02

Extraction into a structured request

Service type, described symptom, property type, address, urgency signals, access constraints, and preferred timing. Every field carries a confidence value and the span of text it came from, so a human reviewing it can see why the agent thought so.

03

A bounded clarification loop

If required fields are missing, the agent asks for them — with a hard cap on turns. Two or three exchanges, then it hands to a human with everything gathered so far. An agent that keeps asking questions forever is worse than no agent.

04

Customer and address resolution

Match against existing records before creating anything. This is fuzzy matching that a human confirms when uncertain, not something the agent decides alone — a wrong match writes a new job onto someone else's history.

05

Availability proposal

The agent reads real availability from the schedule, filtered by skill, region, and job duration, and proposes windows. It never invents a time. If the calendar has nothing, it says so and escalates.

06

Human confirm, then commit

The dispatcher sees the structured request, the proposed slot, and the full conversation on one screen. One action creates the job in the CRM. In steady state this is a few seconds of review rather than five minutes of transcription.

The hard parts nobody warns you about

Emergency detection has to fail open

"Water is coming through the ceiling" and "I smell gas" cannot sit in a queue behind a routine appointment request. Run a deterministic keyword and pattern check before the model does anything, and let the model add a second opinion on top. If either one fires, the conversation escalates to a human immediately and the agent stops driving. Getting this backwards — model first, keywords as a fallback — is the single most consequential design mistake in this whole category.

Addresses are harder than the request

Unit numbers, buildings on a campus, gate codes, and the difference between the billing address and the address with the broken water heater. Validate against an address service, and when the customer has more than one property on file, ask rather than guess. A technician sent to the wrong address costs a half day and a customer.

Returning customers change the whole exchange

If someone messaged eight months ago about the same water heater, the agent should be working from that history, not starting cold. This is the part that makes the agent feel competent rather than like a form with a chat interface — and it is the part that only works if the CRM data is actually reachable, which is often the real project underneath the AI project.

After hours is a different product

Overnight, the agent is not booking anything — it is triaging. Emergencies get routed to whoever is on call; everything else gets acknowledged with an honest expectation of a callback time and lands at the top of the morning queue, already structured. Treating after-hours as the same flow with nobody watching is how a genuine emergency waits until 8am.

Measuring it properly

The metric vendors like to report is containment — the share of conversations handled without a human. It is the wrong target here, because it rewards an agent for not escalating things it should escalate.

  • Requests that became a scheduled job without anyone retyping. This is the number the automation exists to move.
  • Escalation quality. When a human takes over, did the conversation arrive with the fields already gathered, or did they start from zero? A good agent makes escalations cheaper, not rarer.
  • Edit distance on proposals. How much the dispatcher changes before committing. Rising edit distance is your early warning that extraction is drifting.
  • Time to first response, by channel. Usually the change customers actually notice.
  • Missed emergencies. Target is zero, reviewed individually, every time.

Rolling it out without scaring anyone

  1. Shadow mode. The agent processes real messages and produces proposals that nobody sees except you. Compare its output against what the dispatcher actually did. Expect a couple of weeks here.
  2. Draft mode. Proposals appear in the dispatcher's queue as pre-filled drafts. Every one is reviewed. This is where most of the value shows up, and many businesses are happy to stop here permanently.
  3. Narrow autonomy. Pick one intent that is genuinely low-risk — a routine maintenance booking for an existing customer within normal hours — and let the agent complete it end to end. Widen only on evidence.

Two weeks of shadow mode also builds the evaluation set you will need later. Every case where the agent disagreed with the dispatcher is a test you can rerun whenever the prompt, the model, or the schema changes.

One caveat worth being blunt about: if the customer and job data lives somewhere the agent cannot reach, none of this works. That is a legacy integration problem wearing an AI costume, and it is covered in how to connect a legacy system to AI without replacing it.

Frequently asked questions

Will an AI agent talk to my customers directly?

Only as far as you allow. Most businesses start in draft mode, where the agent gathers and structures the request and prepares a reply that a person sends. Full autonomy is introduced later for one narrow, low-risk intent at a time.

What stops it from booking the wrong appointment?

The agent proposes windows read from real availability but never commits them. Creating the job is a deterministic action taken by the system after a human confirms, so there is no path from a generated message to a booked slot.

How does it handle emergencies?

A deterministic keyword and pattern check runs before the model, with the model as a second opinion on top. If either fires, the conversation escalates to a human immediately and the agent stops driving the exchange.

Does this replace our CRM or dispatch software?

No. The agent sits in front of whatever you already run, reading availability and customer history from it and creating jobs in it. If that data is not reachable today, the integration is the first phase of the work.