Skip to content
Writing
NewSemantic RouterPythonMachine LearningArchitectureAI Agents

Semantic Routing for Outbound AI Email: Classifying Intent Before Dispatch

Before letting an AI agent send an email, use semantic routing to classify its intent. Route critical requests to human review while instantly dispatching standard notifications.

The failure of deterministic regex & keyword filters

Traditional keyword blocklists are too brittle to catch nuanced AI hallucinations or policy violations. An agent offering an unauthorized 80% discount might avoid the word "discount", phrasing it as "we have updated your annual invoice to $20". Regex filters fail to detect this violation.

Semantic routing solves this by evaluating vector embeddings of the drafted message against predefined semantic clusters (e.g. Financial Commitments, Legal Claims, Standard Support, Password Reset) with low latency.

Filter StrategyDetection MechanismLatencyFailure Mode
Regex / String SearchKeyword substring match< 1msEasily bypassed by synonyms or paraphrasing
Full LLM Judge PromptSecond model evaluates draft800ms – 2,500msHigh token cost, slow latency, potential jailbreaks
Semantic Vector RouterCosine similarity on embeddings5ms – 15msCatches semantic intent with near-zero latency overhead

Building a Semantic Email Router in Python

Using the open-source semantic-router library with local embeddings (such as HuggingFace MiniLM or Cohere), we classify outbound messages before hitting the send API:

PYTHON
from semantic_router import Route
from semantic_router.encoders import HuggingFaceEncoder
from semantic_router.layer import RouteLayer
import requests

# 1. Define high-risk semantic clusters
financial_route = Route(
    name="financial_risk",
    utterances=[
        "We are refunding your full subscription cost.",
        "Your new discounted rate is $5 per month.",
        "I have credited $500 back to your account.",
        "You do not need to pay the remaining invoice balance."
    ]
)

standard_support = Route(
    name="standard_support",
    utterances=[
        "Here are the instructions to reset your password.",
        "Your support ticket #4102 has been received.",
        "Please find the user manual attached.",
        "Our office hours are 9 AM to 5 PM EST."
    ]
)

encoder = HuggingFaceEncoder(name="sentence-transformers/all-MiniLM-L6-v2")
router = RouteLayer(encoder=encoder, routes=[financial_route, standard_support])

def dispatch_safely(recipient: str, subject: str, draft_text: str):
    decision = router(draft_text)
    
    if decision.name == "financial_risk":
        print(f"[ESCALATION] Message flagged for human financial approval: '{draft_text}'")
        # Enqueue for manual supervisor sign-off in SadaSend approval mode
        return {"status": "queued_for_approval", "route": decision.name}
    
    # Safe to dispatch autonomously
    res = requests.post(
        "https://api.sadasend.com/emails",
        headers={"Authorization": "Bearer sada_live_..."},
        json={"to": recipient, "subject": subject, "text": draft_text}
    )
    return res.json()

Key architectural advantages for enterprise AI teams

  • low latency: Zero external LLM round-trips for intent classification.
  • Zero false positives on common synonyms: Dense vector embeddings understand underlying semantics rather than literal tokens.
  • Auditable policy enforcement: Every routing decision is logged with its cosine similarity score for continuous tuning.
Free plan

Building AI agents that send email?

Scoped API keys, per-key recipient allowlists, approval mode and a hosted MCP server with ten tools — on the free plan, without a card.