Modell-Routing: Verwenden Sie nicht ein Modell für alles

Das richtige Modell für die richtige Aufgabe.

Inhaltsverzeichnis

Das Ausführen eines Modells mit 70 Milliarden Parametern, um eine 200-Wörter-E-Mail zusammenzufassen, ist verschwenderisch. Das Ausführen eines 3-Milliarden-Parameter-Modells zur Überprüfung von Produktionscode ist fahrlässig. Die meisten Systeme liegen irgendwo dazwischen – und genau hier kommt das Modell-Routing ins Spiel.

Es passt die Komplexität der Aufgabe der Fähigkeit des Modells an. Die Kompromisse sind real, aber die Einsparungen auch.

Diagramm der LLM-Modell-Routing-Strategien

Das Routing-Problem

Die meisten Leute beginnen mit einem Modell und bleiben dabei. Das funktioniert, bis man die Kosten, die Latenz oder beides bemerkt. Die Alternative besteht darin, einen Router zu bauen – etwas, das entscheidet, welches Modell welche Anfrage bearbeitet.

In der Praxis funktionieren vier Strategien:

  1. Fähigkeitsbasiert – Routing basierend darauf, was das Modell kann
  2. Kostensensibel – Routing basierend darauf, was Sie ausgeben möchten
  3. Latenzsensibel – Routing basierend darauf, wie schnell Sie es brauchen
  4. Hybrid – Kombination der oben genannten

Jede optimiert etwas anderes. Die Auswahl einer Strategie ist meist eine Entscheidung darüber, was am meisten schmerzt.

Fähigkeitsbasiertes Routing

Der einfachste Ansatz. Klassifizieren Sie die Aufgabe und senden Sie sie an das Modell, das sie handhabt.

Aufgabe Modellgröße Beispiele
Klassifizierung, Tagging 1-3B Qwen3-1.7B, Gemma-2-2B
Zusammenfassung, Extraktion 3-7B Qwen3-8B, Llama-3.1-8B
Code-Generierung 7-14B Qwen2.5-Coder-7B, DeepSeek-Coder-V2
Komplexe Reasoning 14-32B Qwen3-32B, Llama-3.1-70B
Kreatives Schreiben, Analyse 32B+ Qwen2.5-72B, Claude, GPT-4

Wenn die Aufgabe das größere Modell nicht benötigt, nutzen Sie es nicht. Ein 1,5B-Modell bewältigt die Sentiment-Klassifizierung gut. Es wird jedoch keinen kohärenten Aufsatz schreiben.

Die Implementierung ist straightforward (einfach):

ROUTING_RULES = {
    "classify": {"model": "qwen3-1.7B", "max_tokens": 100},
    "summarize": {"model": "qwen3-8B", "max_tokens": 500},
    "code_review": {"model": "qwen2.5-coder-7b", "max_tokens": 2000},
    "reason": {"model": "qwen3-32b", "max_tokens": 4000},
    "creative": {"model": "claude-sonnet-4", "max_tokens": 8000},
}

def route_request(task_type: str) -> dict:
    return ROUTING_RULES.get(task_type, ROUTING_RULES["reason"])

Der Haken ist die Klassifizierung selbst. Wenn Sie den Aufgabentyp falsch bestimmen, routen Sie zur falschen Modellinstanz. Ich habe Systeme gesehen, die Code-Review als “Zusammenfassung” klassifizieren und dabei stillschweigend an Qualität verlieren.

Kostensensibles Routing

Lokale Inferenz glänzt hier. Lokale Modelle sind nach Amortisation der Hardware effektiv kostenlos. Eine RTX 5080 zahlt sich bei moderater API-Nutzung in etwa sechs Monaten zurück.

Modell Input ($/M Token) Output ($/M Token) Lokale Kosten/Stunde
GPT-4o $2,50 $10,00
Claude Sonnet 4 $3,00 $15,00
Qwen2.5-72B (API) $0,50 $2,00
Qwen3-32B (lokal) $0,00 $0,00 ~$0,10
Qwen3-8B (lokal) $0,00 $0,00 ~$0,05

Wenn Sie tausende Anfragen pro Sitzung verarbeiten, schlägt selbst $0,05 Stromkosten $15/M Token.

Budget-basiertes Routing fällt zurück, je mehr Sie ausgeben:

class CostAwareRouter:
    def __init__(self, budget_per_session: float = 0.10):
        self.budget = budget_per_session
        self.spent = 0.0
        self.models = {
            "cheap": {"model": "qwen3-8B", "cost": 0.0},
            "medium": {"model": "qwen3-32b", "cost": 0.0},
            "expensive": {"model": "claude-sonnet-4", "cost": 0.000015},
        }

    def route(self, task: str) -> str:
        ratio = self.spent / self.budget
        if ratio < 0.5:
            return self.models["expensive"]["model"]
        elif ratio < 0.8:
            return self.models["medium"]["model"]
        return self.models["cheap"]["model"]

Die Qualität verschlechtert sich, während Sie zurückfallen. Sie beginnen mit Claude, wechseln zu Qwen3-32B und dann zu Qwen3-8B. Am Ende einer langen Sitzung ist die Ausgabe merklich schlechter. Ob das relevant ist, hängt davon ab, was Sie bauen.

Latenzsensibles Routing

Interaktive Tools brauchen schnelle erste Token. Batch-Jobs können warten. Der Unterschied liegt meist bei einem Faktor von fünf in der Modellgröße.

Anwendungsfall Erstes Token Komplett Maximale Modellgröße
Echtzeit-Chat < 200ms < 2s < 7B
Interaktive Tools < 500ms < 5s < 14B
Batch-Verarbeitung < 1s < 30s Beliebig
Forschung/Analyse < 2s < 60s Beliebig

Wenn Sie Tokens an einen Benutzer streamen, ist die Latenz des ersten Tokens das, was sie spüren. Ein 32B-Modell, das eine halbe Sekunde zum Starten braucht, fühlt sich träge an im Vergleich zu einem 1,5B-Modell, das sofort feuert.

class LatencyAwareRouter:
    def __init__(self):
        self.model_latencies = {
            "qwen3-1.7b": {"first_token": 0.05, "complete": 0.5},
            "qwen3-8B": {"first_token": 0.15, "complete": 2.0},
            "qwen3-32b": {"first_token": 0.5, "complete": 10.0},
            "claude-sonnet-4": {"first_token": 0.3, "complete": 5.0},
        }

    def route(self, target_latency: float) -> str:
        for model, latencies in sorted(
            self.model_latencies.items(),
            key=lambda x: x[1]["complete"]
        ):
            if latencies["complete"] <= target_latency:
                return model
        return "qwen3-1.7b"

Die Latenzwerte sind grob – sie hängen von Ihrer Hardware, Quantisierung und Batch-Größe ab. Messen Sie auf Ihrem eigenen Setup.

Fallback-Strategien

Modelle schlagen fehl. APIs drosseln die Rate. Timeouts passieren. Das Muster, das funktioniert, ist eine Fallback-Kette, geordnet vom besten zum zuverlässigsten:

class FallbackRouter:
    def __init__(self):
        self.fallback_chain = [
            {"model": "claude-sonnet-4", "timeout": 30},
            {"model": "qwen2.5-72b", "timeout": 60},
            {"model": "qwen3-32b", "timeout": 120},
            {"model": "qwen3-8b", "timeout": 300},
        ]

    def route_with_fallback(self, prompt: str) -> str:
        for config in self.fallback_chain:
            try:
                return self.call_model(
                    config["model"], prompt,
                    timeout=config["timeout"]
                )
            except (TimeoutError, APIError) as e:
                log.warning(f"Model {config['model']} failed: {e}")
                continue
        raise RuntimeError("All fallback models failed")

Das letzte Modell in der Kette sollte lokal sein. Es ist langsamer, wird aber nicht wegen eines Netzwerkproblems oder eines API-Schlüssels fehlschlagen.

Wann Routing hilft

Routing macht Sinn, wenn Ihre Arbeitslast gemischt ist. Wenn Sie Klassifizierung, Zusammenfassung und Reasoning im selben System durchführen, spart ein Router Geld und Latenz.

Es macht keinen Sinn, wenn alles, was Sie tun, die gleiche Komplexität hat. Nutzen Sie einfach das Modell, das bei dieser Aufgabe gut ist. Der Router fügt Komplexität hinzu, die Sie nicht brauchen.

Frühes Prototyping ist ein weiterer Grund, es zu überspringen. Lassen Sie die Aufgabe mit einem Modell funktionieren, und fügen Sie Routing hinzu, wenn Kosten oder Latenz tatsächlich zu einem Problem werden.

Kompromisse

Jede Routing-Strategie optimiert etwas und opfert etwas anderes:

  • Einzelnes Modell – einfachste, teuerste, gleichbleibende Qualität
  • Fähigkeitsbasiert – bessere Kosten, höhere Qualität pro Aufgabe, moderate Komplexität
  • Kostensensibel – günstigste, variierende Qualität, moderate Komplexität
  • Latenzsensibel – schnellste, kann Qualität opfern, moderate Komplexität
  • Hybrid – das Beste aus allen, am komplexesten zu implementieren

Produktionssysteme konvergieren meist auf Hybrid. Beginnen Sie mit fähigkeitsbasiertem Routing, fügen Sie Kostensensibilität hinzu, wenn die Rechnung kommt, und Latenzsensibilität, wenn Benutzer über Langsamkeit klagen.

Verwandte Themen

Abonnieren

Neue Beiträge zu Systemen, Infrastruktur und KI-Engineering.