Designing Control Into Autonomy
Businesses running AI voice campaigns need to trust an autonomous agent with live calls — without losing control when it fails. Koonj solves this by splitting ownership: one side builds and governs the agents, tenants, and billing; the other runs campaigns and reads the results. As sole Product Designer, I built that split and a fallback-and-escalation system that catches hallucinations before they become compliance risks.
02 — BACKGROUND
Calling at scale needed a system, not a script
Koonj was built in-house to let businesses run inbound and outbound calling campaigns through AI agents, a category still being defined by tools like Retell, Vapi, and Bland AI. I joined the product at an early stage and owned it end-to-end from there: the admin/client architecture, the design system, and the operational workflows underneath it. That meant one shared system across admins, clients, and resellers: running live AI agent calls with real customers, with no margin for a broken handoff.
03 — PROBLEM
When AI is wrong, the product has to know what to do next
Koonj places real phone calls, to real people, on a business's behalf. Unlike most SaaS admin panels, the thing being administered can be confidently wrong: an agent can misread intent, mishandle a query, and there's no undo once it's said.
let businesses automate calls without losing the ability to catch the agent when it goes wrong?
04 — PROCESS
Designing control into a system that has to move fast
Admins need oversight, clients need speed, and the agent needs room to sound human on a live call, but tightening one of these costs the others. Every decision below is a trade-off, made with its cost in view.
Splitting the panel instead of the permissions
- The obvious approach: one system, role-based permissions. Lock some screens for clients, unlock them for admins.
- Why it broke down: every screen had to be designed for its most restricted version first; clients ended up staring at states meant for someone else, like approving agents they had no real basis to judge.
- The fix: two genuinely separate panels. Admin owns agent creation and vetting end-to-end. Clients only ever see agents already theirs to use, which meant client-side approval could be removed entirely, not just designed around.
Separating the agent's identity from its assignment
- The obvious approach: one flat knowledge base: personality, tone, and campaign facts bundled together.
- Why it broke down: reusing a well-tuned agent for a new campaign meant rebuilding it from scratch.
- The fix: two layers. A personality/core layer defines who the agent is. A campaign layer defines what this specific campaign needs it to know. The same agent now carries into five campaigns without retraining its voice each time.
Designing a failure state, not just preventing failure
- The reality: an AI agent making things up on a live customer call isn't a bug; it's a liability. You can't design your way to zero hallucination.
- The shift: instead of only trying to prevent it, design for what happens when it's about to occur.
- The fix: a conversation-state model the agent falls back to when it risks going off-script, and an escalation layer that treats customer dissatisfaction as a compliance risk, not a technical error, and routes it to a human.
Letting tenants rehearse before the call is real
- Without this: the first time a client would see how an agent actually behaved on their campaign was in front of a real customer.
- The fix: a test flow where tenants run an assigned agent against a specific campaign before it goes live, so mistakes in campaign knowledge or weak fallback responses surface in a sandbox, not on a live call.
Testing against sample data creates a trust-before-use layer before a real person is contacted.
05 — FINAL PRODUCT
What shipped
Two panels, one system underneath. Built directly into code — no Figma handoff, no drift between design and what's live.
01Super admin panel
The control layer. Every agent is created, vetted, and assigned from here. Clients never see this side, only what comes out of it.
- Where an agent gets built: Persona, knowledge base, context variables. Each layer is configured separately, so the same agent can be reused across campaigns without starting over.
personality and campaign knowledge are separate layers in the data model, not just separate steps in the form. That's what makes reuse of agents possible later.
- Built, assigned, watched in one place: Once an agent is ready, it's handed to a tenant to use, not to edit or approve, and it shows up immediately in the same view an admin uses to track every tenant, agent, and transaction at once.
- Also handled here: Invoice generation for postpaid clients, and management of tenants and resellers; the operational weight that stays on this side so the client panel can stay simple.
02Client panel
The action layer. No agent creation, no approval step, just assigning what's already been vetted, launching it, and watching it perform.
- Starting a campaign, not building an agent: A client picks from agents already assigned to them and configures a campaign around it (inbound or outbound, audience, schedule) through a multi-step flow built for speed, not oversight.
five steps, one save state: a client can leave mid-flow and pick up exactly where they stopped, since nothing here needs to be filled in one sitting.
- Every call drop-off traced, every escalation briefed: Sentiment analysis tracks the call stage by stage, pinpointing exactly where it fell apart (here, a fleet-tracking renewal that held fine until a price objection hit). From there, escalation isn't a bare alert: a specialist gets assigned by retention rate, a priority SLA kicks in, a concession is pre-authorized, and the AI writes the briefing, so the human picks up the call already knowing what the customer wants and where it went wrong.
the call didn't just "fail" — the system knows exactly where it broke and why.
- Watching it work: Once live, performance shows up in the same place (call outcomes, volume, and trends) without any of the tenant/reseller/invoicing weight that lives only on the admin side.
- Also handled here: Prepaid or postpaid, set at the account level, so only the relevant flow ever shows, kept fully separate from campaign creation.
Brand identity
Min-width triggers where the layout adds columns or shifts from stacked to side-by-side.
Scales with surface size: tight on small controls, soft on cards, full on tags.
Shadow blur increases with how far a surface sits above the page.
06 — IMPACT
Handed off in a state that worked
Handoff happened before launch. This is what a solo takeover reached in under a month.
Functional at handoff
Tenant onboarding, inbound call flow, call review, audio, and transcriptions: all working. Backend stabilization was still in progress.
Built ahead of the ask
A hold-queue, geo-restrictions, time-of-day limits, all requested by the founder at the final demo. All already built.
He came in expecting gaps and found none.
Knowledge that outlasted the role
Stayed available post-handoff to walk the dev team through flows and logic they hadn't designed themselves.
07 — REFLECTIONS
What this project actually tested
Three things this build asked of me that no brief spelled out.
Inheriting decisions, not a blank slate
Taking this over mid-build meant the panel structure and knowledge-base logic weren't mine to invent from scratch; they were mine to judge: what to keep, what to quietly fix, what to leave alone because touching it would cost more than it solved.
Garbage in,
garbage out
Agent configuration was the biggest "garbage in, garbage out" risk in the whole system. Knowing what I know now, I'd have built reusable agent templates before handoff, not after.
Assumed, not tested
Admin-only agent creation was reasoned from constraints and founder input, not live tenant behavior. I'd specifically test whether tenants actually prefer using pre-built agents, or want some room to configure their own.

