Ein Weg, ein Werkzeug anzuschließen
Als wir zum vierten Mal einen Adapter bauten, damit ein Modell ein Auftragssystem abfragen kann, dauerte es zwei Tage und sah genauso aus wie die drei davor. Das ist kein schweres Problem, sondern eine fehlende Konvention — und dieser Unterschied zählt, wenn man entscheidet, was man behebt.
Dieselben zwei Tage, viermal
Jedes Projekt brauchte dasselbe: einem Modell eine Handvoll Operationen beschreiben, seine Aufrufe annehmen, die Argumente prüfen, ausführen und Ergebnisse in nutzbarer Form zurückgeben. Jedes Mal haben wir das gegen das Framework des jeweiligen Projekts geschrieben, und jede Umsetzung war auf Weisen leicht anders, die niemand gewählt hatte.
Nichts davon war schwierige Arbeit. Es war Arbeit ohne Alleinstellung — und Arbeit ohne Alleinstellung, die immer wieder neu geschrieben wird, ist der Ort, an dem sich Uneinheitlichkeit sammelt: vier leicht verschiedene Fehlerformate, vier Vorstellungen davon, was eine Zeitüberschreitung bedeutet, vier Stellen für dieselbe Korrektur.
Was eine Konvention einbringt
Das Model Context Protocol gibt Werkzeugen eine beschriebene Oberfläche, die ein Modellclient entdecken und aufrufen kann, ohne einen eigens gebauten Adapter. Szeider veröffentlichte um den Jahreswechsel MCP-Solver und stellt ein System der Constraint-Programmierung über das Protokoll bereit, sodass ein Modell einen Solver als Werkzeug nutzen kann.
Genau dieses Beispiel hat uns überzeugt, denn es ist keine Hülle um eine API. Es ist eine deterministische Maschinerie, bereitgestellt als Fähigkeit — genau die Gestalt, auf die es uns ankommt: Das Modell entscheidet, was gefragt wird, und etwas, das kein Modell ist, berechnet die Antwort.
Was wir vereinheitlicht haben
Den Transport, die Beschreibung jedes Werkzeugs, die Gestalt der Fehler und die Rückgabe der Ergebnisse. Das sind die Teile, in denen Abweichung uns nichts einbrachte, und ihre Vereinheitlichung machte aus einem Zwei-Tage-Adapter einen Nachmittag, an dem wir bereits vorhandene Operationen beschreiben.
Wir haben außerdem vereinheitlicht, was ein Werkzeug angeben muss: ob es liest oder schreibt, ob es idempotent ist und welchen Rechteumfang seine Zugangsdaten tragen. Diese drei Angaben steuern unsere Freigaberegeln, und sie in der Werkzeugbeschreibung statt in einem Kommentar zu haben ist der Hauptgrund, warum sich die Regeln erzwingen statt erinnern lassen.
| Vereinheitlicht | Dem Projekt überlassen |
|---|---|
| Transport und Werkzeugbeschreibung | Welche Werkzeuge es überhaupt gibt |
| Fehlergestalt und Ergebnisformat | Was jedes Werkzeug tun darf |
| Lesend oder schreibend, Idempotenz | Freigabepolitik für Schreibvorgänge |
| Angabe des Rechteumfangs | Die Zugangsdaten selbst |
Die Arbeit, die blieb
Zu entscheiden, was ein Werkzeug anbieten soll — der Teil, der immer die eigentliche Arbeit war und von Klempnerei verdrängt wurde. Ein Werkzeug, das Aufträge nach beliebigen Feldern durchsucht, ist leicht zu bauen und schwer zu begrenzen; eines, das Auftrag nach Nummer finden und Aufträge dieses Kunden auflisten anbietet, ist enger und beantwortet die Frage, was das Modell erreichen kann.
Wir entwerfen Werkzeuge heute wie eine API für einen nicht vertrauenswürdigen Client, denn genau das ist ein Modell. Weniger Operationen, engere Parameter und keine Operation, deren Wirkungsradius davon abhängt, dass der Aufrufer ein Argument richtig setzt.
Die Sicherheitseigenschaft
Eine gemeinsame Schnittstelle macht es möglich, eine Regel an einer Stelle zu formulieren: Dieser Client darf diese Werkzeuge mit diesem Rechteumfang aufrufen. Das ist ein echter Fortschritt gegenüber vier Adaptern mit jeweils eigenen Absprachen — und zugleich das, was am ehesten misslingt, weil eine bequeme Voreinstellung darin besteht, einem Server die Vereinigung dessen zu geben, was irgendeines seiner Werkzeuge braucht.
Unsere Server sind deshalb nach Rechteumfang getrennt statt nach Thema. Die lesenden Auftragswerkzeuge und die schreibenden sind getrennte Server mit getrennten Zugangsdaten. Das sind mehr Prozesse im Betrieb — und es beseitigt den Fall, dass ein lesender Assistent nur einen Konfigurationsfehler vom Schreiben entfernt ist.
Was wir nicht übernommen haben
Dynamische Entdeckung im Betrieb. Das Protokoll erlaubt einem Client, zur Laufzeit zu ermitteln, welche Werkzeuge ein Server anbietet. Das ist in der Entwicklung nützlich und nicht, wie wir ausliefern: Die Werkzeugliste eines betriebenen Systems steht fest in der Konfiguration und wird geprüft — denn über ein System, dessen Fähigkeiten sich ohne Deployment ändern können, lässt sich nicht urteilen.
Wir haben auch nicht alles darüber geleitet. Schritte, die eine feste API mit festen Argumenten aufrufen, brauchen überhaupt keine Werkzeugschnittstelle, und eine hinzuzufügen macht aus einem direkten Aufruf einen indirekten ohne Gewinn.
Was es tatsächlich gespart hat
Die fünfte Integration kostete etwa einen halben Tag. Das ist die sichtbare Ersparnis und nicht die wichtige; wichtig ist, dass ein Fehler in der Argumentprüfung heute einmal behoben wird und dass ein neuer Kollege eine Beschreibung liest, wie Werkzeuge funktionieren, statt vier.
Dem steht gegenüber, dass wir eine Abhängigkeit von einer Spezifikation eingegangen sind, die wir nicht kontrollieren und die sich damals schnell bewegte. Wir legen Versionen fest und mussten zweimal nachziehen — ein Preis, den wir zu zahlen bereit waren und den wir jedem, der denselben Schritt erwägt, klar nennen würden.
Was wir nicht behaupten
Wir behaupten nicht, eine Standardschnittstelle mache ein System sicherer. Sie macht eine Richtlinie an einer Stelle ausdrückbar, und eine ausdrückbare Richtlinie, die niemand setzt, ist genauso freizügig wie vier improvisierte. Die Sicherheit kam aus der Trennung der Server nach Rechteumfang — was das Protokoll erlaubt, aber nicht liefert.
Wir behaupten auch nicht, die Sache sei entschieden. Das Ökosystem war jung, als wir es übernommen haben, und eine Konvention ist nur so lange etwas wert, wie genug andere ihr folgen. Das ist eine Wette und kein technisches Urteil.
