Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Prompt Evolution

Evolutionary optimization of prompts, agents, and workflows based on HyperAgents

License: CC BY-NC-SA 4.0 Based on HyperAgents


Prompt Evolution ist ein experimentelles Framework zur evolutionären Optimierung von Prompts und Agentensystemen.

Das Projekt basiert direkt auf HyperAgents und übernimmt dessen Grundidee eines Meta-Agenten, der nicht nur Antworten erzeugt, sondern die Implementierung des Agentensystems selbst untersuchen und verändern kann.

Der erste Referenz-Task ist die evolutionäre Verbesserung eines vorhandenen System-Prompts für einen evidenzbasierten Fact-Checker von X-Posts.

Grundprinzip

Vorhandener Source Prompt
            |
            v
      Prompt Generator
            |
            v
     Candidate Prompt
            |
            v
        Evaluation
            |
            v
        Meta-Agent
            |
            v
   Prompt / Agent / Workflow
        wird angepasst
            |
            +------> nächste Generation

Der Task-Agent erzeugt zunächst aus einem vorhandenen Source Prompt einen verbesserten Kandidaten-Prompt. Dieser wird bewertet. Anschließend erhält der Meta-Agent die Evaluation und analysiert die aktuelle Implementierung.

Im eingeschränkten Modus optimiert er die Prompt-Generierungsstrategie. Im vollständigen Modus darf er zusätzlich relevante Teile des Agenten-Codes und des Workflows verändern.

Evaluationsdaten dürfen nicht verändert werden, um den Score künstlich zu verbessern.

Aktuelles Beispiel: Fact Check

Die Prompt-Evolution-Domain befindet sich unter:

domains/prompt_design/

Die Datei domains/prompt_design/prompt.md enthält den vorhandenen Source Prompt, der verbessert werden soll.

Die Datei domains/prompt_design/guidance.md enthält eine Verbesserungsleitlinie. In der Run-Konfiguration kann guidance auch auf null gesetzt werden; dann wird sie nicht verwendet.

Der Meta-Agent erhält die Bewertung einer Generation als Feedback für den nächsten Evolutionsschritt und verbessert die Strategie, mit der der vorhandene Prompt überarbeitet wird.

Generierte Candidate Prompts, Evaluationen und Reports werden bei einem konfigurierten Lauf unter runs/<run-name>/ abgelegt und nicht in Git gespeichert.

Quickstart

1. Repository klonen

git clone https://github.com/PentumLab/prompt-evolution.git
cd prompt-evolution

2. Python-Umgebung vorbereiten

python3 -m venv venv
source venv/bin/activate

pip install -r requirements.txt

3. Lokale Konfiguration anlegen

cp .env.example .env
cp hyperagent_config.example.json hyperagent_config.json

Für Modelle mit Anthropic-Zugang wird ein Anthropic API-Key benötigt:

ANTHROPIC_API_KEY=...

Für ein lokal bereitgestelltes Modell wird der OpenAI-kompatible vLLM-Endpunkt in der verwendeten Konfiguration unter providers.hosted_vllm_api_base eingestellt:

http://127.0.0.1:8000/v1

hyperagent_config.json ist die lokale, nicht eingecheckte Runtime-Konfiguration. Dort werden Modelle, per-call Output-Limits, kumulative Token-Limits und der Usage-Log-Pfad gesetzt. Das Repository enthält nur hyperagent_config.example.json als sichere Vorlage.

Wichtige Felder:

{
  "models": {
    "meta_agent": "anthropic/claude-haiku-4-5-20251001",
    "task_agent": "hosted_vllm/gemma-4",
    "prompt_design_task_agent": "hosted_vllm/gemma-4"
  },
  "defaults": {
    "max_output_tokens": 16384,
    "max_tool_calls": 40
  },
  "agent_max_output_tokens": {
    "meta_agent": 4000,
    "task_agent": "DEFAULT",
    "prompt_design_task_agent": 8000
  },
  "agent_max_tool_calls": {
    "meta_agent": 20
  },
  "usage": {
    "log_filename": "llm_usage.jsonl",
    "log_path": null
  },
  "model_token_limits": {
    "anthropic/claude-haiku-4-5-20251001": 150000,
    "hosted_vllm/gemma-4": "UNLIMITED"
  }
}

agent_max_output_tokens begrenzt die Output-Tokens pro LLM-Aufruf. agent_max_tool_calls begrenzt die Tool-Aufrufe pro Agent-Lauf. model_token_limits begrenzt den kumulierten Tokenverbrauch pro Modell anhand des Usage-Logs.

Für agent_max_output_tokens, model_max_output_tokens und agent_max_tool_calls gelten:

  • Zahl: genau dieses Limit verwenden
  • "DEFAULT" oder null: den passenden Wert aus defaults verwenden
  • "UNLIMITED" oder -1: kein entsprechendes Limit setzen

4. Task-Agent-Modell bereitstellen

Die mitgelieferte Run-Vorlage verwendet für den Task-Agenten:

hosted_vllm/gemma-4

Vor dem ersten Evolutionslauf muss der dafür verwendete OpenAI-kompatible Modell-Endpunkt erreichbar sein. Andere Modelle werden über models.prompt_design_task_agent, models.meta_agent und evaluator.model in der Run-Konfiguration gewählt.

Automatischer Evolutionslauf

Für einen vollständigen Lauf mit Initialisierung, Generation 0, Meta-Agent, Task-Agent, Prüfer, Resume-Unterstützung und Parent-Auswahl verwende:

PYTHONPATH=. python domains/prompt_design/evolution_loop.py \
  --config configs/prompt_evolution_run.example.json

Eine konkrete Konfiguration kann kopiert und angepasst werden:

cp configs/prompt_evolution_run.example.json configs/my_run.json
PYTHONPATH=. python domains/prompt_design/evolution_loop.py \
  --config configs/my_run.json

Für den ausführlichen Prüfer gibt es zusätzlich configs/prompt_evolution_requirements.example.json. Stelle vor einem neuen Lauf sicher, dass prompt_design_agent.py die beabsichtigte Ausgangsversion ist und im gewählten run_dir noch kein gen_000-Snapshot eines früheren Versuchs liegt. Vorhandene Snapshots werden wiederverwendet; ein neuer Versuch benötigt einen eigenen run_dir.

Der run_dir in der Konfiguration bestimmt den vollständigen Ausgabebereich. Dort liegen unter anderem outputs/prompt_design, llm_usage.jsonl, loop.log, Entscheidungsdaten und optionale Post-Step-Ergebnisse. Wird der Prozess unterbrochen, wird er mit demselben Befehl und --resume fortgesetzt:

PYTHONPATH=. python domains/prompt_design/evolution_loop.py \
  --config configs/my_run.json --resume

Fehlt nach einem Meta-Fehler eine brauchbare Resume-Datei, startet die Loop nur die betroffene Generation erneut. Bereits abgeschlossene Generationen bleiben erhalten. Setze den Generator vor --resume nicht manuell zurück.

Generation 0 ist die erste erzeugte und bewertete Kandidatengeneration. loop.count legt die Zahl der darauf folgenden Generationen fest; --count N begrenzt sie für einen einzelnen Aufruf.

Die Loop wertet jede Generation automatisch aus und stoppt bei fehlenden Artefakten, ungültigen Reports, zu starker Verschlechterung oder erkannter Stagnation. Die Grenzwerte stehen im Abschnitt loop der Run-Konfiguration.

Nach der Initialisierung und nach jeder abgeschlossenen Generation kann ein lokales Skript über post_step aufgerufen werden. Der Hook ist optional; ein Fehler des Skripts ändert die Entscheidung des Evolutionslaufs nicht.

Das Script erhält standardisierte Parameter wie --generation, --run-dir, --output-dir, --source-prompt, --usage-log, --decision-file und --config. Zusätzliche Parameter werden unter post_step.params angegeben. Schlüssel werden als CLI-Optionen übergeben; boolesche Werte werden als Flags behandelt.

Eine Webseite wird durch den Evolutionslauf nicht verpflichtend erstellt.

Manueller Ablauf

Die folgenden Einzelbefehle verwenden hyperagent_config.json und speichern ihre Ergebnisse unter outputs/prompt_design/. Ist in der Shell noch eine Run-Konfiguration aktiv, setze sie vorher zurück:

unset HYPERAGENT_CONFIG

5. Generation 0 erzeugen

Lege zuerst den vorhandenen Prompt in dieser Datei ab:

domains/prompt_design/prompt.md

Optional kann die Verbesserungsleitlinie angepasst werden:

domains/prompt_design/guidance.md

Dann erzeugst du den ersten Candidate Prompt:

PYTHONPATH=. python domains/prompt_design/harness.py --generation 0

Der erzeugte Prompt wird gespeichert unter:

outputs/prompt_design/gen_000/candidate_prompt.txt

Damit entsteht die Ausgangsgeneration aus der eingecheckten, noch nicht evolvierten Prompt-Verbesserungsstrategie. Der Harness verwendet einen bereits vorhandenen gen_000-Snapshot weiter. Prüfe ihn vor einem neuen Experiment, statt nur die aktive prompt_design_agent.py zu ersetzen.

Alternativ kann ein anderer Source Prompt übergeben werden:

PYTHONPATH=. python domains/prompt_design/harness.py \
  --generation 0 \
  --source-prompt /path/to/source_prompt.md

Den aktuellen Zustand der Generationen kannst du jederzeit prüfen:

PYTHONPATH=. python domains/prompt_design/state.py status

Die Ausgabe zeigt pro Generation Score, Parent, Snapshot-Status und ob die Generation als Parent für weitere Evolutionsschritte auswählbar ist.

6. Generation bewerten

Ein automatischer Lauf verwendet den geschützten Prüfer aus domains/prompt_design/evaluator/. Modell, Modus (simple oder comparison), Rollen-Datei, Ergebnisformat und Output-Limit werden in der Run-Konfiguration festgelegt. Eine manuelle Bewertung ist weiterhin für einzelne Tests möglich.

Zwei Prüfschemata sind implementiert:

evaluator.profile / evaluator.result_format Ausgabe
legacy_four_scores / legacy_json Vier Teilwerte bis 25, zusammen höchstens 100, mit feedback. evaluator_prompt_extended.md liefert im gleichen Format ausführlichere Hinweise.
requirements_review / detailed_report Ausführlicher Bericht nach evaluator_v4.md mit acht Kriterien bis 5; bei N/R sinkt die erreichbare Gesamtpunktzahl.

Die Punktzahlen der beiden Schemata sind nicht direkt vergleichbar. Der Meta-Agent bekommt den normalisierten Score und den verfügbaren Prüfbericht. Über meta_agent.role_file kann seine Rolle ebenfalls gewählt werden. Beide Rollentexte werden beim Anlegen eines Runs unter run_assets/ kopiert und für diesen Run beibehalten.

Das Ausgangsprompt wird beim Start von Generation 0 nicht automatisch bewertet; eine getrennte Bewertung beeinflusst den ersten Task-Agenten nicht. Mit einer bereits angelegten Run-Konfiguration lautet der Aufruf:

PYTHONPATH=. python domains/prompt_design/evaluator/evaluator_runner.py \
  --config configs/my_run.json \
  --generation 0 \
  --original-prompt domains/prompt_design/prompt.md \
  --candidate-prompt domains/prompt_design/prompt.md \
  --target-kind original \
  --output-directory runs/<run-name>/outputs/prompt_design/baseline \
  --output-suffix initial_prompt

--generation 0 ist hier nur eine erforderliche Kennung; --target-kind und der Ausgabeordner kennzeichnen das Ergebnis als Bewertung des Ausgangsprompts. Für einen getrennten Vergleich des Ausgangsprompts mit Gemma 4, Haiku 4.5 und GPT-5.6 Luna gibt es außerdem:

python domains/prompt_design/evaluator/evaluate_original.py --dry-run
python domains/prompt_design/evaluator/evaluate_original.py

Die Berichte landen in einem neuen Ordner unter outputs/baseline_v4/ und werden nicht automatisch in einen Evolutionslauf übernommen. Mit wiederholtem --model name=modellkennung lässt sich die Standardauswahl ersetzen.

Der folgende manuelle JSON-Ablauf beschreibt weiterhin das alte Vier-Werte-Schema:

Lege folgende Datei an:

outputs/prompt_design/gen_000/manual_evaluation.json

Beispiel:

{
  "score": 67,
  "methodology": 21,
  "consistency": 18,
  "robustness": 14,
  "efficiency": 14,
  "feedback": "Describe the most important weaknesses and possible improvements."
}

Die vier Teilbewertungen müssen jeweils zwischen 0 und 25 liegen:

  • methodology
  • consistency
  • robustness
  • efficiency

Ihre Summe muss dem Wert von score entsprechen.

7. Evaluation validieren

PYTHONPATH=. python domains/prompt_design/manual_evaluator.py --generation 0

Dadurch entsteht:

outputs/prompt_design/gen_000/report.json

Dieser Report dient als Feedback für den Meta-Agenten.

8. Meta-Agent ausführen

Prompt-Evolution

PYTHONPATH=. python domains/prompt_design/meta_step.py \
  --generation 0 \
  --target-generation 1 \
  --scope prompt

Im Modus prompt bleibt die öffentliche Schnittstelle

generate_prompt(task: str) -> str

erhalten.

Der Task-Agent verwendet weiterhin einen einzelnen Modellaufruf. Der Meta-Agent optimiert die Strategie, mit der der vorhandene Source Prompt verbessert wird.

Der frühere full-Scope ist in der schlanken Prompt-Evolution-Mini-Loop noch nicht aktiviert, weil dieser Ablauf aktuell nur prompt_design_agent.py sauber snapshotet und patcht.

Der Meta-Step erstellt oder aktualisiert:

outputs/prompt_design/gen_001/prompt_design_agent.py
outputs/prompt_design/gen_001/model_patch.diff
outputs/prompt_design/gen_001/meta_agent_chat_history.md
outputs/prompt_design/gen_001/meta_workspace/
outputs/prompt_design/gen_001/metadata.json

Am Ende des Meta-Steps läuft automatisch eine Validierung. Sie prüft, ob ein kompilierbarer Agent-Snapshot existiert, ob sich prompt_design_agent.py gegenüber dem Parent wirklich geändert hat und ob model_patch.diff nicht leer ist. Fehlgeschlagene Läufe werden in metadata.json als failed markiert und nicht als auswählbarer Parent verwendet. Hat der Meta-Agent nur gelesen und keine Änderung vorgenommen, erhält er einen gezielten zweiten Versuch.

Eine Generation kann auch manuell geprüft werden:

PYTHONPATH=. python domains/prompt_design/state.py validate --generation 1

Wenn ein Lauf wegen eines Tokenlimits abbricht, wird ein Resume-State gespeichert:

outputs/prompt_design/gen_001/meta_agent_resume_state.json

Nach Anpassung des Limits kann derselbe Lauf fortgesetzt werden:

PYTHONPATH=. python domains/prompt_design/meta_step.py \
  --generation 0 \
  --target-generation 1 \
  --scope prompt \
  --resume

Beim Resume wird der Parent nicht erneut restored und der bestehende Chatlog nicht gelöscht.

9. Nächste Generation erzeugen

Nach dem Meta-Schritt:

PYTHONPATH=. python domains/prompt_design/harness.py --generation 1

Der nächste Candidate Prompt liegt dann unter:

outputs/prompt_design/gen_001/candidate_prompt.txt

Danach kann Generation 1 wieder bewertet, validiert und als Feedback für einen weiteren Meta-Schritt verwendet werden.

Generation 0
    |
    v
candidate_prompt.txt
    |
    v
manual_evaluation.json
    |
    v
report.json
    |
    v
Meta-Agent verändert die Implementierung
    |
    v
Generation 1

Parent-Auswahl und Restore

Der nächste Evolutionsschritt kann explizit von einer bestimmten Generation starten:

PYTHONPATH=. python domains/prompt_design/meta_step.py \
  --generation 7 \
  --target-generation 9 \
  --scope prompt

Alternativ kann der Parent automatisch gewählt werden:

PYTHONPATH=. python domains/prompt_design/meta_step.py \
  --parent-selection best \
  --target-generation 9 \
  --scope prompt

Verfügbare Auswahlmethoden:

best
bestlast
latest
random
score_prop
score_child_prop

best nimmt bei gleichem Höchstwert die früheste, bestlast die neueste geeignete Generation. Nur bewertete Generationen mit gültigem Snapshot und valid_parent können ausgewählt werden.

Eine gespeicherte Generation kann in den Arbeitsbaum zurückkopiert werden:

PYTHONPATH=. python domains/prompt_design/state.py restore --generation 7

Das überschreibt prompt_design_agent.py mit dem Snapshot aus der gewählten Generation.

Typischer Zyklus

# 1. Candidate Prompt aus vorhandenem Source Prompt erzeugen
PYTHONPATH=. python domains/prompt_design/harness.py --generation 0

# 2. outputs/prompt_design/gen_000/manual_evaluation.json anlegen

# 3. Bewertung validieren
PYTHONPATH=. python domains/prompt_design/manual_evaluator.py --generation 0

# 4. Aus bestem Parent neue Generation erzeugen
PYTHONPATH=. python domains/prompt_design/meta_step.py --parent-selection best --scope prompt

# 5. Candidate Prompt der neuen Generation erzeugen
PYTHONPATH=. python domains/prompt_design/harness.py --generation 1

Danach wird die neue Generation wieder bewertet und als Feedback für den nächsten Meta-Schritt verwendet.

Evolutionsmodi

prompt

Der konservative Modus.

Der Meta-Agent optimiert die Prompt-Generierungsstrategie, während die zentrale generate_prompt(task: str) -> str-Schnittstelle und der einzelne Task-Agent-Modellaufruf erhalten bleiben.

Der hier beschriebene Prompt-Design-Ablauf verwendet prompt.

Aktueller Modellaufbau

Task-Agent, Meta-Agent und Prüfer werden getrennt in der Run-Konfiguration gewählt. Die Vorlagen zeigen unter anderem Gemma 4, Claude Haiku 4.5 und GPT-5.6 Luna als mögliche Modelle.

Pro-Aufruf-Limits stehen in agent_max_output_tokens und evaluator.max_output_tokens; model_token_limits begrenzt den kumulierten Verbrauch je Modell anhand des Usage-Logs.

Output-Struktur

Ein Lauf erzeugt beispielsweise:

runs/<run-name>/
├── prompt_design_agent.py
├── run_assets/
│   ├── evaluator_role.md
│   └── resolved_config.json
└── outputs/
    ├── llm_usage.jsonl
    └── prompt_design/
        ├── archive.jsonl
        ├── gen_000/
        │   ├── prompt_design_agent.py
        │   ├── candidate_prompt.txt
        │   ├── evaluation.json
        │   ├── report.json
        │   └── metadata.json
        └── gen_001/
            ├── prompt_design_agent.py
            ├── model_patch.diff
            ├── meta_agent_chat_history.md
            ├── candidate_prompt.txt
            ├── evaluation.json
            ├── report.json
            └── metadata.json

Diese Dateien sind Experiment-Artefakte und werden nicht in Git eingecheckt.

Ein Post-Step kann einen HTML- oder anderen Report-Generator aufrufen. Das Repository schreibt keine Website verpflichtend vor; das konkrete Script wird über die Run-Konfiguration festgelegt.

Das Forschungstagebuch ist optional. Mit "research_journal": {"enabled": true, "path": "research_journal.jsonl", "read_last_entries": 10} speichert der Run Prüfergebnisse und Meta-Änderungen als JSONL und lesbares Markdown. Die letzten Einträge werden dem Meta-Agenten als Kontext gegeben. Ohne Aktivierung wird kein Tagebuch geschrieben.

Projektstruktur

agent/
    Foundation-Model- und Tool-Anbindung aus HyperAgents

domains/
    HyperAgents-Domains und Prompt-Evolution-Domains

domains/prompt_design/
    prompt.md
        vorhandener Source Prompt, der verbessert werden soll

    guidance.md
        optionale Verbesserungsleitlinie für den Source Prompt

    harness.py
        erzeugt Candidate Prompts für eine Generation aus prompt.md und guidance.md

    manual_evaluator.py
        validiert manuelle Bewertungen und erzeugt report.json

    evaluator/evaluator_runner.py
        ruft den konfigurierten Prüfer auf und speichert seinen Bericht

    evaluator/evaluation_result.py
        vereinheitlicht beide Prüfer-Ergebnisformate

    meta_step.py
        führt den Meta-Agenten mit Evaluation und Evolutionsmodus aus

    state.py
        verwaltet Snapshots, Parent-Auswahl, Restore, Validierung und archive.jsonl

    research_journal.py
        führt bei Aktivierung das Forschungstagebuch

    finish_run.py
        archiviert einen gestoppten manuellen Lauf nach Vorschau und --apply

prompt_design_agent.py
    initialer Prompt-Verbesserer für Generation 0

outputs/
    generierte Experiment-Artefakte
    (nicht in Git gespeichert)

NOTICE.md
    Attribution und Herkunft des Projekts

Sicherheit

Der Meta-Agent kann Dateien und Code verändern. In der aktuellen Prompt-Evolution-Mini-Loop ist dieser Schreibpfad auf die run-eigene prompt_design_agent.py und den jeweiligen meta_workspace ausgerichtet.

Damit gilt dieselbe grundlegende Sicherheitsproblematik wie bei HyperAgents: modellgenerierter Code sollte als nicht vertrauenswürdig behandelt werden.

Experimente sollten bevorzugt in einer isolierten Umgebung, einem Container oder einem entbehrlichen Git-Checkout durchgeführt werden.

Produktionssysteme, sensible Dateien und Zugangsdaten sollten nicht für autonome Code-Evolution freigegeben werden.

Reproduzierbarkeit und Git

Der eingecheckte Stand enthält die Ausgangsimplementierung vor der ersten Evolution.

Generierte Prompts und spätere Evolutionsstände gehören zu einem Experimentlauf und werden nicht als Ausgangszustand des Projekts eingecheckt.

Für reproduzierbare Experimente sollte jeder Lauf von einem bekannten Git-Commit beziehungsweise Tag gestartet werden.

prompt_design_agent.py im Projektstamm ist die Ausgangsversion. tests/prompt_design_agent.py ist eine kopierte Experimentversion und keine Baseline. Vor einem öffentlichen Commit sind die aktive und die gestagte Generator-Datei mit der beabsichtigten Ausgangsversion zu vergleichen. finish_run.py zeigt für den manuellen Lauf unter outputs/prompt_design/ zunächst nur eine Vorschau; --apply archiviert den gestoppten Lauf und stellt die Generator-Datei aus einem Git-Commit oder Tag wieder her.

Der verwendete HyperAgents-Upstream-Stand ist mit folgendem Tag markiert:

hyperagents-base-59a68f6

HyperAgents

Prompt Evolution basiert auf dem HyperAgents-Projekt von Meta Platforms, Inc. and affiliates:

https://github.com/facebookresearch/HyperAgents

Verwendeter Upstream-Basis-Commit:

59a68f6

Dieser Stand ist in diesem Repository zusätzlich markiert als:

hyperagents-base-59a68f6

Prompt Evolution ist ein unabhängiges Projekt und ist weder mit Meta Platforms, Inc. verbunden noch von Meta unterstützt.

Weitere Hinweise zur Herkunft befinden sich in NOTICE.md.

Lizenz

Prompt Evolution wird unter der Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License veröffentlicht.

Siehe:

Die Lizenz erlaubt Nutzung, Veränderung und Weitergabe unter ihren Bedingungen, einschließlich Attribution, NonCommercial und ShareAlike.

Releases

Packages

Contributors

Languages