Multi-Model Systeemontwerp: Wanneer één model niet voldoende is

Kies het eenvoudigste patroon dat werkt.

Inhoud

Single-modelsystemen zijn eenvoudig. Multi-modelsystemen zijn krachtig. De uitdaging ligt niet in het kiezen van modellen, maar in het ontwerpen van de architectuur die ze orchestreert.

Een multi-modelsysteem gaat niet om het hebben van meer modellen. Het gaat om het hebben van het juiste model voor de juiste taak op het juiste moment.

Multi-model LLM-systeemontwerp patronen

Architectuurpatronen

Vijf patronen dekken de meeste gebruiksscenario’s:

Patroon Complexiteit Wanneer te gebruiken Trade-off
Single Model Laagst Prototyping, eenvoudige taken Beperkte capaciteit
Sequentieel Laag Werkflows met meerdere stappen Hogere latentie
Parallel Midden Onafhankelijke taken Hogere kosten
Hierarchisch Hoog Complexe redenering Complexe orkestratie
Ensemble Hoogst Kritieke beslissingen Hoogste kosten

Kies het eenvoudigste dat werkt. Complexiteit is echt, en die hoopt zich op.

Sequentiële architectuur

Verwerk taken door een keten van modellen, elk gespecialiseerd in een stap.

Patroon 1: Pipeline

Pipelinepatroon — de output van elk model voert naar de volgende:

class ModelPipeline:
    def __init__(self):
        self.models = [
            {"model": "qwen3-1.7b", "task": "classify"},
            {"model": "qwen3-8b", "task": "extract"},
            {"model": "qwen3-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

Latentie telt op. Drie modellen in sequentie betekent drie keer de latentie. Gebruik dit alleen wanneer elke stap daadwerkelijk een ander model nodig heeft.

Patroon 2: Router

Routerpatroon — classificeer de taak, routeer naar de specialist:

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

    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)

De classifier is de zwakke schakel. Als deze verkeerd classificeert, routeer je naar het verkeerde model en verlies je kwaliteit. Gebruik een classifier die goed genoeg is — zelfs een kleine werkt als de categorieën duidelijk zijn.

Parallelle architectuur

Verwerk onafhankelijke taken gelijktijdig.

Patroon 1: Fan-Out

Fan-out — voer dezelfde prompt uit door meerdere modellen:

import asyncio

class ModelFanOut:
    def __init__(self):
        self.models = [
            "qwen3-8b",
            "qwen3-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)

Nuttig voor vergelijking, A/B-testing, of wanneer je de beste output wilt kiezen. Duur, maar de kwaliteitswinst is het waard voor kritieke beslissingen.

Patroon 2: Voting

Voting — combineer outputs via consensus:

class ModelVoting:
    def __init__(self):
        self.models = [
            "qwen3-8b",
            "qwen3-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]

Meerderheidsstemmen werken voor classificatie. Voor generatietaken is het laster — je hebt semantische similariteit nodig, geen exacte matches.

Hierarchische architectuur

Gebruik modellen op verschillende niveaus van abstractie.

Patroon 1: Planner-Executor

Planner-executor — een sterk model plant, kleinere modellen voeren uit:

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

    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"], "qwen3-8b")
            result = self.call_model(executor, step["prompt"])
            results.append(result)
        return self.call_model(self.planner, f"Synthesize: {results}")

De planner doet het zware werk. De executors hanteren specifieke taken. Dit patroon werkt goed wanneer de planstap duur is, maar de uitvoeringsstappen goedkoop.

Patroon 2: Supervisor-Worker

Supervisor-worker — een supervisor delegeert en reviewt:

class SupervisorWorker:
    def __init__(self):
        self.supervisor = "qwen3-32b"
        self.workers = ["qwen3-8b", "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}")

De supervisor is de bottleneck. Het plant, delegeert en reviewt. Zorg dat het snel genoeg is, anders vertraagt het hele systeem.

Ensemble-architectuur

Combineer meerdere modellen voor kritieke beslissingen.

Patroon 1: Weighted Ensemble

Gewogen ensemble — score de output van elk model, kies de hoogste:

class WeightedEnsemble:
    def __init__(self):
        self.models = {
            "qwen3-32b": 0.5,
            "claude-sonnet-4": 0.3,
            "qwen3-8b": 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)

Gewichten weerspiegelen je vertrouwen in elk model. Pas ze aan op basis van werkelijke prestaties, niet op benchmarks.

Patroon 2: Consensus Ensemble

Consensus ensemble — vereis overeenstemming, escaleer als deze ontbreekt:

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

    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("qwen3-32b", prompt)

De drempel bepaalt hoe streng consensus is. 0.7 betekent twee derde overeenstemming. Verlaag het voor snellere beslissingen, verhoog het voor meer zekerheid.

Wanneer multi-modelsystemen zinvol zijn

Multi-modelsystemen zijn zinvol wanneer je gemengde workloads hebt, hoge kwaliteit nodig hebt voor kritieke beslissingen, of optimaliseert voor kosten of latentie.

Ze zijn niet zinvol wanneer alle taken een vergelijkbare complexiteit hebben, je prototypt, of eenvoud belangrijker is dan optimalisatie.

De vuistregel: begin met één model. Voeg er meer toe wanneer je tegen een echte beperking stoot — kosten, latentie of kwaliteit. Ontwerp geen complexiteit voordat je het nodig hebt.

Trade-offs

Patroon Kosten Latentie Kwaliteit Complexiteit
Single Model Laagst Laagst Variabel Laagst
Sequentieel Midden Hoog Hoog Midden
Parallel Hoog Laag Hoog Midden
Hierarchisch Hoog Hoog Hoogst Hoog
Ensemble Hoogst Midden Hoogst Hoogst

Elk patroon maakt een trade-off. Kies degene die past bij je beperkingen.

Gerelateerd

Abonneren

Ontvang nieuwe berichten over systemen, infrastructuur en AI-engineering.