ToWow / Engineering-Notiz

Eine Anfrage besucht 11 Agents und bezahlt für 512

Ein vollständiger Netzscan versteckte sich in der Vorverarbeitung. Was sich änderte, als er aus dem Anfragepfad verschwand.

Besuchte Knoten: 11. Vergleiche: unverändert.

In lokalen Tests im September 2026 meldete der Discovery-Prototyp immer dieselben Zähler — bei 32 Agents ebenso wie bei 512. Anfragen breiteten sich höchstens zwei Sprünge weit aus. Die Zahlen entsprachen scheinbar der Erwartung.

Die Zeit änderte sich dennoch. Das 95. Perzentil der Anfragelatenz stieg von 5.66 auf 47.64 Millisekunden. Das Netz wurde 16-mal größer, die Anfrage mehr als achtmal langsamer.

Der Widerspruch verwies auf Arbeit außerhalb der Besuchszählung.

Noch vor dem Start war das ganze Netz durchlaufen

Jeder Agent speichert ein Entdeckungssignal und Verbindungen zu wenigen Nachbarn. An einem Knoten muss die Anfrage beurteilen, ob sich weitere Erkundung in der Nähe lohnt. Dafür erstellt das System eine Nachbarschaftszusammenfassung aus dem öffentlichen Signal des Knotens und seiner direkten Nachbarn.

Im Stadtvergleich möchte die Anfrage nur einige Straßen entlanggehen. Die Zusammenfassung ist die Orientierungstafel an der Kreuzung, die bei der Richtungswahl hilft.

Die frühe Implementierung wählte einen bequemen Ablauf: Zu Beginn jeder Anfrage alle Tafeln neu erstellen, dann die Anfrage losschicken.

# Vereinfachter früher Anfragepfad
adverts = build_all_neighborhood_summaries(network)
return walk_local_routes(request, adverts)

Die zweite Zeile geht tatsächlich nur lokale Wege. Die erste hat bereits das gesamte Netz gescannt.

Die Ressourcenzähler erfassten hauptsächlich Weiterleitung und Vergleiche. „11 Knoten besucht“ war dafür korrekt. Der vollständige Neuaufbau fand davor statt, kostete Zeit und wuchs mit der Netzgröße, erschien aber nicht auf dieser Rechnung.

Datensysteme kennen das Phänomen. Eine Datenbank kann wenige Zeilen zurückgeben und zuvor viele durchsuchen. Auch eine Anfrage mit LIMIT kann zuerst Sortierung oder Indexaufbau bezahlen. Die PostgreSQL-Dokumentation zu EXPLAIN unterscheidet Ausgabezeilen, Startkosten und Gesamtkosten. Jede Größe braucht einen klaren Arbeitsumfang.

Für diesen Prototyp war das Problem konkret: Die durch lokale Besuche eingesparte Arbeit wurde vor den lokalen Besuchen doch ausgeführt.

Zusammenfassungen erst bei Bedarf erstellen

Wir zerlegten den Gesamtaufbau in einzelne Knotenaufrufe. Erreicht die Anfrage eine Kante und braucht deren Nachbarschaft, entsteht nur diese Zusammenfassung. Wird sie innerhalb derselben synchronen Anfrage erneut gebraucht, wird das Ergebnis wiederverwendet.

# Vereinfachter überarbeiteter Anfragepfad
adverts = {}

def summary_for(edge_id):
    if edge_id not in adverts:
        adverts[edge_id] = build_one_neighborhood_summary(edge_id)
    return adverts[edge_id]

return walk_local_routes(request, summary_for)

adverts lebt nur während einer Anfrage. Die nächste liest aktuelle Knoten und Verbindungen neu. Aktualisierungen, Beitritte und Austritte fließen damit natürlich ein. Diese Einfachheit ist beabsichtigt: Der Prototyp arbeitet synchron, während einer Entdeckung wird das Netz nicht nebenläufig geändert. Wiederverwendung innerhalb der Anfrage bringt den wesentlichen Nutzen ohne anfrageübergreifende Cache-Invalidierung.

Der vollständige Aufbau bleibt etwa für Diagnose oder Netzexport nützlich. Er ist nur kein obligatorischer Teil gewöhnlicher Anfragen mehr.

Zwei neue Ressourcenzähler erfassen gebaute Zusammenfassungen und gelesene Beitragsgeber. Der Besuchszähler bleibt erhalten; nun wird auch die Vorbereitung beobachtbar.

Gleiche Last, flachere Latenzkurve

Maschine, Topologie, Anfragen und Konfiguration blieben gleich. Für jede Größe liefen 12 Discovery-Anfragen auf einem festen bidirektionalen Ring. Jeder Knoten war mit Nachbarn bei Versatz 1 und 3 verbunden; die Anfrage durfte höchstens zwei Sprünge machen. Die Tabelle zeigt historische Werte dieses kurzen lokalen Konstruktionstests.

Agents im Netz p95 vorher p95 nachher
32 5.66 ms 4.28 ms
128 13.21 ms 4.91 ms
512 47.64 ms 5.15 ms

Vorher steigt die Latenz mit der Gesamtgröße, nach bedarfsgerechtem Aufbau bleibt sie annähernd konstant

Abbildung 1: Historischer Vorher-Nachher-Vergleich bei gleicher Last. Die horizontale Achse ordnet die drei Testgrößen; Linien dienen der Leseführung. Jeder Punkt zeigt den p95 aus 12 Anfragen.

Bei 512 Agents steigt der Durchsatz von ungefähr 22 auf ungefähr 209 Anfragen pro Sekunde. Jede Anfrage besucht weiterhin 11 Agents, erstellt nun aber nur 10 Zusammenfassungen und prüft 50 Beitragsgeber. Diese beiden Zähler sind bei allen drei Netzgrößen gleich.

Die gepaarte Analyse prüfte Kandidaten, Übergaben, Besuche und bisherige Ressourcenzähler. Sie blieben in den Aufzeichnungen identisch. Die Erklärung ist damit klar: Unbenötigte Vorverarbeitung entfiel. Neue Zeitkurve und neue Arbeitszähler bestätigen einander.

Das gilt für die damalige Einzelmaschine, synchrone Ausführung und konstruierte Topologie. Mit nur 12 Anfragen pro Gruppe ist p95 eine linear interpolierte Kennzahl einer kleinen Stichprobe. Produktionslatenzen hängen außerdem von Parallelität, Netzwerk und Datenänderungen ab. Der wichtige Befund ist ein tatsächlich mit dem Gesamtpool wachsender Vorlauf, der gefunden und beseitigt wurde.

Ein lokaler Algorithmus braucht einen lokalen Anfragepfad

Ein Algorithmus kann in seiner Kernschleife sparsam sein und bei Initialisierung, Serialisierung, Indexpflege oder Aufräumen dennoch alle Daten scannen. Hier lag die Lücke beim Zusammenfassungsaufbau. Die neuen Zähler nehmen ihn in die Kosten derselben Anfrage auf.

Im eigenen System reicht ein kleines Experiment: Die tatsächlich benötigten Objekte bleiben fest, irrelevante Objekte werden vermehrt, und die Ende-zu-Ende-Zeit wird gemessen. Bleiben die Kernoperationen gleich und steigt die Zeit, lohnt die Suche nach nicht verbuchter Arbeit im Anfragepfad.

Nach der Korrektur entsteht nur, was gebraucht wird: 10 Zusammenfassungen, 50 Beitragsgeber. Für eine lokale Anfrage stellt das System endlich nicht mehr die Orientierungstafeln des gesamten Netzes her.


Material: Lokale Kapazitätstests von Discovery Front und gepaarte Analyse vom 1. September 2026. Für diese Fassung wurden Originalvergleiche, Laufkonfiguration und aktueller Zusammenfassungscode geprüft. Der Beispielcode ist vereinfacht. Genaue Fundstellen stehen in SOURCE-NOTES.md. Die Notiz arbeitet ein bestehendes Experiment neu auf.

Next step

If your team is putting agents into real work and wants to talk about Flowness or enterprise AI deployment, email us your industry and the problem you want to solve. hi@towow.ai