Sidecars
Was am anderen Ende eines Tools hängt: ein zustandsloser Dienst neben dem Agenten, der eine Fähigkeit anbietet und nach der Antwort nichts behält. Warum das ein eigener Container ist und nicht eine Funktion im Agenten-Prozess.
Basics
Für alle frei: das Konzept, die Analogie, das Warum.
Ein Agent bekommt Werkzeuge in den Loop, und ein MCP-Server macht sie auffindbar. Beides beantwortet dieselbe Frage nicht: Wer macht eigentlich die Arbeit? Wer parst das PDF, wer rendert das Video, wer transkribiert die Tonspur? Die Antwort heißt in fast allen ernsthaften Aufbauten gleich - ein Sidecar.
Wie viel an dieser Frage hängt, zeigt eine echte Sitzung. Im Session-Viewer liegt ein Beispiel bereit - Knopf „Beispiel-Session laden", die Ansicht steht Pro-Mitgliedern offen -, und die Wachstumskurve dort hat drei Stufen, neben denen alles andere klein aussieht: drei curl-Abrufe, von denen jeder ein komplettes HTML-Dokument in den Kontext kippt. Zusammen sind das 52 489 der 120 547 Zeichen des Verlaufs, 43,5 %. Die teuerste einzelne Nachricht hat 25 400 Zeichen und besteht aus drei vollständigen Fehlerseiten - dreimal „404: This page could not be found". Damit steht neben der Frage, wer die Arbeit tut, sofort die zweite: was davon kommt zurück?
Ein Sidecar ist ein Dienst mit einer Fähigkeit und ohne Gedächtnis
Ein Sidecar ist ein eigener Prozess - in der Praxis ein eigener Container - der neben dem Agenten läuft und genau eine Sache kann. Er nimmt eine Anfrage entgegen, tut die Arbeit, gibt das Ergebnis zurück und vergisst danach, dass es die Anfrage je gab.
Request rein, Ergebnis raus, kein Gedächtnis zwischen zwei Aufrufen.
Das ist die ganze Definition, und die letzte Hälfte ist der wichtige Teil. Zustandslos heißt: Der zweite Aufruf weiß nichts vom ersten. Es gibt keine Sitzung, kein Konto, keinen Fortschritt, der zwischen zwei Anfragen im Speicher hängen bleibt. Dieselbe Eingabe liefert dieselbe Ausgabe - heute, morgen und auf einem frisch gestarteten Container.
Diese eine Eigenschaft kauft dir alles, was danach kommt:
- Neustart ist folgenlos. Ein Dienst ohne Zustand kann jederzeit sterben; er kommt hoch und ist sofort wieder derselbe. Es gibt nichts zu migrieren und nichts wiederherzustellen.
- Skalieren ist trivial. Drei Instanzen desselben Sidecars sind austauschbar. Wer welche Anfrage bekommt, ist egal - es gibt keine „richtige" Instanz, die den Kontext hätte.
- Testen ist ehrlich. Ein
curlgegen den Endpunkt beweist dasselbe wie der Agent. Kein Aufwärmen, keine Vorbedingungen, kein „aber bei mir lief vorher noch das andere".
Die Abgrenzung: Memory hat Zustand, MCP ist das Protokoll
Zwei Nachbarn stehen so dicht daneben, dass sie regelmäßig verwechselt werden.
Gegen Memory (Schritt 7): Ein Memory-Dienst ist der Gegenentwurf - er hat absichtlich Zustand. Sein ganzer Zweck ist, dass der Aufruf von morgen etwas vom Aufruf von heute weiß. Deshalb hat er eine Datenbank, deshalb muss er gesichert, migriert und gelöscht werden können, deshalb ist er ein echtes zweites System mit eigenem Betrieb. Ein Sidecar hat davon nichts. Wenn du dabei bist, deinem Sidecar eine Datenbank zu geben, hast du entweder kein Sidecar mehr oder du hast das Problem falsch geschnitten.
Gegen MCP (Schritt 8): MCP ist die Steckdose, das Sidecar ist das Gerät. Ein MCP-Server beschreibt Werkzeuge und leitet Aufrufe weiter; er ist eine dünne Schicht, oft ein paar hundert Zeilen. Was hinter dem Werkzeug parse_pdf tatsächlich passiert, steht nicht im Protokoll. Beides zusammen ergibt erst ein Werkzeug: MCP macht die Fähigkeit auffindbar und aufrufbar, das Sidecar erbringt sie. Und die Zuordnung ist nicht eins zu eins - ein MCP-Server kann vor mehreren Sidecars stehen, und ein Sidecar kann von einem Agenten ohne jedes MCP direkt per HTTP aufgerufen werden.
| Memory (7) | MCP-Server (8) | Sidecar (9) | |
|---|---|---|---|
| Zustand | ja, das ist der Zweck | keiner (nur Weiterleitung) | keiner, ausdrücklich |
| Was es ist | ein Gedächtnis | ein Protokoll | eine Fähigkeit |
| Bei Neustart | muss überleben | egal | egal |
| Skaliert über | Datenbank | Instanzen | Instanzen |
Warum ein eigener Container und nicht einfach eine Funktion?
Die naheliegende Frage: Wenn das Ding sowieso zustandslos ist - warum nicht als Bibliothek in den Agenten-Prozess, import und fertig? Vier Gründe, und jeder allein reicht schon.
1. Fremde Laufzeit. Dein Agent ist in TypeScript geschrieben, die beste Dokument-Extraktion ist Python, die beste Transkription ist C++ mit CUDA. Ein Sidecar löst das, indem es die Sprachgrenze zur Netzwerkgrenze macht. Dieses Projekt hat genau diesen Fall zweimal: der Docling-Sidecar (infra/sidecars/docling) ist Python neben einer Next.js-Anwendung, und der Render-Sidecar (video/render-server.mjs) läuft auf node:22-bookworm-slim, weil die Chrome-Headless-Shell von Remotion an glibc hängt - der Rest des Stacks ist Alpine. Nicht „wäre schöner", sondern: läuft sonst nicht.
2. Fremde Systemabhängigkeiten. Ein Browser, eine GPU-Laufzeit, ffmpeg, Schriftarten, ein Modell mit zwei Gigabyte Gewichten. All das im Agenten-Image heißt: Jeder Deploy des Agenten zieht diese Last mit, jedes Sicherheits-Update betrifft beide, und das Image, das eigentlich 200 MB groß sein sollte, ist 3 GB groß.
3. Eigene Skalierung. Der Agent ist meist untätig und wartet auf Modell-Antworten. Der Render-Dienst frisst vier Kerne für zwölf Minuten. Getrennt kann man das eine dreimal und das andere gar nicht vervielfachen - oder, wie in diesem Projekt, den teuren Teil ganz auf eine andere Maschine schieben, damit der Webserver nicht unter einem Video zusammenbricht.
4. Eigener Absturz. Ein Speicherleck im PDF-Parser reißt den Prozess mit, in dem es läuft. Läuft es im Agenten, ist der Agent weg - mitsamt allen Gesprächen, die gerade offen sind. Läuft es im Sidecar, bekommt der Agent einen Fehler zurück und sagt „das Dokument konnte ich nicht lesen". Das ist der Unterschied zwischen einer Störung und einem Ausfall.
Was zurückkommt: Spezialisierung spart Kontext
Die vier Gründe oben begründen die Prozessgrenze. Sie sagen nichts darüber, was durch diese Grenze zurückläuft - und daran hängt im Betrieb der zweite Gewinn.
Zurück zur Beispiel-Sitzung. Der Agent dort hat kein Werkzeug für „lies mir diese Seite"; er hat ein Terminal und ruft damit curl auf. Was zurückkommt, ist alles, was der Server geschickt hat: Doctype, Meta-Tags, Stylesheet-Links, der vollständige RSC-Payload von Next.js - und irgendwo darin die eine Zeile, um die es ging. Zwei dieser Antworten bestehen ausschließlich aus Fehlerseiten und machen zusammen 33 151 Zeichen aus, gut ein Viertel des gesamten Verlaufs. Bezahlt wird das dreifach: einmal beim Abholen, einmal in jedem weiteren Modellaufruf, der den Verlauf erneut mitschickt, und einmal an Aufmerksamkeit - je mehr Füllmaterial im Fenster steht, desto schwerer findet das Modell darin das Wesentliche.
Ein Sidecar für Web-Zugriff dreht das um. Der Dienst holt die Seite, verarbeitet sie und gibt das Ergebnis zurück: den extrahierten Text, die drei Tabellenzeilen, den ausgelesenen Preis - oder eben nur „404". Das Rohmaterial bleibt dort, wo es verarbeitet wurde; der Kontext des Agenten sieht die 25 400 Zeichen nie. Das ist der praktische Sinn von „genau eine Sache können": Wer auf eine Fähigkeit spezialisiert ist, weiß auch, was an ihrem Ergebnis überhaupt interessant ist. Und die Ersparnis ist keine Kosmetik - sie entscheidet, ob der Agent nach zehn Abrufen noch weiß, wonach er eigentlich gesucht hat.
Die Gegenprobe, ehrlich benannt: Für sich allein begründet dieses Argument kein Sidecar. Eine Funktion im selben Prozess könnte genauso extrahieren und genauso wenig zurückgeben - Kontexteinsparung ist eine Frage der Arbeitsteilung, nicht der Prozessgrenze. Zum Sidecar wird die Sache erst, wenn zusätzlich einer der vier Gründe oben zutrifft. Beim Web-Zugriff ist das keine hypothetische Bedingung.
Der Fall, an dem alle vier Gründe zusammenfallen: Web-Browsing
Es gibt einen Sidecar, bei dem nicht einer der vier Gründe zutrifft, sondern alle vier gleichzeitig - und er ist deshalb das durchgehende Fallbeispiel dieses Bauteils: ein Agent, der im Web nicht nur lesen, sondern handeln soll. Klicken, tippen, ein Formular ausfüllen, sich durch eine mehrseitige Strecke arbeiten.
Dafür braucht es einen echten Browser, und damit alles auf einmal: eine fremde Laufzeit (ein Chromium samt Systemschriften, rund ein Gigabyte Image), fremde Systemabhängigkeiten, eigene Skalierung (jede offene Sitzung belegt 300-500 MB Arbeitsspeicher, während der Agent daneben nur wartet) und eigenen Absturz (eine Seite, die den Browser hängen lässt, darf nicht das Gespräch mitnehmen).
Dazu kommt etwas, das keine der anderen Fähigkeiten verlangt: Der Dienst braucht ein eigenes Modell neben deinem, weil „klick dich zur Rechnung durch" innen selbst wieder eine Schleife aus Ansehen, Entscheiden und Klicken ist. Damit ist Browsing der schwerste Sidecar überhaupt - und der Fall, an dem sich jede Abwägung zeigt, die man bei den einfachen Familien überspringen darf. Wer die Schleife betreibt und was das kostet, steht in der nächsten Stufe; Rückfragen, Sicherheitsfläche und die Frage, wie man einem fremden Paket überhaupt ansieht, wohin es Daten schickt, im Deep-Dive.
Der Preis, ehrlich benannt
Ein Sidecar ist nicht umsonst. Du handelst dir ein: einen weiteren Container im Compose-File, eine Netzwerkgrenze mit Latenz, eine Serialisierung der Daten in beide Richtungen, einen weiteren Dienst, der beim Deploy gestartet werden muss, und eine zweite Stelle, an der Fehler auftreten können, ohne dass ein Stacktrace beides verbindet.
Deshalb die Faustregel: Ein Sidecar lohnt sich, sobald einer der vier Gründe oben zutrifft - und vorher nicht. Eine Funktion, die Markdown in HTML wandelt, bleibt eine Funktion. Eine Funktion, die dafür einen Browser starten müsste, wird ein Sidecar.
Ein Sidecar ist ein zustandsloser Dienst neben dem Agenten, der genau eine Fähigkeit anbietet: Request rein, Ergebnis raus, kein Gedächtnis zwischen zwei Aufrufen.
Genau dadurch grenzt er sich von seinen Nachbarn ab: Memory hat absichtlich Zustand, MCP ist nur das Protokoll davor. Das Sidecar ist das Gerät hinter der Steckdose.
Ein eigener Container statt einer Funktion lohnt sich, wenn mindestens einer der vier Gründe zutrifft: fremde Laufzeit, fremde Systemabhängigkeiten, eigene Skalierung, eigener Absturz. Trifft keiner zu, schreib eine Funktion.
Vertiefung
Mit kostenlosem Konto: Experimente, Quizze und die Vertiefung.
Anmelden, um diesen Inhalt zu sehen
Dieser Bereich ist Mitgliedern vorbehalten. Logge dich ein, um weiterzulesen.
Jetzt anmeldenDeep-Dive
Für Pro-Mitglieder: die Tiefe für alle, die es wirklich bauen wollen.
Anmelden, um diesen Inhalt zu sehen
Dieser Bereich ist Mitgliedern vorbehalten. Logge dich ein, um weiterzulesen.
Jetzt anmelden