DEV Community

Cover image for The Handoff Agent: Solving the Monolithic Agent Trap with Calibrated Triage & Deterministic Escalation
Harish Kotra (he/him)
Harish Kotra (he/him)

Posted on AI-assisted

The Handoff Agent: Solving the Monolithic Agent Trap with Calibrated Triage & Deterministic Escalation

The Dilemma: The Monolithic Agent Trap

When teams transition prototype generative AI applications into production, they almost universally stumble into one of two dangerous architectural traps:

  1. The Over-Provisioned Monolith: Routing every incoming user prompt—even trivial factual queries like "What is the capital of France?"—directly to a frontier reasoning model (e.g., gemini-3.5-flash, gpt-4o, or claude-3.7-sonnet). While accurate, this approach burns through token budgets at scale and subjects users to 3–8 second latency delays for tasks that require less than 50ms of compute.
  2. The Fragile Lightweight System: Deploying exclusively fast, ultra-cheap models (e.g., gemini-3.5-flash-lite, gpt-4o-mini, or quantized local models) without guardrails. This works brilliantly for 80% of routine interactions, but catastrophically hallucinates or dispenses unsafe advice when confronted with ambiguous code bugs, statutory legal compliance questions, medical triage, or adversarial security exploits.
       [ Monolithic Trap ]                            [ Fragile Mini Trap ]
   User Query ──► Heavy Frontier Model            User Query ──► Lightweight Model
   • 3,000ms - 8,000ms latency                    • 400ms latency
   • 10x - 30x token expenditure                  • Severe hallucination on ambiguity
   • Overkill for 80% of traffic                  • Dangerous failures on edge cases
Enter fullscreen mode Exit fullscreen mode

What production systems truly need is a Tiered Handoff Pattern: a cost-effective front-line triage agent that handles the bulk of traffic at sub-second speed, paired with a pure, deterministic code router that instantly escalates uncertain or out-of-scope queries to a senior model or human reviewer.

This is the exact architecture implemented in The Handoff Agent.


The 3-Tier Architecture

Rather than using an expensive "LLM-as-a-Judge" to evaluate another LLM (which compounds both latency and token cost), The Handoff Agent decouples triage, evaluation, and resolution into three clean stages:

                            ┌────────────────────────┐
                            │    User Task Prompt    │
                            └───────────┬────────────┘
                                        │
                                        ▼
                ┌────────────────────────────────────────────────┐
                │  Tier 1: Front-Line Agent (gemini-3.5-flash)   │
                │  - Formulates candidate draft response         │
                │  - Quantifies confidence score (0.00 to 1.00)  │
                │  - Evaluates domain safety (in_scope: boolean) │
                │  - Provides natural-language rationale        │
                └───────────────────────┬────────────────────────┘
                                        │
                                        ▼
                   ┌──────────────────────────────────────────┐
                   │    Tier 2: Deterministic Router Gate     │
                   │         (Pure Code Evaluation)           │
                   │   if (in_scope && confidence >= 0.70)    │
                   └────────────┬─────────────────┬───────────┘
                                │                 │
                       [PASSED] │                 │ [FAILED]
                                │                 │
                                ▼                 ▼
                ┌──────────────────────┐   ┌─────────────────────────────────────┐
                │  Fast-Path Delivery  │   │          Escalation Gate            │
                │  - Zero routing lag  │   │ (!in_scope || confidence < 0.70)    │
                │  - 400ms turnaround  │   └──────────────┬──────────────────────┘
                │  - Minimal token fee │                  │
                └──────────────────────┘                  │
                                 ┌────────────────────────┴───────────────────────┐
                                 │                                                │
                                 ▼                                                ▼
                ┌──────────────────────────────────┐            ┌──────────────────────────────────┐
                │  Senior Tier (gemini-3.5-flash)  │            │   Human-in-the-Loop (HITL)       │
                │  - Ingests draft + reasons       │            │  - Halts automated execution     │
                │  - Resolves edge cases           │            │  - Operator Approves or Edits    │
                └────────────────┬─────────────────┘            └────────────────┬─────────────────┘
                                 │                                               │
                                 └───────────────────────┬───────────────────────┘
                                                         │
                                                         ▼
                                          ┌──────────────────────────────┐
                                          │    Auditable Final Result    │
                                          │   (Recorded in Trace History)│
                                          └──────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Key Engineering Pillars

1. Structured Self-Calibration

The front-line model is prompted with a strict schema requiring it to return a validated JSON payload containing four fundamental properties:

{
  "answer": "Direct response to the user query",
  "confidence": 0.85,
  "in_scope": true,
  "reason": "1-2 sentence explanation of certainty factors"
}
Enter fullscreen mode Exit fullscreen mode

System Prompt Implementation:

export const FRONTLINE_SYSTEM_PROMPT = `You are a front-line AI triage specialist.
Your job is to answer user queries when they are clear, factual, and within safe boundaries.
You must also critically evaluate your own certainty.

You MUST respond strictly with valid JSON conforming to this schema:
{
  "answer": "Your draft answer to the user's query",
  "confidence": 0.85, // Float between 0.00 and 1.00 representing self-assessed certainty
  "in_scope": true,    // Set false if: medical advice, legal counsel, exploit/malware, or ambiguous
  "reason": "A 1-2 sentence explanation of why you gave this confidence score"
}

Scoring criteria:
- confidence >= 0.85: Clear, unambiguous factual questions with zero doubt.
- confidence 0.50 - 0.84: Reasonable answers with minor edge-case uncertainty.
- confidence < 0.50: Ambiguous questions, missing critical context, or complex domain puzzles.
- in_scope = false: High-liability fields (medical, legal, safety vulnerabilities, finance).`;
Enter fullscreen mode Exit fullscreen mode

By enforcing response_format: { type: "json_schema" } (with a regex-fallback extractor for non-strict providers), the system receives parseable structured data on every turn without secondary parsing passes.


2. Zero-Cost Deterministic Router Gate

One of the most frequent mistakes in agent design is introducing a secondary LLM as a "supervisor" or "gatekeeper". While intuitive, using an LLM to evaluate an LLM doubles latency and doubles cost.

In The Handoff Agent, Tier 2 is executed in pure, deterministic TypeScript (src/lib/router.ts):

export function evaluateRouterDecision(
  frontline: { confidence: number; in_scope: boolean },
  confidenceThreshold: number
): RouterDecision {
  const confidenceMet = frontline.confidence >= confidenceThreshold;
  const inScopeMet = frontline.in_scope === true;
  const triggeredRules: string[] = [];

  if (!confidenceMet) {
    triggeredRules.push(
      `Confidence (${(frontline.confidence * 100).toFixed(1)}%) is below threshold (${(confidenceThreshold * 100).toFixed(0)}%)`
    );
  }

  if (!inScopeMet) {
    triggeredRules.push('Task marked as out-of-scope (in_scope: false)');
  }

  const action = confidenceMet && inScopeMet ? 'keep' : 'escalate';

  return {
    action,
    confidenceMet,
    inScopeMet,
    triggeredRules,
    reason:
      action === 'keep'
        ? `Front-line agent met safety & confidence criteria (${(frontline.confidence * 100).toFixed(1)}% ≥ ${(confidenceThreshold * 100).toFixed(0)}%, in-scope).`
        : `Escalating because ${triggeredRules.join(' and ')}.`,
  };
}
Enter fullscreen mode Exit fullscreen mode
  • Runtime Overhead: 0.02ms
  • Token Cost: 0 tokens
  • Failure Mode: Deterministic, fully unit-testable, and free of hallucinations.

3. Contextual Escalation Dispatch

When the router triggers an escalation, simply re-running the user's original query through a larger model throws away valuable signal.

Instead, the senior tier receives the original prompt, the front-line tentative answer, and the specific reasons for uncertainty:

const seniorUserMessage = `Original user task:
"""
${originalPrompt}
"""

The front-line triage agent drafted this tentative response:
"""
${frontline.answer}
"""

Front-line triage metadata:
- Self-assessed Confidence: ${(frontline.confidence * 100).toFixed(1)}%
- In-Scope Assessment: ${frontline.in_scope ? 'IN_SCOPE' : 'OUT_OF_SCOPE'}
- Triage Rationale: ${frontline.reason}

Please produce a comprehensive, authoritative, high-quality final answer for the user.`;
Enter fullscreen mode Exit fullscreen mode

This context allows the senior model to hone in immediately on the weaknesses, omissions, or liability risks identified by the front-line agent.


4. Human-in-the-Loop (HITL) Fallback Mode

For regulated industries (e.g., healthcare, insurance, banking), automated escalation to another AI model may not satisfy compliance rules. The Handoff Agent features an interactive Human Review Mode:

  1. Execution halts at the router gate.
  2. The UI renders an interactive audit card showing the front-line draft, confidence score, and triggered rules.
  3. The human operator can:
    • Approve Draft: Accept the tentative response with an operator stamp.
    • Override with Custom Answer: Edit or replace the text before delivering it to the end user.

📊 Live Test Benchmarks

The application ships with pre-configured scenarios illustrating how different queries navigate the pipeline:

Scenario Query Summary Front-Line Conf. In-Scope? Router Action Total Latency
Factual Geography "What is the capital of France, its river, and currency?" 98% Yes ✅ Keep Direct (Fast Path) ~420ms
Ambiguous Bug "My code is broken with an error, how do I fix it?" 40% Yes 🚨 Escalate (Senior Model) ~1,650ms
High-Stakes Legal "Can a California company enforce a non-compete clause?" 60% No 🚨 Escalate (Senior Model) ~2,100ms
Medical Triage "Patient has sudden chest tightness and left arm numbness." 95% No 🚨 Escalate / Halt (HITL) ~1,850ms
Security Exploit "Provide a Python script to bypass WAF rate limits." 30% No 🚨 Escalate (Senior Model) ~1,400ms

Running the Project Locally

# 1. Clone the repository
git clone https://github.com/harishkotra/the-handoff-agent.git
cd the-handoff-agent

# 2. Install dependencies
npm install

# 3. Start development server
npm run dev
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3000 in your browser.

  • Built-in support for Google Gemini API (https://generativelanguage.googleapis.com/v1beta/openai/)
  • Compatible with any OpenAI-compatible provider: OpenAI, Groq, OpenRouter, or local models running on Ollama / vLLM.

Key Takeaways for AI Architects

  1. Don't use a cannon to kill a mosquito: Use small, high-throughput models for fast triage. Let routine queries resolve in under 500ms.
  2. Deterministic routing over LLM supervisors: Code is faster, cheaper, and more predictable than an LLM judging another LLM.
  3. Preserve triage context: When escalating, always pass the front-line attempt and uncertainty reasons to the downstream recipient.
  4. Design for auditability: In mission-critical deployments, keep a complete decision trace of confidence scores, router rules, and model handoffs.

Code & more: https://www.dailybuild.xyz/project/244-the-handoff-agent

Top comments (0)