Startseite / Artikel

Kunden-Gedächtnis für KI-Agenten unter strenger Token-Budget-Beschränkung

Wie eine Agenten-Gedächtnisschicht Fakten extrahiert, die Wichtigkeit bewertet, bei einem Kosinuswert von 0,92 Duplikate entfernt, Vektoren in pgvector speichert und innerhalb einer Obergrenze von 2.048 Token mit Eviction-Logik abruft.

Verlag: REACTAPP.TOP8 Min. Lesezeit1942 Wörter

Quellen: Engineering a Multi-Agent AI Platform — Part 6: Memory Under Token Constraints

Ein Supportmitarbeiter spricht mit einem Kunden, und alles, was benötigt wird, muss in ein einziges Kontextfenster passen. GPT-4o bietet 128 K Token, während kleinere Modelle möglicherweise nur 32 K oder weniger bieten. In diesem Fenster müssen der Systemprompt, die Definitionen der Tools, das abgerufene Wissen, das laufende Gespräch sowie alles, was der Mitarbeiter über diese bestimmte Person in Erinnerung hat, untergebracht werden. Dieser Text beschreibt ein Speicherdesign für diese Konfiguration: wie Fakten aus abgeschlossenen Gesprächen extrahiert, bewertet, dedupliziert, als Vektoren gespeichert und unter strengen Tokenbegrenzungen erneut abgerufen werden.

Das Fenster ist ein Budget, kein unendlicher Speicher

Alles, was über einen Kunden bekannt ist, wird in den Prompt eingefüllt, wodurch die anderen Eingaben eingeengt werden. Die Wissensabfrage wird abgekürzt, die Gesprächshistorie gekürzt, und der Systemprompt kann so weit zurückversetzt werden, dass das Modell die eigenen Anweisungen aus den Augen verliert.

Wird nichts mitgeliefert, behandelt der Agent jedes Gespräch wie ein erstes Treffen. Ein Kunde, der nach der Zeit seines Termins fragt, erhält die Antwort „Ich habe diese Information nicht“, obwohl er sie bereits letzten Dienstag angegeben hat.

Die Lösung besteht in einer festgelegten Obergrenze für das Gedächtnis des Kunden. Im hier beschriebenen Design beträgt diese 2.048 Tokens. Innerhalb dieser Obergrenze speichert das System die für diesen Kunden in diesem Gespräch wichtigsten Fakten – nicht alle Fakten, nicht zufällige, sondern nur die richtigen.

Fakten aus abgeschlossenen Gesprächen extrahieren

Sobald ein Gespräch beendet ist, durchläuft es ein Konsolidierungsprozess, der nach wertvollen Fakten sucht, die aufbewahrt werden sollten. Die Extraktion erfolgt mithilfe eines LLM (GPT-4o-mini) unter Verwendung einer strukturierten Anfrage, die fragt, welche faktischen Informationen über den Kunden gewonnen werden können, sowie eine Bewertung jedes Faktors von 0 bis 1 hinsichtlich Spezifität, Handhabbarkeit und Häufigkeit vornimmt.

„Spezifisch“ ist das Schlüsselwort. Die Fakten müssen diesen Kunden beschreiben und keine allgemeinen Beobachtungen liefern. „Zieht Terminen am Morgen den Vorzug“ ist ein Fakt. „Stellte eine Frage“ hingegen nicht.

Das Modell antwortet mit einem JSON-Array, wobei jeder Eintrag einen Textstring sowie eine Wichtigkeitsbewertung enthält. Der Prozess übernimmt nur solche Fakten, die mindestens 0,5 Punkte erreichen. Dadurch werden unwichtige Beobachtungen, die in der Regel bei 0,2 bis 0,3 liegen, ausgeschlossen, während alles behalten wird, was später hilfreich sein könnte.

Ein typischer Austausch von zehn Nachrichten liefert zwei bis vier geeignete Fakten, während eine längere Fehlerbehebungssitzung sechs bis acht liefern kann. Die meisten Gespräche ergeben mindestens einen solchen Fakt.

Was die Wichtigkeitsbewertung darstellt

Die einzige Zahl von 0,0 bis 1,0 kombiniert drei Eigenschaften.

  • Spezifität. Wie spezifisch ist die Information für diesen Kunden? „Zieht E-Mails dem Telefon vor“ ist spezifisch, während „Ist Kunde“ es nicht ist.
  • Handhabbarkeit. Kann der Agent diese Information nutzen, um beim nächsten Mal besser antworten? „Hat ein wiederkehrendes Problem mit Rechnung #4821“ erfüllt diese Kriterien, während „Sagte Hallo“ das nicht tut.
  • Wiederholung. Wird die Information in mehreren Gesprächen relevant sein? Die Zeitzone UTC+3 taucht jedes Mal bei Terminplanungen auf, während eine Frage zum Wetter des Tages nur einmal vorkommt.

Das Team hinter der Gestaltung versuchte, separate Bewertungen pro Dimension zu verwenden, stellte jedoch fest, dass eine kombinierte Bewertung besser kalibriert ist und die Anfrage einfacher hält. Laut ihren Messungen schließt die 0,5er-Grenze etwa 60 Prozent der extrahierten Informationen aus und behält nur die hochrelevanten.

Embeddings und Doppelkontrolle

Jeder überlieferte Fakt ist als 3072-dimensionaler Vektor gespeichert, was einfach die Ausgabegröße des verwendeten Embedding-Modells ist – nämlich OpenAI’s text-embedding-3-large. Mehr Dimensionen ermöglichen präzisere Unterscheidungen bei der Ähnlichkeit, was vorteilhaft ist, wenn man eine umformulierte Wiederholung von einer wirklich neuen Information unterscheiden muss.

Bevor ein neuer Fakt gespeichert wird, wird er mit jedem vorhandenen Fakt dieses Kunden verglichen. Eine Kosinusähnlichkeit von über 0.92 bedeutet „Duplikat, überspringen“.

Warum diese Zahl? Die Menschen drücken dieselbe Sache auf viele verschiedene Weise aus. „Präferiert die E-Mail-Kommunikation“, „Möchte per E-Mail kontaktiert werden“ und „Sagte, er prüft sein Handy nicht oft und nutzt stattdessen E-Mail“ beschreiben alle denselben zugrundeliegenden Sachverhalt. Bei 0,92 erkennt das System solche semantischen Wiederholungen zuverlässig. Niedrigere Schwellenwerte wie 0,85 oder 0,88 führten dazu, dass tatsächlich unterschiedliche Fakten miteinander vermischt wurden, während höhere Werte wie 0,95 oder 0,97 es zuließen, dass zu viele Umformulierungen angesammelt werden.

Die Überprüfung findet in jedem Konsolidierungszyklus statt. Ohne sie würde ein Kunde, der in jedem Chat seine Zeitzone erwähnt, Dutzende nahezu identischer Einträge sammeln, wodurch Speicher- und Abrufkapazitäten durch Wiederholungen verschwendet würden.

Warum Postgres mit pgvector

Die Fakten befinden sich in PostgreSQL, wobei die pgvector-Erweiterung die Ähnlichkeitssuche übernimmt. Eine customer_memories-Zeile enthält:

  • content, die Tatsache als reiner Text
  • embedding, eine vector(3072)-Spalte, die für Suchvorgänge nach Ähnlichkeit verwendet wird
  • importance, die bei der Extraktion zugewiesene Bewertung
  • source_channel, wo die Tatsache erfasst wurde (Webchat, WhatsApp, Sprachkommunikation usw.)
  • created_at, Zeit des ersten Einfügens
  • last_accessed_at, letzte Zeit, zu der sie in einem Chat verwendet wurde

Eine spezielle Datenbank wie Qdrant oder Pinecone wäre die übliche Alternative, doch es gibt drei Gründe dagegen.

  1. Die Sammlungen sind sehr klein. Höchstens 500 Fakten pro Kunde. Ein separates Service hinzuzufügen bedeutet zusätzliche Netzwerkübertragungen, Verbindungsverwaltung sowie Konsistenzprobleme, die bei dieser Größe nicht notwendig sind.
  2. Transaktionen sind wichtig. Die Daten gehören zum Kundenprofil. Wenn ein Kunde gemäß GDPR gelöscht wird, müssen seine Daten zusammen mit allem anderen verschwinden. Bei pgvector handelt es sich dabei um eine einzige Transaktion, während ein separater Vektor-Speicher eine verteilte Konsistenz erfordern würde.
  3. Die Abfrage ist einfach. Filtern Sie nach customer_id mit einer exakten Übereinstimmung und sortieren Sie anschließend nach Vektorähnlichkeit – pgvector bewältigt dies effizient mit einem komplexen Index.

Die Wissensdatenbank ist eine andere Angelegenheit. Produktdokumente, FAQs und Richtlinienhandbücher befinden sich in Qdrant, weil diese Sammlung groß ist, mit Tausenden von Dokumenten pro Mieter arbeitet, starken Zugriffszahlen standhält und keine transaktionale Verbindung zu relationalen Daten benötigt. Verschiedenes Problem, unterschiedliches Werkzeug.

Aufruf mit Token-Obergrenze

Wenn eine neue Nachricht eintrifft und der Agent antworten muss, wird die Speicherabfrage aktiviert:

  1. Einbetten der eingehenden Nachricht mit demselben 3072-dimensionalen Modell, das für die Speicherung verwendet wird.
  2. Aus customer_memories die zehn nächstgelegenen Zeilen für diesen customer_id auswählen, sortiert nach der <=>-Entfernung zwischen jeder gespeicherten Embedding und dem Abfragesatz.
  3. Durch die Ergebnisse in Reihenfolge der Ähnlichkeit gehen und dabei eine laufende Token-Zählung führen.
  4. Die Anzahl der Tokens pro Faktum auf len(content) / 4 schätzen – ein grober, aber konservativer Wert.
  5. Sofort aufhören, sobald die Hinzufügung des nächsten Faktums die 2.048 Token überschreiten würde.
  6. last_accessed_at für jedes abgerufene Faktum aktualisieren.

Der Operator <=> gibt die Kosinus-Entfernung an; daher bedeutet ein kleinerer Wert eine engere Übereinstimmung mit der aktuellen Nachricht.

Die Obergrenze ist festgelegt. Der Agent erhält die relevantesten Fakten, die in 2.048 Tokens passen, sortiert nach Relevanz. Wenn der wichtigste Fakt 800 Tokens umfasst, passen vielleicht nur zwei oder drei hinein, und wenn jeder Fakt kurz ist – bei 50 bis 80 Tokens – könnten fünfzehn bis zwanzig passen. Das Budget passt sich automatisch an den tatsächlichen Inhalt an, ohne manuelle Anpassung. Die Standardwert von zehn Zeilen ist in der Praxis selten von Bedeutung, da meist zuerst die Token-Obergrenze eine Rolle spielt, doch sie verhindert, dass die Datenbankabfrage unbegrenzt wird.

Die Schreiboperation last_accessed_at erfüllt zwei Aufgaben. Sie teilt der Aussortierungsrichtlinie mit, welche Fakten weiterhin ihren Platz behalten, und zeigt an, auf welche Erinnerungen der Agent tatsächlich zurückgreift und welche ungenutzt bleiben.

Die 500-Fakten-Obergrenze und wer aussortiert wird

Ein Kunde kann maximal 500 gespeicherte Fakten haben. Diese Obergrenze sorgt für vorhersehbare Speicherkosten pro Kunde und bewahrt eine schnelle Abrufgeschwindigkeit, da die Kosinusähnlichkeit bei 500 Vektoren schnell und aussagekräftig ist, während sie bei über 50.000 Vektoren ungenau wird.

Wenn eine Konsolidierung einen Fakt speichern möchte und der Kunde bereits 500 Fakten hat, beginnt die Entfernung. Die Reihenfolge der Entfernung lautet:

  1. Fakten, die seit 90 Tagen oder länger unberührt sind und daher veraltet sowie wahrscheinlich nicht mehr relevant sind.
  2. Unter den verbleibenden Fakten der mit dem niedrigsten Wichtigkeitswert.
  3. Bei Gleichstand wird der älteste created_at-Wert berücksichtigt.

Neunzig Tage passen in den Geschäftskontext. Eine Information, die vor drei Monaten erworben wurde und seitdem nie verwendet wurde, ist unwahrscheinlich noch relevant, während eine Information, die vor sechs Monaten erworben wurde und wöchentlich genutzt wird – wie beispielsweise eine Zeitzone-Einstellung – dauerhaft bestehen bleibt, da ihr last_accessed_at ständig aktualisiert wird. Die Löschung erfolgt nach jeder Konsolidierung, die die Obergrenze erreicht, und betrifft nur das Notwendige, in der Regel eine bis drei Informationen, nicht eine massenhafte Löschung.

Erinnerung und Wissen sind unterschiedliche Dinge

Die beiden Systeme lösen unterschiedliche Probleme und konkurrieren um denselben Speicherplatz.

Die Erinnerung ist kundenbezogen, klein, persönlich und aus Interaktionen entstanden: Der Name der Tochter ist Amara, Berichte sollten in PDF-Format vorliegen, ein früherer Lieferbeschwerdefall wurde mit einem Rabatt von 15 % gelöst. Das Wissen hingegen ist mieterbezogen oder global, umfangreich, gemeinsam genutzt und von Menschen erstellt: Produktdokumentation, Preislisten, Rückgaberegelungen und Fehlerbehebungshilfen.

Jeder erhält sein eigenes Token-Budget – 2.048 für das Gedächtnis und ein größeres, in der Regel 4.096 bis 8.192, für das Wissen. Sie teilen sich das Kontextfenster des Modells, ohne sich gegenseitig zu beeinträchtigen. Selbst wenn das Gedächtnis sein gesamtes Budget ausnutzt, erhält das Wissen weiterhin sein volles Budget.

Diese Aufteilung verhindert ein problematisches Szenario. Ohne getrennte Budgets könnte ein Kunde mit 500 detaillierten Fakten alle Wissensabrufe verdrängen, wodurch der Agent sich an alles über die Person erinnern würde, aber die Produktdokumentation, die er zur Unterstützung benötigt, vergessen würde.

Wie das Gedächtnis die Tiefe des Schlussfolgerungsvermögens beeinflusst

Das Gedächtnis versorgt außerdem auf zwei Arten den Komplexitätsklassifier, der entscheidet, wie viel Schlussfolgerungsarbeit eine Anfrage erfordert.

Das Erste ist das Signal der „Kontextabhängigkeit“. Wenn die Abfrage hochrelevanten Fakten liefert, was einer geringen Kosinus-Distanz zur aktuellen Nachricht entspricht, steigt die Bewertung von context_dependency. Der Klassifikator interpretiert dies als „die richtige Antwort hängt von kundenbezogenen Daten ab“ und kann die Anfrage an eine höhere Ebene der Logikverarbeitung senden. Die Frage „Können Sie meinen Auftrag überprüfen?“ erhält eine höhere Bewertung, wenn in den gespeicherten Fakten ein ausstehender Auftrag erwähnt wird, im Vergleich zur gleichen Frage eines Kunden ohne Bestellhistorie.

Der zweite Faktor ist der Wettbewerb mit dem Denkbudget. Im vollständigen Chain-of-Thought-Modus stellt das Modell je nach Komplexität 4.096 oder 16.384 Token für das Denken zur Verfügung. In die Anfrage eingefügte Merkmalsdaten verbrauchen Token aus demselben begrenzten Fenster, sodass ein Kunde mit 2.048 Token an Speicher weniger Platz hat als einer mit 200 Token. Die Budgets werden unabhängig voneinander verwaltet, wobei jedes ein fester Obergrenzwert darstellt; daher tauscht das System sie niemals aus.

Die noch ungelösten Probleme

Zwei Schwierigkeiten sind im Architekturdiagramm nicht zu sehen.

Faktendrift. Die Präferenzen ändern sich. Was früher „Morgentermine bevorzugt“ lautete, kann nach drei Monaten zu „Nachmittagstermine bevorzugt“ werden. Das System erkennt nicht automatisch Widersprüche zwischen neuen und alten Fakten. Der Schwellenwert von 0,92 fängt diese manchmal auf, wenn die neue Angabe dem alten Ausdruck weit genug ähnelt, um übereinzustimmen – doch nicht zuverlässig. Derzeit bleiben alte Fakten aufgrund der Alters- und Zugriffsrichtlinien bestehen, und eine bessere Handhabung von Widersprüchen steht auf der Agenda.

Extraktionshalluzinationen. Das zur Extraktion verwendete LLM schließt gelegentlich Dinge ab, die niemand gesagt hat. Eine neutral gestellte Frage, die auf bestimmte Weise formuliert ist, könnte als „Kunde scheint mit dem Produkt unzufrieden zu sein“ gespeichert werden. Die Schwellenwert von 0,5 beseitigt die schwächsten Schlussfolgerungen, aber nicht alle. Die Doppelungsbeseitigung hilft indirekt, da erfundene Schlussfolgerungen selten wieder auftauchen und daher als selten genutzte Einträge verbleiben, bis sie durch Löschungen entfernt werden.

Es handelt sich hier um keine endgültige Lösung. Beide Probleme werden durch die Obergrenze, die Löschrichtlinie sowie das Zugriffsfrequenzsignal gemanagt, wodurch aktuelle, häufig genutzte und wichtige Informationen bevorzugt werden. Veraltete Vermutungen und überholte Präferenzen rücken nach hinten und werden entfernt, wenn Platz benötigt wird.

Zusammenfassung der beiden Abläufe

Nach einem Gespräch extrahiert der Konsolidierungsprozess mithilfe des LLM Fakten, bewertet deren Bedeutung, filtert bei einem Wert von 0,5, erzeugt Embeddings, entfernt Duplikate ab einem Kosinus-Schwellenwert von 0,92, speichert das Neue und löscht Inhalte, sobald die Obergrenze von 500 Fakten erreicht ist. Vor der Erstellung einer Antwort wird die eingehende Nachricht in ein Embedding umgewandelt, die wichtigsten Fakten werden anhand der Kosinus-Ähnlichkeit ausgewählt, innerhalb des 2.048-Token-Limits zusammengefasst und in den Kontext des Agents eingefügt.

Verwandte Artikel

  • Von einem einzigen großen Prompt zu einem modularen AutoGen-Einkaufsassistenten — Warum ein einzelner Chatbot-Prompt im E-Commerce versagt und wie eine AutoGen- sowie MCP-Architektur das Verständnis von Sprache von der deterministischen Geschäftslogik trennt.