The challenge
Support was split across seven channels, each with its own tooling, macros and quality bar. The same question got a different answer depending on where a customer asked it.
Previous automation attempts had been tuned to maximise deflection, which pushed unresolved contacts back to customers and inflated the numbers while making the experience worse.
Approach
01
One engine, many adapters
Resolution logic lives in one place; each channel is a thin adapter handling formatting and transport. This is what made answers consistent across channels.
02
Calibrate confidence against real outcomes
The escalation threshold was set from measured resolution outcomes, not picked as a round number. Contacts resolved below threshold were reviewed to check the calibration held.
03
Optimise for resolution, not deflection
Success is a closed contact the customer did not reopen. Deflection rate is deliberately not a tracked target, because it rewards the wrong behaviour.
04
Escalation preserves everything
The human receives the full thread, the attempted resolution and the confidence reasoning. No context is lost at the boundary.
Architecture
Intake
Seven channel adapters normalise incoming contacts into a single internal format.
Retrieve
Pinecone-backed retrieval over help content, past resolutions and product documentation.
Reason
LangGraph resolution flow with tool access to account and order systems for actual resolution, not just answers.
Decide
Confidence scoring per turn determines resolve, clarify or escalate.
Serve
FastAPI layer with per-channel adapters and full thread logging.
Results
61%Resolved without escalation
44%Faster first reply
7Channels unified
1Consistent answer per question
0Context lost on escalation
What I took from itRefusing to track deflection rate was the most important decision on the project. Every prior attempt had optimised that number upward while customer satisfaction fell, and the metric was the cause.