Multimodell-Systemdesign: Wenn ein einzelnes Modell nicht ausreicht

Wählen Sie das einfachste Muster, das funktioniert.

Inhaltsverzeichnis

Einzelmodellsysteme sind einfach. Multimodellsysteme sind leistungsstark. Die Herausforderung besteht nicht darin, Modelle auszuwählen, sondern die Architektur zu gestalten, die sie orchestriert.

Ein Multimodellsystem bedeutet nicht, einfach mehr Modelle zu haben. Es geht darum, das richtige Modell für die richtige Aufgabe zur richtigen Zeit einzusetzen.

Multi-model LLM system design patterns

Architekturmuster

Fünf Muster decken die meisten Anwendungsfälle ab:

Muster Komplexität Wann verwenden Kompromiss
Einzelmodell Niedrigste Prototyping, einfache Aufgaben Begrenzte Fähigkeiten
Sequenziell Niedrig Mehrstufige Workflows Höhere Latenz
Parallel Mittel Unabhängige Aufgaben Höhere Kosten
Hierarchisch Hoch Komplexes Reasoning Komplexe Orchestrierung
Ensemble Höchste Kritische Entscheidungen Höchste Kosten

Wählen Sie das einfachste Muster, das funktioniert. Komplexität ist real und sie addiert sich.

Sequenzielle Architektur

Verarbeiten Sie Aufgaben durch eine Kette von Modellen, wobei jedes Modell auf einen Schritt spezialisiert ist.

Muster 1: Pipeline

Pipeline-Muster – die Ausgabe jedes Modells fließt in das nächste:

class ModelPipeline:
    def __init__(self):
        self.models = [
            {"model": "qwen2.5-1.5b", "task": "classify"},
            {"model": "qwen2.5-7b", "task": "extract"},
            {"model": "qwen2.5-32b", "task": "reason"},
        ]

    def process(self, input: str) -> str:
        current = input
        for model_config in self.models:
            current = self.call_model(
                model_config["model"],
                self.create_prompt(model_config["task"], current)
            )
        return current

Die Latenz addiert sich. Drei Modelle in Folge bedeuten dreifache Latenz. Verwenden Sie dies nur, wenn jeder Schritt tatsächlich ein anderes Modell benötigt.

Muster 2: Router

Router-Muster – klassifizieren Sie die Aufgabe und leiten Sie sie an den Spezialisten weiter:

class ModelRouter:
    def __init__(self):
        self.classifier = "qwen2.5-1.5b"
        self.specialists = {
            "code": "qwen2.5-coder-7b",
            "math": "qwen2.5-32b",
            "creative": "claude-sonnet-4",
            "general": "qwen2.5-7b",
        }

    def route(self, prompt: str) -> str:
        task_type = self.classify(prompt)
        model = self.specialists.get(task_type, self.specialists["general"])
        return self.call_model(model, prompt)

Der Klassifizierer ist die Schwachstelle. Wenn er falsch klassifiziert, wird an das falsche Modell geleitet und die Qualität leidet. Verwenden Sie einen Klassifizierer, der gut genug ist – selbst ein kleiner reicht aus, wenn die Kategorien klar sind.

Parallele Architektur

Verarbeiten Sie unabhängige Aufgaben gleichzeitig.

Muster 1: Fan-Out

Fan-Out – führen Sie denselben Prompt durch mehrere Modelle:

import asyncio

class ModelFanOut:
    def __init__(self):
        self.models = [
            "qwen2.5-7b",
            "qwen2.5-32b",
            "claude-sonnet-4",
        ]

    async def process(self, prompt: str) -> list[str]:
        tasks = [self.call_model(model, prompt) for model in self.models]
        return await asyncio.gather(*tasks)

Nützlich für Vergleiche, A/B-Tests oder wenn Sie die beste Ausgabe auswählen möchten. Teuer, aber der Qualitätszuwachs ist bei kritischen Entscheidungen wertvoll.

Muster 2: Voting

Voting – kombinieren Sie Ausgaben durch Konsens:

class ModelVoting:
    def __init__(self):
        self.models = [
            "qwen2.5-7b",
            "qwen2.5-32b",
            "claude-sonnet-4",
        ]

    def vote(self, prompt: str) -> str:
        responses = [self.call_model(model, prompt) for model in self.models]
        from collections import Counter
        votes = Counter(responses)
        return votes.most_common(1)[0][0]

Mehrheitsvoting funktioniert für die Klassifizierung. Bei Generierungsaufgaben ist es schwieriger – Sie benötigen semantische Ähnlichkeit, nicht exakte Übereinstimmungen.

Hierarchische Architektur

Verwenden Sie Modelle auf verschiedenen Abstraktionsebenen.

Muster 1: Planner-Executor

Planner-Executor – ein starkes Modell plant, kleinere Modelle führen aus:

class PlannerExecutor:
    def __init__(self):
        self.planner = "qwen2.5-32b"
        self.executors = {
            "code": "qwen2.5-coder-7b",
            "search": "qwen2.5-7b",
            "math": "qwen2.5-7b",
        }

    def process(self, task: str) -> str:
        plan = self.call_model(self.planner, f"Plan: {task}")
        results = []
        for step in self.parse_plan(plan):
            executor = self.executors.get(step["type"], "qwen2.5-7b")
            result = self.call_model(executor, step["prompt"])
            results.append(result)
        return self.call_model(self.planner, f"Synthesize: {results}")

Der Planner übernimmt die schwere Arbeit. Die Executors erledigen spezifische Aufgaben. Dieses Muster funktioniert gut, wenn der Planungsschritt teuer ist, die Ausführungsschritte jedoch günstig.

Muster 2: Supervisor-Worker

Supervisor-Worker – ein Supervisor delegiert und überprüft:

class SupervisorWorker:
    def __init__(self):
        self.supervisor = "qwen2.5-32b"
        self.workers = ["qwen2.5-7b", "qwen2.5-coder-7b"]

    def process(self, task: str) -> str:
        assignments = self.call_model(self.supervisor, f"Assign: {task}")
        results = []
        for assignment in self.parse_assignments(assignments):
            result = self.call_model(
                assignment["worker"], assignment["task"]
            )
            results.append(result)
        return self.call_model(self.supervisor, f"Review: {results}")

Der Supervisor ist der Flaschenhals. Er plant, delegiert und überprüft. Stellen Sie sicher, dass er schnell genug ist, sonst verlangsamt sich das gesamte System.

Ensemble-Architektur

Kombinieren Sie mehrere Modelle für kritische Entscheidungen.

Muster 1: Weighted Ensemble

Weighted Ensemble – bewerten Sie die Ausgabe jedes Modells und wählen Sie die höchste aus:

class WeightedEnsemble:
    def __init__(self):
        self.models = {
            "qwen2.5-32b": 0.5,
            "claude-sonnet-4": 0.3,
            "qwen2.5-7b": 0.2,
        }

    def decide(self, prompt: str) -> str:
        responses = {
            model: self.call_model(model, prompt)
            for model in self.models
        }
        scores = {}
        for model, response in responses.items():
            score = self.evaluate(response) * self.models[model]
            scores[response] = scores.get(response, 0) + score
        return max(scores, key=scores.get)

Die Gewichte spiegeln Ihr Vertrauen in jedes Modell wider. Passen Sie sie basierend auf der tatsächlichen Leistung an, nicht auf Benchmarks.

Muster 2: Consensus Ensemble

Consensus Ensemble – erfordern Sie Zustimmung, eskalieren Sie bei Uneinigkeit:

class ConsensusEnsemble:
    def __init__(self, threshold: float = 0.7):
        self.threshold = threshold
        self.models = [
            "qwen2.5-32b",
            "claude-sonnet-4",
            "qwen2.5-7b",
        ]

    def decide(self, prompt: str) -> str:
        responses = [
            self.call_model(model, prompt)
            for model in self.models
        ]
        from collections import Counter
        votes = Counter(responses)
        max_votes = max(votes.values())

        if max_votes / len(self.models) >= self.threshold:
            return votes.most_common(1)[0][0]

        return self.call_model("qwen2.5-32b", prompt)

Die Schwelle steuert, wie streng der Konsens ist. 0,7 bedeutet eine Zwei-Drittel-Zustimmung. Senken Sie sie für schnellere Entscheidungen, erhöhen Sie sie für höhere Sicherheit.

Wann Multimodellsysteme sinnvoll sind

Multimodellsysteme sind sinnvoll, wenn Sie gemischte Workloads haben, hohe Qualität für kritische Entscheidungen benötigen oder nach Kosten oder Latenz optimieren.

Sie sind nicht sinnvoll, wenn alle Aufgaben ähnlich komplex sind, Sie prototypen oder wenn Einfachheit wichtiger ist als Optimierung.

Die Faustregel: Beginnen Sie mit einem Modell. Fügen Sie weitere hinzu, wenn Sie eine echte Einschränkung erreichen – Kosten, Latenz oder Qualität. Entwerfen Sie keine Komplexität, bevor Sie sie benötigen.

Kompromisse

Muster Kosten Latenz Qualität Komplexität
Einzelmodell Niedrigste Niedrigste Variabel Niedrigste
Sequenziell Mittel Hoch Hoch Mittel
Parallel Hoch Niedrig Hoch Mittel
Hierarchisch Hoch Hoch Höchste Hoch
Ensemble Höchste Mittel Höchste Höchste

Jedes Muster bietet einen Kompromiss. Wählen Sie dasjenige, das Ihren Einschränkungen entspricht.

Verwandte Themen

Abonnieren

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