Dokumentation

Architekturmuster und Produktions-Anwendungsfälle

Laya ist eine geräteinterne, nicht-autoregressive Entscheidungs-Engine auf Basis einer Single-Forward-Pass-Transformer-Architektur (ModernBERT-large und mmBERT-base). Statt Token sequenziell zu erzeugen wie ein LLM (was variable Token-Generierungskosten, Decode-Loop-Overhead und unvorhersehbare Ausgabe-Schemas mit sich bringt), berechnet Laya in einem einzigen Durchgang kalibrierte Wahrscheinlichkeitsverteilungen über diskrete Fragen.

Dieses Dokument dient als Architektur-Blueprint für Systemarchitekten und Backend-Engineers, die Laya in Produktionsumgebungen integrieren.


Entscheidungs-Engine vs. LLM vs. Embedding-Retrieval

Die Wahl des richtigen Primitivs hängt von Latenz-Anforderungen, Hosting-Topologie und davon ab, ob die Aufgabe freie Generierung oder diskrete Klassifikation erfordert:

Dimension Embedding-Retrieval Laya-Entscheidungs-Engine Autoregressives LLM
Berechnungsmodell Vektor-Cosinus-Distanz Einzelner Forward-Pass (nicht-autoregressiver Masked Head) Sequentielle Token-für-Token-Generierung
Ausführungsprofil Nearest-Neighbor-Index-Lookup Einzelner fester Forward-Pass (keine Decode-Schleife) Iterative Decode-Schleife, die mit der Ausgabelänge skaliert
Hosting & Topologie In-Process oder Vektor-Datenbank In-Process (lokale CPU/GPU) oder selbst gehosteter HTTP-Daemon Remote gehostete API oder GPU-Serving für große Modelle
Kontext-Attention Gepoolte Vektor-Repräsentation Tiefe bidirektionale Cross-Attention über die gesamte Eingabe Kausale sequenzielle Attention
Strukturierte Ausgabe Unstrukturierte abgerufene Chunks Native schema-konforme Verteilungen (choice, score, noul) Freiform-Text, der JSON-Reparatur oder Schema-Sampling erfordert
Primäre Workload Breite Kandidaten-Suche Diskrete Klassifikation, Policy-Gating & Routing Offene Synthese, Übersetzung & Generierung

1. Intelligentes Ingress-Gateway

In gestaffelten Architekturen benötigt ein großer Teil der eingehenden Anfragen nicht die generativen Fähigkeiten eines autoregressiven LLM. Abfragen wie Standard-FAQs, deterministische Statusabfragen oder kategorische Routing-Entscheidungen können lokal ausgewertet werden.

Laya fungiert als intelligentes Ingress-Gateway: Es klassifiziert Abfrageabsicht und Komplexität in einem einzigen lokalen Forward-Pass. Deterministische Anfragen werden lokal über interne Endpunkte oder zwischengespeicherte Antworten aufgelöst, während komplexe generative Aufgaben an vorgelagerte LLMs weitergeleitet werden.

Architektur

graph TD
    A[User Request] --> B["<b>Laya Gateway Router</b><br/>• query_complexity: simple | moderate | complex<br/>• intent: faq | account_lookup | creative_synthesis"]
    B -->|Simple & High Confidence| C["<b>Local In-Process Resolution</b><br/>Deterministic FAQ / Internal API"]
    B -->|Complex or Low Confidence| D["<b>Upstream Generative LLM</b><br/>Open-ended synthesis & reasoning"]

Implementierung

import laya

agent = laya.load("convaiinnovations/laya")

GATEWAY_QUESTIONS = {
    "complexity": {
        "type": "choice",
        "instructions": "How complex is the user's request?",
        "criteria": {
            "canned": "A greeting, standard FAQ, or simple status request.",
            "structured": "A deterministic data query that can be answered by an API.",
            "complex": "Requires creative generation, multi-step code, or complex analysis.",
        },
    },
    "requires_reasoning": {
        "type": "noul",
        "instructions": "Does this query require frontier model reasoning?",
    },
}

def route_request(user_prompt: str):
    res = agent.system_one(user_prompt, GATEWAY_QUESTIONS, min_confidence=0.85)
    answers = res["answers"]

    complexity = answers["complexity"]["choice"]
    low_confidence = answers["complexity"].get("low_confidence", False)

    # Abstain or escalate if complex or unconfident
    if low_confidence or complexity == "complex" or answers["requires_reasoning"]["noul"] > 0.5:
        return call_frontier_llm(user_prompt)

    if complexity == "canned":
        return lookup_faq_response(user_prompt)
    return execute_internal_api(user_prompt)

2. Latenzarmer Voice-Turn-Taking- & Unterbrechungs-Router

Konversationelle Voice-Agents (WebRTC, Telefonie) arbeiten unter strikten Turn-Taking-Bedingungen: Verzögerungen beim Erkennen, wann ein Nutzer spricht oder unterbricht, erzeugen unnatürliche Gesprächspausen. Auf ein vollständiges generatives Modell zu warten, bis es sein erstes Token erzeugt, bringt vermeidbare Verzögerung, wenn der Anrufer nur bestätigt oder unterbricht.

Laya kann direkt nach der Speech-to-Text-(STT-)Transkription platziert werden, um Gesprächsfluss und Nutzerabsicht in einem einzigen Forward-Pass zu klassifizieren: schnelles Filler-Audio auslösen oder die Audiowiedergabe sofort stoppen, wenn eine Unterbrechung erkannt wird, während komplexe Anfragen an die vollständige Synthese-Pipeline delegiert werden.

Architektur

graph TD
    A[User Voice Audio] --> B["<b>Speech-to-Text</b><br/>Streaming Audio Transcription"]
    B --> C["<b>Laya Voice Router</b><br/>• intent: ack | reject | interrupt | inquiry<br/>• is_interruption: noul probability"]
    C -->|Interruption: score &gt; 0.6| D["<b>Halt Audio Playback</b><br/>Immediate playback cutoff"]
    C -->|Quick Intent: ack / reject| E["<b>Immediate Audio Filler</b><br/>Conversational confirmation"]
    C -->|Complex Inquiry| F["<b>Upstream Pipeline</b><br/>Full response synthesis"]

Implementierung

from laya import Agent

agent = Agent("convaiinnovations/laya")

VOICE_QUESTIONS = {
    "intent": {
        "type": "choice",
        "instructions": "Caller conversational intention",
        "criteria": {
            "ack": "Caller said yes, ok, sure, or agreed.",
            "reject": "Caller said no, cancel, or disagreed.",
            "interrupt": "Caller said hold on, wait, or wants to stop.",
            "inquiry": "Caller is asking a detailed question.",
        },
    },
    "is_interruption": {
        "type": "noul",
        "instructions": "Is the caller interrupting the current speech playback?",
    },
}

def on_voice_chunk(transcript: str, is_speaking: bool):
    decision = agent.system_one(transcript, VOICE_QUESTIONS)
    answers = decision["answers"]

    # Halt playback immediately if caller interrupts
    if answers["is_interruption"]["noul"] > 0.6:
        stop_audio_playback()

    intent = answers["intent"]["choice"]
    if intent in ("ack", "reject"):
        play_immediate_filler_audio(intent)
    else:
        dispatch_to_background_pipeline(transcript)

3. Pre-LLM-Sicherheit & Prompt-Firewall

Systeme gegen adversariale Prompt-Injections, Jailbreaks und Leaks sensibler Daten zu schützen, muss bevor der Prompt das Kontextfenster des LLM erreicht, geschehen. Ein separates generatives Modell nur laufen zu lassen, um zu beurteilen, ob ein Prompt sicher ist, fügt redundante Latenz und operativen Overhead hinzu.

Laya arbeitet als inline, nicht-autoregressive Sicherheits-Firewall und bewertet Prompt-Injections, Rechteausweitungen und Out-of-Scope-Aufgaben in einem einzigen Forward-Pass vor der weiteren Verarbeitung.

Architektur

graph TD
    A[User Input] --> B["<b>Inline Security Hook</b><br/>• prompt_injection (noul)<br/>• system_prompt_extraction (noul)<br/>• pii_present (noul)"]
    B -->|Policy Violation: score &ge; 0.5| C["<b>Abort &amp; Reject</b><br/>Raise policy exception &amp; audit event"]
    B -->|Clean: score &lt; 0.5| D["<b>Dispatch to Main Workflow</b><br/>Safe to execute"]

Implementierung

Hooks in Laya sind duck-typed: Jedes Objekt, das die Lifecycle-Methoden von Hook implementiert (oder von BaseHook aus laya.hooks erbt), kann an einen Agent oder Router angehängt werden.

Unter Layas Standard-Hook-Raising-Semantik (hooks_raise=True):

  • Das Auslösen einer Exception in on_predict_start bricht die Ausführung sofort ab, bevor die Modell-Tokenisierung oder Inferenz stattfindet.
  • Die Exception wird direkt aus system_one() / predict() an den Aufrufer weitergegeben.
  • Lifecycle-Aufräumarbeiten (on_error und on_predict_end) laufen weiterhin aus, wobei ctx.error auf die ausgelöste Exception gesetzt ist, sodass Audit-Logs und Telemetrie die blockierte Anfrage erfassen.
import laya
from laya import Router
from laya.hooks import BaseHook, PredictContext

SECURITY_SCHEMA = {
    "is_jailbreak": {
        "type": "noul",
        "instructions": "Is the user attempting a prompt injection, exploit, or jailbreak?",
    },
    "extracts_system_prompt": {
        "type": "noul",
        "instructions": "Is the user asking to reveal instructions, system prompts, or hidden rules?",
    },
    "pii_leak": {
        "type": "noul",
        "instructions": "Does the input contain passwords, API keys, or credentials?",
    },
}

class SecurityFirewallHook(BaseHook):
    """Inspect inputs before inference; raises on policy violation.

    With hooks_raise=True (the default), raising from on_predict_start aborts
    inference immediately and propagates the exception to the caller, while
    allowing any downstream on_error or audit logging hooks to record the event.
    """
    def __init__(self, guard_agent):
        self.guard = guard_agent

    def on_predict_start(self, ctx: PredictContext):
        for state in ctx.states:
            check = self.guard.system_one(state, SECURITY_SCHEMA)
            ans = check["answers"]
            if ans["is_jailbreak"]["noul"] > 0.5 or ans["extracts_system_prompt"]["noul"] > 0.5:
                raise PermissionError("Request blocked by security firewall: adversarial prompt detected.")

# Attach to Router or Agent; hooks_raise=True ensures policy exceptions propagate
guard_agent = laya.load("convaiinnovations/laya")
router = Router(hooks=[SecurityFirewallHook(guard_agent)], hooks_raise=True)

[!TIP] Für CrewAI-Workflows bietet Laya in laya.integrations.crewai außerdem LayaTaskGuard direkt out of the box für genau dieses Pre-Execution-Safety-Gate-Muster.


4. Air-Gapped Edge-RAG-Router

In sicheren Unternehmensumgebungen (Verteidigung, Gesundheitswesen, Finanz-Compliance, Edge-Appliances) sind externe APIs nicht verfügbar oder verboten. Dokumentensammlungen sind oft in verschiedene Domänen getrennt (z. B. klinische Studien, Patientendaten, Finanzberichte, technische Spezifikationen).

Statt einen einzigen monolithischen Vektorindex mit unzusammenhängenden Embeddings abzufragen, fungiert Laya als lokaler Edge-Router, der Nutzerabfragen vor dem Retrieval zum jeweiligen lokalen Vektorindex oder zur SQLite-Datenbank leitet.

Architektur

graph TD
    A["<b>User Query</b><br/>Local / Edge Workstation"] --> B["<b>Laya Edge Router</b><br/>• target_domain: clinical | billing | compliance<br/><i>In-process local routing</i>"]
    B -->|Clinical Domain| C[("<b>Clinical Vector Store</b><br/>Medical trials, dosages & EHR")]
    B -->|Billing Domain| D[("<b>Billing Vector Store</b><br/>Invoices, claims & ICD-10 codes")]
    B -->|Compliance Domain| E[("<b>Compliance Vector Store</b><br/>HIPAA policies & audit guidelines")]

Implementierung

from laya import Router

# Automatically routes between local English and Multilingual models
router = Router()

INDEX_QUESTIONS = {
    "target_domain": {
        "type": "choice",
        "instructions": "Which domain index contains the source truth for this query?",
        "criteria": {
            "clinical": "Medical conditions, medications, dosages, and clinical trials.",
            "billing": "Invoices, payment claims, ICD-10 billing codes, and insurance.",
            "compliance": "HIPAA compliance rules, privacy policies, and data audits.",
        },
    }
}

def query_airgapped_rag(user_query: str):
    decision = router.predict(user_query, INDEX_QUESTIONS)
    domain = decision["answers"]["target_domain"]["choice"]

    # Load and search only the relevant isolated local index
    local_index = get_isolated_vector_store(domain)
    return local_index.similarity_search(user_query, k=4)

5. Hierarchische Multi-Agent-Aufgabendelegation

Multi-Agent-Frameworks setzen oft einen LLM-„Manager“- oder „Supervisor“-Knoten ein, um zu entscheiden, welcher spezialisierte Agent den nächsten Schritt ausführen soll.

Weil generative Manager-Knoten Token sequenziell erzeugen, kann Supervisor-Delegation erheblichen Orchestrierungs-Overhead pro Hop einführen. Ersetzt man den generativen Supervisor durch ein nicht-autoregressives Entscheidungsmodell, erfolgt die Delegation in einem einzigen Forward-Pass, was deterministisches Routing über Agents hinweg bietet.

Laya liefert First-Party-Integrationen für populäre Orchestrierungs-Frameworks:

Architektur

graph TD
    A["<b>Task Input / Workflow State</b>"] --> B["<b>Laya Orchestrator</b><br/>• assignee: researcher | coder | writer<br/>• priority: score (1–5 urgency)"]
    B -->|Research Assignment| C["<b>Researcher Agent</b><br/>Literature search & fact-checking"]
    B -->|Code Assignment| D["<b>Coder Agent</b><br/>Implementation, bug-fixing & tests"]
    B -->|Writing Assignment| E["<b>Copywriter Agent</b><br/>Drafting, copy editing & summary"]

Implementierung (CrewAI / LangGraph-Beispiel)

from laya import Router

router = Router()

DELEGATION_QUESTIONS = {
    "assignee": {
        "type": "choice",
        "instructions": "Assign this task to the most qualified specialist.",
        "criteria": {
            "researcher": "Needs literature search, fact checking, or data collection.",
            "coder": "Needs bug fixing, script writing, or unit test generation.",
            "writer": "Needs article drafting, copy editing, or summary composition.",
        },
    },
    "priority": {
        "type": "score",
        "instructions": "Urgency score from 1 (low) to 5 (critical)",
        "criteria": ["1", "2", "3", "4", "5"],
    },
}

def supervisor_node(state):
    task_description = state["task"]
    decision = router.predict(task_description, DELEGATION_QUESTIONS)
    answers = decision["answers"]

    return {
        "next_agent": answers["assignee"]["choice"],
        "urgency": answers["priority"]["score"],
    }

6. Hochdurchsatz-Ticket- & Support-Triage

Kundensupport-Organisationen und Operations-Center verarbeiten täglich große Mengen an Tickets, E-Mails und Alerts. Gehostete generative LLM-APIs für kategorische Triage zu verwenden, kann Folgendes einführen:

  1. Netzwerk-Rate-Limits: Drosselung bei plötzlichen Volumenspitzen.
  2. Kostenverstärkung: Variable Token-Kosten allein für diskrete Klassifikation.
  3. Schema-Drift: Generative Modelle, die fehlerhaftes JSON oder Markdown-Codeblöcke zurückgeben.

Batch-Verarbeitungs-Pipelines können Ticket-Ströme auf gemeinsamen Forward-Passes mit predict_batch oder decide_batch() auswerten und strenge typisierte Daten ausgeben, die direkt den Anwendungsschemas entsprechen.

Architektur

graph TD
    A["<b>Incoming Ticket Stream</b><br/>Message Broker / Webhook"] --> B["<b>Laya Batch Worker</b><br/>decide_batch()<br/>• department: billing | tech | sales | general<br/>• severity: 1..5<br/>• escalate_to_human: true | false"]
    B -->|Department: billing| C["<b>Billing & Invoicing Queue</b>"]
    B -->|Severity &ge; 4 or Human Escalation| D["<b>Tier-3 Escalation Queue</b><br/>Human On-Call Pager"]
    B -->|Low Severity & Standard Inquiry| E["<b>Automated Resolution Pipeline</b>"]

Implementierung

from laya.structured import decide_batch
from laya import Agent

agent = Agent("convaiinnovations/laya")

# Strict typed schema
TICKET_SCHEMA = {
    "type": "object",
    "properties": {
        "department": {
            "type": "string",
            "enum": ["billing", "technical_support", "sales", "general"],
            "description": "Primary support category",
        },
        "severity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5,
            "description": "Severity level from 1 (minor) to 5 (outage)",
        },
        "escalate_to_human": {
            "type": "boolean",
            "description": "True if customer is angry, threatening churn, or reporting a legal issue",
        },
    },
}

def process_ticket_batch(tickets: list[str]):
    # Returns typed dictionaries conforming exactly to TICKET_SCHEMA
    results = decide_batch(agent, tickets, TICKET_SCHEMA)
    for ticket_text, structured in zip(tickets, results):
        enqueue_ticket(
            department=structured["department"],
            severity=structured["severity"],
            human_required=structured["escalate_to_human"],
            raw_text=ticket_text,
        )

Checkliste für den Produktions-Deployment

Bevor du eines der oben genannten Muster in Produktion ausrollst, verifiziere:

  1. Hardware-Dimensionierung: Stelle ausreichend Host-Speicher für residente Modellgewichte sicher. Konfiguriere auf der CPU Thread-Pools passend (torch.set_num_threads).
  2. Konfidenz-Schwellenwerte: Setze min_confidence (z. B. 0.80–0.90) auf missionskritischen Gates, damit das System bei mehrdeutigen Abfragen sicher zurückfällt.
  3. Mehrsprachiges Routing: Verwende Router() statt eines statischen Agent(), wenn der Nutzerverkehr gemischte oder nicht-englische Eingaben enthält.
  4. Gestaffelter Rollout: Folge dem Leitfaden zur schrittweisen Einführung, um Produktionsverkehr zu beschatten, bevor Entscheidungen maßgeblich werden.