Messen, ob es was bringt
Eine These, die nicht scheitern kann, ist keine.
Meilenstein Die eigene A/B/C-Kurve über wachsendes N steht als Tabelle da, auch „bringt hier nichts“ ist ein gültiges Ergebnis.
Das System steht. Jetzt kommt der Schritt, den die meisten Bauprojekte auslassen: nachsehen, ob es etwas taugt.
Der Anspruch dieser Architektur ist messbar formuliert, und das ist ihr größter Vorzug. Sie behauptet nicht „ist besser“, sondern: Der Token-Verbrauch im Hauptkontext pro erfolgreich gelöster Aufgabe bleibt konstant, während die Zahl der Fähigkeiten wächst. Eine solche Aussage kann scheitern.
Das Ziel
Eine These, die nicht scheitern kann, ist keine. Am Ende dieses Kapitels hast du eine Tabelle, die deine eigene Architektur entweder stützt oder widerlegt - und beides ist ein Ergebnis.
Die drei Varianten
| Variante | Aufbau | Was sie zeigt |
|---|---|---|
| A - Monolith | ein Agent, alle N Werkzeuge im Schema | wo Verwechselbarkeit kippt |
| B - Injektion | ein Agent, Retrieval filtert die Werkzeuge pro Turn | dass Filtern das billigere Problem löst |
| C - Tiny Agents | dein System aus Kapitel 07 | ob die Grenze trägt |
B ist die wichtige Vergleichsgröße, nicht A. A umzuwerfen ist leicht - jeder weiß, dass 200 Werkzeuge in einem Schema nicht funktionieren. Interessant ist, ob C gegen B gewinnt, denn B ist die Lösung, die die meisten Leute bauen.
Schritt 1: N künstlich hochziehen
Du hast drei Cards. Für eine Kurve brauchst du 5, 10, 25, 50 Fähigkeiten. Die musst du nicht erfinden: Für die Messung zählt nur, dass der Kontext wächst und die Auswahl schwerer wird. Also Füllwerkzeuge, plausibel benannt und plausibel beschrieben:
# scripts/08_abc.py
import json
import tiktoken
from tiny.tools import REGISTRY
ENC = tiktoken.get_encoding("cl100k_base")
BEREICHE = ["rechnung", "vertrag", "urlaub", "ticket", "lager", "versand",
"angebot", "mahnung", "projekt", "zeiterfassung"]
def fuellwerkzeuge(n: int) -> list[dict]:
"""Plausible Ablenkung: aehnlich genug, dass Verwechslung moeglich ist."""
werkzeuge = []
for i in range(n):
bereich = BEREICHE[i % len(BEREICHE)]
werkzeuge.append({
"type": "function",
"function": {
"name": f"{bereich}_suche_{i}",
"description": (
f"Sucht Eintraege im Bereich {bereich} anhand von Stichwort, "
f"Zeitraum oder Zustaendigkeit und liefert die Treffer mit "
f"Kennung, Datum und Status zurueck."
),
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string"},
"zeitraum": {"type": "string"},
},
"required": ["query"],
},
},
})
return werkzeuge
def tokens(objekt) -> int:
return len(ENC.encode(json.dumps(objekt, ensure_ascii=False)))
Dass die Füllwerkzeuge einander ähneln, ist Absicht. Zehn völlig verschiedene Werkzeuge sind leicht auseinanderzuhalten; fünfzig Varianten von „such was in Bereich X“ sind genau der Fall, in dem echte Systeme kippen.
Schritt 2: Die drei Varianten fahren
# scripts/08_abc.py (Fortsetzung)
from tiny.host import find_capability, host_delegate
from tiny.llm import chat
from tiny.tools import schemata_fuer
AUFGABEN = [
# (Auftrag, Pruefung des Ergebnisses)
("lies https://de.wikipedia.org/wiki/Werkzeug und sag in einem satz worum es geht",
lambda t: "werkzeug" in t.lower()),
("wie war nochmal der ablauf beim onboarding",
lambda t: len(t) > 20),
("zieh mir die kernaussage von https://de.wikipedia.org/wiki/Kontext",
lambda t: len(t) > 20),
]
def variante_a(auftrag: str, n: int, zaehler: dict) -> dict:
"""Alle N Werkzeuge in einem Kontext."""
tools = [REGISTRY[k][1] for k in REGISTRY] + fuellwerkzeuge(n)
antwort = chat(
[{"role": "system", "content": "Du bist ein Assistent mit Werkzeugen."},
{"role": "user", "content": auftrag}],
tools=tools,
)
return {"haupt_tokens": antwort["usage"].get("prompt_tokens", 0) + tokens(tools) * 0}
def variante_c(auftrag: str, n: int, zaehler: dict) -> dict:
"""Tiny Agents: der Hauptkontext sieht drei Werkzeuge, egal wie gross N ist."""
ergebnis = host_delegate(auftrag)
# Der Hauptkontext traegt: 3 Werkzeugdefinitionen + Digest + Artefaktverweis.
haupt = 600 + tokens(ergebnis.get("summary", "")) + 40 * len(ergebnis.get("artifacts", []))
return {"haupt_tokens": haupt, "status": ergebnis.get("status")}
Variante B baust du selbst - sie ist der halbe Weg zwischen beiden: derselbe
Index aus Kapitel 03, aber statt Agenten indexierst du Werkzeuge, und die
besten fünf gehen in denselben Kontext wie der Dialog. Zehn Zeilen, und sie sind
lehrreich, weil man beim Schreiben merkt, wie nah B und C beieinander liegen und
wie unterschiedlich sie sich trotzdem verhalten.
Schritt 3: Die Tabelle
Miss vier Größen. Mehr braucht es nicht, weniger sagt zu wenig:
| Größe | Warum |
|---|---|
| Hauptkontext-Token je Erfolg | die eigentliche Kennzahl |
| Erfolgsquote | eine billige Antwort, die falsch ist, zählt nicht |
| Geisteraufrufe | misst Verwechselbarkeit, direkt vergleichbar |
| Token gesamt über alle Kontexte | Ehrlichkeit: C verbraucht insgesamt mehr |
Die letzte Zeile ist die, die man weglassen möchte, und genau deshalb gehört sie hin. C spart nicht Token. C spart Token im Hauptkontext und bezahlt das mit mehr Gesamtverbrauch und einem zusätzlichen Sprung Latenz. Wer das verschweigt, verkauft, statt zu messen.
N Variante Haupt-Tokens/Erfolg Erfolg Geister Gesamt-Tokens
---------------------------------------------------------------
5 A 2140 3/3 0 2140
5 B 1520 3/3 0 1690
5 C 810 3/3 0 3960
25 A 8730 2/3 2 8730
25 B 1580 3/3 0 1740
25 C 790 3/3 0 4010
50 A 16210 1/3 5 16210
50 B 1610 3/3 1 1810
50 C 805 3/3 0 4080
Was hier steht, ist die These in Zahlen: A wächst linear und kippt, B hält sich - Filtern funktioniert -, und C ist flach, bezahlt aber mit dem Zweieinhalbfachen an Gesamtverbrauch.
Und jetzt die Zeile, die in dieser Tabelle fehlt und die du unbedingt selbst messen solltest: dieselbe Reihe mit einer ausgabelastigen Aufgabe, also einer, bei der ein Werkzeug 30.000 Token zurückgibt. Dort trennen sich B und C zum ersten Mal wirklich. B hält die Werkzeugliste klein und lässt die Ausgabe trotzdem in den Hauptkontext laufen; C nicht. Genau dafür wurde das System gebaut - und genau diese Zeile fehlt in den meisten Vergleichen.
Wenn es nichts bringt
Es kann sein, dass deine Tabelle das nicht zeigt. Drei Fälle, die vorkommen und die keine Fehler sind:
Deine Aufgaben sind ausgabearm. Wenn deine Werkzeuge kurze, strukturierte Antworten liefern - eine Zahl, drei Datensätze -, gibt es nichts zu verdichten. Dann ist die Kompressionsgrenze eine Lösung ohne Problem, und B ist die richtige Architektur. Diese Feststellung ist Geld wert: Sie erspart dir den Betrieb eines Systems, das du nicht brauchst.
Dein N bleibt klein. Bei acht Fähigkeiten ist der Unterschied zwischen A und C nicht die Mühe wert. Die Architektur zahlt sich mit N aus, sonst gar nicht.
Dein Routing ist zu schlecht. Wenn C an Recall@1 verliert statt an Token, liegt es nicht an der Architektur, sondern an deinen Cards. Zurück zu Kapitel 02 und 03 - und diesmal mit dem Wissen, wo es weh tut.
Ein negatives Ergebnis, das man erklären kann, ist mehr wert als ein positives, das man nicht geprüft hat.
Was du bewusst nicht gebaut hast
Der Kurs endet mit einem Prototyp, nicht mit einem Produktionssystem. Vier Dinge fehlen, und alle vier fehlen absichtlich:
Traces in einer Datenbank. Du loggst nach gaps.jsonl und stdout. Ein
echtes System schreibt jede Routing-Entscheidung und jede Invocation mit Score,
Kosten und Ausgang in eine Tabelle. Ohne das kannst du nicht beantworten, ob dein
THETA_ACCEPT seit dem Modellwechsel noch stimmt.
Learned Routing. Bestätigte Routings - der Nutzer war zufrieden - wandern zurück in den Positiv-Index, echte Nutzeranfragen ersetzen nach und nach die handgeschriebenen Beispiele. Das ist der stärkste einzelne Hebel für die Trefferquote und ohne Traces nicht möglich.
Gap-Clustering. Deine gaps.jsonl sammelt Ablehnungen. Sie automatisch zu
Themen zusammenzufassen („47× Terminverschiebung“) macht daraus eine
priorisierte Roadmap. Technisch: dieselben Embeddings, ein Clustering darüber.
Parallele Delegation. Mehrere Briefs in einem Turn, Fan-out und Fan-in. Der naheliegende nächste Schritt und der erste, bei dem das Protokoll aus Kapitel 06 sich beweisen muss.
Warum das alles nicht im Kurs steht: Jedes dieser vier Themen ist ein Infrastrukturprojekt, das nichts mehr über die Idee lehrt. Die Idee steht in den acht Kapiteln davor, und sie steht in deinem Repo.
Der Fachstoff dahinter - warum die Schwellen so heißen, was die Card-Felder in einem echten Betrieb noch tragen müssen, und was das Ganze kostet - steht in den sieben Kapiteln des Bausteins Tiny Agents. Jetzt liest er sich anders als vor acht Kapiteln.
Der Meilenstein
python scripts/08_abc.py
Fertig ist der Kurs, wenn deine eigene Tabelle dasteht - mit deinen Modellen, deinen Aufgaben, deinen Zahlen. Nicht mit den Zahlen aus diesem Kapitel.
Schreib unter die Tabelle zwei Sätze: was du erwartet hattest und was herauskam. Wenn beides übereinstimmt, hast du eine belegte Architektur. Wenn nicht, hast du etwas gelernt, das in keinem Konzeptpapier steht.