magentic: LLM-Aufrufe als typannotierte Python-Funktionen
Seamlessly integrate LLMs as Python functions
Auf einen Blick
- Was ist das?
- Die Bibliothek verbindet Prompt-Templates, pydantic-Schemas und Funktionsaufrufe zu normalen Python-Funktionen. Wer Agents baut, sollte wissen, wo die Dekoratoren enden und wo eigener Code beginnt.
- Für wen ist es gedacht?
- Wer bereits pydantic-Modelle für seine Datenstrukturen pflegt und Agents aus testbaren Einzelfunktionen zusammensetzen will, findet in magentic eine naheliegende Abstraktion. Wer einen visuellen Graph-Editor, persistente Langzeit-Gesprächsspeicher oder nicht-Python-Dienste braucht, ist hier falsch.
- Darf ich es kommerziell nutzen?
- Ja. MIT 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?
- Die Aktivität lässt nach. Die letzten Commits kamen vor 6 Monaten.
- 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 die Dekoratoren schließen
Ein LLM-Aufruf in einer Python-Anwendung beginnt meist als String-Baukasten: Prompt zusammensetzen, JSON per Hand parsen, Felder validieren, Fehler abfangen. magentic dreht das um. Eine Funktion mit dem Dekorator @prompt hat keinen Rumpf, sondern nur eine Signatur. Die Parameter werden in das Template eingesetzt, der Rückgabetyp bestimmt, was das Modell liefern muss. Im README steht das Beispiel einer Funktion dudeify(phrase: str) -> str, die einen Text umformuliert. Sobald der Rückgabetyp ein pydantic-Modell ist, liefert der Aufruf ein validiertes Objekt statt eines Strings, im Beispiel eine Superhero-Instanz mit name, age, power und enemies. Adressiert sind damit Teams, die LLM-Aufrufe wie gewöhnliche Funktionsaufrufe behandeln wollen, inklusive Typprüfung durch mypy oder pyright und Autovervollständigung in der IDE. Das ist ein enges, aber klar umrissenes Ziel: keine Plattform, keine Oberfläche, eine Bibliothek für Python-Code, der bereits existiert.
Vom Template zum validierten Rückgabewert
Der Datenfluss ist in drei Stufen zerlegbar. Zuerst füllt magentic die Platzhalter im Template mit den Argumenten des Aufrufs. Bei @prompt ist das ein einzelner Text, bei @chatprompt eine Folge von Nachrichtenobjekten wie SystemMessage, UserMessage und AssistantMessage. Laut README werden Formatfelder in geschweiften Klammern in allen Nachrichten ersetzt, mit Ausnahme von FunctionResultMessage. Zweitens wird aus der Rückgabeannotation ein Schema abgeleitet, das an das Modell übergeben wird. Drittens wird die Antwort gegen dieses Schema geprüft. Schlägt die Prüfung fehl, greift der als LLM-Assisted Retries bezeichnete Mechanismus, bei dem das Modell die Gelegenheit bekommt, seine Ausgabe an das Schema anzupassen. Ein Punkt, den die Dokumentation offenlässt: wie viele solcher Versuche unternommen werden und wie der Fehler aussieht, wenn alle scheitern. Wer auf deterministisches Verhalten angewiesen ist, muss das selbst nachlesen und testen.
Funktionsaufrufe und die Rolle von prompt_chain
Bei Funktionsaufrufen kehrt sich die Richtung um. Das Modell entscheidet, welche Funktion es aufrufen will, und @prompt gibt ein FunctionCall-Objekt zurück. Dieses Objekt trägt die Funktion und die vom Modell erfundenen Argumente. Ausgeführt wird nichts automatisch: Der aufrufende Code entscheidet, wann output() ausgeführt wird. Das ist eine bewusste Trennung und der interessanteste Teil des Designs, weil sie Nebenwirkungen wie Netzwerkzugriffe oder Schreiboperationen unter Kontrolle des Anwendungsentwicklers lässt. @prompt_chain hebt diese Trennung auf. Der Dekorator löst FunctionCall-Objekte selbst auf, schickt das Ergebnis zurück an das Modell und wiederholt das, bis eine endgültige Antwort vorliegt. Im README ruft describe_weather zuerst get_current_weather auf und formuliert danach den Satz über das Wetter in Boston. Beide Varianten lassen sich verschachteln: Eine mit @prompt dekorierte Funktion kann als functions-Parameter an eine andere übergeben werden. Der README begründet das damit, dass einzelne Komponenten so isoliert getestet werden können.
Installation und die erste Konfiguration
Die Installation ist einzeilig: pip install magentic, alternativ uv add magentic. Für OpenAI genügt die Umgebungsvariable OPENAI_API_KEY. Andere Anbieter laufen über die Konfigurationsseite, die im README für OpenAI, Anthropic und Ollama verlinkt ist. Konkrete Schlüsselnamen für diese Anbieter stehen im vorliegenden Material nicht, deshalb lässt sich hier nicht sagen, welche Umgebungsvariablen oder Klassen genau zu setzen sind. Die Funktionssignaturen selbst brauchen keinen Rumpf, nur drei Punkte als Platzhalter, gefolgt von einem Kommentar, der erklärt, dass der Rumpf nie ausgeführt wird. Ein Detail mit Folgen: Werkzeugfunktionen werden über ihre Docstrings beschrieben, wie im Beispiel search_twitter mit dem Text Searches Twitter for a query. Diese Beschreibung ist das, was das Modell liest, wenn es zwischen mehreren Funktionen wählt. Schlechte Docstrings führen zu falschen Funktionsaufrufen, und dagegen hilft kein Typannotation.
Wo das Modell die Kontrolle behält
Die härteste Grenze liegt nicht im Code, sondern im Modell. Jede Funktion, die auf einem Rückgabetyp beruht, hängt davon ab, dass das Modell das Schema einhält. Die LLM-Assisted Retries mildern das, beseitigen es aber nicht. Wer eine Zahlung auslösen oder eine Datenbankzeile löschen lässt, sollte FunctionCall nicht blind ausführen, sondern die Argumente gegen eigene Regeln prüfen. Ein zweiter Punkt betrifft Streaming. StreamedStr und AsyncStreamedStr erlauben es, Text während der Generierung zu verarbeiten, aber ein gestreamter Text ist kein validiertes pydantic-Objekt. Strukturierte Ausgabe und Streaming sind zwei verschiedene Betriebsarten, und die Wahl hängt davon ab, ob der Nutzer Zeichen für Zeichen mitlesen soll oder ob nachgelagerter Code ein fertiges Objekt braucht. Ein dritter Punkt: Die Bibliothek ist auf Python festgelegt. Ein Dienst in Go oder TypeScript kann dieselben Prompts nicht über diese Abstraktion teilen.
Alternative: LangChain und der Unterschied im Ansatz
LangChain verfolgt einen anderen Ansatz. Dort werden Prompts, Modelle und Ausgabeparser als austauschbare Objekte verkettet, häufig über LCEL-Ausdrücke, und der Umfang reicht von Dokumentenladern über Vektorspeicher bis zu fertigen Agentenklassen. Der Unterschied liegt im Zentrum der Abstraktion. magentic macht die Python-Funktion zum Zentrum: Der Rückgabetyp ist das Schema, der Docstring ist die Werkzeugbeschreibung, und die Typprüfung des Editors arbeitet mit. LangChain macht die Kette zum Zentrum, was mehr fertige Bausteine mitbringt, aber auch mehr Schichten zwischen dem eigenen Code und dem Modellaufruf. Für ein Projekt, das bereits pydantic-Modelle für API-Antworten nutzt, ist der Weg über magentic kürzer. Für ein Projekt, das Dokumente indexieren, mehrere Vektordatenbanken vergleichen und einen vorgefertigten Agenten mit Speicher einsetzen will, spart LangChain Arbeit, die magentic nicht abdeckt.
Wartung, Versionen und Lizenz
Der Stand vom 11. März 2026 zeigt v0.41.1 als jüngste Veröffentlichung, davor v0.41.0 im Oktober 2025 und v0.40.0 im Juni 2025. Die Null vor dem Punkt bleibt bestehen, und die Abstände zwischen den Releases liegen bei mehreren Monaten. Das bedeutet nicht Stillstand, aber es bedeutet, dass die öffentliche Schnittstelle formell noch nicht als stabil zugesagt ist. Ein Minor-Sprung kann Verhalten ändern, das eigene Prompts betrifft. Wer magentic produktiv einsetzt, sollte die Version pinnen, statt pip install magentic ohne Einschränkung in eine Produktionsumgebung zu schreiben. Die Lizenz ist MIT, also permissiv: Nutzung, Änderung und Weitergabe sind erlaubt, sofern der Copyright-Hinweis und der Lizenztext beibehalten werden. Das ist keine Rechtsberatung, und wer die Bibliothek weiterverbreitet oder in ein größeres Werk einbettet, sollte die genauen Pflichten selbst prüfen. Für die Beobachtbarkeit verweist das README auf OpenTelemetry und eine Integration mit Pydantic Logfire, was bedeutet, dass Spans und Traces an eine externe Infrastruktur angebunden werden müssen, wenn man sie nutzen will.
Redaktionelles Fazit
Wer bereits pydantic-Modelle für seine Datenstrukturen pflegt und Agents aus testbaren Einzelfunktionen zusammensetzen will, findet in magentic eine naheliegende Abstraktion. Wer einen visuellen Graph-Editor, persistente Langzeit-Gesprächsspeicher oder nicht-Python-Dienste braucht, ist hier falsch. Vor der Übernahme sollte man die Versionsnummer pinnen, einen eigenen Provider gegen die Konfigurationsdokumentation prüfen und den Retry-Pfad mit einem absichtlich zu strengen pydantic-Modell provozieren, um zu sehen, wie sich das Verhalten bei Schema-Verstößen äußert.
Community-Notizen