DSPy: Prompts systematisch optimieren statt von Hand pflegen
DSPy erklärt: Wie Signaturen, Module und Optimierer zusammenarbeiten, was der erste Versuch kostet und wann sich systematische Prompt-Optimierung lohnt.
Veröffentlicht am

DSPy lohnt einen Versuch, wenn sich eine wiederkehrende KI-Aufgabe bewerten lässt und die manuelle Pflege ihrer Prompts zunehmend Arbeit macht. Das Framework verlagert diese Arbeit in ein Python-Programm mit einer Optimierungsschleife. Der unten vorgestellte kleine Versuchsaufbau sieht bis zu 100 einstufige Programmdurchläufe vor, ohne Wiederholungsversuche. Solange im Unternehmen keine Einigkeit darüber besteht, was eine richtige Antwort ausmacht, muss zunächst diese Frage geklärt werden.
Geprüft am 15. Oktober 2026 anhand der aktuellen DSPy-Dokumentation, der Angaben auf PyPI und der Modellpreise von Google. PyPI führt DSPy 3.4.1, veröffentlicht am 12. Oktober 2026, für Python ab 3.10 bis unter 3.16. Das zu installierende Paket heißt dspy. Paketmetadaten auf PyPI.
Was ist DSPy, und was bedeutet „Kompilieren“ hier?
DSPy ist ein quelloffenes Python-Framework, mit dem sich Aufgaben für Sprachmodelle als Programme definieren lassen. Anschließend verbessert es deren Prompts oder, mit bestimmten Optimierern, die Modellgewichte. Sein Nutzen liegt darin, Verbesserungen anhand einer selbst festgelegten Erfolgsdefinition wiederholbar zu machen. Dass der erste generierte Prompt einen sorgfältig von Hand geschriebenen übertrifft, verspricht es nicht. Überblick zu DSPy.
Als Bild hilft eine Probe: Die Signatur beschreibt den Auftrag, das Modul die Durchführung und die Metrik den Bewertungsmaßstab. Der Optimierer verändert etwas, prüft das Ergebnis und behält nützliche Änderungen bei. Ohne Bewertungsmaßstab lässt sich endlos anders proben, ohne zu wissen, ob das Ergebnis besser wird.
Signaturen legen die Aufgabe fest
Eine Signatur definiert Eingaben, Ausgaben und Aufgabenanweisungen. "ticket -> category" bedeutet: Ein Ticket geht hinein, eine Kategorie kommt heraus. Eine als Klasse definierte Signatur kann typisierte Felder und einen Docstring zur Erläuterung der Aufgabe ergänzen. Die Wahl der Felder bleibt entscheidend: Ein Optimierer kann nicht ausgleichen, dass im Unternehmen unklar ist, was „dringend“ bedeutet. Dokumentation zu Signaturen.
DSPy-Module bestimmen den Ablauf
Ein Modul setzt eine Strategie zur Bearbeitung der Aufgabe um. dspy.Predict ist der grundlegende Baustein für Vorhersagen. dspy.ChainOfThought ergänzt vor der Antwort ein Feld für den Gedankengang. dspy.ReAct unterstützt eine Schleife aus Schlussfolgerungen und Tool-Aufrufen. Reicht ein einzelner Modellschritt nicht aus, lassen sich Module in Python kombinieren. Dokumentation zu Modulen.
Für die Zuordnung von Support-Tickets empfiehlt sich zunächst Predict. Eine Tool-Schleife zur Klassifizierung einer kurzen Nachricht erhöht die Komplexität, bevor überhaupt feststeht, dass sie gebraucht wird.
Kompilieren heißt hier optimieren
Ein Optimierer verändert ausgewählte Teile eines Programms anhand von Beispielen und einer Metrik. Bei der Prompt-Optimierung liefert .compile() ein Programm mit überarbeiteten Anweisungen oder Demonstrationen zurück, also Beispielen im Prompt. Daraus entsteht weder eine native ausführbare Datei, noch entfallen künftige Modellaufrufe. Das Training der Modellgewichte erfordert einen anderen Optimierer. Leitfaden zur Wahl des Optimierers.
DSPy-Tutorial: das Minimalbeispiel aus der aktuellen Dokumentation
Das aktuelle Einstiegsprogramm erzeugt ein Haiku. An diesem kleinen Beispiel wird die Schnittstelle sichtbar, ohne Datenbank, Tools oder eine Suche nach besseren Prompts einzubeziehen.
Zunächst wird die geprüfte Version in der Python-Umgebung installiert:
python -m pip install 'dspy[litellm]==3.4.1'Die Umgebungsvariable GEMINI_API_KEY muss einen gültigen API-Schlüssel für Google Gemini enthalten. Der folgende Code wird als first_dspy.py gespeichert und mit python first_dspy.py ausgeführt:
import os
import dspy
lm = dspy.LM(
"gemini/gemini-2.5-flash-lite",
api_key=os.environ["GEMINI_API_KEY"],
engine="litellm",
)
dspy.configure(lm=lm)
haiku_signature = "subject -> haiku"
haiku_generator = dspy.Predict(haiku_signature)
result = haiku_generator(subject="computer science")
print(result.haiku)Die letzten vier Zeilen entsprechen dem ersten Programm der aktuellen Dokumentation. Die Einrichtung folgt dem Muster zur Modellkonfiguration von DSPy. Als Modell kommt hier Google Gemini 2.5 Flash-Lite zum Einsatz, damit das spätere Experiment durchgehend ein günstiges Modell nutzt. Die Anbieterkennung folgt der Gemini-Integration von LiteLLM; das ausdrücklich angegebene Backend wird von der DSPy-LM-API unterstützt.
DSPy erstellt aus der Signatur einen Prompt, sendet ihn an das konfigurierte Modell und liest das zurückgegebene Feld haiku aus. Das Beispiel zeigt eine Inferenz, keinen Optimierungslauf. Es wird hier weder ein bestimmtes Gedicht noch eine Qualitätsverbesserung zugesichert.
Prompt-Optimierung mit DSPy braucht eine Metrik
Ohne Metrik keine aussagekräftige Optimierung. Eine Metrik ist eine Funktion, die eine Vorhersage in einen Bewertungswert übersetzt. Bei der Ticketzuordnung kann sie die vorhergesagte Kategorie mit einem von Menschen bestätigten Label vergleichen. Bei einer generierten Antwort kann die Bewertung der Korrektheit ein Kriterienraster oder eine ausführbare Prüfung erfordern. Die Metrikschnittstelle von DSPy nimmt die Bewertungsfunktion entgegen; was das Unternehmen belohnen sollte, entscheidet das Framework nicht. Metriken und Evaluation.
Deshalb ist ein kleiner Evaluationsdatensatz mit Labels so wichtig. Statt immer wieder „Fasse dich kurz“ in „Antworte knapp“ umzuschreiben, lohnt es sich, tatsächliche Fehler zu sammeln: eine Erstattungsanfrage, die beim technischen Support landet, ein Anmeldeproblem, das als Rechnungsfrage eingestuft wird, oder eine Nachricht mit zwei Anliegen. Das gewünschte Ergebnis wird festgelegt, bevor die Ausgabe eines neuen Prompts betrachtet wird.
Für einen ersten Pilotversuch bieten sich 60 unterschiedliche Beispiele an, bewusst aufgeteilt in 20 Trainings-, 20 Validierungs- und 20 abschließende Testbeispiele. Diese Größen sind ein Vorschlag für den Versuch, weder Vorgaben von DSPy noch ein Nachweis für Zuverlässigkeit im Produktivbetrieb.
- Trainingsbeispiele liefern Material, aus dem der Optimierer lernen kann.
- Validierungsbeispiele helfen beim Versionsvergleich und bei Entwicklungsentscheidungen.
- Abschließende Testbeispiele bleiben unangetastet, bis der Kandidat und die Bewertungsregeln feststehen.
Zusammengehörige Tickets desselben Kunden oder Vorfalls müssen derselben Teilmenge zugeordnet werden. Andernfalls können nahezu identische Beispiele den Eindruck erwecken, ein optimierter Prompt lasse sich besser verallgemeinern, als es tatsächlich der Fall ist. Auch seltene, aber relevante Fehler gehören in den Datensatz; die Teilmengen sollten nicht ausschließlich aus einfachen Fällen bestehen.

Zur Aussage „ohne Metrik“ gehört eine genaue Einschränkung: Ein unoptimiertes DSPy-Programm lässt sich auch ohne Metrik ausführen, und LabeledFewShot kann Beispiele hinzufügen, ohne sie zu bewerten. Das ist Konfiguration, aber kein Beleg dafür, dass eine Änderung die Aufgabe besser löst. Ebenso braucht nicht jede Aufgabe eine von Hand geschriebene Referenzantwort: Eine ausführbare Korrektheitsprüfung kann das nötige Signal liefern. Für Klassifizierungsaufgaben im Unternehmen sind bestätigte Labels meist der klarste Ausgangspunkt. Few-Shot-Baseline.
DSPy-Optimierer: Welche Namen stehen in der aktuellen Dokumentation?
Der beste Einstieg ist der einfachste Optimierer, der einen konkret benennbaren Fehler angeht. Eine umfangreichere Suche hilft nur, wenn die Metrik bessere Kandidaten von schlechteren unterscheiden kann.
Der aktuelle API-Index der Optimierer enthält genau diese Einträge: BetterTogether, BootstrapFewShot, BootstrapFewShotWithRandomSearch, BootstrapFinetune, BootstrapRS, COPRO, Ensemble, GEPA, InferRules, KNN, KNNFewShot, LabeledFewShot, MIPROv2 und SIMBA.
Nicht hinter jedem Eintrag steht ein eigenständiger Suchalgorithmus. BootstrapRS ist ein Alias für BootstrapFewShotWithRandomSearch; KNN ist die von KNNFewShot verwendete Hilfskomponente zum Abrufen von Beispielen. Der aktuelle Auswahlleitfaden nennt außerdem AvatarOptimizer für agentenartige Programme, obwohl dieser im API-Index fehlt. Details zur Optimiererfamilie, Auswahlleitfaden.
MIPROv2 schlägt Anweisungen vor und untersucht Kombinationen aus Anweisungen und Demonstrationen mithilfe Bayes'scher Optimierung. Dabei fließen bisherige Bewertungen in die weitere Suche ein. SIMBA arbeitet mit kleinen Datenstapeln, sogenannten Minibatches, und schlägt Regeln oder Demonstrationen vor. Das sind unterschiedliche Ansätze, keine umbenannten Varianten von BootstrapFewShot. MIPROv2-API, SIMBA-API.
GEPA lässt ein Reflexionsmodell die Rückmeldungen aus Programmausführungen auswerten und Änderungen an den Anweisungen vorschlagen. Eine Bewertung mit einer konkreten Erklärung wie „Erstattungsanfragen gehören zur Abrechnung, auch wenn sie ein defektes Feature erwähnen“ liefert ein hilfreicheres Signal als ein bloßer Fehlerwert. Die ausführliche Dokumentation lässt rein numerische Metriken zu, erläutert aber, dass dabei die reichhaltigeren Rückmeldungen verloren gehen. Funktionsweise von GEPA.
Den ersten Optimierungslauf klar begrenzen
Ein kleines Experiment mit BootstrapFewShot lässt sich leichter kalkulieren als eine offene Suche nach besseren Anweisungen. Der folgende Aufbau verwendet ein Predict-Modul, eine deterministische Metrik für die Labels und dasselbe Modell für die Rolle des Lehrers und für die Vorhersagen.
DSPy BootstrapFewShot: ein bewusst kleiner Durchlauf
Benötigt werden train.jsonl, validation.jsonl und test.jsonl mit jeweils 20 unterschiedlichen, von Menschen gelabelten Tickets. Jede Zeile enthält ein JSON-Objekt mit text und label; zulässige Labels sind billing, technical, account und other. Eine Bitte um Änderung der Rechnungsadresse könnte beispielsweise das Label billing erhalten. Hier werden eigene Beispiele gebraucht, keine Haiku-Ausgaben.
Dieses separate Skript wird als optimize_tickets.py gespeichert und nach dem Setzen desselben API-Schlüssels ausgeführt:
import json
import os
from typing import Literal
import dspy
lm = dspy.LM(
"gemini/gemini-2.5-flash-lite",
api_key=os.environ["GEMINI_API_KEY"],
engine="litellm",
cache=False,
)
dspy.configure(lm=lm)
class RouteTicket(dspy.Signature):
"""Choose the support queue responsible for the ticket's main request."""
text: str = dspy.InputField()
label: Literal["billing", "technical", "account", "other"] = (
dspy.OutputField()
)
def load_examples(path):
with open(path, encoding="utf-8") as source:
rows = [json.loads(line) for line in source if line.strip()]
assert len(rows) == 20
return [dspy.Example(**row).with_inputs("text") for row in rows]
train = load_examples("train.jsonl")
validation = load_examples("validation.jsonl")
test = load_examples("test.jsonl")
assert len({e.text for e in train + validation + test}) == 60
def correct_label(example, prediction, trace=None):
return prediction.label == example.label
program = dspy.Predict(RouteTicket)
evaluate = dspy.Evaluate(
devset=validation, metric=correct_label, num_threads=1
)
print("Baseline validation:", evaluate(program).score)
optimizer = dspy.BootstrapFewShot(
metric=correct_label,
max_bootstrapped_demos=4,
max_labeled_demos=0,
max_rounds=1,
)
optimized = optimizer.compile(program, trainset=train)
print("Optimized validation:", evaluate(optimized).score)
# Freeze this candidate before opening the final test results.
final_test = dspy.Evaluate(
devset=test, metric=correct_label, num_threads=1
)
print("Baseline final test:", final_test(program).score)
print("Optimized final test:", final_test(optimized).score)
optimized.save("candidate_ticket_router.json")Dies ist eine Anpassung auf Grundlage des dokumentierten BootstrapFewShot-Konstruktors und der Evaluationsschnittstelle, kein behauptetes Benchmark-Ergebnis. Der Aufbau fordert bis zu vier erfolgreiche Demonstrationen an, erlaubt einen Bootstrap-Versuch je Trainingsbeispiel und ergänzt keine unveränderten gelabelten Demonstrationen. Die gespeicherte Datei ist ein Kandidat zur Prüfung; sie wird nicht automatisch für den Produktivbetrieb freigegeben.
Für diesen Aufbau ergibt sich folgende Rechnung:
- Baseline auf dem Validierungsdatensatz: 20 Programmdurchläufe.
- Bootstrapping auf dem Trainingsdatensatz: bis zu 20 Lehrermodell-Durchläufe, gegebenenfalls weniger, sobald genügend Demonstrationen die Prüfung bestehen.
- Optimiertes Programm auf dem Validierungsdatensatz: 20 Programmdurchläufe.
- Beide Versionen auf dem abschließenden Testdatensatz: 40 Programmdurchläufe.
Insgesamt sind das bis zu 100 einstufige Durchläufe, einschließlich Evaluation; auf die Kompilierung allein entfallen höchstens 20. Bei genau einer erfolgreichen Modellanfrage je Durchlauf, ohne Wiederholungsversuche und ohne Ausweichverfahren beim Parsen, ergeben sich daraus höchstens 100 Aufrufe des Aufgabenmodells. Der vorherige Haiku-Funktionstest wird separat gezählt. Ein LLM als Bewerter, eine Agentenschleife, Wiederholungsversuche oder ein weiterer Optimierungsversuch verändern die Gesamtzahl.

Bei Googles Standard-Listenpreisen für kostenpflichtige Textverarbeitung mit Gemini 2.5 Flash-Lite von $0.10 je Million Eingabetokens und $0.40 je Million Ausgabetokens kosten 100 Aufrufe mit angenommenen durchschnittlich 1,000 Eingabe- und 100 Ausgabetokens $0.014: 100,000 ÷ 1,000,000 × $0.10 + 10,000 ÷ 1,000,000 × $0.40. Googles Preisübersicht.
Das ist eine reine Modellkostenrechnung, weder eine gemessene Rechnungssumme noch eine Ausgabenobergrenze. Die Annahme zu den Eingabetokens muss die Formatierung durch DSPy und die angehängten Demonstrationen einschließen. Längere Tickets, umfangreichere Ausgaben und kostenpflichtige Denkschritte erhöhen den Betrag. Batch- oder Cache-Rabatte sind in der Schätzung nicht enthalten. Maßgeblich ist die tatsächliche Verbrauchsaufstellung des Anbieters.
DSPy im Vergleich zu manuellen Prompts und Fine-Tuning
DSPy eignet sich, wenn ein messbares Programm auf wiederholbare Weise verbessert werden soll. Erfüllt ein von Hand geschriebener Prompt die Anforderungen bereits, kann er bleiben. Fine-Tuning kommt infrage, wenn es Belege dafür gibt, dass Prompt-Änderungen nicht ausreichen, und ein Modelltraining zu den Rahmenbedingungen des Betriebs passt.
Diese Verfahren lassen sich miteinander verbinden. DSPy enthält BootstrapFinetune, und BetterTogether kombiniert Prompt- und Gewichtsoptimierung. Für die Praxis zählt, was verändert und gepflegt wird, nicht welcher Begriff fortschrittlicher klingt. Prompt- und Gewichtsoptimierung.
Der entscheidende Punkt zeigt sich im Betrieb: Muss bei jedem Modellwechsel oder neuen Fehlerfall jemand mehrere Prompts von Hand überarbeiten, wird eine anhand von Bewertungen gesteuerte Optimierungsschleife interessant. Erfüllt ein kurzer Prompt die Abnahmekriterien bereits, ist der Nutzen eines Framework-Wechsels nicht belegt.
Für wen lohnt sich DSPy – und wer sollte warten oder darauf verzichten?
Für Entwickler lohnt sich der Einstieg bei einer wiederkehrenden Aufgabe, einer funktionierenden Baseline und repräsentativen Fehlerfällen. Ticketzuordnung und strukturierte Extraktion sind geeignete Ausgangspunkte, weil sich die erwarteten Ausgaben prüfen lassen. Zunächst sollte eine kleine Komponente optimiert werden, bevor das System wächst. Die Grenze von DSPy liegt in der Qualität des Optimierungsziels: Es kann einen Kandidaten mit höherem Bewertungswert auswählen, obwohl die Metrik das falsche Verhalten belohnt.
Die Prozessverantwortlichen sollten Labels und Fehlerprioritäten festlegen. Für eine Supportleitung kann ein falsch zugeordneter Vorfall beim Kontozugriff deutlich schwerer wiegen als eine gewöhnliche Rechnungsfrage. Gewichtet die Bewertung beide gleich, kann die Optimierung den Prioritäten der Leitung widersprechen. Diese Regel muss geklärt werden, bevor die Entwicklung den Auftrag erhält, den Bewertungswert zu verbessern.
Einkaufsverantwortliche sollten Nachweise anhand bisher ungesehener Beispiele verlangen. Zu klären ist, welche Baseline als Vergleich diente, welche Fälle sich verschlechtert haben, welche Bestandteile das Programm bei der Ausführung nun enthält und ob der Ablauf seine Latenzanforderungen weiterhin erfüllt. Der Name eines Optimierers ist kein Abnahmenachweis. Die Promptfoo-Besprechung auf dieser Website bietet ergänzende Lektüre für Teams, die ihre Evaluationsarbeit organisieren.
Für gelegentliches Texten, einmalige Recherchen oder Abläufe, die sich schneller ändern, als Beispiele gesammelt werden können, sollten Fachteams auf DSPy verzichten. Das gilt auch, wenn niemand Python-Code pflegen kann oder Einigkeit über eine Bewertungsregel fehlt. Ein guter Prompt, eine Checkliste und menschliche Prüfung können die angemessenere Lösung sein. Abwarten ist sinnvoll, wenn das eigentliche Problem fehlende Quelldaten oder ein undefinierter Prozess sind: Eine bessere Formulierung liefert weder das eine noch das andere.
Welche Versprechen rund um DSPy gehen zu weit?
„Programmieren statt Prompten“ lässt Prompts nicht verschwinden. DSPy erzeugt und verwaltet sie; Menschen definieren weiterhin die Aufgabe, beurteilen Fehler und entscheiden, ob das Ergebnis akzeptabel ist.
„Kompilieren“ bedeutet nicht, dass das Modell dauerhaft etwas gelernt hat. Bei Prompt-Optimierern besteht das gelernte Ergebnis aus Anweisungen oder Demonstrationen. Zur Inferenz wird weiterhin ein Modell aufgerufen, und Demonstrationen belegen Platz im Prompt. Der gelernte Zustand lässt sich als JSON speichern und in ein frisches Programm laden. Speichern und Laden.
„Automatische Optimierung“ garantiert keinen Erfolg. Der aussagekräftige Vergleich ist der mit dem bisherigen Verfahren anhand ungesehener Eingaben. Eine höhere Bewertung während der Entwicklung kann auf Überanpassung, einen zu nachsichtigen Bewerter oder einen Datensatz zurückgehen, in dem kostspielige Fehler fehlen.
Außerdem gilt: Metrikaufrufe sind keine Anbieteraufrufe. Bei GEPA begrenzt max_metric_calls die Anzahl der Bewertungsaufrufe. Die Reflexion ruft ebenfalls ein Modell auf, und das bewertete Programm kann seinerseits mehrere Anfragen auslösen. Die auto-Einstellungen stehen daher für keinen allgemeingültigen Rechnungsbetrag. Budgetsteuerung bei GEPA.
Häufige Entwicklerfragen zu DSPy
Wie funktioniert DSPy?
Eine Signatur legt Eingaben und Ausgaben fest. Dazu werden Module ausgewählt oder kombiniert und ein Sprachmodell konfiguriert. Ein Adapter erstellt die Nachrichten und liest die Ergebnisse aus. Anschließend kann ein Optimierer ausgewählte Programmteile anhand von Beispielen und einer Metrik verbessern.
Ist DSPy für den Produktivbetrieb geeignet?
Die Eignung für den Produktivbetrieb muss am konkreten Programm beurteilt werden. Dazu gehören eine festgelegte Paketversion und Modellkonfiguration, eine aufbewahrte Baseline, Tests repräsentativer Fehlerfälle und definierte Kriterien für eine Rückkehr zur vorherigen Version. Dass eine aktuelle Veröffentlichung existiert, bescheinigt dem eigenen Ablauf keine Produktionsreife.
Ist DSPy noch relevant?
Ja, für wiederkehrende, messbare Aufgaben mit Sprachmodellen, deren Prompts gepflegt werden müssen. Geringer ist der Nutzen, wenn ein einfacher Prompt den Bedarf bereits deckt oder der Aufgabe eine stabile Bewertungsregel fehlt.
Was unterscheidet LangChain von DSPy?
LangChain ist ein Framework zum Aufbau von Agenten mit Modell- und Tool-Integrationen. DSPy zeichnet sich dadurch aus, Modellaufgaben zu deklarieren und Programme anhand von Metriken zu optimieren. Die Wahl richtet sich nach dem Problem: Sollen die Komponenten eines Agenten verbunden oder eine bewertbare Aufgabe systematisch verbessert werden? Überblick zu LangChain.
Lassen sich mit DSPy Prompts optimieren?
Ja. Je nach Optimierer kann DSPy Demonstrationen auswählen, Anweisungen überarbeiten oder beides gemeinsam durchsuchen. Die Prompt-Optimierung lässt die zugrunde liegenden Modellgewichte unverändert; Fine-Tuning ist ein gesonderter Weg.
Wer hat DSPy entwickelt?
DSPy wurde von Omar Khattab und Mitwirkenden entwickelt. Das Repository wird unter Stanford NLP gepflegt; der wissenschaftliche Zitierhinweis des Pakets nennt die beteiligten Autoren. Projekt und Autoren.
Wie funktioniert GEPA in DSPy?
GEPA nutzt Rückmeldungen aus Programmausführungen, um durch ein Reflexionsmodell Änderungen an Anweisungen vorzuschlagen, bewertet die Kandidaten und gibt ein ausgewähltes Programm zurück. Konkrete Fehlerrückmeldungen liefern der Suche mehr Anhaltspunkte als ein Bewertungswert allein. Eine Qualitätsverbesserung ist dadurch nicht garantiert.
Wofür steht die Abkürzung DSPy?
DSPy steht für Declarative Self-improving Python, wie es in der offiziellen Paketbeschreibung angegeben ist.
Der nächste Schritt
Am Montag wird ein wiederkehrender Fehler bei der Ticketzuordnung oder Datenextraktion ausgewählt. Die zuständige Person für den Prozess versieht repräsentative Beispiele mit Labels. Dann werden eine Baseline festgehalten, eine Bewertungsregel definiert und ein begrenztes Experiment durchgeführt. Vor der Freigabe des Kandidaten werden die geänderten Antworten geprüft. Lässt sich die Bewertung noch nicht definieren, besteht die nächste sinnvolle Aufgabe darin, sich auf die fachliche Regel zu einigen.
Praxisnahe Erklärungen zur KI-Entwicklung im Newsletter erhalten.
- Veröffentlicht
- Kategorie
- Build
- Sprache








