Ein KI-Agent ohne belastbares Gedächtnis ist ein brillanter Werkstudent mit Amnesie. Er liefert montags einen sauberen Fix, vergisst die Codebase bis dienstags und führt mittwochs dieselbe Regression wieder ein. Bei CodeCourier sind wir oft gegen diese Wand gelaufen - bis wir Memory nicht mehr als Feature, sondern als Kern-Substrat behandelten. Dieser Beitrag ist der Engineering Deep Dive, wie unsere Contexts-Schicht funktioniert: Embedding-Strategie, hybride Retrieval-Pipeline, Scoping-Modell, Eval-Framework und die überraschenden Lehren, die wir unterwegs eingesammelt haben.
Ich schreibe das von Builder zu Builder. Wenn du AI agent memory für einen Coding-Agent, einen Support-Agent oder einen internen Copilot entwirfst, werden dich die gleichen architektonischen Fragen einholen. Wir benennen sie und zeigen die Antworten, die wir in Produktion geschickt haben.
1. Was ist durable context für einen KI-Agenten?
Durable agent context ist das persistente, abrufbare, gescopte Wissen, das Agenten-Läufe überlebt und zur Inferenzzeit selektiv in das Kontextfenster eines Modells injiziert wird. Anders als der Konversations-Buffer (stirbt mit der Session) und anders als Fine-Tuning (friert Wissen in Gewichte) ist durable context heißer, editierbarer, adressierbarer State, den ein Agent lesen, zitieren und aktualisieren kann - ohne Retraining.
Bei CodeCourier ist ein Context die Einheit dieses belastbaren Gedächtnisses. Konkret: ein versioniertes Bündel von Fragmenten - Absätze, Code-Beispiele, ADRs, Runbooks, Zusammenfassungen vergangener Issue Sessions, Sicherheitsrichtlinien - adressierbar per ID, gescopt auf Organisation, Repository, Persona oder Session, und indiziert für hybrid retrieval (lexikalisch plus semantisch, mit Reranker). Wenn eine neue Issue Session in einer Sandbox startet, werden die passenden Contexts automatisch ausgewählt, gerankt, komprimiert und an den Prompt geheftet.
Unsere interne Kurzform: Gewichte sind für Skills, Context ist für Fakten. Wenn das Wissen sich schneller ändert als dein nächster Trainingslauf, gehört es in die Context-Schicht.
2. Warum naives RAG bei Engineering-Agenten zerbricht
Das naive Rezept - alles chunken, embedden, Vektoren speichern, Top-K-Cosinus-Suche, an den Prompt anhängen - funktioniert einigermaßen für einen Marketing-Doc-Chatbot. Bei einem Engineering-Agenten kollabiert es schnell. Fünf Fehler-Modi, die wir im Feld gemessen haben:
- Semantischer Drift bei code-nahen Queries. Dichte Embeddings stufen "authentication" und authorization als nahe Zwillinge ein. Der Agent zieht die falsche Policy und schreibt zuversichtlich kaputte Middleware. Auf einem Golden Set lag naives Cosinus-Retrieval bei recall@10 = 0,61 für mehrdeutige Auth-Queries; unsere hybride Pipeline hob das auf 0,87.
- Chunk-Grenzen zerreißen Semantik. Ein 512-Token-Chunk schneidet mitten durch einen Funktionskörper. Der Agent bekommt die zweite Hälfte einer SQL-Transaktion und keine Ahnung, was zurückgerollt wurde.
- Top-K ist undurchsichtig. Wenn ein Agent halluziniert, brauchst du eine Postmortem. Reine Vektor-Suche hinterlässt keine Audit-Spur außer "diese acht Vektoren waren am nächsten" - nicht falsifizierbar, nicht reparierbar.
- Keine Scope-Sicherheit. Embeddings eines Tenants lecken ins Retrieval eines anderen Tenants, weil der Index global ist. Der CISO erfährt davon. Du hast eine schlechte Woche.
- Recency-Rot. Das Embedding eines sechs Monate alten ADR ist genauso "nah" wie das von gestern, das es ersetzt hat. Ohne Frische-Signal zitiert der Agent die Leiche.
Naives RAG ist eine Demo. Eine ernsthafte RAG architecture for agents braucht hybrid retrieval, strukturiertes Scoping, Frische-Signale, Zitate und eine Eval-Schleife, die Regressionen vor dem Release fängt.
3. Unsere Architektur auf einen Blick
Stell dir drei vertikale Spuren vor. Links eine Ingestion-Spur: nimmt Quelldokumente entgegen - Markdown, Code, Transkripte, frühere Agenten-Outputs - und gibt normalisierte Fragmente aus. In der Mitte eine Index-Spur: schreibt diese Fragmente parallel in einen BM25-Invertierten-Index und einen Dense-Vektor-Index, mit gemeinsamen Fragment-IDs. Rechts eine Retrieval-Spur: bedient Agenten-Queries, fächert lexikalische und dichte Suche auf, fusioniert Kandidaten, rerankt mit Cross-Encoder und gibt ein kleines, zitierbares Bündel zurück, das ins Prompt-Budget passt.
End-to-End läuft die Pipeline in sieben geordneten Stufen:
- Normalize - Rauschen entfernen, Whitespace kanonisieren, Sprache erkennen, Quell-Metadaten anhängen (repo, path, author, timestamp).
- Split - code-aware Chunking mit Overlap; AST- Grenzen für Code, Heading-Grenzen für Prosa.
- Embed - dichte Vektoren pro Fragment plus sparse lexikalische Signatur.
- Index - schreibt in Dense-Store (HNSW) und BM25-Shard, per Fragment-ID, mit Scope-Tags.
- Retrieve - pro Query parallel BM25 top-100 und dense top-100.
- Fuse + rerank - Reciprocal Rank Fusion mergt, ein Cross-Encoder Reranker scort die Top-50.
- Compose - Scope-Filter, Frische-Boosts, Citation-Graph, manuelle Pins; komprimieren und an den Agent-Prompt heften.
Jede Stufe ist unabhängig beobachtbar. Jedes Fragment, das im Prompt landet, ist zurückverfolgbar bis zum Quelldokument, zur Chunker-Version, zur Embedding-Model-Version und zum Rerank-Score. Diese Auditierbarkeit macht das System in Produktion debugbar - und ist das, was naiven RAG-Implementierungen am ersten Tag fehlt.
4. Embedding-Strategie - Modell, Chunking, Dedup
Drei Entscheidungen dominieren Embedding-Qualität: welches Modell, wie splitten, wie dedupen.
Modell-Wahl
Wir nutzen ein 1024-dimensionales General-Purpose-Embedding für Prosa und ein code-spezialisiertes Embedding für Quelldateien, in getrennten Namespaces. Modalitäten in einen Namespace zu mischen senkte Recall um rund 9 Punkte auf unserem internen Eval; das Code-Embedding zieht funktions-förmigen Inhalt in seinem eigenen Raum näher zusammen, das Prosa-Modell handhabt ADRs und Policies besser. Wir re-embedden bei jedem Model-Upgrade und halten die Vorgänger-Generation 14 Tage als Shadow-Window aktiv.
Code-aware Chunking
Generische 512-Token-Fenster zerschreddern Funktionen. Wir splitten Code an AST-Grenzen - Funktion, Klasse, Top-Level- Statement - und hängen einen Header mit Dateipfad und umschließendem Symbol an. Prosa splittet an der Heading-Hierarchie. Beide Modi halten 64 Tokens Overlap, um grenzüberschreitende Semantik zu erhalten. Mittlere Fragment-Größe: 320 Tokens; p95 bei 780.
Dedup und kanonische Fragmente
Engineering-Korpora stecken voller Near-Duplicates: dasselbe Code-Beispiel in drei Runbooks, derselbe Absatz vom Wiki ins README gespiegelt. Wir berechnen pro Fragment eine SimHash-Signatur und kollabieren Near-Duplicates (Hamming Distance ≤ 3) zu einem kanonischen Fragment mit mehreren Quell-Pointern. Das reduzierte den Index bei einem repräsentativen Tenant um 34% und verbesserte die Reranker-Präzision, weil der Cross-Encoder seine Kapazität nicht mehr an Zwillinge verschwendet.
5. Hybrid retrieval - BM25 + dense + Reranker
Hybrid retrieval ist die tragende Wand einer ernsthaften agent knowledge base. Dichte Embeddings fangen Paraphrasen; BM25 fängt exakte Identifier - Funktionsnamen, Error-Codes, Spaltennamen. Keines allein reicht.
Unser Retrieval-Call, im Pseudo-Schema:
POST /contexts/retrieve
{
"query": "warum verwirft der Rate-Limiter Requests bei Bursts?",
"scope": {
"org_id": "org_7Hk2",
"repo_id": "repo_courier-api",
"persona_id": "persona_backend-sre",
"session_id": "iss_2026-03-19-A91"
},
"budget_tokens": 3200,
"k_lexical": 100,
"k_dense": 100,
"rerank_top": 50,
"freshness_halflife_days": 90,
"min_score": 0.42
}
200 OK
{
"fragments": [
{
"id": "frag_8f21",
"doc_id": "adr_rate-limit-v4",
"version": 4,
"score": 0.913,
"tokens": 412,
"source": "runbooks/rate-limit.md#burst",
"updated_at": "2026-02-11T08:14:00Z"
}
],
"trace_id": "trc_8c1d"
}
Zahlen, an denen wir uns in Produktion messen lassen:
- recall@10 = 0,87 auf dem Engineering Golden Set (1.200 gelabelte Queries), gegenüber 0,61 mit reinem Cosinus.
- MRR@10 = 0,74 nach Cross-Encoder-Rerank.
- p50 Retrieval-Latenz = 88 ms, p95 = 240 ms bei Budget ≤ 4k Tokens, inklusive Rerank.
- Halluzinationsrate auf der Endantwort des Agenten (LLM-as-judge mit menschlichen Stichproben) fiel von 14,1% auf 3,2%, nachdem der Reranker ausgerollt war.
Der Reranker ist ein kleiner Cross-Encoder. Er scort 50 Kandidaten, wir behalten, was nach Kompression ins Token-Budget passt. Kompression ist mit Absicht dumm - wir streichen Boilerplate-Header, behalten den Heading-Pfad, paraphrasieren nie den Inhalt. Agenten zitieren exakten Text oder gar nichts.
6. Scoping und Berechtigungen - Repo, Org, Persona, Session
Scope-Sicherheit ist nicht verhandelbar. Ein einzelner Embedding-Index für mehrere Tenants ist ein Daten-Exfiltrations-Incident mit Kalender-Einladung. Wir hängen Scope-Tags zur Schreibzeit an jedes Fragment und erzwingen sie zur Abfragezeit - nicht per Post-Filter, sondern per Query-Time-Index-Partitionierung.
Vier Scopes, bottom-up ausgewertet:
- Session - ephemere Fragmente aus der aktuellen Issue Session, nur in dieser Session sichtbar.
- Persona - Fragmente an eine spezifische Persona gebunden (z. B. Backend-SRE, Frontend-Accessibility-Reviewer); sie biasen Retrieval in Richtung Persona-Domäne.
- Repository - code-nahes Wissen, gescopt auf ein Repo, erbt dessen Zugriffsrichtlinie.
- Organization - repo-übergreifendes Wissen wie Security-Policy und Brand-Voice, durch Organisationsmitgliedschaft gegated.
Zur Retrieve-Zeit wird das ACL-Set des aufrufenden Principals mit dem Scope-Set jedes Kandidaten-Fragments geschnitten. Ein Fragment ohne Überlapp wird nicht einmal gescort. Wir behandeln Scope als Korrektheits-Eigenschaft, nicht als Feature-Flag, und testen es wie Auth-Code. Die Disziplin ist in unserer Security-Übersicht dokumentiert.
7. Ranking und Frische - Recency, Citations, Pins
Relevanz ist eine Funktion aus Ähnlichkeit, Recency, Autorität und Operator-Intent. Der finale Ranker ist eine gewichtete Mischung:
score(f) = w_r * rerank(f, q)
+ w_f * exp(-age_days(f) / halflife)
+ w_c * citation_pagerank(f)
+ w_p * is_pinned(f, scope)
Gewichte sind pro Persona getunt. Die Contexts eines Security-Reviewers neigen zu Autorität (Citation-Graph und Pins); ein Frontend-Agent, der ein offenes Issue fixt, neigt zu Frische. Der Citation-Graph wird offline gebaut: wenn ein Fragment auf andere Fragmente verlinkt oder von ihnen zitiert wird, akkumuliert es PageRank-ähnliche Autorität. Manuelle Pins gewinnen immer - ein Tech Lead kann ein Fragment in einem Scope nach oben pinnen, und das System gehorcht ohne Widerrede.
Recency nutzt einen Half-Life-Decay, keinen harten Cutoff. Ein zwei Jahre alter ADR kann auftauchen, wenn nichts Frischeres existiert; ein eine Woche alter ADR zum gleichen Thema dominiert einfach. Die Half-Life ist konfigurierbar; Default sind 90 Tage für Engineering-Inhalte und 365 Tage für Policy.
8. Eval-Framework - wie wir Retrieval-Qualität messen
Retrieval-Qualität ist die einzige Zahl, die zählt, und die einfachste, sich selbst zu belügen. Unser eval framework ruht auf drei Ebenen, jede teurer und ehrlicher als die letzte.
- Golden Sets. 1.200 gelabelte Queries mit handkuratierten Ideal-Fragmenten. Läuft bei jeder Pipeline-Änderung. Recall@k, MRR@k, nDCG@k, plus Breakdowns pro Scope.
- Regression-Replays. Echte Produktions-Queries (anonymisiert und freigegeben) gegen die Kandidaten-Pipeline gespielt; wir diffen die abgerufenen Fragmente und flaggen jede Query, deren Top-3 sich um mehr als einen Token-Overlap- Schwellwert verändert.
- End-to-End-Agent-Evals. Vollständige Agenten-Läufe in isolierten Sandboxes gegen gescorte Tasks; wir beurteilen Endergebnisse mit LLM-as-judge plus menschlichen Stichproben. Nur diese Ebene misst, was wir tatsächlich ausliefern.
Jeder PR, der den Retrieval-Pfad berührt, muss die vorige Pipeline auf dem Golden Set schlagen oder mit schriftlicher Ausnahmegenehmigung landen. Die meisten Engineering-Teams investieren hier zu wenig. Wir haben Versionen ausgeliefert, die in der Demo top aussahen und in Produktion drei Punkte Recall verloren haben. Tun wir nicht mehr.
9. Überraschende Design-Entscheidungen
Weniger schreiben, mehr verlinken
Kunden versuchten, ganze Notion-Exporte und komplette Slack-Archive in Contexts zu kippen. Recall sank. Der Reranker ertrank in Near-Duplicates und der Agent verlor den Fokus. Wir bauten das UI so um, dass minimale Fragmente erzwungen werden - die kleinste Einheit, die eine Entscheidung erfasst - und ergänzten On-Demand-Link-Auflösung. Median-Fragment-Länge fiel von 1.400 Tokens auf 320. Die Halluzinationsrate fiel mit.
Struktur schlägt Prosa
Fragmente als Bulletpoint-Entscheidungs-Listen übertreffen dieselbe Information als fließende Prosa. Unsere Hypothese: der Agent behandelt Struktur als billig zu parsendes Scaffolding und verwendet mehr Aufmerksamkeit auf den Inhalt. Wir backen das in die Authoring-Guidance in unseren Guides ein.
Embeddings sind ein Tiebreaker, kein Primär-Signal
Kontraintuitiv für jeden, der mit reinem Vektor-RAG groß geworden ist, aber BM25 + Scope-Filter erledigen die Hauptlast. Das dichte Embedding klärt Gleichstände und rettet Paraphrasen-Queries. Wenn wir nur eines ausliefern könnten, wäre es BM25.
Negative Contexts funktionieren
Wir ergänzten negative Fragmente - explizite Anti-Patterns und bekannte Footguns - und sahen einen messbaren Rückgang wiederkehrender Regressionen. Bei einer Bug-Klasse eines Kunden (stille Retries, die 5xx-Errors maskieren) sanken Wiederholungs-Incidents um 41%, nachdem das Anti-Pattern-Fragment im Repo-Scope angepinnt war.
Owner oder Verfall
Jedes Fragment hat einen benannten menschlichen Owner. Wenn das System ein Fragment als veraltet markiert - oft referenziert, sechs Monate nicht editiert - bekommt der Owner einen Nudge in seinen Workflow. Ohne Owner verfällt der Index zu Zombie-Dokumentation; mit Owner verzinst er sich.
10. Naives RAG vs Contexts - Vergleich
| Dimension | Naives RAG | CodeCourier Contexts |
|---|---|---|
| Retrieval | nur Dense-Cosinus | BM25 + dense + Cross-Encoder-Rerank |
| recall@10 (Golden Set) | 0,61 | 0,87 |
| p95-Latenz | ~120 ms (ohne Rerank) | ~240 ms (mit Rerank) |
| Halluzinationsrate (Endantwort) | 14,1% | 3,2% |
| Scope-Sicherheit | Post-Filter (leaky) | Index-Partitionierung + ACL-Intersection |
| Frische | keine | Half-Life-Decay + manuelle Pins |
| Auditierbarkeit | nur Vektor-IDs | Fragment-ID + Version + Quelle + Rerank-Score |
| Authoring-Disziplin | dump and pray | minimale Fragmente + Owner + Versionen |
Die Gewinne summieren sich. Schnelleres, präziseres Retrieval macht den Prompt kleiner, senkt Inferenz-Kosten und Tail-Latenz, erlaubt mehr Schritte pro Issue Session, produziert bessere Agenten-Outputs, die als kanonische Fragmente in die Contexts zurückfließen.
11. Offene Fragen und was als Nächstes kommt
Wir sind nicht fertig. Drei Fäden sind aktiv im Flug. Team-übergreifende Contexts - ein Plattform-Team veröffentlicht einen Context, den nachgelagerte Teams ohne eigenen Fork abonnieren - ist das meistgewünschte Feature in der Queue und das schwerste, ohne Scope-Garantien zu brechen. Persona-konditioniertes Reranking nutzt die aktive Persona als zusätzliches Reranker-Feature, sodass dieselbe Query für einen SRE und einen Accessibility-Reviewer verschiedene Fragmente liefert. Workflow-aware Retrieval bindet Contexts in den Workflow Builder ein, sodass ein Schritt, der Stripe-Code editiert, automatisch das Payments-Runbook zieht, ohne dass jemand es verkabelt.
Wenn du einen tieferen Blick auf die Plattform willst, ist die CodeCourier-Startseite die schnellste Tour, und praktische Patterns dokumentieren wir laufend im Engineering-Blog. Wenn du selbst an einer Agent-Memory-Schicht baust und Notizen vergleichen willst, melde dich über Contact.
12. FAQ
Was ist AI agent memory?
AI agent memory ist das persistente, abrufbare Wissen, das ein Agent über Sessions hinweg nutzt. Es unterscheidet sich vom Konversations-Buffer (ephemer) und von Modell-Gewichten (statisch). Praktisches Agent-Memory kombiniert durable context (Fakten, Entscheidungen, Code), Retrieval (BM25 + dense + Rerank) und ein Scoping-Modell, das steuert, wer was sieht.
Warum nicht einfach das Modell auf unserer Codebase finetunen?
Fine-Tuning brennt Wissen in Gewichte - der falsche Ort für Fakten, die wöchentlich wechseln. Es ist außerdem teuer, lahm in der Iteration, schwer auditierbar und pro Tenant unmöglich zu scopen. Durable context gewinnt bei Kosten, Frische und Governance. Fine-Tuning für Skills (Stil, Format, Verhalten), nicht für Fakten.
Warum ist hybrid retrieval besser als reine Vektor-Suche?
Dichte Embeddings glänzen bei Paraphrasen, übersehen aber exakte Identifier; BM25 trifft Identifier, übersieht Paraphrasen. Beides per Reciprocal Rank Fusion und Cross-Encoder-Reranker zu fusionieren hob unseren recall@10 von 0,61 auf 0,87 auf einem gelabelten Engineering-Golden-Set.
Wie groß sollte ein Context-Fragment sein?
Kleiner als du denkst. Unser Median liegt bei 320 Tokens, p95 bei 780. Kleine Fragmente reranken präziser, komponieren besser und lassen mehr Budget für das eigene Argumentieren des Agenten.
Wie verhindert ihr, dass Tenants ineinander lecken?
Scope wird zur Abfragezeit per Index-Partitionierung und ACL-Intersection erzwungen - nicht per Post-Filter. Fragmente ohne Scope-Überlapp mit dem Aufrufer-Principal werden nie gescort. Wir testen Scope wie Auth-Code.
Wie messt ihr Retrieval-Qualität?
Drei Ebenen: ein 1.200-Query-Golden-Set mit Recall, MRR und nDCG; Replays anonymisierter Produktions-Queries mit Diff-Detection; und End-to-End-Agenten-Läufe, gescort von LLM-as-judge plus menschlichen Stichproben. Jeder PR im Retrieval-Pfad muss die vorige Pipeline schlagen oder mit explizitem Waiver landen.
Zählen Embeddings oder BM25 mehr?
BM25 trägt in unserem System mehr Gewicht, als die meisten Teams erwarten. Wenn wir nur eines ausliefern könnten, wäre es BM25 + Scoping. Das dichte Embedding verdient seinen Platz bei Paraphrasen und beim Tiebreaking zwischen Code und Prosa.
Was ist ein negative context, und warum hilft er?
Ein negative context ist ein Fragment, das ein Anti-Pattern oder einen bekannten Footgun kodiert. An einen Scope gepinnt sagt es dem Agenten, was er nicht tun soll. Wir haben bei bestimmten Bug-Klassen 30 bis 40% Rückgang bei Wiederholungs-Regressionen gemessen, nachdem das richtige Anti-Pattern-Fragment angepinnt war.
Die Context-Schicht ist der Teil einer Agenten-Plattform, der einmalige Cleverness in akkumulierende institutionelle Intelligenz verwandelt. Bau sie wie Infrastruktur - versioniert, gescopt, mit Ownern und klein - und deine Agenten hören auf, Werkstudenten mit Amnesie zu sein.