Kategorie: Erklärer

  • Sechs Hebel für bessere KI-Agenten: Wie das NOOA-Framework die Leistung von Modellen vervielfacht

    Sechs Hebel für bessere KI-Agenten: Wie das NOOA-Framework die Leistung von Modellen vervielfacht

    Du kaufst ein Auto mit 600 PS, aber die Karosserie ist aus Pappe, die Lenkung schwammig und die Bremsen sind Spielzeug. Damit gewinnst du kein Rennen. So ist es auch mit KI-Agenten. Viele konzentrieren sich nur auf das Modell – GPT, Claude oder Llama – und vergessen, dass die Umgebung, in der das Modell agiert, ebenso wichtig ist. Dieses Grundgerüst nennen Fachleute den Harness. Ein Forscherteam von NVIDIA zeigt: Allein die Architektur dieses Harness kann ein Modell doppelt so gut abschneiden lassen – bei halbem Token-Verbrauch. Das klingt übertrieben. Aber schauen wir uns die Details an.

    Das Team um NVIDIA Labs hat NOOA veröffentlicht – NVIDIA Object-Oriented Agents. Die Idee ist einfach, aber mächtig: Ein Agent ist kein komplexes Geflecht aus Prompt-Vorlagen, Tool-Schemas, Callback-Code und Workflow-Graphen mehr. Stattdessen wird er zu einem einzigen Python-Objekt. Seine Methoden sind seine Fähigkeiten, seine Felder sein Zustand, seine Docstrings seine Prompts, und seine Typannotationen durchgesetzte Verträge. Du schreibst eine Klasse mit einer Methode, die nur aus ... (Ellipsis) besteht. Diese Methode wird zur Laufzeit von einem LLM-gesteuerten Loop ausgefüllt. Methoden mit einem normalen Rumpf laufen deterministisch. Das bedeutet: Agentenentwicklung wird zu normaler Softwareentwicklung. Du kannst einen Agenten differenzieren, code-reviewen, unit-testen, versionieren und umgestalten – von Menschen und von KI-Coding-Agenten, mit denselben Werkzeugen wie für jeden anderen Code.

    Sechs konkrete Schnittstellen-Ideen treiben das NOOA-Harness an. Sie sind wie die Zylinder eines Motors – jeder trägt zur Gesamtleistung bei. Gehen wir sie durch.

    1. Typisierte Ein- und Ausgabe. Statt Freitext zu produzieren und auf einen korrekten Parser zu hoffen, werden alle Aufrufe mit getypten Argumenten und validierten Rückgabewerten ausgeführt. Fehler werden früh abgefangen.

    2. Referenzübergabe (Pass by Reference). Bisher wurde jedes Tool-Ergebnis als Text in den Kontext geschrieben – bei großen Dateien explodiert der Token-Verbrauch. NOOA übergibt dem Modell einen Live-Verweis auf das Python-Objekt. Das Modell sieht eine typisierte, begrenzte Vorschau, der volle Wert bleibt im Ausführungskontext lebendig. Das spart Tokens und beschleunigt die Verarbeitung.

    3. Code als Aktion. Das Modell handelt, indem es Python schreibt: Methodenaufrufe, Kontrollstrukturen, Variablen – wie ein Entwickler. Keine brüchigen JSON-Schemas, sondern ausführbarer Code in derselben Umgebung wie der Agent.

    4. Programmierbare Schleifensteuerung. Die Orchestrierungsschleifen sind normales Python. Der Entwickler kann sie schreiben, aber auch das Modell selbst kann sie anpassen. Das gibt Flexibilität wie bei menschlichen Programmierern.

    5. Expliziter Objektzustand. Der Zustand eines Agenten lebt nicht nur im Gesprächsverlauf, sondern in dauerhaften, getypten Feldern auf dem Objekt. Der Agent kann sich Dinge merken, auch wenn der Kontext abgeschnitten ist. Dieser Zustand ist versionierbar und testbar.

    6. Vom Modell aufrufbare Harness-APIs. Kontextblöcke und Ereignishistorien sind nicht verborgen. Das Modell kann sie über API-Aufrufe inspizieren und verwalten. Es kann seine eigene Erinnerung kuratieren – gezielt schreiben, abfragen und korrigieren. Statt einer undurchsichtigen Blackbox gibt es einen transparenten, steuerbaren Speicher.

    Dieser Speicher ist ein weiteres Kernstück von NOOA. Statt automatischer Hintergrund-Zusammenfassung gibt es einen Langzeitspeicher, den der Agent selbst verwaltet. Aufzeichnungen tragen Typen, Wichtigkeit und Tags. Sie sind über Beziehungen wie „unterstützt“, „widerspricht“ und „abgeleitet von“ in einem Wissensgraphen vernetzt. Eine Hintergrund-Reflexion konsolidiert den Speicher: Duplikate werden zusammengeführt, verwandte Aufzeichnungen verknüpft, Episoden zu Erkenntnissen destilliert und irrelevante Informationen entfernt. Das alles passiert in einer menschenlesbaren SQLite-Datei, die Teams inspizieren, sichern und mit Standardpraktiken überprüfen können. Mehrere Agenten können sich einen Speicher teilen, während sie getrennte Besitzverhältnisse behalten. In der ARC-AGI-3-Auswertung verbesserte das System die RHAE um +11,8 Punkte gegenüber dem gleichen Agenten mit dateibasierten Notizen.

    Die Ergebnisse: Auf SWE-bench Verified erreicht NOOA mit GPT-5.5 82,2% – über dem bisherigen Spitzenwert von 79,2%. Mit Opus 4.6 sind es 79,8%. Und das mit einem allgemeinen, 253-zeiligen Agenten ohne benchmarkspezifische Prompts. Im Cybersicherheitsbereich CyberGym L1 löst NOOA 86,8% der Aufgaben mit GPT-5.5 – der Spitzenwert unter offenen Agenten, noch vor den meisten führenden geschlossenen Systemen. Der Agent hatte keinen Netzwerkzugriff, und eine regelbasierte „Cheat-Prüfung“ lief über jede Trajektorie. Die Ergebnisse stammen aus logischem Denken über den Code, nicht aus dem Nachschlagen bekannter Schwachstellen. Keine cybersicherheitsspezifische Steuerung wurde verwendet. Bei allgemeinem logischem Denken auf ARC-AGI-3 erreicht ein einzelner NOOA-Agent 50,2% mittlere RHAE mit GPT-5.5 und 85,1% mit GPT-5.6-sol – zu Kosten unter 20 Dollar pro Spiel.

    Die Effizienz ist bemerkenswert. NOOA benötigt auf SWE-bench Verified nur 29 LLM-Aufrufe und etwa 1,1 Millionen Tokens pro Aufgabe. Vergleichbare Harnesses kommen auf 66 Aufrufe und 2,2 Millionen Tokens bei niedrigerer Genauigkeit. Das halbiert die Kosten bei gleicher oder besserer Leistung. Zwei Mechanismen treiben das: die Referenzübergabe (Tool-Ergebnisse werden nicht in den Kontext serialisiert) und die daraus resultierende Vermeidung von Context Compaction. Weil die Ergebnisse live bleiben, sind Transkripte append-only und Cache-tauglich über die gesamte Sitzung.

    Stell dir vor, du musst ein kniffliges Problem lösen. Statt jedes Mal das gesamte Handbuch neu zu lesen, hast du einen Assistenten, der dir nur die relevanten Seiten zeigt und dir erlaubt, direkt mit den Werkzeugen zu arbeiten. Genau das macht NOOA. Der Entwickler kann deterministische Prüfungen und Modelllogik auf einem einzigen getypten Objekt vereinen – jeder Verifikationsschritt läuft als erzwungener Code, nicht als lose Anweisung.

    Das Team hat NOOA als offene Forschungsvorschau veröffentlicht. Framework, Tests, Benchmark-Agent und Evaluierungsmethodik sind öffentlich. Teams können den Ansatz überprüfen und darauf aufbauen. Die Botschaft: Der Harness eines Agenten ist kein nachrangiges Detail. Er ist der entscheidende Hebel, um aus einem guten Modell einen herausragenden Agenten zu machen. Alles, was du dafür brauchst, ist Python, etwas Objektorientierung und die Bereitschaft, über das reine Modell-Tuning hinauszuschauen.

    Quelle: developer.nvidia.com

  • Warum TanStack RSC fallen ließ – und was das für dein nächstes Projekt bedeutet

    Warum TanStack RSC fallen ließ – und was das für dein nächstes Projekt bedeutet

    Man kauft keinen teuren Kühlschrank nur für Milch. Der Kühlschrank funktioniert, aber nach ein paar Monaten merkt man: Die Milch bleibt auch in einer Kühlbox frisch. Genau das ist dem TanStack-Team mit React Server Components (RSC) passiert. Sie kehrten zu klassischem Server-Side Rendering (SSR) zurück.

    Tanner Linsley, Kopf hinter TanStack, beschrieb den Wechsel auf dem offiziellen Blog. Eine pragmatische Entscheidung, basierend auf harten Daten, nicht auf Hype. Sie wirft eine Frage auf: Wann ist ein neues Werkzeug die richtige Wahl – und wann wird es zum Hindernis?

    Der Anfang: RSC als Retter

    Vor Monaten war tanstack.com ein RSC-Paradebeispiel. Die Seite war content-lastig – Blogposts, Docs, Codebeispiele. Problem: Jeder Seitenaufruf lud ein schweres Markdown- und Syntax-Highlighting-Paket in den Browser. Rund 1,1 MiB JavaScript pro Docs-Seite, davon 358 KiB für Shiki und Begleiter. Eine unnötige Last für den Browser.

    RSC schien die Lösung. Statt den schweren Renderer zum Client zu schicken, rendert man Markdown und Highlighting auf dem Server, schickt fertiges HTML (Flight-Payload). Der Browser hat weniger Arbeit. Die Performance-Sprünge waren beeindruckend: Total Blocking Time fiel von 1.200 ms auf 260 ms, Transfergröße von 1.101 KiB auf 785 KiB. Lighthouse-Scores gingen hoch. RSC hielt sein Versprechen.

    Die unerwartete Einsicht

    Im Alltag zeigte sich die Komplexität. Linsley beschreibt, wie die Content-Pipeline immer mehr Schichten bekam: Markdown wurde zu JSX in server-only Dateien, JSX zu Flight-Payload, Route-Komponenten empfingen contentRsc – ein fast unkenntlicher Wert. Jede Änderung erforderte Wissen über Runtime-Grenzen, Bundler-Konfiguration, spezielle Dateien. Nicht unmöglich, aber unnötig aufwendig.

    Der entscheidende Moment: Das Team entfernte Drittanbieter-Anzeigen von der Seite. Plötzlich war der größte Übeltäter nicht das Ad-Tracking, sondern der Content selbst. Die Frage: Brauchen wir wirklich 358 KiB für Syntax-Highlighting? Oder geht es einfacher?

    Der Bau eines schlankeren Werkzeugs

    Das Team entwickelte zwei eigene Pakete: @tanstack/markdown und @tanstack/highlight. Klein, spezifisch, auf die Anforderungen von tanstack.com zugeschnitten. Kein Generalistenwerkzeug, sondern Spezialwerkzeuge. Ergebnis: Statt 358 KiB wanderten nur noch etwa 27 KiB zum Client – kein Grund mehr für eine ganze RSC-Architektur.

    Der Trade-Off wurde klar: RSC löste ein Abhängigkeitsproblem durch Architektur. Nachdem die Abhängigkeit schrumpfte, blieb die Architektur mit ihren Kosten: spezielle Routen, Flight-Serialisierung, Server-only-Komponenten, verzwickter Context.

    Zurück zu SSR – und die Ergebnisse

    Das Team entfernte die RSC-Content-Pipeline. Der Migrations-Commit 92b1c481 löschte oder benannte neun Dateien für RSC-spezifische Content-Rohre um, plus acht alte Rendering-Plugins. Insgesamt 555 Zeilen RSC-Code und 994 Zeilen alte Renderer flogen raus. Der Content-Pfad wurde einfach: Serverfunktionen geben Content-Daten zurück, eine Markdown-Komponente rendert lokal.

    Die Performance auf den wichtigsten Routen:

    • /blog/react-server-components: RSC: 76 Lighthouse, 139 ms TBT, 1.086 KiB / SSR: 67 Lighthouse, 66 ms TBT, 889 KiB
    • /router/latest/docs/overview: RSC: 71 Lighthouse, 209 ms TBT, 1.017 KiB / SSR: 71 Lighthouse, 115 ms TBT, 836 KiB

    Der Lighthouse-Score beim Blog ist etwas niedriger, aber Bytes und TBT sind besser. Der Renderer wiegt jetzt etwa 27 KiB – ein Bruchteil des alten Shiki-Stacks. Der Vorteil zeigt sich bei wiederholten Seitenaufrufen.

    Warum sechs Seiten den Unterschied machen

    Beim ersten Aufruf lädt SSR den Renderer einmal. Danach nur noch reine Daten (Markdown, Quelldaten) – nicht den gerenderten Komponentenbaum. RSC hingegen schickt bei jeder Navigation erneut ein serialisiertes Flight-Payload mit dem gesamten Server-Teil.

    Lokale Tests: Für einen Blogpost sparte SSR 5,6 KiB pro Anfrage gegenüber RSC. Bei sechs Seiten pro Session (Durchschnitt auf tanstack.com) multipliziert sich das. Einmal 27 KiB für den Renderer zahlen, dann jedes Mal sparen – eine lohnende Wette. RSC verwandelte eine einmalige Client-Abhängigkeit in wiederkehrende serialisierte Ausgabe. Sinnvoll bei großer Abhängigkeit, nicht nach Verkleinerung.

    Die Lektion: Wann ist RSC wirklich die richtige Wahl?

    Linsley selbst sagt: RSC löst ein Problem, wenn die Server-Abhängigkeit riesig ist. Ein schwerer Markdown-Renderer, eine große Grafikbibliothek, ein komplexer Parser. Sobald die Abhängigkeit verkleinert ist, entfällt die Rechtfertigung für die Komplexität.

    Erkenntnis: Tool-Entscheidungen basieren auf Messungen, nicht auf Trends. RSC ist kein Selbstzweck. Die TanStack-Geschichte zeigt: Nach dem ersten Erfolg lohnt es sich zu fragen: War das nötig? Wie sieht der Preis im Alltag aus?

    Für viele Projekte ist RSC perfekt. Für content-lastige Seiten mit kontrollierten Abhängigkeiten ist klassisches SSR mit eigenen Paketen oft einfacher und schneller. Devise: Verstehe dein Problem, miss deine Lösung, und tausche den Kühlschrank gegen eine Kühlbox.

    Quelle: tanstack.com

  • KI-Integration: Warum dein Team keine neuen SDKs für jedes Modell braucht

    KI-Integration: Warum dein Team keine neuen SDKs für jedes Modell braucht

    Ein Team arbeitet monatelang an einer KI-Anwendung. Sie läuft stabil. Dann kommt ein neues Modell – schneller, billiger, besser im Reasoning. Das Product-Team will es sofort testen. Von außen scheint es ein simpler Austausch: Modellnamen ändern, Evaluierungen laufen lassen. Aus Plattform-Perspektive ist das selten so einfach. Das neue Modell kommt über einen Provider, den die Anwendung nicht unterstützt. Dann wartet ein weiteres SDK, andere Authentifizierung, abweichendes Anfrageformat, neues Fehlermodell, eigene Umgebungsvariablen und provider-spezifisches Verhalten. Die Herausforderung ist nicht der Zugang zu mehr Modellen, sondern dass jedes neue Modell zum eigenen Infrastrukturprojekt werden kann.

    Der Autor eines aktuellen Blogbeitrags beschreibt dieses Dilemma präzise. Er argumentiert, dass Teams, die ihre Anwendung direkt mit einem LLM-Provider verbinden, sich auf mehr verlassen als nur auf das Modell: SDK, Credentials, Request/Response-Schemata, Streaming, Tool-Aufrufe, Rate-Limits, Retry-Logiken, Modell-IDs und Nutzungsdaten. Sobald provider-spezifische Logik im Code ist, infiziert sie Secrets-Management, Observability, Testing, Deployment-Pipelines und Incident-Response. Mit zwei Providern ist das beherrschbar. Doch mit neuen Anbietern, deprecated Modellen, API-Änderungen und verschiedenen Workloads wird es unübersichtlich. Das Team wartet keine KI-Anwendung mehr – es pflegt eine interne Provider-Kompatibilitätsschicht.

    Diese Situation ist nicht neu. Softwareteams kennen das Problem aus der Zeit vor reproduzierbaren Paketmanagement- und containerisierten Umgebungen. Damals brachen Anwendungen wegen inkompatibler Bibliotheken, Laufzeiten und Betriebssysteme. Ein Update einer Abhängigkeit konnte eine andere Komponente zerstören. Deployments in verschiedene Umgebungen führten zu unterschiedlichen Ergebnissen. Wir nannten das „Dependency Hell“. Die Herausforderung lag nicht in Abhängigkeiten an sich, sondern in der engen Kopplung von Code an Systeme, die sich unabhängig entwickeln. Die Lösung: stabile Grenzen wie Paketmanager, Lockfiles, Container und konsistente Schnittstellen. Heute sehen wir dasselbe Muster mit LLM-Providern. Jeder hat eigenes SDK, APIs, Credentials, Modelle, Tools, Abrechnung. Wenn wir Anwendungen direkt verbinden, reproduzieren wir die Kopplung, die wir woanders beseitigt haben.

    Die entscheidende Einsicht: Der Lebenszyklus der Anwendung muss vom Lebenszyklus des Modells entkoppelt werden. Ein neues Modell sollte eine Konfigurationsänderung sein, keine Anwendungsneuschreibung. Anwendungen und Modelle haben unterschiedliche Release-Zyklen. Änderungen an der Anwendung erfordern Code-Review, Sicherheitschecks, Integrationstests, gestaffelte Deployments und Produktionsfreigaben. Neue Modelle erscheinen kontinuierlich und müssen oft schnell evaluiert oder umgeleitet werden. Otari bietet einen stabilen OpenAI/Anthropic-kompatiblen Endpunkt zwischen Anwendungen und Providern. Die Anwendung sendet eine Anfrage mit einem einzigen API-Key, während Provider-Auswahl, upstream-Credentials, Routing-Richtlinien und Fallback-Verhalten hinter dem Gateway bleiben. Es unterstützt derzeit mehr als 40 Provider. Die Integration der Anwendung bleibt stabil.

    Diese Trennung erlaubt der Anwendung, das Produktverhalten zu besitzen, während die Plattform Modellzugriff und Betriebsrichtlinien übernimmt. Statt „Welcher Code muss geändert werden?“, fragt das Team „Welches Modell soll diesen Workload bedienen?“. Otari ersetzt nicht das ingenieurmäßige Urteilsvermögen. Teams müssen weiterhin Qualität, Latenz, Datenschutz, Zuverlässigkeit und Preis bewerten. Der Dienst entfernt lediglich die wiederholte Integrationsarbeit.

    Ein kleineres Modell sollte nicht gleich eine kleinere Plattform bedeuten. Modellfähigkeit und Plattformfähigkeit sind nicht dasselbe. Leichtere oder Open-Weight-Modelle können wegen Kosten, Latenz, Datenschutz oder Deployment-Anforderungen besser geeignet sein. Aber ihnen fehlen oft die verwalteten Fähigkeiten von Frontier-Modell-APIs. Otari hilft, diese Lücke zu schließen, indem es modellagnostische Werkzeuge wie Websuche und sandboxed Code-Ausführung über dasselbe Gateway bereitstellt. Sobald Werkzeuge vom Provider entkoppelt sind, werden kleinere Modelle interessanter.

    Fragmentierung geht über die Integration hinaus. Direkte Provider-Integrationen fragmentieren Code, verteilen Credentials über Systeme und teilen finanzielle Transparenz über mehrere Konten und Abrechnungs-Dashboards. Otari speichert upstream-Provider-Credentials zentral; Anwendungen verwenden workspace-bezogene API-Keys. Die Anwendung benötigt nie direkten Zugriff auf das Provider-Secret. Das schafft eine sauberere Sicherheitsgrenze. Credentials können zentral verwaltet und rotiert werden, Anwendungszugriff kann getrennt skaliert werden, der Schaden durch einen geleakten Key ist begrenzt. Kosten und Nutzung werden konsolidiert: Otari zeichnet Requests und Kosten über alle Provider hinweg auf und unterstützt Budgets, Transparenz und Ausgabenkontrollen. So wird Kostenmanagement näher an den Request herangerückt. Statt unerwartete Nutzung erst nach mehreren Rechnungen zu entdecken, können Teams Limits definieren und Ausgaben durch dieselbe Kontrollebene verfolgen, die den Modellzugriff autorisiert.

    Bau das Produkt, nicht eine weitere Provider-Abstraktion. Die Modellwahl ändert sich ständig. Teams werden neue Modelle übernehmen, ältere ausmustern und Workloads routen. Einen permanenten Provider vorherzusagen, ist keine realistische Plattformstrategie. Ebenso wenig ist es nachhaltig, provider-spezifische Logik in jeder Anwendung neu zu erfinden. Der tragfähige Ansatz: der Anwendung einen stabilen Vertrag geben und die Modellschicht dahinter evolvieren lassen. Modelle müssen getestet werden. Kosten gemessen. Zuverlässigkeit und Sicherheit designt. Aber diese Entscheidungen in einer dedizierten Kontrollebene, nicht durch Rewrites im Anwendungscode. Hör auf, neuen Provider-Integrationen hinterherzurennen. Bau das Produkt gegen eine stabile Schnittstelle und lass das Modell-Ökosystem sich dahinter verändern. Otari zeigt mit seinem Multi-Provider-Routing-Guide, wie eine einzige Integration Requests routen, Credentials zentralisieren, Fallback-Verhalten hinzufügen und Nutzung sowie Kosten in eine operative Ansicht bringen kann.

    Das ist keine Zukunftsmusik. Es ist eine Lektion aus Jahrzehnten Software-Engineering. Wir haben gelernt, Abhängigkeiten hinter stabilen Schnittstellen zu verstecken. Jetzt wenden wir das auf KI-APIs an. Was bedeutet das? Dass du deine Produktentwicklung nicht jedes Mal unterbrechen musst, wenn ein neues Modell erscheint. Dass du betriebliche Komplexität an eine zentrale Stelle delegieren kannst. Dass du die Innovationskraft des Modell-Ökosystems nutzen kannst, ohne in provider-spezifischem Code zu ertrinken. Die Zukunft der KI-Anwendungen liegt nicht darin, jeden neuen Anbieter einzeln zu integrieren, sondern eine stabile Basis zu haben, während das Modell-Layer sich im Hintergrund entwickelt.

    Quelle: blog.mozilla.ai

  • Vektorsuche optimieren, wenn RAM zu teuer wird: On-Disk vs. In-Memory ANN Indizes

    Vektorsuche optimieren, wenn RAM zu teuer wird: On-Disk vs. In-Memory ANN Indizes

    Du arbeitest an einem Projekt, bei dem die Datenbank täglich um Millionen neuer Vektoren wächst. Anfangs passt alles in den Arbeitsspeicher – Antwortzeiten sind niedrig, Kosten überschaubar. Doch der Index wird größer, die monatliche Cloud-Rechnung steigt. Irgendwann kostet der reine RAM für deinen Vektorindex mehrere tausend Euro pro Monat. Wie optimiert man die Vektorsuche, wenn RAM zur teuren Ressource wird?

    Die Antwort liegt in der Architektur der Approximate Nearest Neighbor (ANN) Algorithmen, genauer in der Entscheidung zwischen In-Memory und On-Disk Indizes. Eine Vektordatenbank besteht aus drei Komponenten: den Embeddings (numerische Repräsentationen des Text- oder Bildkorpus), dem Suchalgorithmus samt Indexstruktur (Qualität und Geschwindigkeit) und der Speicherung (RAM, Festplatte oder hybrid). Embeddings sind in der Literatur ausführlich behandelt. Der Fokus liegt hier auf den Suchalgorithmen – speziell den ANN-Verfahren.

    Exakte Suche vs. Approximate Nearest Neighbor

    Zwei grundlegende Ansätze: Die exakte Suche (kNN) durchläuft alle Einträge und berechnet für jeden den Abstand zur Anfrage. Sie liefert perfekte Ergebnisse, aber die Latenz skaliert linear mit der Indexgröße. Bei einer Million Vektoren wird es langsam, bei einer Milliarde unpraktikabel. Viele moderne Vektordatenbanken verzichten bei kleinen Sammlungen auf den Indexbau und fallen auf kNN zurück – der Overhead für ein paar tausend Vektoren lohnt nicht.

    ANN-Algorithmen vermeiden den vollständigen Scan, indem sie Abkürzungen im Datenraum schaffen. Die meisten modernen Vertreter – HNSW oder DiskANN – nutzen eine Graphstruktur für schnelle Sprünge zu den nächsten Nachbarn. Die Kunst liegt in der Balance: Ein guter ANN-Algorithmus opfert ein wenig Genauigkeit, um Latenz und Skalierbarkeit drastisch zu verbessern.

    Zwei Welten: In-Memory vs. On-Disk ANN

    Der Artikel unterscheidet zwei Gruppen von ANN-Algorithmen: solche, die den gesamten Index oder große Teile im RAM halten (In-Memory), und solche, die RAM sparen, indem sie Daten auf der Festplatte belassen und nur eine schlanke Routing-Schicht im Speicher vorhalten (On-Disk). Beide können prinzipiell sowohl im RAM als auch auf der Festplatte betrieben werden, liefern aber die besten Ergebnisse, wenn man sie wie vorgesehen einsetzt.

    Die bekannteste In-Memory-ANN ist HNSW (Hierarchical Navigable Small World). Sie verwendet einen mehrschichtigen Graphen: Eine Anfrage startet in der obersten, dünn besetzten Ebene, hangelt sich von Knoten zu Knoten zum nächsten Nachbarn, steigt dann in die nächsttiefere Ebene ab und wiederholt das Spiel, bis sie in der dichten unteren Ebene landet. Solange der gesamte Graph im RAM liegt, liefert HNSW extrem niedrige Latenzen – oft einstellige Millisekunden. Der Haken: Sobald der Index zu groß wird, um in den RAM zu passen – oder die RAM-Kosten explodieren –, bleibt nur der Umzug auf die Festplatte. Und da zeigt HNSW seine Schwäche: Die Graphstruktur erzeugt viele nicht-sequentielle Festplattenzugriffe bei jedem Hop. Die Folge: Latenzen steigen von Millisekunden auf Hunderte von Millisekunden oder mehr.

    Genau hier setzen On-Disk-ANN-Algorithmen an. Der Autor stellt zwei prominente Vertreter vor: SPANN und DiskANN.

    SPANN: Cluster-basierte On-Disk-Suche

    SPANN folgt dem Vorbild des invertierten Index (IVF): Die Vektoren werden in Cluster gruppiert, jedes Cluster wird durch einen Zentroiden repräsentiert. Die Zentroiden – quasi die Routing-Information – bleiben im RAM, während die eigentlichen Vektoren eines Clusters auf der Festplatte hintereinander abgelegt werden. Das sorgt für sequentielle Lesevorgänge. Bei der Suche findet die Anfrage zunächst die vielversprechendsten Cluster über ihre Zentroiden und lädt dann die Vektoren dieser Cluster von der Festplatte als Block. Dadurch reduziert sich die Anzahl der I/O-Operationen drastisch. Der Autor verweist auf Turbopuffer, eine Datenbank, die auf SPFresh aufbaut (einem Nachfolger von SPANN), oder auf Chroma DB in der Cloud-Version.

    DiskANN: Single-Layer-Graph mit Quantisierung

    DiskANN verwendet einen anderen Ansatz: einen einschichtigen Graphen namens Vamana. Die Idee ist, die Anzahl der Hops und damit die Anzahl der zufälligen Festplattenzugriffe zu minimieren, indem der Graph bewusst einige längere Kanten enthält – nicht nur die nächsten Nachbarn. Zusätzlich werden die Vektoren stark quantisiert (auf wenige Bits) im RAM gehalten, während die vollen Float-Präzisionsvektoren auf der Festplatte liegen. So kann die Routing-Schicht schnell entscheiden, welche Knoten besucht werden müssen, und lädt dann nur deren vollständige Vektoren bei Bedarf. DiskANN findet sich beispielsweise in Milvus oder in einer PostgreSQL-Erweiterung (pg_diskann).

    Die Kostenfrage: RAM vs. Festplatte

    Eine Rechnung: Cloud-RAM kostet etwa 5 US-Dollar pro Gigabyte und Monat, EBS (Remote Disk) liegt bei rund 0,08 – 0,10 $, lokale NVMe-SSDs bei 0,20 – 0,25 $. RAM ist etwa 50‑mal teurer als Remote Disk. Für einen Index mit 100 Millionen Vektoren in 1024 Dimensionen (Float32) benötigt man bei einer Replikation von 3 etwa 1,2 TB Speicher. Nicht quantisiert im RAM: rund 6000 $ pro Monat. Mit skalare Quantisierung (25 % Speicher) immer noch 1500 $. Dagegen: Remote Disk knapp 120 $, lokale Disk etwa 300 $. Das Verhältnis wird extremer, wenn der Index auf eine Milliarde Vektoren wächst – dann kostet RAM nicht quantisiert etwa 60.000 $.

    Diese Zahlen zeigen: On-Disk-Verfahren sind nicht nur eine Notlösung, sondern oft die einzige wirtschaftlich sinnvolle Option, sobald die Indizes in den Milliardenbereich gehen.

    Der Preis der Ersparnis: Latenz

    Die Kostensenkung ist nicht kostenlos. On-Disk-ANN-Indexe müssen die Daten von der Festplatte laden, das ist immer langsamer als ein RAM-Zugriff. Die tatsächliche Latenz hängt stark von der Hardware und dem Cache-Status ab. Der Autor zitiert Zahlen aus dem SPANN-Paper: 90 % Recall bei etwa einer Millisekunde mittlerer Latenz auf einer einzelnen Maschine mit lokaler SSD. In der Praxis, etwa bei Turbopuffer, misst man bei warmem Index auf schnellem Speicher etwa 14 Millisekunden (p50), bei kaltem Index aus dem Objektspeicher dagegen 874 Millisekunden – ein Faktor 60 allein durch den Cache. Generell gilt: On-Disk-ANN ist langsamer als HNSW im RAM, aber für viele Anwendungen (etwa RAG, wo die Ergebnisse ohnehin an ein Reranking und ein LLM weitergereicht werden) sind 100 Millisekunden Aufschlag völlig unkritisch. Nur wenn es auf jede Millisekunde ankommt – etwa bei agentischen Gedächtnissystemen mit vielen Abfragen pro Anfrage –, sollte man besser beim teuren RAM bleiben.

    Wähle mit Bedacht

    Die Entscheidung zwischen In-Memory- und On-Disk-ANN ist eine Abwägung von Kosten, Latenz und Skalierungsanforderungen. Für kleine bis mittlere Indizes (bis zu einigen zehn Millionen Vektoren) ist HNSW im RAM die beste Wahl – schnell, ausgereift, und die Kosten sind noch überschaubar. Sobald die Indizes jedoch in die Hunderte Millionen oder Milliarden gehen, werden On-Disk-Algorithmen wie SPANN oder DiskANN wirtschaftlich. Selbst wenn die Latenz etwas höher ist: Wenn man die Daten richtig organisiert – lokale SSDs statt Remote Disk, mit Quantisierung und warmem Cache –, kommt man in Bereiche, die für die meisten KI-Anwendungen völlig akzeptabel sind.

    RAM ist schnell, aber teuer. Festplatte ist langsam, aber günstig. Die moderne Vektorsuche bietet clevere Algorithmen, die den Unterschied überbrücken – wenn man die Trade-offs versteht und die richtige Architektur für den eigenen Anwendungsfall wählt.

    Quelle: towardsdatascience.com

  • OAuth 2.1 und MCP mit Cloudflare Workers: Authentifizierte KI-Tools selbst gebaut

    OAuth 2.1 und MCP mit Cloudflare Workers: Authentifizierte KI-Tools selbst gebaut

    Warum deine KI plötzlich rechnen kann – und wie du die Kontrolle behältst

    Du arbeitest mit einem KI-Assistenten wie Claude, Gemini oder ChatGPT und möchtest, dass er echte Berechnungen durchführt – etwa Zahlen aus deiner Datenbank addieren oder Benutzerdaten abrufen. Das ist mit dem Model Context Protocol (MCP) schon heute möglich. MCP ist ein offener Standard, der KI-Anwendungen den Zugriff auf externe Werkzeuge erlaubt – ähnlich wie ein Betriebssystem Treiber für Hardware bereitstellt. In diesem Beitrag bauen wir einen eigenen MCP-Server mit einem Taschenrechner-Tool, hosten ihn auf Cloudflare Workers und rüsten eine OAuth 2.1-Authentifizierung nach. Am Ende verstehst du die Zusammenhänge und hast einen einsatzbereiten Prototypen.

    Das Fundament: Ein Cloudflare Worker als MCP-Server

    Der Autor beginnt mit einem fast leeren Cloudflare Worker, den man über die Kommandozeile mit dem Hello World-Template für TypeScript anlegt. Nach der Einrichtung liegt der Code in src/index.ts. Um daraus einen MCP-Server zu machen, installiert er drei Abhängigkeiten: das offizielle @modelcontextprotocol/sdk, Cloudflares agents-Bibliothek (die einen Adaptor für MCP bereitstellt) und zod zur Validierung von Eingaben. Diese Pakete übernehmen den Großteil der Implementierung – du konzentrierst dich auf die eigentlichen Werkzeuge, sogenannte Tools.

    Das erste Tool: Ein Calculator mit Persönlichkeit

    Ein MCP-Tool ist wie ein kleiner API-Endpunkt. Es besteht aus Namen, Beschreibung, Eingabe-Schema (definiert mit Zod) und einer Handler-Funktion. Der Autor zeigt das an einem Taschenrechner-Tool, das Addition, Subtraktion, Multiplikation und Division zweier Zahlen beherrscht. Die Handler-Funktion ermittelt anhand eines übergebenen Operators die richtige Operation und gibt das Ergebnis als Text zurück. Fehler wie eine Division durch Null werden abgefangen. Wichtig: Für jede eingehende Anfrage wird eine neue Instanz des MCP-Servers erzeugt – das verhindert, dass Daten zwischen Sitzungen durchsickern.

    Damit der Worker die MCP-Anfragen annimmt, wird der MCP-Server an die fetch-Funktion des Workers angebunden. Der Pfad lautet /mcp. Fertig ist der erste funktionsfähige MCP-Server. Der Autor testet ihn direkt mit Claude Desktop, indem er in den Einstellungen einen neuen Connector anlegt – Name: „Calculator“, URL: die Adresse des laufenden Workers plus /mcp. Der lokale Worker läuft meist unter http://localhost, und nicht jeder KI-Client akzeptiert unsichere Verbindungen. Abhilfe schaffen ein HTTPS-Tunnel via ngrok oder das Deployment des Workers über pnpm run deploy. Nach dem Einrichten fragt der Autor Claude: „Addiere 5 und 8“. Claude erkennt das Tool, ruft es mit den richtigen Argumenten auf, der Server antwortet mit 13, und Claude präsentiert das Ergebnis – ein Kreislauf, der auf klaren Protokollen beruht.

    Hinter den Kulissen: JSON-RPC im Detail

    Die Kommunikation zwischen KI-Client und MCP-Server läuft über JSON-RPC, ein schlankes Protokoll für entfernte Prozeduraufrufe. Der Autor zeigt die tatsächlichen Anfragen, die Claude sendet. Zuerst fragt der Client tools/list ab: Der Server antwortet mit Namen, Beschreibung und Eingabe-Schema des verfügbaren Tools. Anhand dieser Metadaten entscheidet die KI, wann und wie das Tool einzusetzen ist. Bei der eigentlichen Aktion schickt Claude einen tools/call-Request mit den konkreten Parametern – in unserem Fall die Zahlen und die gewünschte Operation. Der Server führt die Berechnung aus und sendet das Ergebnis zurück. Dieses Zusammenspiel ist erweiterbar: Neue Tools lassen sich durch Hinzufügen weiterer Definitionen integrieren.

    Warum ein offener MCP-Server riskant sein kann

    Bisher kann jeder, der die URL kennt, den Taschenrechner benutzen. Für öffentliche Daten wie Wetter- oder Dokumentations-APIs ist das in Ordnung. Sobald persönliche oder geschäftskritische Daten ins Spiel kommen, brauchst du eine Zugriffskontrolle. Der Autor zeigt, was passiert, wenn der Server einfach einen 401 Unauthorized zurückgibt: Claude reagiert mit mehreren Folgeanfragen – es versucht den Protected Resource Metadata Endpoint, dann den Authorization Server Metadata Endpoint und schließlich eine Dynamic Client Registration. All das sind erratische Versuche, die fehlschlagen, weil die entsprechenden Endpunkte nicht existieren. Ein schlichter 401 reicht nicht; der Server muss dem Client mitteilen, wo er gültige Zugangsdaten bekommt.

    OAuth 2.1 als Türsteher für deine KI-Tools

    Hier kommt OAuth 2.1 ins Spiel, der aktuelle Standard für sichere Autorisierung. Der MCP-Server muss dem Client über den HTTP-Header WWW-Authenticate mitteilen, wo sich die Protected Resource Metadata (PRM) befindet. Diese PRM wiederum enthält die URL des Authorization Servers. Der Autor nutzt für diesen Teil PropelAuth, einen Dienst, der mit wenigen Klicks einen vollständigen OAuth 2.1-konformen Autorisierungsserver bereitstellt. Nach der Aktivierung der MCP-Unterstützung in der PropelAuth-Oberfläche legt der Autor anwendungsspezifische Scopes an – etwa op:add, op:sub, op:mult und op:div. Scopes sind wie Berechtigungsstempel: Ein Client kann nur dann eine bestimmte Rechenoperation ausführen, wenn der Benutzer dem entsprechenden Scope zugestimmt hat.

    Den MCP-Server mit dem Authorization Server verbinden

    Jetzt wird der MCP-Server mit dem PropelAuth-Authorization Server verknüpft. Dazu implementiert der Autor den PRM-Endpunkt, der die Adresse des Authorization Servers sowie die unterstützten Scopes auflistet. Außerdem korrigiert er den 401-Header, sodass Claude den PRM-Endpunkt direkt findet – ohne Rätselraten. Nach dem Neustart des Connectors in Claude Desktop öffnet sich ein Browserfenster mit dem PropelAuth-Login. Nach erfolgreicher Anmeldung wird der Benutzer aufgefordert, den angeforderten Scopes zuzustimmen. Erst nach dieser Zustimmung erhält der Client ein Access Token, das er bei jeder weiteren Anfrage mitschickt.

    Der letzte Schritt ist die Validierung des Tokens auf Serverseite. Der Autor implementiert eine Funktion, die das Access Token aus dem Authorization-Header extrahiert und an den Token Introspection Endpoint von PropelAuth sendet. Dieser Endpunkt prüft, ob das Token gültig ist, wem es gehört und welche Scopes der Benutzer freigegeben hat. Der MCP-Server extrahiert diese Informationen in ein benutzerdefiniertes User-Objekt und leitet es an die Tool-Handler weiter. Innerhalb des Calculator-Tools wird dann geprüft, ob der Benutzer den erforderlichen Scope für die gewünschte Operation besitzt – etwa op:add für Addition. Fehlt die Berechtigung, lehnt der Server die Anfrage ab.

    Der vollständige authentifizierte Workflow

    Mit allen Komponenten ergibt sich ein klarer Ablauf: Ein Benutzer verbindet Claude Desktop mit dem MCP-Server. Claude fragt /mcp ab und erhält einen 401 mit dem PRM-Link. Daraufhin lädt Claude die PRM, identifiziert den Authorization Server und startet den OAuth-Flow über den Browser des Benutzers. Nach Login und Zustimmung erhält Claude ein Token. Mit diesem Token ruft Claude tools/list auf – der Server validiert das Token und gibt die Liste erlaubter Tools zurück. Schließlich ruft Claude tools/call für die gewünschte Rechnung auf, das Token wird erneut geprüft, und nur wenn die Scopes passen, darf gerechnet werden. Der gesamte Vorgang ist für den Benutzer weitgehend unsichtbar, bis auf den Login-Schritt.

    Was bedeutet das für dich?

    Der Autor zeigt, dass die Kombination aus MCP, Cloudflare Workers und einem modernen Autorisierungsdienst wie PropelAuth eine schlanke, aber leistungsfähige Plattform für KI-gestützte Tools ergibt. Du musst kein OAuth-Experte sein, um geschützte MCP-Server zu betreiben – die Spezifikationen sind ausgereift, die Bausteine liegen bereit. Wichtig ist, dass du die Prinzipien verstehst: Jeder MCP-Client muss sich über OAuth 2.1 authentifizieren, und jeder Tool-Zugriff kann feingranular über Scopes gesteuert werden. Das ist eine solide Basis für Produktivumgebungen. In Zukunft werden immer mehr KI-Clients MCP unterstützen, und wer heute die Grundlagen beherrscht, ist für die nächste Welle der Mensch-Maschine-Interaktion gerüstet. Bau dir deinen eigenen MCP-Server, mach ihn sicher und lass die KI für dich rechnen – aber nur mit deiner Erlaubnis.

    Quelle: propelauth.com