Modell / Datensatz
InternLM/lagent avatar
InternLM/lagent

Lagent: Agenten als PyTorch-Schichten, mit Gedächtnis als Zustand

A lightweight framework for building LLM-based agents

2.280 Sterne243 ForksPythonApache-2.0
GitHub

Auf einen Blick

Was ist das?
Lagent ist ein schlankes Python-Framework, das Agenten nach dem Vorbild von PyTorch-Modulen aufbaut. Nachrichtenfluss, Gedächtnis und Antwortformat sind getrennte Bausteine, und genau diese Trennung ist der eigentliche Kern des Projekts.
Für wen ist es gedacht?
Wer Agenten mit klarer Trennung von Nachrichtenobjekt, Gedächtnis und Antwortformat bauen will und Python ohnehin als Zielsprache hat, findet in Lagent eine kleine, überschaubare Basis. Wer fertige Tool-Integrationen, stabile Release-Zyklen oder eine dokumentierte Migrationsstrategie braucht, sollte zuerst die Release-Historie und die readthedocs-Dokumentation prüfen, bevor er Lagent als Fundament wählt.
Darf ich es kommerziell nutzen?
Ja. Apache-2.0 ist eine freizügige Lizenz: Sie dürfen darauf aufbauende Software nutzen, verändern und verkaufen, solange Sie die Urheberrechts- und Lizenzhinweise beibehalten.
Wird es noch gepflegt?
Ja. Die letzten Commits kamen vor 2 Tagen.
In welcher Sprache ist es geschrieben?
Hauptsächlich Python, laut der Sprachstatistik von GitHub.

Die Antworten beruhen auf den GitHub-Daten des Projekts (zuletzt abgeglichen am 15. September 2026) und auf unserer Analyse. Sie sind keine Rechtsberatung.

TIEFGEHENDE OPEN-SOURCE-ANALYSE

Welche Lücke Lagent schließt

Wer einen LLM-Agenten ohne Framework baut, schreibt am Ende drei Dinge von Hand: eine Klasse, die den Gesprächsverlauf hält, eine Funktion, die diesen Verlauf in das Nachrichtenformat des jeweiligen Modells übersetzt, und einen Parser, der aus der Modellantwort strukturierte Daten zieht. Diese drei Teile wachsen in jedem Projekt unterschiedlich zusammen, und beim Wechsel des Modells bricht meist der mittlere Teil. Lagent setzt genau hier an und trennt die drei Aufgaben in benannte Objekte. Die Zielgruppe sind Python-Entwickler, die einen Agenten aufsetzen wollen, ohne eine vollständige Orchestrierungsplattform mitzunehmen. Das Repository beschreibt die Designphilosophie als an PyTorch angelehnt: Nutzer sollen nur Schichten erstellen und den Nachrichtenfluss zwischen ihnen definieren. Der Vergleich ist nicht nur rhetorisch, er zeigt sich in der API. Ein Agent verhält sich wie ein aufrufbares Objekt, und sein Zustand lässt sich serialisieren, ähnlich wie man Modellgewichte speichert. Wer bereits mit PyTorch denkt, findet die Struktur sofort wieder.

AgentMessage als Nachricht und als Protokolleintrag

Die zentrale Datenstruktur ist AgentMessage. Laut README trägt sie die Felder content, sender, formatted, extra_info, type, receiver und stream_state. Das ist mehr als ein Chat-Tupel. sender und receiver erlauben gerichtete Kommunikation zwischen mehreren Agenten, type erlaubt eine Klassifizierung der Nachricht, und stream_state zeigt über AgentStatusCode an, ob ein Streaming-Durchlauf beendet ist. In den Beispielausgaben des README steht am Ende der Nachricht stream_state=<AgentStatusCode.END: 0>. Das formatted-Feld bleibt in einfachen Beispielen None und wird erst gefüllt, wenn ein output_format konfiguriert ist. Diese Aufteilung ist die interessanteste Designentscheidung des Projekts: der rohe Modelltext bleibt in content erhalten, die geparste Struktur landet daneben in formatted. Wer also nachträglich wissen will, was das Modell tatsächlich geschrieben hat, muss nicht auf einen Parser vertrauen, der möglicherweise etwas weggelassen hat. Der Preis dafür ist ein Nachrichtenobjekt mit sieben Feldern, von denen in einem Einzelagenten-Setup vier dauerhaft leer bleiben. Das ist Ballast, aber bewusst platzierter Ballast.

Der Ablauf in __call__ und warum das Gedächtnis dort liegt

Das README zeigt den Ablauf als Pseudocode. __call__ führt pre_hooks aus, hängt die Eingabenachricht an das Gedächtnis, ruft forward auf, hängt die Ausgabenachricht an das Gedächtnis und führt post_hooks aus. Die Begründung im Text ist explizit: Das Gedächtnis wird in __call__ und nicht in forward befüllt. Das hat eine konkrete Folge für alle, die eine Unterklasse schreiben. Wer forward überschreibt, muss sich nicht um die Speicherung kümmern, bekommt aber auch keine Kontrolle darüber, wann gespeichert wird. Wer dagegen das Gedächtnisverhalten ändern will, muss __call__ überschreiben oder auf die Hooks ausweichen. Der forward selbst macht laut README drei Schritte: der Aggregator formt aus dem Gedächtnis eine Nachrichtenliste, self.llm.chat bekommt diese Liste, und bei gesetztem output_format wird die Antwort durch parse_response geschickt. Sitzungen werden über session_id getrennt, standardmäßig 0. Ein agent.reset() leert das Gedächtnis dieser Sitzung. Inspektionsmöglichkeiten gibt es zwei: agent.memory.get_memory() liefert die Liste der AgentMessage-Objekte, agent.state_dict() liefert ein Dictionary mit dem Schlüssel memory, in dem die Nachrichten als einfache Dictionaries stehen. Der zweite Weg ist der, der sich für Persistenz anbietet.

Der Aggregator als austauschbarer Übersetzer

DefaultAggregator ist die Komponente, die AgentMessage in das OpenAI-Nachrichtenformat bringt. Das README beschreibt sie als unter der Haube aufgerufen und zeigt die Signatur: aggregate(messages, name, parser, system_instruction). Wer Few-Shot-Beispiele fest in den Kontext einbauen will, leitet eine eigene Klasse ab und erweitert aggregate. Das Beispiel im README heißt FewshotAggregator, nimmt eine Liste von Dictionaries entgegen und hängt sie nach der Systemanweisung ein. Bemerkenswert ist die Zusammenführungslogik in diesem Beispiel: Aufeinanderfolgende Nutzernachrichten werden an die letzte user-Nachricht angehängt statt als neue Einträge eingefügt, und Nachrichten, deren sender dem Agentennamen entspricht, werden zu role='assistant'. Diese Zusammenführung ist eine Konvention, keine Vorschrift. Wer sie nicht will, schreibt einen eigenen Aggregator. Genau das ist die Stärke der Konstruktion: Der Übersetzungsschritt zwischen internem Format und Modellformat ist ein Objekt mit einer Methode, kein verstreuter Code. Die Kehrseite: Das README dokumentiert DefaultAggregator nur über dieses eine Beispiel. Was passiert, wenn sender weder der Agentenname noch ein Nutzer ist, lässt sich aus dem Material nicht ableiten.

Installation und der erste Aufruf

Die Installation erfolgt laut README aus dem Quelltext: git clone https://github.com/InternLM/lagent.git, dann cd lagent, dann pip install -e . Ein PyPI-Paket existiert unter dem Namen lagent, worauf das PyPI-Badge verweist. Die Modellanbindung im ersten Beispiel nutzt VllmModel mit den Argumenten path, meta_template, tp, top_k, temperature, stop_words und max_new_tokens. Als meta_template dient INTERNLM2_META, als Modellpfad Qwen/Qwen2-7B-Instruct. Der Agent selbst entsteht aus Agent(llm, system_prompt). Aufgerufen wird er mit einem AgentMessage-Objekt, das sender='user' und content trägt. Das zurückgegebene Objekt ist wieder eine AgentMessage, im Beispiel mit content='急' und sender='Agent'. Zwei Dinge fallen auf. Erstens ist die Modellanbindung nicht auf vLLM festgelegt, das README nennt VllmModel nur als Beispiel. Zweitens sind die Parameter wie tp und top_k Durchreichungen an die Inferenzschicht, keine Lagent-eigenen Konzepte. Für den Einstieg reicht der gezeigte Code, für den Betrieb muss man die Parameter der jeweiligen Modellklasse kennen, und dazu gibt das README keine Übersicht.

Grenzen: Parsing, Reifegrad und die fehlende Dokumentation im README

Die Antwortformatierung über output_format ist der fragilste Teil. Das README zeigt nur den Anfang eines Beispiels mit ToolParser und dem Systemprompt "逐步分析并编写Python代码解决以下问题。", danach bricht das Material ab. Wie ToolParser mit fehlerhaften Modellantworten umgeht, ob er eine Ausnahme wirft, None zurückgibt oder den Rohtext durchreicht, ist aus dem vorliegenden README nicht ersichtlich. Das ist relevant, weil Agenten mit Werkzeugaufrufen genau dort scheitern, wo das Modell ein Format nicht einhält. Ein zweiter Punkt ist der Reifegrad. Die Release-Liste zeigt v0.5.0rc2 vom November 2024, v0.5.0rc3 vom März 2025 und agentrl_rc0 vom Mai 2026. Alle drei tragen Release-Candidate-Kennungen. Wer auf stabile Versionen angewiesen ist, findet in diesem Material keinen Hinweis auf eine finale 0.5.0. Der letzte Push liegt laut Metadaten im August 2026, das Projekt ist also nicht archiviert und wird weiter bearbeitet. Ein dritter Punkt betrifft die Dokumentation: Das README verweist auf lagent.readthedocs.io, deckt selbst aber nur Agent, Memory, Aggregator und den Beginn der Parser ab. Alles darüber hinaus, etwa das Zusammenspiel mehrerer Agenten, ist hier nicht belegt. Wer einen Multi-Agenten-Aufbau plant, sollte die readthedocs-Seiten vor der Entscheidung lesen, nicht das README.

Wo LangChain und ähnliche Projekte anders ansetzen

Der naheliegende Vergleich ist LangChain, und der Unterschied liegt nicht im Funktionsumfang, sondern in der Richtung der Abstraktion. LangChain liefert fertige Bausteine für Werkzeuge, Datenquellen und Ketten, die man kombiniert. Lagent liefert wenige Basisklassen und erwartet, dass man die Kombination selbst schreibt. Konkret: In Lagent ist der Übersetzungsschritt zum Modellformat ein Aggregator-Objekt, das man ableitet, wenn das Standardverhalten nicht passt. In einem bausteinorientierten Framework ist derselbe Schritt meist in eine vorgefertigte Kette eingebaut und nur über Konfiguration beeinflussbar. Das macht Lagent schlanker und leichter nachvollziehbar, kostet aber alles, was nicht im Kern steckt. Ein zweiter Unterschied ist die Zustandsbehandlung. Lagent speichert das Gedächtnis im Agenten selbst, session_id-getrennt, und bietet mit state_dict() einen Serialisierungspfad. Wer den Verlauf in einer externen Datenbank halten will, muss das selbst anschließen. Wer viele fertige Integrationen braucht und weniger Kontrolle über den Nachrichtenfluss, ist bei einem größeren Framework besser aufgehoben. Wer die Kontrolle will und den Umfang klein halten möchte, bei Lagent.

Lizenz, Wartung und was vor der Übernahme zu prüfen ist

Lagent steht unter Apache-2.0. Das erlaubt kommerzielle Nutzung, Modifikation und Weitergabe, verlangt aber die Beibehaltung der Lizenzhinweise und enthält eine ausdrückliche Patentgewährung sowie eine Klausel zu Marken. Wer das Projekt forkt und unter eigenem Namen verbreitet, sollte den Markenabschnitt lesen. Das ist keine Rechtsberatung, sondern der Hinweis darauf, wo im Lizenztext die relevanten Abschnitte stehen. Zur Wartung: Die Release-Kennungen rc deuten darauf hin, dass die 0.5er-Linie noch nicht abgeschlossen ist. Ein Upgrade von v0.5.0rc2 auf v0.5.0rc3 kann daher API-Änderungen mitbringen, ohne dass das README eine Migrationsanleitung nennt. Wer Lagent produktiv einsetzt, sollte die Version in der Abhängigkeitsdatei festnageln und vor jedem Sprung die Release Notes lesen. Konkret zu prüfen sind drei Dinge: ob die eigene Modellklasse in der aktuellen Version noch dieselben Parameter akzeptiert, ob ToolParser fehlerhafte Antworten so behandelt, wie der eigene Ablauf es braucht, und ob die readthedocs-Dokumentation den geplanten Multi-Agenten-Fall überhaupt abdeckt.

Redaktionelles Fazit

Wer Agenten mit klarer Trennung von Nachrichtenobjekt, Gedächtnis und Antwortformat bauen will und Python ohnehin als Zielsprache hat, findet in Lagent eine kleine, überschaubare Basis. Wer fertige Tool-Integrationen, stabile Release-Zyklen oder eine dokumentierte Migrationsstrategie braucht, sollte zuerst die Release-Historie und die readthedocs-Dokumentation prüfen, bevor er Lagent als Fundament wählt.

Offizielle Quellen

  1. InternLM/lagent on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Community-Notizen

Community-Notizen