2 Punkte von GN⁺ 2023-10-17 | 1 Kommentare | Auf WhatsApp teilen
  • Letta ist ein Projekt zum Aufbau von KI auf Basis von fortschrittlichem Speicher, die im Lauf der Zeit lernen und sich selbst verbessern kann
  • Die Nutzung unterteilt sich in Letta Code, mit dem Agents im lokalen Terminal ausgeführt werden, und die Letta API, mit der Agents in Anwendungen integriert werden
  • Die CLI erfordert Node.js 18+; nach der Installation mit npm install -g @letta-ai/letta-code startet man mit letta einen Agent mit Speicher auf dem lokalen Computer
  • Letta-Code-Agents helfen beim Programmieren und bei Aufgaben, die auf einem Computer erledigt werden können, unterstützen skills und subagents und bringen vorgefertigte Skills/Subagents für fortschrittlichen Speicher und kontinuierliches Lernen mit
  • Letta ist modellunabhängig; das README empfiehlt Opus 4.5 und GPT-5.2 für die beste Performance und verweist zur Orientierung bei der Rangfolge auf das model leaderboard
  • Die Letta API dient dazu, zustandsbehaftete Agents in Anwendungen zu integrieren, und bietet eine voll ausgestattete Agents API sowie Python- und TypeScript-SDKs
    • TypeScript/Node.js-Paket: @letta-ai/letta-client
    • Python-Paket: letta-client
    • Das Beispiel zeigt den Ablauf, bei dem mit LETTA_API_KEY und einem Letta API key ein Agent erstellt und Nachrichten gesendet werden
  • Die Nutzung von Letta und zugehörigen Letta-Diensten setzt die Zustimmung zur privacy policy und zu den terms of service voraus

1 Kommentare

 
GN⁺ 2023-10-17
Meinungen auf Hacker News
  • Wir sind die Autoren von MemGPT. Wenn ihr Fragen zur Implementierung habt, beantworten wir sie gern.
    Wenn ihr es selbst ausprobieren möchtet, könnt ihr im Discord-Bot auf dem MemGPT-Discord-Server (https://discord.gg/9GEQrxmVyE) sehen, wie das Bearbeiten des Speichers funktioniert. Wenn man mit dem Bot spricht, sieht man, wie MemGPT den Speicher verändert, um Profile über den Nutzer und über sich selbst zu aktualisieren.
    Da alles Open Source ist, könnt ihr es auch lokal mit dem Code unter https://github.com/cpacker/MemGPT ausführen. Im Repository gibt es außerdem ein dokumentenzentriertes Beispiel, in dem man mit MemGPT über die LlamaIndex-API-Dokumentation spricht.

  • Ich frage mich, warum alles innerhalb eines einzigen Kontextfensters abgewickelt wird. Als ich vor ein paar Monaten mit etwas Ähnlichem experimentiert habe, habe ich es in Vorverarbeitungs-/Nachverarbeitungsschritten über mehrere Agenten parallelisiert.
    Zum Beispiel wusste das Haupt-Kontextfenster nicht, dass Speicher erzeugt oder durchsucht wurde; ein Nachprozessor erstellte und speicherte automatisch Speicher aus der Unterhaltung, und die gesamte Unterhaltung wurde ebenfalls in einer Vektordatenbank gespeichert. Ein Vorprozessor fügte automatisch passende Erinnerungen und Kontext für die Unterhaltung ein und schrieb sogar die History so um, dass es aus Sicht des Haupt-Kontextfensters so aussah, als wäre dieser Speicher schon immer vorhanden gewesen.
    So konnte man im Haupt-Kontextfenster viel Platz sparen, der sonst für unnötige System-Prompts usw. verbraucht worden wäre.

    • Gute Punkte. Wem man im Chatbot-Kontext die Speicherverwaltung überlässt, ist eine Designentscheidung, und ich sehe grob zwei Ansätze: implizite Speicherverwaltung und explizite Speicherverwaltung.
      Beim impliziten Ansatz weiß das „Haupt-LLM“, im Chat also der „Unterhaltungs-Thread“, nichts von der Speicherverwaltung im Hintergrund. Diese Verwaltung kann ein „Speicher-LLM“, ein regelbasiertes Skript, ein kleines neuronales Netz usw. übernehmen.
      Der explizite Ansatz entspricht MemGPT, bei dem ein einzelnes LLM alles übernimmt. Bestehende Forschung zu Multi-Session-/Long-Range-Chats verwendet in der Regel einen impliziten Ansatz mit einem separaten Speichererzeugungsprozess, und auch die Speicherablagen von Consumer-Chatbots sind wahrscheinlich größtenteils implizit.
      Explizite Speicherverwaltung erfordert komplexes Befolgen von Anweisungen, weshalb sie mit den meisten derzeit öffentlich verfügbaren LLMs schwierig ist. Wir sehen uns gerade Ansätze wie Fine-Tuning offener Modelle an, um das zu lösen.
      Die Trade-offs sind genau die, die du genannt hast. Beim impliziten Ansatz muss man nicht alle Anweisungen zur Speicherverwaltung in den Pre-Prompt des LLM packen. Die gesamte Systemnachricht von MemGPT umfasst etwa 1.000 Tokens. Umgekehrt macht explizite Speicherverwaltung das Gesamtsystem deutlich einfacher, wenn das LLM korrekt funktioniert, weil der Overhead entfällt, mehrere LLM-Modelle in parallelen Threads zu verwalten.
    • Interessanter Ansatz. Ich baue etwas Ähnliches, bei dem Transaktionsdaten als Teil des Feedback-Loops in das Kontextfenster eingefügt werden, um die History neu zu schreiben.
      Ich halte LLMs und Natural Language Processing für eine zunehmend praktikable Schnittstelle zu strukturierten Daten. Wenn in einem bestimmten Geschäftskontext Daten entstehen, werden die Daten extrahiert, Embeddings erzeugt und eine Vektordatenbank aufgebaut.
      In der Nachverarbeitung erstellt und speichert ein Nachprozessor nach der Antwort des Hauptmodells automatisch Speicher auf Basis der Unterhaltung. So wird wichtiger Kontext gespeichert, ohne das Hauptmodell mit dieser Aufgabe zu belasten. Als Teil der Anfrage wird auch relevante Business-Logik ausgeführt und anschließend zurück ins System gespeist.
      In der Vorverarbeitung prüft der Vorprozessor vor dem Senden einer neuen Eingabe an das Hauptmodell den gespeicherten Speicher, fügt relevanten Kontext ein und führt ebenfalls Logik aus. Er gibt dem Hauptmodell gewissermaßen eine „Auffrischung“ zu früheren Gesprächen, damit es konsistentere und informationsreichere Antworten vorbereitet.
    • Multi-Agenten haben ziemlich viel Potenzial. Ich denke, da Agentenantworten ein gewisses Maß an Entropie haben, lohnt es sich umso mehr, das auszuprobieren.
  • Zu dem, was bei den Einschränkungen steht: Wenn Llama-2-70B-Varianten, selbst wenn sie für Funktionsaufrufe feinabgestimmt wurden, fehlerhafte Funktionsaufrufe erzeugen oder Funktionen außerhalb des bereitgestellten Schemas halluzinieren, kann man grammatikbasiertes Sampling verwenden.
    Damit lässt sich zumindest sicherstellen, dass Funktionsaufrufe syntaktisch korrekt sind.
    [0] https://github.com/ggerganov/llama.cpp/tree/master/grammars

    • Grammatikbasiertes Sampling ist eine gute Idee und passt sehr gut zu etwas wie MemGPT. Als wir MemGPT mit Nicht-gpt-4-Modellen getestet haben, waren die Probleme mit dem größten Einfluss auf die Leistung Missbrauch von Funktionsargumenten und Funktionshalluzinationen.
      Zum Beispiel gab auch ein großes Modell, das mit Daten für Funktionsaufrufe feinabgestimmt wurde (https://huggingface.co/jondurbin/airoboros-l2-70b-2.1#agentf...), meist parsebares JSON aus, aber die Argumente oder Funktionsnamen waren falsch.
      Etwa wenn es Daten schreiben sollte, gab es statt des im Pre-Prompt angegebenen korrekten Aufrufs working_context.append einen völlig nicht spezifizierten Aufruf personal_diary.add aus.
  • Nur anhand des Titels dachte ich, es ginge um den neuronalen Speicher eines LLM, also nicht um Kontext, sondern um Speicher auf Gewichtsebene, der während eines Gesprächs verändert wird – etwa Methoden zum Memory Editing wie ROME [1].
    Ich war froh zu sehen, dass es tatsächlich eine coole RAG-Arbeit ist, und werde demnächst meine eigene Version von MemEditGPT bauen.
    [1] https://arxiv.org/abs/2202.05262

    • Wenn du beitragen möchtest, kannst du gern ein Issue oder einen PR im Repository eröffnen. Alles ist Open Source und Apache 2.0; wir prüfen aktiv, wie sich gängige Workflows in die CLI integrieren lassen.
      Wie du richtig verstanden hast, bearbeitet MemGPT nicht die LLM-Gewichte wie ROME. Der „Speicher“ in MemGPT liegt nicht auf Gewichtsebene, sondern auf Text-/Token-Ebene.
      Das Kernkonzept besteht darin, dem LLM die Fähigkeit zu geben, ein im Kontext gehaltenes Working-Memory-Scratchpad zu bearbeiten und über Funktionen externen Kontext zu lesen und zu schreiben. Ein wichtiges Detail ist, dass Lesevorgänge wegen der endlichen Kontextbegrenzung immer seitenweise, also in Chunks, erfolgen.
      MemGPT kann bei einer einzelnen Nutzereingabe Funktionen verketten und mehrfach iterativ lesen und schreiben. Dadurch kann es, wie im Beispiel zur LlamaIndex-API-Dokumentation im README, eine große Dokumentendatenbank durchsuchen, Informationen aus mehreren Quellen zusammenführen und eine Antwort zurückgeben.
  • Eine Zeit lang hatte ich den Verdacht, dass die Webversion von ChatGPT (chat.openai.com, nicht die API) innerhalb von Gesprächen ungefähr so arbeitet. Selbst bei sehr langen Chat-Historien hatte ich eher das Gefühl, dass die Qualität allmählich nachlässt, statt dass plötzlich alles vergessen wird.
    Natürlich kann es sein, dass im Kontext mehr Hinweise stecken, als ich dachte.
    Jedenfalls halte ich es für sehr wahrscheinlich, dass solche Ideen künftig zur Grundfunktion aller Chatbots werden.

    • Rekursive Zusammenfassung ist eine einfache und beliebte Methode, um die Illusion eines unendlichen Kontexts zu erzeugen. Wenn Platz frei werden muss, komprimiert man einfach die ältesten N Nachrichten zu einer einzigen Zusammenfassungsnachricht.
      Das ist verlustbehaftet und wichtige Informationen gehen letztlich verloren, aber die Leistung kann relativ sanft abfallen. MemGPT verwendet zusätzlich zu der gesamten expliziten Speicherverwaltung auch implizite rekursive Zusammenfassungen.
    • Es bleiben viel mehr Hinweise erhalten, als man denkt. Außerdem umfasst das Kontextfenster bei normalem englischem Text etwa 12 Seiten, und durch den System-Prompt wird nicht viel Platz verschwendet.
      Wenn man eine auch nur halbwegs interessante Aufgabe gestellt hat, ist die Ausgabe stark durch den Prompt geprägt. Da es nur eine einzelne Stichprobe aus vorheriger Ausgabe/Historie gibt, gehen statt einer glatten Wahrscheinlichkeitsverteilung einige Informationen verloren, und weil mehrere Eingaben auf dieselbe Ausgabe abgebildet werden können, gehen erneut Informationen verloren.
      In der Praxis sind Prompts aber oft die einfachste und kürzeste Formulierung, die einem einfällt, um das gewünschte Ergebnis zu bekommen. Wenn das LLM diesen Prompt also schätzt, ist seine Interpretation des fehlenden Kontexts wahrscheinlich halbwegs korrekt. Das heißt: Viele Informationen, die verschwunden zu sein scheinen, bleiben in der LLM-Ausgabe erhalten, und selbst wenn alter Kontext herausgeschoben wird, ist die Menge der auf einmal verlorenen Information nicht allzu groß.
    • Der Grund, warum ChatGPT Leistungseinbußen zeigt, ist, dass es nichts Besonderes tut, um den Speicher über die Kontextlänge hinaus zu erweitern.
      Es gibt viele triviale Techniken, um verlustbehafteten Speicher zu implementieren. Zum Beispiel kann man Tokens per Average Pooling zusammenfassen, ähnlich wie es Sentence Transformers tun. Ich weiß nicht genau, warum diese Methode so selten verwendet wird, um viel Kontext in einen Prompt zu komprimieren. Im Grunde wirkt sie als mittelfristiger Speicher.
    • Was geschlossene Modelle tatsächlich tun, ist nicht bekannt, aber einigen Prompt-Angriffen nach zu urteilen scheinen sie neben den in diesem Thread erwähnten Dingen auch rekursive Zusammenfassung zu verwenden.
    • Nach meinem Eindruck schneiden sie einfach nur gerade so viele der ältesten Tokens aus dem Gespräch heraus, wie nötig ist, um unter dem Token-Limit zu bleiben. Es verschlechtert sich nicht so, als hätte die Unterhaltung einen mittelfristigen Speicher.
  • Ich erinnere mich nicht an den Namen, aber es gibt bereits eine esoterische Programmiersprache, die Befehle unzuverlässig ausführt. Wenn man das Programm sorgfältig entwirft, kann man erreichen, dass Befehlssequenzen mit einer Zuverlässigkeit von 99 %, 99,9 % usw. ausgeführt werden.

    • Wahrscheinlich war es Java2000.
      20 Jahre später wurde derselbe Ansatz im Infrastrukturbereich unter dem Namen „Chaos Engineering“ ganz ohne Ironie populär.
    • Es ist Malbolge ein wenig ähnlich, aber offenbar nicht exakt dasselbe. https://en.m.wikipedia.org/wiki/Malbolge
  • Update: Ich habe gerade einen permanenten Discord-Chatbot veröffentlicht, der auf MemGPT implementiert ist. Man kann ihn hier ausprobieren: https://discord.gg/9GEQrxmVyE
    Mit dem GitHub-Code kann man lokal sowohl eine Chatbot-Demo als auch eine Demo eines Dokumenten-Q&A-Bots ausführen, dem man Fragen zur API-Dokumentation über MemGPT stellen kann.

  • Ich denke, die größte Einschränkung von LLMs ist das Kontextfenster. Selbst hervorragende Schlussfolgerungsfähigkeiten stoßen in realen Anwendungsfällen häufig an die Grenzen des Kontextfensters.

    • Genau. Ich hoffe, dass die hier vorgestellten Techniken eine Richtung aufzeigen, wie man permanente Chatbots entwerfen kann.
  • Ich stimme der Erklärung zu, dass rekursive Zusammenfassung zwar eine einfache Methode ist, um mit überlaufenden Kontextfenstern umzugehen, aber im Kern verlustbehaftet ist und am Ende große Löcher im Systemspeicher erzeugt.
    Allerdings macht MemGPT dasselbe und hat dasselbe Problem. Es unterscheidet sich nur insofern etwas, als es die Historie selektiv durchsucht und für jede Anfrage generiert, statt alles rekursiv zusammenzufassen. Die Idee ist schön.
    Ich bin aber skeptisch. Dieser Ansatz stützt sich fundamental auf die Annahmen, dass der vorhandene Kontext ein mit niedriger Entropie zusammenfassbarer Kontext ist und dass die Anfrage nur von einem Teil der Historie abhängt.
    Bei Chats oder „Fragen aus einer riesigen Dokumentensammlung beantworten“ kann das zutreffen. Aber bei Codegenerierung, wo der Kontext dicht mit nicht wegwerfbaren Informationen wie bestimmten API-Definitionen gefüllt ist und ein breiter Kontext wie viele API-Definitionen benötigt wird, sind beide Annahmen falsch.
    Struktur und Implementierung sind interessant und die Demo ist beeindruckend, aber ich finde es schade, dass Arbeiten zu Zusammenfassungen die grundlegenden Grenzen dieses Ansatzes nicht anerkennen.

    • Danke, dass du dir das Paper angesehen hast. Um Missverständnisse zu vermeiden: Rekursive Zusammenfassung ist nur ein Teil des Speichermanagements von MemGPT.
      Wie gesagt, die Gesprächs-Queue von MemGPT wird wie in früheren Arbeiten oder vielen Chatbot-Implementierungen per rekursiver Zusammenfassung verwaltet. Es gibt aber auch einen davon unabhängigen les- und beschreibbaren „festen“ Bereich des LLM-Speichers, der im Paper „Arbeitskontext“ genannt wird.
      Daher kann MemGPT sowohl auf automatisch erzeugte rekursive Zusammenfassungen als auch auf den Arbeitskontext zugreifen, den MemGPT aktiv aktuell hält.
      Beides ist außerdem getrennt vom externen Kontext von MemGPT, der per Funktionsaufruf in die Gesprächs-Queue geholt wird. In allen Beispielen erfolgt das Lesen des externen Kontexts unkomprimiert und seitenweise, ohne Zusammenfassung.
      Wenn die Queue-Zusammenfassung ausgelöst wird, erhält MemGPT eine Systembenachrichtigung. Falls also bestimmte Details aus der Gesprächs-Queue erhalten bleiben müssen, kann es sie in den Arbeitskontext schreiben, bevor sie gelöscht oder zusammengefasst werden.
      In den Beispielen für interaktive Agenten wird der Arbeitskontext verwendet, um Kernfakten über Nutzer und Agent zu speichern und so ein konsistentes Gespräch aufrechtzuerhalten. Den Arbeitskontext sieht das LLM immer, daher muss er nicht separat abgerufen werden.
      Beim Dokumenten-Q&A kann der Arbeitskontext verwendet werden, um die aktuelle Aufgabe/Frage und deren Fortschritt zu verfolgen. Bei komplexen Anfragen hilft er MemGPT, Details wie frühere Suchen oder frühere Seitenanforderungen nachzuhalten.