Meta-Engineering von AI-Systemen: von Traces zu besserer Memory
Automatische Übersetzung
Dieser Artikel wurde automatisch aus der englischen Originalversion übersetzt.
Dieser Artikel eröffnet Meta-Engineering AI Systems, einen sechsteiligen Leitfaden zu Closed-Loop AI Engineering: Agents untersuchen Fehler, testen Änderungen und nutzen die Ergebnisse, um AI-Systeme zu verbessern.
Das Verhalten einer AI-Anwendung hängt von mehr als ihrem Model ab. Prompts, abgerufene Informationen, gespeicherte Memory, Tools und Anwendungscode beeinflussen das Ergebnis. Wenn eine Antwort falsch ist, können mehrere Änderungen plausibel erscheinen. Die Engineering-Aufgabe besteht darin zu entscheiden, welche Änderung hilft, welche Kosten sie verursacht und was sie außerdem beeinträchtigt.
Mit Meta-Engineering bezeichne ich hier die Gestaltung des Verbesserungsprozesses selbst: welche Evidenz der Agent sieht, was er ändern darf, wie wir seine Vorschläge testen und wer über ihre Übernahme entscheidet. Closed-Loop beschreibt, wie dieser Prozess aus seinen Experimenten lernt. Jedes Ergebnis beeinflusst, was wir als Nächstes ausprobieren oder verwenden – auch dann, wenn eine vorgeschlagene Änderung scheitert.
Wir können diese Arbeit schrittweise automatisieren. Eine Person kann die exakt zu testenden Änderungen vorgeben, für einen Suchalgorithmus eine Menge zulässiger Alternativen definieren oder den nächsten Vorschlag an einen LLM Agent delegieren. Der Runner testet jeden Kandidaten und bewahrt die Evidenz für die nächste Entscheidung auf. Diese Serie konzentriert sich darauf, Agents in diesen Prozess einzubinden und dabei Execution, Evaluation und Adoption unter expliziter Kontrolle zu halten.
Die zentrale Frage aller sechs Teile lautet, wie viel dieser Arbeit wir an einen Agent delegieren können, während die Evidenz und die Entscheidung zur Übernahme einer Änderung vertrauenswürdig bleiben. Wir beginnen damit, das gesamte System abzubilden, und bauen anschließend eine kleine funktionierende Version rund um Agent Memory.
Was den Loop schließt
Es gilt, zwei unterschiedliche Loops im Blick zu behalten. Innerhalb einer Agent-Anwendung wählt der Runtime Loop eine Aktion aus, ruft ein Tool auf, beobachtet das Ergebnis und setzt die aktuelle Aufgabe des Users fort. Der Improvement Loop arbeitet über verschiedene Versionen dieser Anwendung hinweg. Er untersucht das Verhalten abgeschlossener Runs und testet Änderungen, die spätere Runs verbessern sollen.
Der Improvement Loop beginnt mit Evidenz: einer falschen Antwort, einer unerwünschten Zustandsänderung, überhöhten Kosten oder einem anderen beobachtbaren Fehler. Ein Trace hält die Schritte fest, die zu diesem Ergebnis geführt haben. Der Proposer wählt einen Kandidaten aus, also eine konkrete Version einer Änderung. Ein Runner führt den Kandidaten für definierte Tasks aus, und ein Evaluator prüft das resultierende Verhalten anhand der Anforderungen. Im Live-Experiment dieses Artikels ist ein LLM Agent der Proposer:
Die Evaluation liefert die Grundlage für eine Entscheidung; sie autorisiert sich nicht selbst. Jemand muss entscheiden, ob der gemessene Nutzen die Übernahme der Änderung rechtfertigt – einschließlich ihrer Auswirkungen auf Kosten, Berechtigungen und anderes erforderliches Verhalten. In dieser Serie beginnen wir mit einem Human Reviewer. Der Proposer kann eine Änderung vorschlagen, aber weder die Checks umschreiben noch sein eigenes Budget erhöhen oder sich selbst die Genehmigung erteilen.
Es gibt zwei Rückgabepfade. Die Experimenthistorie fließt in spätere Vorschläge ein – auch dann, wenn ein Kandidat abgelehnt wird. Wird ein Kandidat genehmigt und übernommen, liefert sein Verhalten durch die Nutzung neue Evidenz. Änderungen reversibel zu halten, ist wichtig, wenn diese Evidenz dem ursprünglichen Experiment widerspricht. Einen Score zu erfassen, ist nur ein Schritt; der Loop schließt sich erst, wenn die Evidenz beeinflusst, was wir als Nächstes ausprobieren oder verwenden.
Das, was verbessert wird, ist das Target. Dabei kann es sich um eine Memory Policy, eine Retrieval Pipeline, Code zur Tool-Auswahl oder das Programm handeln, das den Context eines Models zusammenstellt. Model Training ist eine weitere mögliche Intervention. Der Loop funktioniert auch mit fixierten Model Weights: Der Agent kann das umgebende Programm verbessern, ohne ein Model zu trainieren. Diese erste Demo enthält bereits den äußeren LLM Agent. Spätere Teile stärken den Evaluator und prüfen, ob sich Agentic Search im Vergleich zu einfacheren Methoden lohnt.
Entscheiden, wie viel der Suche delegiert werden soll
Angenommen, du weißt bereits, was du ausprobieren möchtest: Vergleiche zwei Models in einem Extraktionsschritt oder teste Memory-Schwellenwerte von 0.6, 0.7 und 0.8. Du kannst diese Auswahl selbst vorgeben und Ausführung, Scoring und Reporting automatisieren. Nachdem du die Ergebnisse gelesen hast, wählst du das nächste Experiment. Der Feedback Loop funktioniert auch dann, wenn das System die Kandidaten nicht selbst erfunden hat.
Ich verwende vier Arbeitsmodi, um diese Aufteilung sichtbar zu machen. Die Abbildung zeigt eine Möglichkeit, schrittweise mehr Experimentdesign zu delegieren: Beginne mit exakt vorgegebenen Model-Auswahlen, lasse das System Settings und genehmigte Components durchsuchen oder bitte einen Agent, Fehler zu untersuchen und das nächste Experiment auszuwählen. Der Mensch legt für jeden Versuch weniger fest und bestimmt weiterhin die Regeln für die Suche.
Die Namen der Modi beschreiben praktische Anordnungen für diese Serie und keine branchenweit standardisierte Autonomie-Skala. Was sich ändern darf und wer die Änderung auswählt, sind getrennte Entscheidungen. Optunas Beispiele für Search Spaces kombinieren die Model-Auswahl mit Parameterbereichen. Scikit-learns Pipeline Search vergleicht alternative Components durch eine gewöhnliche Grid Search. Das Ersetzen einer Component macht den Prozess daher nicht automatisch agentischer. Die Breiten der Abbildung veranschaulichen die Aufteilung der Arbeit in diesen Beispielen; sie stellen keine gemessenen Anteile von Kontrolle oder Aufwand dar.
Eine von einem Agent gesteuerte Untersuchung beschreibt, wie der nächste Versuch ausgewählt wird. Der Agent liest Fehlschläge und frühere Ergebnisse, schlägt eine Änderung vor und passt sich nach dem Test an. Das entspricht der Unterscheidung in Anthropic’s workflow and agent patterns: Ein vordefinierter Prozess kann die Ausführung automatisieren, während ein Agent seine nächsten Schritte anhand des Feedbacks bestimmt. Auch hybride Verfahren sind möglich: DSPy’s MIPROv2 verwendet ein Model, um Instructions vorzuschlagen, und Bayesian Optimization, um deren Kombinationen zu durchsuchen. Für einen festen Model-Vergleich ist kein LLM-Proposer erforderlich; seine Ergebnisse fließen in den Feedback Loop ein, wenn sie das nächste Experiment oder die nächste Systemversion bestimmen.
Berechtigungen für Vorschlag, Ausführung und Übernahme bleiben getrennt. Ein Agent kann vor jedem Run eine Änderung zur Genehmigung vorlegen oder zulässige Änderungen unbeaufsichtigt testen, während eine Person die Übernahme prüft. Eine Liste genehmigter Komponenten benötigt weiterhin kompatible Implementierungen; die Berechtigung zur Auswahl eines Adapters schließt nicht die Berechtigung ein, einen Adapter zu schreiben. In jedem Modus bleibt der Agent innerhalb der zulässigen Änderungen, der festgelegten Checks und des Budgets und kann sich keine Deployment-Freigabe selbst erteilen. Mehr delegierte Arbeit lässt außerdem Raum für Aufsicht: Anthropic’s study of deployed agents beschreibt, wie Nutzer von der Genehmigung einzelner Aktionen zur Überwachung und zum Eingreifen übergehen.
Alle Modi können dasselbe Experiment Ledger verwenden: eine Aufzeichnung jedes versuchten Changes. Halten Sie den Kandidaten und seinen Parent, den genauen Change und dessen Quelle, die Versionen von Test und Umgebung, das Ergebnis, die Kosten sowie jeden Fehlschlag oder jede Ablehnung fest. Diese Historie ermöglicht es einer Person, den nächsten Vorschlag an einen Agent zu übergeben – oder die Kontrolle wieder zu übernehmen –, ohne die Belege zu verlieren. Scores aus verschiedenen Testversionen müssen weiterhin unterschieden werden.
Diese Demo kombiniert Configuration Search mit von einem Agent gesteuerter Untersuchung. Wir definieren fünf Settings, die Tests, das Budget und die Selection Rule. Der Agent wählt anhand des Feedbacks die Werte und die nächste Hypothese; Python führt die Tests automatisch aus. Die Human Release Review bleibt davon getrennt. Das Repository akzeptiert außerdem ein candidate JSON supplied by a person über lab evaluate. Model Sweeps, Component Adapters und von Agents geschriebener Code sind weitergehende Designoptionen für spätere Abschnitte und keine implementierten Modi dieser Memory-Demo.
Warum das jetzt untersuchen?
Das Feedback-Prinzip ist aus dem Engineering vertraut. Die jüngere Arbeit, die mich interessiert, setzt Coding Agents in den Untersuchungs- und Experimentprozess ein. Sie liefert konkrete Implementierungen, die wir untersuchen können, statt von uns zu verlangen, dass wir annehmen, autonome Verbesserung werde funktionieren.
Karpathy’s autoresearch definiert ein kompaktes Experiment: Ein Trainingsprogramm ändern, es unter einem festen Training-Time-Budget ausführen, das Validation-Ergebnis prüfen und festhalten, ob der Versuch übernommen, verworfen oder mit einem Crash beendet wurde. Die Instructions trennen die editierbare Trainingsdatei vom festen Evaluationscode. Diese Trennung macht sowohl die vorgeschlagene Arbeit als auch ihr Erfolgskriterium überprüfbar.
Meta-Harness, ein Preprint vom März 2026, untersucht ein anderes Ziel: den Code, der steuert, welche Informationen eine LLM-Anwendung für ihr Model speichert, abruft und präsentiert. Sein Proposer kann über ein Dateisystem den Quellcode, die Scores und die Execution Traces früherer Kandidaten einsehen. Die Experimenthistorie wird zum Arbeitsmaterial für die nächste Untersuchung.
Diese Projekte motivieren die Engineering-Frage dieser Serie: Was muss das umgebende System leisten, sobald ein Agent Untersuchungen durchführen und Änderungen vorschlagen kann, damit diese Experimente nützlich werden? Mehr Versuche allein führen nicht zu besseren Entscheidungen. Ein schwacher Evaluator kann eine schädliche Änderung belohnen, und ein Suchprozess kann diese Schwäche wiederholt ausnutzen. Wir werden den Wert agentischer Vorschläge mit einfacheren Alternativen vergleichen, statt einen Vorteil vorauszusetzen.
Wie die sechs Teile ein System aufbauen
Die Artikel entwickeln gemeinsam ein kumulatives Companion-Projekt. Jeder Teil greift eine Frage auf, die das vorherige Experiment offenlässt, und ergänzt den Mechanismus, der für ihre Untersuchung erforderlich ist.
| Teil | Frage | Was zum selben System hinzugefügt wird |
|---|---|---|
| 1. Von Traces zu besserer Memory | Können wir einen Fehler in eine überprüfbare Verbesserung verwandeln? | Ein Memory Tool, ein LLM Proposer, begrenzte Experimente, Feedback und gespeicherte Evidenz. |
| 2. Bewertbar werden | Erkennt der Evaluator nützliche Änderungen, einschließlich scheinbarer Gewinne mit schädlichen Folgen? | Stärkere Evaluation, bewusst herbeigeführte False Wins und Prüfungen dessen, was die Scores belegen. |
| 3. Das Improvement Harness | Welche Teile können wir für verschiedene Ziele und Arbeitsmodi wiederverwenden? | Gemeinsame Execution, Historie und Berechtigungen für menschliche, klassische und LLM Proposer. |
| 4. Suchstrategien vergleichen | Wie viel Proposal-Arbeit lohnt es sich, an einen Agent zu delegieren? | Vergleiche mit menschlicher und klassischer Suche bei abgestimmten Budgets und erlaubten Änderungen. |
| 5. Assured Improvement | Welche Evidenz reicht aus, um einen scheinbaren Gewinner zu übernehmen? | Tiefere adversariale Tests, stufenweise Übernahme und Rollback-Kontrollen. |
| 6. Von der Historie zu Trainingsdaten | Können überprüfte Experimente eine gelernte Komponente verbessern? | Ein kleines Verifier- oder Policy-Training-Experiment, verglichen mit einfacheren Reparaturen. |
Privacy Checks und Human Review gehören in die erste Version. Teil 5 verstärkt diesen Schutz, sobald der Proposer zusätzliche Fähigkeiten erhält. Ebenso untersucht Teil 6 eine mögliche Nutzung der angesammelten Evidenz; jeder frühere Teil muss nützlich bleiben, ohne ein neues Model zu trainieren.
Dem äußeren Agent ein kleines, inspizierbares Ziel geben
Stell dir einen Assistant vor, der sich an Adas Kontaktdaten erinnert. Am 1. Januar erfährt er, dass sie in Berlin lebt. Am 3. Januar erfährt er von einem Umzug nach Paris, der am 10. Januar wirksam wird. Fragt man ihn am 5. Januar nach ihrer Stadt, antwortet er: Paris.
Die Memory enthält beide Fakten. Die Retrieval-Regel bevorzugt den zuletzt empfangenen, ohne zu prüfen, wann er gültig wird. Das ist ein konkreter Fehler, den ein Improvement Agent untersuchen kann.
Das Ziel ist bewusst nur ein Memory Tool, kein vollständiger Assistent. Es empfängt vorbereitete Fakten, speichert sie oder lehnt sie ab und ruft für eine Frage einen Wert ab. Writer, Datumsverarbeitung, Retrieval und Antwortauswahl sind gewöhnliches Python. Konversationsextraktion und die Generierung natürlichsprachlicher Antworten lassen wir außerhalb dieses Experiments, damit wir feststellen können, was eine Regeländerung tatsächlich bewirkt hat.
Das LLM befindet sich in der äußeren Schleife des Python-Experiments. Der Agent erhält die Testergebnisse, entscheidet, welche Einstellungen geändert werden sollen, und bekommt anschließend das nächste Ergebnis zurück. Die aufgezeichneten Kampagnen verwenden ein echtes Model, um diese Änderungen auszuwählen.
Durch diese Aufteilung können wir den Engineering Loop testen, ohne eine zweite Quelle für Model-Verhalten innerhalb des Memory Tools einzuführen. In einer größeren Anwendung könnten beide Loops Models verwenden. Hier genügt ein LLM, um den Verbesserungsprozess agentisch zu machen. Ein anderes LLM kann dieselbe Proposer-Rolle übernehmen; seine Vorschläge müssen demselben Schema folgen und dieselben Checks bestehen.
Experiment untersuchen
Das Begleit-Repository auf GitHub enthält den äußeren Agent, das Memory Tool, die Tests und kompakte Reports aus drei realen LLM-Kampagnen. Vollständige Requests, Responses und Traces sind in einem Checksum-gesicherten Evidence-Archiv verfügbar. Der Experiment-Report dokumentiert die vorgeschlagenen Änderungen, ihre gemessenen Ergebnisse und die jeweilige Entscheidung, den Prozess zu beenden. Später im Artikel verwenden wir das Repository, um eine neue Kampagne auszuführen.
Einen Test verstehen, bevor der Score gelesen wird
Ein Szenario ist eine vollständige Testgeschichte. Ein Event ist eine an das Memory Tool gesendete Aktion: Schreiben, Abfragen oder Löschen. Das Szenario mit dem zukünftigen Umzug umfasst vier Events:
city = Berlinspeichern, gültig ab dem 1. Januar.city = Parisspeichern, empfangen am 3. Januar, aber gültig ab dem 10. Januar.- Am 5. Januar nach der Stadt fragen. Berlin erwarten.
- Am 12. Januar nach der Stadt fragen. Paris erwarten.
Die Inputs sind bereits strukturiert. Der Paris-Fakt enthält beispielsweise den Owner (north Workspace, User ada), das Subject (account), die Property (city), den Value (Paris) und das Gültigkeitsdatum. Die Strings Berlin und Paris stammen aus den Testdaten und werden nicht von einem Model generiert, das Memories aus einer Konversation erstellt.
Confidence ist ein vorgegebener Score, anhand dessen entschieden wird, ob ein vorgeschlagener Fakt gespeichert wird. Der Writer vergleicht ihn mit min_confidence. Ein Vorschlag mit delivery = courier und dem Score 0.4 wird beim Baseline-Schwellenwert von 0.7 abgelehnt, bei einem Schwellenwert von 0.2 jedoch gespeichert. Der Testautor gibt den Score vor; er ist keine gemessene Wahrscheinlichkeit dafür, dass der Vorschlag korrekt ist. Wir evaluieren, wie die Storage-Regel mit diesen Scores umgeht, nicht, ob ein Model sie zuverlässig schätzen kann.
Jedes Szenario beginnt mit einer leeren Python-Liste von Memory Records. Akzeptierte Updates beenden den Gültigkeitszeitraum des vorherigen Werts und hängen einen neuen Record an. Nach den beiden City Writes beschreiben die Records Folgendes:
| Wert | Empfangen | Gültig ab | Gültig bis |
|---|---|---|---|
| Berlin | 1. Januar | 1. Januar | 10. Januar, ausgeschlossen |
| Paris | 3. Januar | 10. Januar | Kein Enddatum |
Die Answer Function gibt den ersten abgerufenen Record zurück, der zur angeforderten Property passt. Der Evaluator vergleicht diesen Wert mit der erwarteten Antwort. Ein vollständiges Szenario ist nur dann erfolgreich, wenn jede Antwort korrekt ist und jede anwendbare Data-Rule-Prüfung erfolgreich ist. Für Deletion, Owner Isolation und unzulässige Writes gibt es neben der Answer Quality eigene Prüfungen.
Die Tests übergeben die Owner IDs direkt; diese Demo verfügt über kein Authentication System. Ein echter Service muss diese IDs aus dem authentifizierten Request beziehen. Die explizite Ablehnung eines Inputs, der als Instruction gekennzeichnet ist, demonstriert außerdem nicht die Erkennung von Instructions, die in gewöhnlichem Text verborgen sind.
Gib auch der Memory ein Schema
Die Facts benötigen eigene Regeln. Für das Muster, bei dem Schemas den gespeicherten State und dessen Lifecycle steuern, verwende ich Schema-Guided Agent Memory (SGAM). Hier demonstrieren wir einen kleinen Teil davon: typisierte Facts, Ownership, Source References, Validity Intervals und Deletion. Das spätere SGR Schema steuert, was der äußere Agent vorschlagen kann; dieses Memory Schema steuert, was das Tool speichern kann.
Der Paris Record nach dem zweiten Write enthält:
{
"tenant": "north",
"user": "ada",
"entity": "account",
"key": "city",
"value": "Paris",
"confidence": 0.95,
"source": "user",
"valid_from": "2026-01-10",
"schema_version": 1,
"memory_type": "fact",
"id": "m002",
"source_event_id": "future-move:event-2",
"observed_at": "2026-01-03",
"valid_to": null,
"supersedes_memory_id": "m001"
}
source_event_id verweist auf das Event, das Paris geliefert hat. supersedes_memory_id verknüpft Paris mit dem Berlin Record, m001. schema_version: 1 identifiziert das Record-Format; es bedeutet nicht, dass das Programm alte Daten automatisch migrieren kann.
MemoryRecord und Memory.write() erzwingen dieses Format. Fehlende Source References, ungültige Datumsangaben und fehlerhafte Felder werden abgelehnt, bevor sich die gespeicherte History ändert. Ein geschlossenes Intervall muss nach seinem Beginn enden. Berlin kann am 10. Januar enden, während Paris an diesem Tag beginnt; keiner der beiden Records hat ein leeres Intervall.
Angenommen, der nächste Write lautet Rome, ebenfalls mit Wirkung ab dem 10. Januar. Der Writer lehnt diesen Konflikt ab und lässt Paris unverändert. Ein zweiter Paris Fact für dasselbe Datum verwendet den Record einfach erneut. Ein Update mit einem früheren Effective Date wird ebenfalls abgelehnt: Dieser kleine Writer rekonstruiert keine verspätet eintreffende History. Das sind feste Policies, die der äußere Agent nicht ändern kann. Seine Einstellung deduplicate steuert wiederholte Confirmations mit einem späteren Effective Date.
Die Baseline ignoriert beim Lesen weiterhin absichtlich Subject- und Date-Filter. Sie speichert gültige Records, kann aber den falschen auswählen. Diesen Fehler soll der Agent beheben. Owner Isolation gilt für jede Configuration, und Deletion entfernt alle Versionen der angeforderten Property innerhalb des Subjects dieses Owners.
Dies ist eine In-Memory-Demonstration dieser SGAM-Regeln. Es gibt keine dauerhafte Datenbank, keinen Retention Service und kein Migrationssystem. Separate Writer-Regressionstests prüfen abgelehnte Schreibvorgänge und Intervallgrenzen; sie sind keine zusätzlichen Szenarien im Score der 20-Szenarien-Kampagne.
Den Agent eine Änderung auswählen lassen
Eine Kampagne ist ein Versuch, die ursprüngliche Konfiguration zu verbessern, und beginnt mit einer neuen Agent-Historie. Eine Iteration ist ein Aufruf, in dem der Agent eine Änderung vorschlägt oder sich zum Beenden entscheidet. Die nächste Iteration erhält Feedback aus den vorherigen.
Die Kampagne beginnt damit, dass nur die Baseline ausgeführt wird. Sie besteht 13 von 20 Szenarien. Anschließend geben wir dem Agent:
- die aktuellen Einstellungen und ihre Bedeutungen;
- die Messwerte der Baseline;
- Traces aus fehlgeschlagenen Szenarien, abgelehnten Schreibvorgängen und doppelten Bestätigungen;
- die Änderungen, die er vorschlagen darf;
- frühere Vorschläge und deren Ergebnisse, sofern vorhanden.
Die erste Anfrage enthält keine fertigen verbesserten Konfigurationen. Das Repository enthält außerdem vier manuell vorbereitete Konfigurationen zur Erklärung der Memory-Mechanik, aber der Live-Agent startet nicht mit diesen Antworten.
Der Agent kann fünf Einstellungen im vorhandenen Tool ändern:
| Einstellung | Auswirkung der Änderung |
|---|---|
min_confidence | Ändert den minimal erforderlichen übermittelten Score zum Speichern eines Fakts. |
filter_entity | Beschränkt den Retrieval auf das angeforderte Thema, etwa „Zuhause“ statt „Arbeit“. |
time_aware | Beschränkt den Retrieval auf Fakten, die am angeforderten Datum gültig sind. |
deduplicate | Verwendet einen identischen aktiven Fakt erneut, statt eine weitere Bestätigung zu speichern. |
top_k | Legt fest, wie viele Records vor dem Packen des Antwortkontexts ausgewählt werden. |
Ein Vorschlag darf höchstens zwei Einstellungen ändern. Für numerische Werte gelten Grenzen: Die Confidence liegt zwischen 0 und 1, top_k zwischen 1 und 8. Der Contract dokumentiert die zulässigen Konfigurationsänderungen des Tools; das Agent-Schema und der Validator ergänzen die Regeln für Vorschläge.
Der Agent hat in diesem Prozess weder Shell- noch Filesystem-Tools. Er kann Python, erwartete Antworten, Owner-Isolation, Löschverhalten, das Memory-Schema, Konfliktbehandlung, Scoring, Budgets oder die Release-Autorität nicht ändern. Seine Ausgabe besteht aus Daten, die Python akzeptieren oder ablehnen kann. Dies ist ein kleines Konfigurationsexperiment und keine Sandbox für beliebigen, von einem Agent geschriebenen Code.
Jeden Vorschlag als SGR-Entscheidungs-Record erstellen
Ich verwende Schema-Guided Reasoning, um die Entscheidung überprüfbar zu machen. Jede Model-Antwort enthält dieselben Felder:
| Feld | Was der Leser überprüfen können sollte |
|---|---|
observations | Welches übermittelte Szenario und welches Ereignis stützen die vorgeschlagene Änderung? |
hypothesis | Welche Regel scheint das Problem zu verursachen? |
predicted_effect | Was sollte sich verbessern, wenn wir die Änderung testen? |
action | Schlägt der Agent eine Änderung vor oder beendet er den Vorgang? |
patch | Welche zulässigen Einstellungen sollten geändert werden? |
Der OpenAI-Responses-Request verwendet ein striktes JSON Schema, das aus Pydantic-Modellen generiert wird. Objekte lehnen zusätzliche Felder ab, und jedes Patch-Feld ist erforderlich, darf aber null sein – das bedeutet: „Diese Einstellung unverändert lassen.“ Structured Outputs schränkt die Form der Response ein. Python prüft weiterhin, ob Referenzen existieren, Werte zulässig sind und die vorgeschlagene Konfiguration noch nicht getestet wurde.
Das Schema beweist weder die Hypothese noch legt es die interne Reasoning des Models offen. Es handelt sich um knappe Entscheidungsprotokolle, die wir anhand von Evidenz prüfen können.
In der ersten aufgezeichneten Iteration identifizierte der Agent Retrieval über mehrere Subjects hinweg sowie Fakten, die außerhalb ihres Gültigkeitsintervalls zurückgegeben wurden. Seine tatsächliche Response schlug diesen Patch vor:
{
"min_confidence": null,
"filter_entity": true,
"time_aware": true,
"deduplicate": null,
"top_k": null
}
Diese beiden Einstellungen wurden vom Model ausgewählt. Der Runner stellte die Parent-ID bereit und vergab die Candidate-ID; das Model konnte die Änderung weder auf einen beliebigen Parent noch auf eine beliebige Datei umleiten.
Die Änderung durch Python verfolgen
Sowohl die Baseline als auch die neue Konfiguration speichern dieselben Datensätze für Berlin und Paris. Die vorgeschlagene Änderung beeinflusst, welche Datensätze Retrieval berücksichtigen darf.
In Memory.query() aktivieren diese Schalter zwei Filter:
if self.config.filter_entity:
eligible = [r for r in eligible if r["entity"] == event["entity"]]
if self.config.time_aware:
eligible = [r for r in eligible if valid_at(r, event["as_of"])]
Die Gültigkeitsprüfung schließt das Startdatum ein und das Enddatum aus:
def valid_at(item: dict, at: str) -> bool:
return item["valid_from"] <= at and (
item["valid_to"] is None or at < item["valid_to"]
)
Die Datumsangaben verwenden YYYY-MM-DD, sodass ihre String-Reihenfolge der kalendarischen Reihenfolge entspricht. Bei der Frage vom 5. Januar wird Paris ausgeschlossen, weil der Datensatz erst am 10. Januar gültig wird. Berlin bleibt verfügbar. Bei der Frage vom 12. Januar ist Paris gültig und Berlin historisch.
Python führt die vorgeschlagene Konfiguration für alle 20 Stories aus. Diese erste Änderung verbessert die Erfolgsrate von 13/20 auf 19/20; alle implementierten harten Checks bestehen. Da zwei Filter gemeinsam geändert werden, misst der Gewinn über die gesamte Suite ihren kombinierten Effekt. Der City Trace zeigt, was der Datumsfilter in diesem konkreten Fall bewirkt hat.
Der Runner wählt diese Konfiguration als Parent für das nächste Experiment aus. Diese Auswahl deployt sie nicht. Das Model erhält im nächsten Request das gemessene Ergebnis, die ausgewählten Einstellungen und die verbleibende Evidenz.
Die nächste Entscheidung muss das Ergebnis verwenden
Hier ist die vollständige erste Campaign. Jede Zeile ist eine echte Model-Response und kein vorab formulierter Schritt in einem Demonstrationsskript:
| Iteration | Vorschlag des Agents | Aktion von Python | Aktuell bestes Ergebnis |
|---|---|---|---|
| 1 | Subject- und Datumsfilter aktivieren | Validiert und getestet; Verbesserung ausgewählt | 19/20 |
| 2 | Identische Bestätigungen deduplizieren | Getestet; ausgewählt, weil der Speicherbedarf ohne schlechtere Antworten sank | 19/20 |
| 3 | min_confidence von 0.7 auf 0.6 senken | Getestet; ausgewählt, weil das letzte fehlschlagende Szenario bestand | 20/20 |
| 4 | Stoppen | Stop-Entscheidung protokolliert; keine weitere Änderung vorgenommen | 20/20 |
Die zweite Antwort verwies auf das Szenario mit doppelten Bestätigungen. Diese Story schreibt language = German dreimal. Die Deduplizierung behält einen Record statt drei bei und bewahrt dabei die Antwort. Über die gesamte Suite hinweg sank die durchschnittliche Anzahl gespeicherter Records von 1.70 auf 1.60, während der Erfolg weiterhin bei 19/20 lag.
Der dritte Vorschlag behob einen anderen Fehler. Für eine nützliche Sprachpräferenz wurde ein Confidence-Wert von 0.6 angegeben, der unter dem aktuellen Schwellenwert 0.7 lag. Durch die Absenkung des Schwellenwerts auf 0.6 wurde sie zugelassen, während der unsichere Courier-Vorschlag mit 0.4 weiterhin abgelehnt wurde. Der Erfolg stieg auf 20/20; die durchschnittliche Anzahl gespeicherter Records betrug 1.65, weil die Memory nun die zusätzliche nützliche Information behielt.
Beim vierten Aufruf entschied sich der Agent, zu stoppen: Aus den bereitgestellten Belegen ließ sich keine weitere unterstützte Änderung ableiten. Das ist eine Entscheidung des Models und kein Beleg dafür, dass die Konfiguration global optimal ist.
Die nächste Anfrage enthält die aktuellen Ergebnisse und vorherigen Entscheidungen. Nachdem der Agent festgestellt hatte, dass sein Retrieval-Fix geholfen hatte, wandte er sich der Speicherung und der Zulassung von Schreibvorgängen zu. Der Runner stellte weder diese nächsten Patches noch eine vorab formulierte Abfolge von Schritten bereit.
Die Auswahlregel ist festgelegt: Alle harten Checks müssen erfolgreich sein; anschließend wird ein besserer Erfolg im vollständigen Szenario bevorzugt, und bei gleichem Erfolg die geringere Anzahl gespeicherter Records. Ein schlechteres Ergebnis lässt den bisherigen Parent unverändert. Die Tests decken diesen Ablehnungspfad ebenfalls mit einem skriptgesteuerten, regressiven Vorschlag ab; dabei handelte es sich in diesen drei Live-Kampagnen nicht um eine gemessene Qualitätsregression.
Ein separater Development-Run enthält eine echte Validierungsablehnung: Der Agent verwies auf agent-01, eine Candidate-ID, als wäre es ein Szenario. Die Antwort entsprach dem JSON-Schema, aber ihre Referenz identifizierte kein bereitgestelltes Event. Daher lehnte Python sie vor der Evaluation ab. Der Controller gibt die abgelehnte Antwort und den spezifischen Validierungsfehler als Feedback zurück; Offline-Tests prüfen dieses Verhalten. In den drei unten berichteten Kampagnen gab es keine Validierungsfehler.
Die Search-Kampagne wiederholen, nicht den deterministischen Test
Dieselbe Memory-Konfiguration und dieselben Inputs erzeugen dieselben Antworten. Eine Wiederholung dieser Evaluation liefert keine zusätzlichen Hinweise zur Antwortqualität. Der Runner prüft eine neue Konfiguration einmal und verwendet verifizierte Parent-Ergebnisse für Vergleiche wieder.
Der äußere Agent kann unterschiedliche Vorschläge auswählen, daher haben wir drei unabhängige Kampagnen ausgeführt. Jede begann bei derselben Baseline von 13/20, erhielt eine neue History und umfasste höchstens vier Model-Entscheidungen. Keine Kampagne erhielt die Entdeckungen der vorherigen Kampagne.
| Kampagne | Model-Entscheidungen | Evaluierte Vorschläge | Vor der Evaluation abgelehnte Vorschläge | Ausgewählter Erfolg | Grund für das Ende |
|---|---|---|---|---|---|
| 1 | 4 | 3 | 0 | 20/20 | Agent stoppte |
| 2 | 4 | 3 | 0 | 20/20 | Agent stoppte |
| 3 | 4 | 3 | 0 | 20/20 | Agent stoppte |
Alle drei Kampagnen wählten dieselbe Abfolge: beide Retrieval-Filter aktivieren, Bestätigungen deduplizieren, den Confidence-Schwellenwert auf 0.6 absenken und anschließend stoppen.
Es gab 12 Model-Aufrufe: neun Vorschläge, die Python evaluierte, gefolgt von drei Stop-Entscheidungen. Jede Kampagne führte die Baseline plus drei neue Konfigurationen für 20 Stories aus: 80 Memory-Tool-Ausführungen pro Kampagne. Die 20 Stories blieben während der gesamten Kampagne unverändert.
Alle drei wählten dieselben finalen Einstellungen. Das ist eine kleine Beobachtung zu einem einzelnen Model, Prompt, Ziel und einer öffentlichen Testsuite. Sie schätzt nicht, wie zuverlässig der Optimizer unbekannte Systeme verbessern wird. Ein aussagekräftigerer Vergleich gehört an eine spätere Stelle der Serie: wiederholte Kampagnen mit identischen Budgets, konkurrierenden Proposal-Methoden und Tests, die der Proposer nicht einsehen kann.
Qualität und Kosten auf der richtigen Ebene betrachten
Das Experiment verursacht zwei unterschiedliche Kosten. Die Ausführung des Memory-Tools beansprucht lokale CPU-Zeit und führt keine Model Calls aus. Die Ausführung des äußeren Proposers verbraucht Input- und Output-Tokens. Ein Provider-Kostenfeld mit dem Wert null in einem Memory-Evaluationsbericht beschreibt nur das innere Tool; es sind nicht die Kosten der Kampagne.
Für die aufgezeichnete Studie vom 11. September 2026 verwendeten wir GPT-5.6 Luna (gpt-5.6-luna), den Reasoning-Aufwand low, das gespeicherte SGR-Schema samt Instructions und maximal 4.096 Output-Tokens pro Call. Das Programm deaktivierte automatische SDK-Retries und setzte ein Request-Timeout von 60 Sekunden. Exakte Requests, zurückgegebene Model-IDs, Usage-Daten und Call-Dauern werden aufbewahrt.
Die Token-basierte Kostenschätzung für die 12 Model Calls beträgt USD 0.039177 bei einem konfigurierten Budget von USD 0.50. Die Berechnung verwendet die veröffentlichten Model-Tarife, enthält den in den Usage-Daten ausgewiesenen Cache-Write-Aufschlag und ignoriert Cache-Read-Rabatte. Es handelt sich um eine konservative Schätzung auf Basis der aufgezeichneten Usage-Daten, nicht um eine Rechnung. Hardware- und Entwicklungszeit sind in diesem Betrag nicht enthalten.
Vor jedem Call reserviert der Runner eine obere Schätzung auf Grundlage der begrenzten Input-Größe und der maximalen Output-Tokens. Wenn das verbleibende Budget diese Reservierung nicht abdecken kann, beendet er die Ausführung. Fehlgeschlagene oder unterbrochene Calls bleiben im Datensatz erhalten; wenn keine Usage-Daten verfügbar sind, wird ihr reservierter Betrag beibehalten, statt als null behandelt zu werden.
Bei der Antwortqualität bedeutet 20/20, dass jede Antwort und jede anwendbare Hard Check für diese 20 vorbereiteten Stories bestanden wurde. Das bedeutet nicht, dass es sich um produktionsreife Memory handelt. Alle Stories sind öffentliche Entwicklungsfälle; ausgewählte Traces und das Feedback der Suite stehen dem Proposer zur Verfügung. Sie decken Updates, historische Fragen, Unsicherheit, Duplikate, Distraktoren, die Trennung von Ownern, Löschungen und unzulässige Writes ab. Die Labels search, evaluation und adversarial strukturieren die ursprüngliche Suite; sie machen keinen dieser Fälle zu einem Hidden-Test-Set.
Diese kleine Suite greift Ideen aus LongMemEval, MemoryAgentBench, VehicleMemBench und GateMem auf. Die Inputs und das Scoring stammen von uns; die Ergebnisse reproduzieren diese Benchmarks nicht.
Du kannst außerdem vier von Hand vorbereitete Konfigurationen im Repository vergleichen. Sie zeigen, warum das Akzeptieren weiterer Fakten Antworten verschlechtern kann und wie sich die Speicherung verbessern lässt, ohne die Antwortqualität zu erhöhen. Außerdem veranschaulichen sie die von Menschen spezifizierte Seite derselben Experimentinfrastruktur: Der Autor liefert die Kandidaten, und Python evaluiert sie. Sie sind nützliche Lehrvergleiche, aber kein Beleg dafür, dass agentisches Search einen kompetenten Menschen oder eine andere Search-Methode übertrifft.
Eine neue Agent-Kampagne ausführen
Damit der Agent neue Proposals auswählt, klone das Companion-Repository und lade die aufgezeichneten Nachweise herunter:
git clone --branch v0.2.2 --depth 1 https://github.com/slavadubrov/meta-engineering-ai-lab.git
cd meta-engineering-ai-lab
uv sync --frozen
uv run --frozen python scripts/fetch_evidence.py
uv run --frozen python -m lab verify artifacts/agent-study-03 --source
Der Download prüft SHA-256 und stellt die vollständigen Aufzeichnungen unter artifacts/ wieder her. Dabei werden keine Model-Aufrufe durchgeführt. Wenn du die Evidenz bereits heruntergeladen hast, überspringe diesen Schritt und führe den Verifizierungsbefehl aus.
Speichere ein OPENAI_API_KEY in einer lokalen Datei .env.local. Das Repository ignoriert diese Datei. Führe anschließend Folgendes aus:
uv run --frozen --env-file .env.local python -m lab campaign \
--live --campaigns 3 --iterations 4 --budget-usd 0.50 \
--output artifacts/my-agent-study
--live aktiviert Provider-Aufrufe explizit. Ein Key in der Umgebung macht weder die Offline-Memory-Befehle noch den Browser zu einem Live Agent. --campaigns 3 erstellt drei unabhängige Agent-Historien; --iterations 4 begrenzt die Entscheidungen innerhalb jeder einzelnen Historie. Verwende für jede Studie ein neues Output-Verzeichnis: Vorhandene Evidenz wird niemals überschrieben.
Öffne artifacts/my-agent-study/report.md für die Kampagnenergebnisse und Links zu jedem Request, jeder Response und jeder Python-Evaluation. Vergleiche die vorgeschlagenen Änderungen mit der oben aufgezeichneten Kampagne: Der Agent kann sich anders entscheiden, obwohl die Memory-Tests deterministisch sind.
Die README ordnet den Code und die Befehle zu. Der eingefrorene Kampagnenbericht sowie der Archiv-Checksum und Beispielindex ermöglichen es Leserinnen und Lesern, die Evidenz dieses Artikels direkt zu untersuchen.
Experiment-Historie von der User Memory getrennt halten
Das Memory-Tool speichert Adas Stadt und Sprache. Die Experiment-Historie speichert, was der Agent gesehen hat, den vorgeschlagenen Patch, etwaige Ablehnungen, die daraus resultierenden Messwerte und welche Konfiguration zum nächsten Parent wurde. Diese Stores erfüllen unterschiedliche Zwecke.
Jede Iteration bewahrt den exakten Request mit Instructions und Schema, die Provider-Response, Usage und Timing, das Validierungsergebnis sowie jede abgeschlossene Evaluation auf. Fehlgeschlagene Vorschläge bleiben sichtbar. File-Hashes verknüpfen die gespeicherte Evidenz mit der für das Experiment verwendeten Implementierung und den Inputs.
Diese Fakten sind synthetisch, daher kann der öffentliche Datensatz vollständige Zustände enthalten. Reale Traces benötigen eine separate Retention Policy: Wenn ein Fakt aus dem Memory-Tool gelöscht wird, werden frühere Kopien aus Experiment-Logs oder Backups dadurch nicht entfernt. Der Löschtest der Demo prüft die Records und späteren Reads des Tools, nicht die Löschung aus jedem möglichen Store.
Was der nächste Artikel hinterfragen muss
Wir haben nun einen Agent innerhalb des Improvement Loops. Er schlägt eine Änderung vor, erhält ein gemessenes Ergebnis, wählt die nächste Änderung und kann entscheiden, den Prozess zu beenden. Ungültige Vorschläge durchlaufen einen separaten Rejection Path und bleiben im Record erhalten. Seine Autorität ist auf die Konfiguration beschränkt; Testing und Release Review bleiben separate Verantwortlichkeiten.
Das nächste Risiko ist der Evaluator selbst. Wenn Erfolg dadurch belohnt wird, dass jeder Fakt behalten wird, kann der Agent lernen, auch Vermutungen zu bewahren. Wenn eine Suite nur nach der aktuellen Stadt fragt, kann sie eine Änderung übersehen, die nützliche Historie zerstört. Ein leistungsfähigerer Proposer kann schwache Messungen effizienter ausnutzen.
Part 2, Make It Scorable Before You Make It Autonomous, untersucht, wie diese Messungen getestet werden können, bevor dem Proposer mehr Freiheit gegeben wird. Die 20/20 der ersten Kampagne ist der Ausgangspunkt für diese Untersuchung.