„Füg einen Cloud-Fallback hinzu“ klingt nach einem Konfigurations-Flag. Für ein Retrieval-System ist es eher ein Datenintegritätsproblem, das sich als Konfigurations-Flag tarnt.
Textgenerierung ist zustandslos — ist ein Provider langsam, nimmt man einen anderen, und hinterher merkt es niemand. Embedding ist das nicht. Embedding schreibt in eine Tabelle, die du monatelang abfragen wirst, und eine Abfrage ist nur dann sinnvoll, wenn der Encoder, der die Abfrage eingebettet hat, mit dem Encoder übereinstimmt, der die Zeilen eingebettet hat.
Die Cloud-Integration des Fantom MCP Servers besteht größtenteils aus der Maschinerie, die nötig ist, um genau das sicher zu machen.
Fünf Rollen, getrennt geroutet
Es gibt keinen einzelnen „Cloud verwenden“-Schalter, denn die fünf Inferenzrollen haben tatsächlich unterschiedliche Anforderungen. Jede wird nach ihrer eigenen Policy geroutet:
Die vier Policies:
| Policy | Verhalten |
|---|---|
local |
Nur lokale GPU und Sidecar-Hosts. Nichts verlässt das Netzwerk. |
cloud |
Nur OpenRouter. Überhaupt keine GPU erforderlich. |
aggregate |
Beides, in einem gemeinsamen Fan-out-Pool, aus derselben Queue ziehend. (Standard) |
backup |
Lokal zuerst, Cloud in Reserve gehalten. |
aggregate ist der Standard, weil es diejenige Policy ist, die Hardware nutzt, für die du bereits bezahlt hast, und trotzdem eine Lastspitze abfängt.
Das Gate, das das sicher macht
Unter aggregate landen lokale und Cloud-Vektoren in derselben Tabelle, verschachtelt, während desselben Laufs. Wenn die beiden Serving-Stacks keine austauschbaren Vektoren erzeugen, ist die Kosinus-Distanz nicht mehr vergleichbar und das Retrieval verschlechtert sich unbemerkt — ohne jede Möglichkeit zu erkennen, welche Zeilen woher stammen.
Kompatibilität ist deshalb keine Warnung. Sie ist eine harte Vorbedingung: ein Provider, der den Test nicht bestanden hat, darf niemals auch nur einen einzigen Text bedienen.
Die Prüfung ist bewusst grobschlächtig: dieselben Probetexte über beide Routen einbetten, für jedes zugehörige Paar die paarweise Kosinus-Ähnlichkeit bilden, verlangen, dass das Minimum 0,99 überschreitet, und verlangen, dass die zurückgegebene Dimension exakt der konfigurierten Breite entspricht.
Die interessante Zahl ist die, die durchgefallen ist. Der gemessene Kosinus zwischen dem lokalen Modell und dem Cloud-Modell liegt bei 0,976 — nah genug, um in einer Stichprobe in Ordnung auszusehen, bequem unter der Grenze, und genau der Grund, warum es die cloud-Policy gibt. Diese beiden Encoder sind nicht austauschbar; wenn du also den Cloud-Encoder verwenden willst, muss der gesamte Index daraus aufgebaut werden. Das ist kein Workaround, das ist die Policy, die ihre Arbeit tut.
Das heißt, die Referenz ist nicht immer lokal. Unter den drei Policies, bei denen GPUs bedienen, muss die Referenz lokal sein, denn die Übereinstimmung mit den bereits in der Tabelle vorhandenen Zeilen ist genau die Eigenschaft, die geprüft wird. Unter cloud wäre ein Vergleich gegen ein lokales Modell bedeutungslos — es wird nie ein lokaler Vektor geschrieben —, also wird ein anderer Cloud-Provider zur Referenz, und das Gate bleibt ansonsten unverändert. Abgeschaltet wird es nie.
Die Einschränkung, benannt statt versteckt
Wenn es genau einen Cloud-Provider gibt, existiert kein Gegenüber, und providerübergreifende Konsistenz ist inhaltsleer: ein Provider kann sich nicht mit sich selbst uneins sein, und er allein schreibt jede Zeile. Das Gate prüft dann Dimension und Upstream-Pin, sonst nichts.
Das ist eine echte Einbuße an Abdeckung. Ein einzelner gepinnter Upstream kann seinen Serving-Stack hinter demselben Pin mit der Zeit trotzdem ändern — ein Host, der eine andere Quantisierung desselben Model-Slugs ausrollt — und unter einem Cloud-Regime mit nur einem Provider fängt das nichts ab. Gut zu wissen, wenn du diese Konfiguration betreibst.
Warum Embedding gepinnt wird und Reranking nicht
Zwei OpenRouter-Upstreams, die denselben Model-Slug bedienen, garantieren keine identischen Vektoren. Eine ungepinnte Embedding-Route kann daher einen Vektorraum zwischen Anfragen aufspalten — dieselbe Korruption, nur auf leiserem Weg. Deshalb muss jede Embedding-Route ihren Upstream-Provider benennen, und das System schlägt fehl (fail closed), wenn sie es nicht tut.
Reranking ist zustandslos — es bewertet eine Kandidatenliste und schreibt nichts — und braucht deshalb keinen Pin.
Ein Budget, oberhalb aller Provider gehalten
Hier ist die Falle, die den gesamten Cloud-Pfad prägt: OpenRouter limitiert pro Key, nicht pro Aufrufer.
Jeder Sidecar bekommt denselben Key. Drei Provider mit je acht gleichzeitigen Anfragen sind vierundzwanzig Anfragen gegen ein gemeinsames Budget. Eine Obergrenze pro Provider kann das Limit nicht schützen — die Grenze muss oberhalb aller Provider sitzen.
Ein paar Details darin lohnt es sich hervorzuheben.
Die Permit-Einheit ist Nebenläufigkeit, nicht Anfragen pro Minute. Ein ermitteltes rate_limit ist ein RPM-Wert und wird deshalb über die selbst gemessene Round-Trip-Latenz des Pools umgerechnet — Little's Law —, was bedeutet, dass es sich bei Latenzdrift selbst neu ableitet, statt auf einem Wert aus der Startzeit festzuhängen.
Ein als glaubwürdig geltender RPM-Wert wird zusätzlich direkt durchgesetzt, als Sliding-Window-Gate, damit eine kurzzeitig zu hohe Latenzschätzung das Konto nicht überfährt. Aber dieses zweite Gate ist nur für einen RPM-Wert scharf geschaltet, dem überhaupt jemand traut. Ein gedecktes Konto, dessen Key ein degeneriertes Rate-Limit meldet — oder gar keines, was die moderne Variante ist —, wird stattdessen anhand seines Guthabens dimensioniert und bekommt kein Window-Gate. Es auf ein rudimentäres „1 pro Minute“ scharf zu schalten war schlicht schlechter: es hielt den gesamten Cloud-Fan-out auf einer Anfrage pro Minute.
Der Backoff ist adaptiv, nie ein sofortiger Retry. Ein 429 halbiert das effektive Budget und startet einen mit Jitter versehenen Cooldown; ein anhaltend sauberes Zeitfenster führt es Permit für Permit wieder in Richtung Obergrenze.
Die Defaults sind bewusst zaghaft. Vier Permits, wenn nichts ermittelt werden konnte, denn Spielraum anzunehmen, den man nicht auslesen konnte, ist der Weg zu einem 429-Sturm und einer halb geschriebenen Tabelle. Und eine harte Obergrenze von 256, weil ein Tippfehler in einem Override-Feld das Konto nicht auslasten sollte.
Lokale GPUs sind vollständig ausgenommen. Arbeit wird pro Provider gezogen, ein blockierter Cloud-Provider hört also einfach auf zu ziehen, während die lokalen weiterlaufen. Ein Cloud-Rate-Limit bremst die Cloud; es legt deine Hardware nicht lahm.
Umgang mit dem Key
Der OpenRouter-Key ist aus Sicht des Fantom MCP Servers write-only. Er kommt mit einer Admin-Anfrage an, geht direkt über den WebSocket-Frame an den Sidecar, der ihn verwenden wird, und wird nie in die Konfiguration geschrieben, nie geloggt, von keinem Endpunkt zurückgegeben und nie über den Aufruf hinaus gehalten.
Persistiert wird nur, was sicher persistierbar ist: welchen Rollen ein Modell zugeordnet ist, welcher Upstream gepinnt ist, die Routing-Modi und die Tatsache, dass ein Push stattgefunden hat. Ein erneuter Push ohne Key ist der Normalfall, wenn man einen Modus oder ein Modell ändert — der Sidecar führt einen partiellen Push mit dem Eintrag zusammen, den er bereits hält.
Was standardmäßig wo läuft
- Reranker —
qwen/qwen3-reranker-8b - Code-Assistent —
poolside/laguna-s-2.1 - RLM-Sandbox —
deepseek/deepseek-v4-flash, mit einem Fallback-Modus „nur lokal“
Embedding-Modelle werden pro Deployment gewählt, denn genau diese Wahl bestimmt, was dein Index ist. Die Code-Vektortabelle ist ein einziger Raum mit 2560 Dimensionen; alles oben Beschriebene existiert, um das so zu halten.
Worum es geht
Nichts davon macht die Cloud schneller. Was es einbringt, ist die Möglichkeit, etwas Konkretes zu sagen: dass jede Zeile im Index von einem Encoder geschrieben wurde, der nachweislich austauschbar mit dem ist, der deine Abfrage einbetten wird, dass kein einzelnes Projekt das Konto auffressen kann, und dass die GPUs weiterarbeiten, wenn die Cloud drosselt.
„Füg einen Cloud-Fallback hinzu“ ist wirklich ein Konfigurations-Flag. Alles in diesem Beitrag ist das, was darunter wahr sein muss, bevor sich dieses Flag gefahrlos umlegen lässt.
Der Fantom MCP Server ist source-available unter github.com/Project-SandStar/FantomMcpServer. Frühere Beiträge: die Sidecar-Flotte und das RLM · sprachübergreifende Code-Intelligenz.