Dokumentation

Intent-Routing

Klassifiziere eingehende Anfragen und route jede zum optimalen Handler: deterministische Logik, ein spezialisiertes LLM oder ein Mensch.

Nicht jede Nutzeranfrage braucht dieselbe Art von Handler. Manche lassen sich mit einem Datenbank-Lookup beantworten. Manche brauchen ein LLM mit domänenspezifischem Kontext. Manche brauchen einen Menschen. TypeSafe kann vor all diesen als schneller, günstiger Klassifizierer sitzen, der bestimmt, welcher Handler aufgerufen wird.

Beispiel: Routing im Kundenservice

Stell dir vor, du baust ein Kundenservice-System. Nachrichten kommen herein und müssen an den richtigen Handler geroutet werden. Statt jede Nachricht durch ein teures LLM zu schicken, um herauszufinden, um welche Art von Anfrage es sich handelt, klassifizierst du zuerst und routest entsprechend.

%%{init: {"fontFamily": "Inter, sans-serif", "flowchart": {"rankSpacing": 35, "wrappingWidth": 300, "subGraphTitleMargin": {"top": 12, "bottom": 36}}}}%%
flowchart LR
    message["customer message"]

    subgraph req["TypeSafe evaluates questions<br/>in parallel"]
        direction TB
        intent["<b>Choice:</b> intent"]
        complexity["<b>Score:</b> complexity"]
        %% Invisible links stack the questions; they are answered in parallel.
        intent ~~~ complexity
    end

    message -- "one request<br/>message + 2 questions" --> req
    req -- "one response<br/>2 answers with<br/>confidence" --> confidence{"<b>intent confidence<br/>≥ 0.5?</b><br/>your code"}
    confidence -- "no" --> human["human agent"]
    confidence -- "yes" --> route{"<b>which intent?</b><br/>"}
    route -- "order_status" --> order["order lookup<br/>deterministic code"]
    route -- "product_question" --> product["product specialist LLM"]
    route -- "return_exchange" --> returns["returns specialist LLM"]
    route -- "complaint" --> escalate{"<b>complexity > 1<br/>or its confidence < 0.5?</b><br/>"}
    escalate -- "yes" --> human
    escalate -- "no" --> complaint["complaint resolution LLM"]

Schritt 1: Absicht und Komplexität klassifizieren

questions
{
  "intent": {
    "type": "choice",
    "instructions": "The primary intent of this customer message",
    "criteria": {
      "order_status": "Asking about an existing order",
      "product_question": "Asking about a product before buying",
      "return_exchange": "Wants to return or exchange something",
      "complaint": "Unhappy with experience, wants resolution"
    }
  },
  "complexity": {
    "type": "score",
    "instructions": "How complex is this request to resolve",
    "criteria": [
      "Simple lookup or standard procedure",
      "Requires some judgment or multi-step process",
      "Unusual situation, edge case, or escalation needed"
    ]
  }
}

Schritt 2: Zum optimalen Handler routen

routing.py

def route_ticket(ticket_id, response):
    intent = response.answers["intent"]
    complexity = response.answers["complexity"]

    if intent.confidence < 0.5:
        # If we don't have enough confidence to classify, route to a human agent
        return route_to_human_agent(ticket_id)

    if intent.choice == "order_status":
        handle_order_status(ticket_id)

    elif intent.choice == "product_question":
        handle_with_llm(ticket_id, PRODUCT_SPECIALIST)

    elif intent.choice == "return_exchange":
        handle_with_llm(ticket_id, RETURNS_SPECIALIST)

    elif intent.choice == "complaint":
        low_confidence = complexity.confidence < 0.5
        # A higher complexity.score leans toward the "escalation needed" end of the scale.
        if complexity.score > 1 or low_confidence:
            # Too complex for safe automation, or we're not sure about the complexity; route to a human.
            route_to_human_agent(ticket_id)
        else:
            handle_with_llm(ticket_id, COMPLAINT_RESOLUTION)

Eine Absicht routet zu deterministischem Code ohne LLM. Zwei routen zu verschiedenen spezialisierten LLMs, jedes mit anderem Kontext geladen. Eine nutzt den Komplexitäts-Score, um zwischen einem LLM und einem Menschen zu entscheiden. TypeSafe erledigt die Klassifizierung in einem einzigen schnellen Aufruf; die teuren Ressourcen werden nur für die Anfragen aufgerufen, die sie tatsächlich brauchen.

Beachte die zusätzliche Konfidenzprüfung beim Komplexitäts-Score. Wie in Konfidenz besprochen, ist es immer wichtig, die Bedeutung eines niedrigen Konfidenzwerts im Kontext des Systems und der Tragweite der Entscheidung zu bedenken.