# Schwärme aus Sub-Agenten

> Wann ein Panel, eine Jury oder ein Fanout von Sub-Agenten sinnvoll ist, die vier Dateien dahinter, Austeilen mit Seed, das Budget von 26, ehrliche Auswertungen und ein durchgespieltes Käuferpanel.

Canonical: https://bmad-plus.rochetta.fr/de/docs/concepts/swarm/
Language: de
BMAD+ version: 0.23.1
Documentation reviewed: 2026-10-19
Author: Laurent Rochetta
License: MIT

BMAD+ Dokumentation › [Konzepte](https://bmad-plus.rochetta.fr/de/docs/concepts/) › Schwärme aus Sub-Agenten

Ein Schwarm (swarm) besteht aus vielen Sub-Agenten, die je einmal dieselbe Art Arbeit leisten: dreißig simulierte Käufer, die einen Pitch lesen, drei Juroren, die ihn je durch eine Linse lesen, ein Autor pro Seite einer Website. Moderator ist dein Assistent; er erledigt nie die Arbeit einer Einheit. `bmad-plus swarm` führt Buch: Es validiert die Dateien, teilt die Einheiten aus, schreibt ein Briefing pro Sub-Agent, prüft jede Antwortdatei und zählt nur die gültigen. Es ruft nie ein Modell auf, öffnet keine Netzwerkverbindung und startet keinen Prozess. Diese Seite richtet sich an alle, die eine Botschaft, eine Seite oder einen Plan an vielen Lesern testen oder wiederkehrende Arbeit im Budget auf Sub-Agenten verteilen wollen.

<a id="video-ask-then-swarm"></a>
Video: [Erst fragen, dann der Schwarm](https://bmad-plus.rochetta.fr/media/ask-then-swarm-en.mp4) — Die Intake-Fragen, das Budget von 26 und die Freigabe, Wellen von Sub-Agenten und eine Auswertung, die klarstellt, dass simulierte Einheiten keine Menschen sind.
[Untertitel (WebVTT)](https://bmad-plus.rochetta.fr/media/ask-then-swarm-de.vtt)

Transkript:

> Bevor ein Pack handelt, fragt es. Der Intake stellt jeweils ein paar Fragen und markiert die Pflichtfragen. Wo du keine Antwort hast, schlägt es einen Standardwert vor oder hält die Frage als unbekannt fest, samt Risiko. Die Antworten werden zu einem Briefing, und nichts darin ist erfunden. Dann der Schwarm. Standardmäßig darf ein Lauf 26 Sub-Agenten nutzen, bevor der Assistent dich fragen muss. Willst du mehr, wartet der Lauf mit dem Status needs-approval, bis ein Mensch zustimmt. Nach der Freigabe arbeiten die Sub-Agenten standardmäßig in Wellen von zehn, jeder liest ein Briefing und schreibt eine Antwort. Die Laufzeit prüft jede Antwortdatei und zählt nur die gültigen. Diese Auswertung besteht aus Demodaten und beginnt mit ihrem Hinweis: Simulierte Einheiten sind keine Menschen. Lies die Raten als Obergrenze und bestätige sie mit echten Menschen.

Transkript mit Bildbeschreibung:

- **0:00** Im Bild: Ein einzelner bernsteinfarbener Lichtpunkt in einer dunklen blaugrünen Wolke, von dem schwache Strahlen ausgehen. Die Einblendung lautet auf Englisch „Ask first“. Sprechtext: Bevor ein Pack handelt, fragt es.
- **0:04** Im Bild: Ein Terminalfenster mit dem Titel „~/app“. Es wird der Befehl bmad-plus intake plan getippt, mit der intake.yaml des Packs Design und einer Antwortdatei. Das Bild zoomt auf das Ergebnis: „design-read (design): not ready — 0 answered, 0 defaulted, 0 unknown“ und, orange umrahmt, „Must-haves still open: surface_kind, audience, job“. Darunter der erste Block von Fragen (höchstens 6 pro Nachricht), jeweils mit Typ und dem Vermerk „must-have“, wo er zutrifft: surface_kind, audience, job, brand_assets, design_system und aesthetic_family. Dann wird bmad-plus intake record getippt, mit drei Antworten (surface_kind=dashboard; audience=„Accountants in a practice, on a desktop, at month end“; job=UNKNOWN) und einem Standardwert für design_system. Der nächste Block von Fragen erscheint: brand_assets, aesthetic_family, variance, motion, density und stack. Der Bildschirm endet auf einer gelben, umrahmten Zeile: „Unknown: job — risk: There is no goal to review against, so hierarchy and the primary action cannot be judged, only decorated.“ Der gesamte Terminaltext ist englisch. Sprechtext: Der Intake stellt jeweils ein paar Fragen und markiert die Pflichtfragen. Wo du keine Antwort hast, schlägt es einen Standardwert vor oder hält die Frage als unbekannt fest, samt Risiko.
- **0:19** Im Bild: Zwei Terminalbereiche. Links wird bmad-plus intake render getippt; es gibt „Brief written to _bmad-output/design/brief.md (3238 bytes); the intake is ready.“ aus. Der rechte Bereich öffnet brief.md und scrollt hindurch. Unter Überschriften wie „Who and why“ erscheint jede Frage mit ihrer Antwort („dashboard“; „Accountants in a practice, on a desktop, at month end“) oder mit „Answer: not asked yet.“ und einer Zeile „Feeds: brief.md#…“. Das Scrollen hält bei einer Überschrift an, „Open questions“. Der erste Eintrag ist umrahmt: „job (must-have): unknown — risk: There is no goal to review against, so hierarchy and the primary action cannot be judged, only decorated.“ Darunter eine Liste weiterer Einträge, alle mit „not asked yet“ markiert: brand_assets, aesthetic_family, variance, motion, density, stack, accessibility_target, languages und weitere. Sprechtext: Die Antworten werden zu einem Briefing, und nichts darin ist erfunden.
- **0:29** Im Bild: Ein Terminal. Der Befehl bmad-plus swarm init wird getippt, mit einer Schwarmdefinition, einem Profil, einer Kontextdatei, 40 Einheiten (--n 40) und dem Seed 7, gefolgt von einem Echo des Exit-Codes. Die Ausgabe: „buyer-panel-20261018-asuq: needs approval.“ (die Wörter „needs approval“ sind umrahmt) „The run needs 40 sub-agents and the budget is 26: ask the user, then re-run init with --approved --seed 7.“ und „exit code: 2“ (umrahmt). Derselbe Befehl wird noch einmal mit --approved ausgeführt. Das Bild zoomt auf das Ergebnis, wobei „panel of 40 units“ umrahmt ist: „buyer-panel-20261018-zho8: panel of 40 units, budget 26, approval user. Seed 7 (same seed, same cards).“ und „Next: bmad-plus swarm briefs buyer-panel-20261018-zho8“. Der gesamte Terminaltext ist englisch. Sprechtext: Dann der Schwarm. Standardmäßig darf ein Lauf 26 Sub-Agenten nutzen, bevor der Assistent dich fragen muss. Willst du mehr, wartet der Lauf mit dem Status needs-approval, bis ein Mensch zustimmt.
- **0:46** Im Bild: Bernsteinfarbene Partikel schießen aus einem hellen Zentrum und bilden vor einem dunkelvioletten Hintergrund einen sich weitenden Ring. Die Einblendung lautet auf Englisch „Waves of 10“. Sprechtext: Nach der Freigabe arbeiten die Sub-Agenten standardmäßig in Wellen von zehn, jeder liest ein Briefing und schreibt eine Antwort.
- **0:56** Im Bild: Ein Terminal. bmad-plus swarm briefs buyer-panel-20261018-zho8 gibt „40 of 40 units need a sub-agent, in waves of 10.“ aus und listet die Briefings Welle für Welle auf, jeweils mit dem Pfad einer Briefing-Datei (B001.md, B011.md, B021.md, B031.md). Darunter stehen die Anweisung „Each sub-agent: Read the brief and follow it exactly; it is your whole instruction.“ und der Offenlegungshinweis „Simulated units are not people. Read rates as an upper bound and confirm with real ones.“ Dann gibt bmad-plus swarm check „8 of 40 valid answers.“ aus und listet die Probleme: „B009 invalid: field "buys" must be true or false“ (umrahmt), „B010 missing: no answer file“, „B011 missing: no answer file“ und „B012 … B040 (missing)“. Sprechtext: Die Laufzeit prüft jede Antwortdatei und zählt nur die gültigen.
- **1:07** Im Bild: Zwei Terminalbereiche. Links wird bmad-plus swarm tally buyer-panel-20261018-zho8 getippt; es gibt den Pfad von tally.md, „8 of 40 units counted; 32 skipped.“ und die Zeile „Disclosure:“ aus. Der rechte Bereich öffnet tally.md und scrollt durch kurze zitierte Antworten, nach Segment (mid career, high earner) und Verhalten (occasional, explorer, daily regular) gruppiert, und hält dann bei „Numbers: price_floor“ an: eine Tabelle mit den Spalten group, count, median, mean, min und max. Die erste Zeile, „all“, zeigt 8, 3.65, 3.7, 3 und 4.5. Es folgen Zeilen für drei Segmente und drei Verhaltensweisen. Sprechtext: Diese Auswertung besteht aus Demodaten und beginnt mit ihrem Hinweis: Simulierte Einheiten sind keine Menschen.
- **1:16** Im Bild: Unter Wasser: Viele durchscheinende Blasen treiben in blauem Licht, und zwei von ihnen leuchten bernsteinfarben und nähern sich, bis sie sich überlappen. Die Einblendung lautet auf Englisch „Simulated units are not people.“ Sprechtext: Lies die Raten als Obergrenze und bestätige sie mit echten Menschen.

> **Warnung · Simulierte Einheiten sind keine Menschen** Ein Panel liefert die Lesart eines Modells, das Käufer spielt. Behandle seine Raten als Obergrenze, die mit echten Menschen zu bestätigen ist, und seine Zitate als das, was eine simulierte Einheit geschrieben hat, nie als Testimonials oder Nutzerinterviews. Jede Auswertung beginnt mit diesem Satz.

<a id="when-to-use"></a>
## Wann ein Schwarm sinnvoll ist

**Die drei Arten von Schwarm**

| Art | Die Einheiten stammen aus | Typischer Einsatz | Was die Auswertung zeigt |
| --- | --- | --- | --- |
| `panel` | Ein Profil: Die Einheiten werden nach exakten Quoten aus einem Seed ausgeteilt. | Simulierte Käufer, Leser oder Nutzer, die einen Pitch, einen Preis, eine Seite lesen. | Eine Rate je Gruppe, Zählungen, wörtliche Zitate, Zahlen. |
| `jury` | Eine Liste in der Definition: eine Einheit pro Eintrag, jede mit einem `lens`. | Eine kritische Gegenlesung eines Pitches, einer Seite oder eines Plans, ein Blickwinkel pro Juror. | Zählungen und Zitate je Blickwinkel. |
| `fanout` | Eine Einheitendatei, die du beim Init schreibst: eine Einheit pro Eintrag, jede mit disjunktem Schreib-`scope`. | Zu schreibende Seiten, zu dokumentierende Module, vorzubereitende Szenen, je ein Sub-Agent. | Eine Rate und Zahlen; als dauerhafter Nexus-Plan exportierbar. |

Ein Panel und eine Jury laufen als Sitzungs-Sub-Agenten: Dein Assistent startet sie, wartet und liest ihre Dateien. Ein Fanout kann genauso laufen oder mit `swarm plan` als dauerhafter Nexus-Plan exportiert werden, wenn die Arbeit die Sitzung überleben muss, pro Einheit eine unabhängige Prüfung braucht oder das Repository ändert.

<a id="when-not"></a>
### Wann nicht

- Wenn du echte Menschen fragen kannst. Ein Schwarm probt; er misst nicht.
- Bei zwei oder drei Aufgaben. Frage den Agent direkt oder nutze `parallel` von Nexus.
- Bei Arbeit, in der ein Ergebnis vom anderen abhängt. Einheiten sind konstruktionsbedingt unabhängig.
- Um kostenpflichtige Medien zu erzeugen. Bild-, Video- und Audioerzeugung deckt das Budget nie ab: Der Assistent fragt jedes Mal.

In 0.23.0 liefert kein Pack eine Schwarm-Definition: Laufzeit und Moderations-Skill gehören zu Core, und die auf dieser Seite verwendeten Definitionen sind Testfixtures im BMAD+-Repository (`tests/fixtures/swarm/`). Die Definition liefert ein Pack oder du. Diese Dateien sind nicht im npm-Paket enthalten; diese Seite zeigt jede vollständig, sodass du sie unverändert anlegen kannst.

<a id="how-it-flows"></a>
## Der Ablauf von Anfang bis Ende

**Dateien und Befehle**

```text
definition + profile|list|units + context
        |
      init ---- over budget? exit 2 "needs approval": ask a human, re-run with --approved
        |
   cards.json  (frozen)
        |
     briefs ---- one brief per unit, in waves
        |
  one sub-agent per brief  ->  answers/<unit>.json
        |
      check ---- missing / invalid, with reasons
        |  (second chance once; save files a printed reply)
      tally ---- tally.json + tally.md, disclosure first
```

1. **init** Validiert die Definition, das Profil bzw. die Einheitendatei, die Kontextdateien und die Briefing-Vorlage; teilt die Karten aus oder listet sie; wendet das Budget an. Ein Panel braucht `--n` (1 bis 1000); der Seed wird gezogen und festgehalten, wenn du keinen angibst. Ein Lauf über dem Budget endet hier mit Exit-Code 2.

   ```sh
   npx bmad-plus swarm init --definition swarm/buyer-panel.json --profile swarm/profile.json --context pitch=swarm/pitch.md --n 30 --seed 7
   ```
2. **briefs** Rendert ein Briefing für jede Einheit ohne gültige Antwort aus der eingefrorenen Vorlage, der Karte und den eingefrorenen Kontexten und druckt die Wellen (10 Einheiten pro Welle, sofern `--wave` nichts anderes sagt) mit dem Briefing-Pfad jeder Einheit.

   ```sh
   npx bmad-plus swarm briefs RUN
   ```
3. **Eine Welle starten** Dein Assistent startet pro Briefing einen Sub-Agenten mit genau einer Anweisung: das Briefing lesen und genau befolgen; es ist die gesamte Anweisung. Er fasst das Briefing nicht zusammen, ergänzt keinen Kontext und führt nie zwei Einheiten in einem Sub-Agenten zusammen. Er wartet auf die ganze Welle, bevor die nächste startet.
4. **check** Listet jede Einheit mit fehlender oder ungültiger Antwort samt Grund. Exit-Code 0, wenn alle Einheiten gültig sind, sonst 1.

   ```sh
   npx bmad-plus swarm check RUN
   ```
5. **Eine zweite Chance, einmal** Führe `briefs` erneut aus (es rendert nur Einheiten ohne gültige Antwort) und starte diese Einheiten neu. Eine Einheit, die ihre Antwort ausgegeben statt geschrieben hat, wird mit `save RUN UNIT --input FILE` abgelegt, wobei die Datei die Antwort dieser Einheit wörtlich enthält. Eine Einheit, die nach der zweiten Welle fehlt, bleibt fehlend.

   ```sh
   npx bmad-plus swarm save RUN B005 --input swarm-inbox/B005.txt
   ```
6. **tally** Zählt nur gültige Antworten und schreibt `tally.json` und `tally.md`. Einheiten ohne gültige Antwort werden als übersprungen aufgeführt und in der Nennerzeile mitgezählt. Der Offenlegungshinweis ist die erste Zeile von `tally.md`.

   ```sh
   npx bmad-plus swarm tally RUN
   ```
7. **plan (nur Fanout)** Statt die Sub-Agenten in der Sitzung auszuführen, wird der Fanout als Nexus-Plan exportiert. Siehe die Nexus-Seite.

   ```sh
   npx bmad-plus swarm plan RUN --out .bmad-plus/swarm/reports/RUN/plan.json
   ```

`swarm inspect RUN` zeigt jederzeit den Zustand eines Laufs (Einheiten, mit Briefing, gültig, ungültig, fehlend) und schreibt nichts. Exit-Codes: 0 erledigt, 2 `needs-approval` (zuerst muss ein Mensch Ja sagen), 1 unvollständig oder Fehler. Mit `--json` trägt jede Ausgabe `schemaVersion: 1` und einen `status`.

<a id="budget"></a>
## Das Budget, die Wellen und die Freigabe

Drei Schlüssel im Block `swarm` von `_bmad/config.yaml` setzen die Grenzen. Der Installer schreibt den Block mit seinen Standardwerten; ein von einer früheren Version aktualisiertes Projekt hat keinen Block und bekommt dieselben Standardwerte.

**Der swarm-Block**

| Schlüssel | Standard | Bedeutung |
| --- | --- | --- |
| `budget` | 26 | Sub-Agenten, die ein Lauf nutzen darf, bevor der Assistent dich fragen muss. Ganzzahl von 1 bis 1000. |
| `wave` | 10 | Gleichzeitig gestartete Sub-Agenten. Der Assistent wartet auf eine Welle, bevor die nächste startet. Ganzzahl von 1 bis 1000. |
| `media_credits` | `ask` | Kostenpflichtige Erzeugung (Bilder, Video, Audio) wird nie von einem Budget freigegeben. Einziger erlaubter Wert ist `ask`. |

Ist `n` größer als das Budget und fehlt `--approved`, legt `init` den Lauf mit dem Status `needs-approval` an, endet mit 2 und schreibt kein Briefing. Der Assistent stellt dir einen Satz mit der Zahl („Dieses Panel braucht 30 Sub-Agenten; das Budget ist 26. Starten?“). Erst nach deinem Ja führt er `init` mit `--approved` und demselben Seed erneut aus. Er übergibt `--approved` nie nach eigenem Ermessen. Der abgelehnte Lauf ist endgültig: Spätere Befehle darauf antworten `needs-approval` und schreiben nichts.

**Abgelehnt, dann freigegeben: ein Panel von 30 bei Budget 26**

```text
$ npx bmad-plus swarm init --definition swarm/buyer-panel.json --profile swarm/profile.json --context pitch=swarm/pitch.md --n 30 --seed 7
buyer-panel-20261019-g1i9: needs approval. The run needs 30 sub-agents and the budget is 26: ask the user, then re-run init with --approved --seed 7.
# Exit-Code 2. Es wurde kein Briefing geschrieben.
$ npx bmad-plus swarm init --definition swarm/buyer-panel.json --profile swarm/profile.json --context pitch=swarm/pitch.md --n 30 --seed 7 --approved
buyer-panel-20261019-vqkf: panel of 30 units, budget 26, approval user.
Seed 7 (same seed, same cards).
Next: bmad-plus swarm briefs buyer-panel-20261019-vqkf
```

Ausgabe eines echten Laufs. Quelle: bmad-plus 0.23.0, 2026-10-19

<a id="files"></a>
## Die vier Dateien, Feld für Feld

Die Laufzeit lehnt ein unbekanntes Feld, einen falschen Typ und eine Grenzverletzung ab; sie rät nie. Jeder Pfad ist projektrelativ mit `/` als Trenner. Der Pfad der Briefing-Vorlage ist relativ zur Definitionsdatei.

<a id="file-definition"></a>
### 1. Die Definition (JSON)

**Felder der Definition**

| Feld | Regel |
| --- | --- |
| `schemaVersion` | Muss `1` sein. |
| `id` | 1 bis 64 Kleinbuchstaben, Ziffern oder `-`. Eröffnet die Lauf-ID. |
| `kind` und `units.source` | Das Paar muss zusammenpassen: `panel` mit `profile`, `jury` mit `list`, `fanout` mit `input`. |
| `units.idPrefix` | 1 bis 4 Buchstaben. Pflicht beim Panel; optional bei einer Jury, deren Einträge keine `id` haben; fehlt beim Fanout. |
| `units.list` | Nur Jury: 1 bis 1000 Einträge, jeder mit einem Text `lens` und weiteren Text-, Zahlen- oder Boolean-Feldern; eine optionale `id`. |
| `pack` | Optionale Pack-ID, im Lauf festgehalten. |
| `title` | Überschrift der Auswertung. |
| `brief.template` | Einfacher relativer Pfad zu einer Markdown-Datei, ohne `.`- oder `..`-Teile. |
| `brief.context` | Namen der Kontextdateien, die der Moderator beim Init übergeben muss (`--context NAME=FILE`). Jede ist Pflicht; höchstens 20. |
| `answer.required` | Felder, die vorhanden sein müssen. `id` ist implizit und immer Pflicht. |
| `answer.fields` | Höchstens 50 Felder, jedes typisiert (siehe nächste Tabelle). Ein Sub-Agent darf kein nicht deklariertes Feld schreiben. |
| `tally` | `rate` (ein Boolean-Feld), `groupBy` (bis zu 5 Kartenfelder, die jede Karte trägt), `counts` (Enum-Felder), `quotes` (Textfeld auf je Gruppe behaltene Zitate, 1 bis 10), `numbers` (Integer- oder Zahlenfelder). |
| `disclosure` | 1 bis 500 Zeichen, in jeder Auswertung und in der Ausgabe von `briefs` zuerst gedruckt. |

**Typen der Antwortfelder**

| Typ | Optionen | Akzeptierter Wert |
| --- | --- | --- |
| `boolean` | keine | `true` oder `false`. |
| `integer` | `min`, `max` | Eine ganze Zahl innerhalb der Grenzen. |
| `number` | `min`, `max` | Eine beliebige Zahl innerhalb der Grenzen. |
| `string` | `min`, `max` (Länge) | Text; standardmäßig 0 bis 4000 Zeichen, Obergrenze 20000; `min` wird am getrimmten Text geprüft. |
| `enum` | `values` (1 bis 50, verschieden) | Einer der aufgeführten Werte. |
| `list` | `maxItems` (Standard 50, Obergrenze 200) | Eine Liste nicht leerer Texte, je bis zu 1000 Zeichen. |

<a id="file-profile"></a>
### 2. Das Profil (nur Panel)

**Felder des Profils**

| Feld | Regel |
| --- | --- |
| `subject`, `target` | Was beurteilt wird und wer urteilt. Dokumentation für Leser der Datei. |
| `dimensions` | 1 bis 10 Dimensionen, jede mit einem `name` und 1 bis 50 `values`. Die Anteile einer Dimension ergeben zusammen 1. |
| `values[].value`, `share` | Das Label eines Werts und sein Anteil am Panel. |
| `values[].ranges` | Optionale numerische Bereiche, die beim Austeilen dieses Werts gezogen werden, etwa `"income": [38000, 85000]`. Jeder Wert einer Dimension deklariert dieselben Bereichsnamen. |
| `values[].note` | Optionaler Satz. Er wird zum Kartenfeld `<dimension>_note` (leer bei Werten ohne Notiz). |
| `ranges` (oberste Ebene) | Bereiche, die einmal pro Karte gezogen werden. Ganzzahlige Grenzen ergeben Ganzzahlen; andere Grenzen Zahlen mit zwei Nachkommastellen. |
| `pools` | Benannte Satzlisten. Pro Karte wird ein Eintrag jedes Pools ausgeteilt. |

Kartenfelder sind die Dimensionsnamen, ihre Bereichsnamen, die Bereichsnamen der obersten Ebene, die Pool-Namen und die Notizen. Namen müssen verschieden sein, und `id`, `scope` und `lens` sind reserviert. Personennamen werden nicht ausgeteilt: Ein Briefing, das einen braucht, zieht ihn aus einem vom Pack gelieferten Pool.

<a id="file-units"></a>
### 3. Die Einheitendatei (nur Fanout)

**swarm/units.json**

```json
{
  "schemaVersion": 1,
  "units": [
    { "id": "about", "scope": "site/about", "title": "About us", "tone": "warm" },
    { "id": "pricing", "scope": ["site/pricing", "site/data/prices.json"], "title": "Pricing", "tone": "plain" },
    { "id": "contact", "scope": "site/contact", "title": "Contact", "tone": "short" }
  ]
}
```

- `id`: 1 bis 64 Kleinbuchstaben, Ziffern, `_` oder `-`. Sie wird zur Nexus-Task-ID.
- `scope`: ein Pfad oder eine Liste von bis zu 20, portabel und projektrelativ, nie `.git` oder `.bmad-plus`. Scopes sind paarweise disjunkt: Keiner darf einen anderen enthalten.
- Jedes andere Feld muss Text, Zahl oder Boolean sein; es wird zu einem Kartenfeld, im Briefing als `{{card.field}}` verfügbar.

Die Definition zu dieser Einheitendatei hat kein Profil; `init` nimmt die Einheiten mit `--units`, zum Beispiel `npx bmad-plus swarm init --definition swarm/page-fanout.json --units swarm/units.json`. Hier die Definition des Fanouts `site-pages` aus dem Beispiel am Ende dieser Seite, danach ihre Briefing-Vorlage.

**swarm/page-fanout.json (die Definition)**

```json
{
  "schemaVersion": 1,
  "id": "site-pages",
  "kind": "fanout",
  "title": "One sub-agent per page of the site",
  "units": { "source": "input" },
  "brief": { "template": "briefs/page.md", "context": [] },
  "answer": {
    "required": ["id", "done", "words"],
    "fields": {
      "done": { "type": "boolean" },
      "words": { "type": "integer", "min": 0 },
      "note": { "type": "string", "max": 200 }
    }
  },
  "tally": { "rate": "done", "numbers": ["words"] },
  "disclosure": "Each page was written by a separate sub-agent from the same brief; read them together before publishing."
}
```

**swarm/briefs/page.md (die Vorlage)**

```md
# Page {{unit.id}}

Write the page "{{card.title}}" under `{{card.scope}}`, {{card.tone}} in tone. Touch nothing
outside that folder.

When the page is written, write a JSON object to `{{answer.path}}` with `id` ("{{unit.id}}"),
`done`, `words` (the word count) and an optional `note`.

{{disclosure}}
```

<a id="file-template"></a>
### 4. Die Briefing-Vorlage (Markdown) und die Kontexte

**Platzhalter: nichts anderes ist zwischen doppelten Klammern erlaubt**

| Platzhalter | Ergibt |
| --- | --- |
| `{{card.<field>}}` | Das Kartenfeld; eine Liste wird kommagetrennt ausgegeben. |
| `{{context.<name>}}` | Die beim Init übergebene Kontextdatei, wörtlich und im Lauf eingefroren. |
| `{{answer.path}}` | Der absolute Pfad der Antwortdatei, die der Sub-Agent schreiben muss. |
| `{{run.id}}`, `{{unit.id}}` | Die Lauf-ID und die Einheiten-ID. |
| `{{disclosure}}` | Der Offenlegungshinweis der Definition. |

> **Warnung · Die Laufzeit filtert nichts** Kartenwerte, Pool-Einträge, Felder gelisteter Einheiten und Kontextdateien erreichen den Sub-Agenten Wort für Wort. Ein Pool-Eintrag, der wie eine Anweisung klingt, landet im Briefing als Anweisung. Das Pack verantwortet seine Pools, Einheitenfelder und Vorlagen; du verantwortest die Kontexte, die du übergibst. Lies einen Kontext, bevor du ihn übergibst, und übergib nie eine Datei, die du nicht gelesen hast: Sie steht in jedem Briefing, samt Geheimnissen und Anweisungen. Ein unbekannter Platzhalter, ein Kartenfeld, das einer Karte fehlt, ein nicht deklarierter Kontext oder ein literales `{{` in der Vorlage lassen `init` scheitern.

<a id="dealing"></a>
## Deterministisches Austeilen und Seeds

Dasselbe Profil, dasselbe `--n` und derselbe `--seed` ergeben immer dieselben Karten. Jede Dimension wird nach exakter Quote verteilt (größter Rest, Gleichstand nach Deklarationsreihenfolge): Bei Anteilen von 0,45, 0,40 und 0,15 enthalten zwanzig Karten 9, 8 und 3 Einheiten dieser Werte, egal welcher Seed. Die Wertespalte wird dann von einem SHA-256-basierten Generator gemischt, und Karte k nimmt die Position k jeder Spalte; Bereiche und Pool-Einträge folgen der Reihe nach. Der Seed (0 bis 2147483647) steht in `run.json`.

Das macht einen Vorher-nachher-Vergleich ehrlich. Um zwei Fassungen eines Pitches zu testen, führst du dasselbe Profil mit demselben `--n` und `--seed` aus und änderst nur die Kontextdatei: Die Käufer sind dieselben, geändert hat sich nur der Pitch. Einheiten-IDs sind das Präfix plus die auf mindestens drei Stellen aufgefüllte Position (`B001`, `B030`, `B1000`).

<a id="refusals"></a>
## Abgelehnte Antworten und was nie geschieht

Eine Antwort zählt nur, wenn `answers/<unit>.json` eine reguläre Datei ist, als JSON-Objekt gelesen wird, eine `id` gleich der Einheiten-ID und alle Pflichtfelder trägt, kein unbekanntes Feld deklariert und jeden Typ und jede Grenze erfüllt. `check` meldet eine Einheit als `missing` (keine Datei) oder `invalid` (mit Gründen). `save` wendet dieselben Regeln auf das erste ausgewogene JSON-Objekt in einer ausgegebenen Antwort an und lehnt ab, wenn keines gefunden wird, wenn die Validierung scheitert (auch eine falsche `id`), wenn die Einheit schon eine gültige Antwort hat und bei einem Lauf, der noch eine Freigabe braucht. Eine abgelehnte Antwort ändert nichts auf der Platte.

**Eine Antwort wird abgelegt, eine andere abgelehnt**

```text
$ npx bmad-plus swarm save buyer-panel-20261019-2ftt B005 --input swarm-inbox/B005.txt
buyer-panel-20261019-2ftt: answer of B005 filed at /work/demo/app/.bmad-plus/swarm/runs/buyer-panel-20261019-2ftt/answers/B005.json
$ npx bmad-plus swarm save buyer-panel-20261019-2ftt B006 --input swarm-inbox/B006.txt
Swarm: Reply of unit B006 refused: field "buys" must be true or false.
# Die erste Datei enthält einen Satz gefolgt von einem gültigen JSON-Objekt; die zweite ein Objekt, dessen Feld buys der Text „maybe“ ist. Exit-Codes 0 und 1.
```

Ausgabe eines echten Laufs. Quelle: bmad-plus 0.23.0, 2026-10-19

<a id="honesty"></a>
## Die Ehrlichkeitsregeln

- Nie für eine Einheit antworten: weder durch Schreiben einer Antwortdatei noch durch „Reparieren“ einer ungültigen noch durch Ablegen mit `save` von etwas, das ein Sub-Agent nicht ausgegeben hat.
- Nie ein Briefing bearbeiten. Eine Änderung gehört in die Vorlage oder die Definition und dann in einen neuen Lauf.
- Der Offenlegungshinweis kommt einmal und zuerst: Die Auswertung beginnt damit, und der Assistent wiederholt ihn einmal in seinem Bericht, vor jeder Zahl.
- Raten sind eine Obergrenze, die mit echten Menschen zu bestätigen ist. Zitate sind das, was eine simulierte Einheit geschrieben hat.
- Der Seed reist mit dem Ergebnis: gleicher Seed, gleiche Karten, damit ein Vergleich ein Vergleich ist.
- Eine gültige Antwort ist eine wohlgeformte. Nichts beweist, dass ein Sub-Agent sein Briefing gelesen, in seiner Karte geblieben oder die Wahrheit gesagt hat; Qualität ist deine Lesart der Auswertung.
- Antworten werden von außerhalb des Zustandsbaums abgelegt: `save --input` nimmt eine vom Host geschriebene Projektdatei (etwa in `swarm-inbox/`), nie einen Pfad unter `.bmad-plus/`.

<a id="worked-panel"></a>
## Ein durchgespieltes Käuferpanel

Das Szenario: Eine Kaffeebar namens Orbit will wissen, wie ein urbaner Berufstätiger auf ihren Pitch reagiert. Die Dateien unten sind die Test-Fixtures des BMAD+-Repositorys, hier unverändert verwendet: die Definition, das Profil und die Briefing-Vorlage. Der Pitch selbst besteht aus zwei Sätzen.

**swarm/buyer-panel.json (die Definition)**

```json
{
  "schemaVersion": 1,
  "id": "buyer-panel",
  "kind": "panel",
  "pack": "marketfit",
  "title": "Simulated buyers see the pitch",
  "units": { "source": "profile", "idPrefix": "B" },
  "brief": { "template": "briefs/buyer.md", "context": ["pitch"] },
  "answer": {
    "required": ["id", "buys", "reason_code", "reason"],
    "fields": {
      "buys": { "type": "boolean" },
      "reason_code": { "type": "enum", "values": ["price", "habit", "need", "trust", "other"] },
      "reason": { "type": "string", "max": 600 },
      "price_floor": { "type": "number", "min": 0 },
      "visits_per_week": { "type": "integer", "min": 0, "max": 14 },
      "would_tell": { "type": "list", "maxItems": 3 }
    }
  },
  "tally": {
    "rate": "buys",
    "groupBy": ["segment", "behaviour"],
    "counts": ["reason_code"],
    "quotes": { "reason": 2 },
    "numbers": ["price_floor"]
  },
  "disclosure": "Simulated units are not people. Read rates as an upper bound and confirm with real ones."
}
```

**swarm/profile.json (das Profil)**

```json
{
  "schemaVersion": 1,
  "subject": "Orbit espresso bar",
  "target": "Urban professionals who buy coffee most days",
  "dimensions": [
    {
      "name": "segment",
      "values": [
        { "value": "early career", "share": 0.45, "ranges": { "income": [38000, 85000] } },
        { "value": "mid career", "share": 0.4, "ranges": { "income": [85000, 150000] } },
        { "value": "high earner", "share": 0.15, "ranges": { "income": [150000, 210000] } }
      ]
    },
    {
      "name": "behaviour",
      "values": [
        { "value": "daily regular", "share": 0.2, "note": "same drink, same place, most mornings" },
        { "value": "explorer", "share": 0.5 },
        { "value": "occasional", "share": 0.3, "note": "a treat, not a routine" }
      ]
    }
  ],
  "ranges": { "age": [24, 38], "walk_minutes": [1.5, 12] },
  "pools": {
    "objection": ["too steep for a drink", "my place is closer", "I do not know the brand"],
    "habit": ["you pass the street on the way to work", "you order the same thing every day"]
  }
}
```

**swarm/briefs/buyer.md (die Vorlage)**

```md
# You are unit {{unit.id}} of run {{run.id}}

You are one simulated buyer. Stay inside this card for the whole task.

- Segment: {{card.segment}}, income {{card.income}}
- Behaviour: {{card.behaviour}} ({{card.behaviour_note}})
- Age {{card.age}}, {{card.walk_minutes}} minutes on foot from the bar
- Your first objection: {{card.objection}}
- Your habit: {{card.habit}}

## The pitch

{{context.pitch}}

## Your answer

Write a JSON object to `{{answer.path}}` with the fields `id` (exactly "{{unit.id}}"), `buys`,
`reason_code` (price, habit, need, trust or other), `reason` (your own words, 600 characters at
most) and, when you have one, `price_floor`.

{{disclosure}}
```

**swarm/pitch.md (der Kontext)**

```text
Orbit opens at 7, two streets from the station. A flat white is 4.20, the loyalty card gives
the tenth one free, and the bar keeps your usual order under your name.
```

Seed 7 und 30 Einheiten ergeben diese erste Karte (aus `cards.json`). Das Briefing, das der Sub-Agent erhält, ist die Vorlage mit dieser Karte, dem Pitch und dem Antwortpfad.

**Die Karte der Einheit B001**

```json
{
  "id": "B001",
  "segment": "mid career",
  "income": 114720,
  "behaviour": "occasional",
  "behaviour_note": "a treat, not a routine",
  "age": 32,
  "walk_minutes": 8.99,
  "objection": "I do not know the brand",
  "habit": "you order the same thing every day"
}
```

Im Protokoll unten würde der Assistent 30 Sub-Agenten in drei Wellen starten. Um die Dateien, das Werkzeug und die Auswertung ohne Modell zu zeigen, wurden fünf Antworten für diese Demonstration von Hand geschrieben (vier als Dateien, eine über `save`), und eine sechste Antwort wurde abgelehnt. Die Auswertung zählt also 5 von 30 Einheiten und nennt die anderen 25. Die Zitate unten stammen daher ebenfalls nicht von einem Modell: Sie sind Demonstrationstext.

**Die Demonstrationsantworten (je eine Datei in answers/; B005 und B006 sind mit save abgelegte Antworten)**

```text
answers/B001.json    { "id": "B001", "buys": true, "reason_code": "habit", "reason": "The bar keeps my usual order under my name, so I would stop at a tenth coffee for free.", "price_floor": 3.8 }
answers/B002.json    { "id": "B002", "buys": false, "reason_code": "price", "reason": "A flat white at 4.20 is more than my usual place, and it is closer.", "price_floor": 3.2 }
answers/B003.json    { "id": "B003", "buys": true, "reason_code": "need", "reason": "Opening at seven fits my route to the station, and I order the same drink every morning.", "price_floor": 4.5 }
answers/B004.json    { "id": "B004", "buys": false, "reason_code": "trust", "reason": "I do not know the brand and nothing in the pitch tells me why I should switch.", "price_floor": 3.5 }
swarm-inbox/B005.txt Here is my answer as a buyer.
                     { "id": "B005", "buys": true, "reason_code": "habit", "reason": "Same drink, same place, most mornings: the loyalty card would pay for itself.", "price_floor": 4.2 }
swarm-inbox/B006.txt { "id": "B006", "buys": "maybe", "reason_code": "other", "reason": "I could go either way." }
```

**Von den Briefings zur Auswertung, mit fünf von Hand geschriebenen Demonstrationsantworten**

```text
$ npx bmad-plus swarm briefs buyer-panel-20261019-2ftt
buyer-panel-20261019-2ftt: 30 of 30 units need a sub-agent, in waves of 10.
Wave 1:
  B001  /work/demo/app/.bmad-plus/swarm/runs/buyer-panel-20261019-2ftt/briefs/B001.md
  B002  /work/demo/app/.bmad-plus/swarm/runs/buyer-panel-20261019-2ftt/briefs/B002.md
# ... Einheiten B003 bis B010, dann Wellen 2 und 3 (B011 bis B030) ...
Each sub-agent: Read the brief and follow it exactly; it is your whole instruction.
Disclosure: Simulated units are not people. Read rates as an upper bound and confirm with real ones.
# Vier Antwortdateien (B001 bis B004) werden nun von Hand in answers/ geschrieben.
$ npx bmad-plus swarm check buyer-panel-20261019-2ftt
buyer-panel-20261019-2ftt: 4 of 30 valid answers.
  B005  missing: no answer file
  B006  missing: no answer file
# ... und so weiter bis B030. Exit-Code 1.
$ npx bmad-plus swarm tally buyer-panel-20261019-2ftt
/work/demo/app/.bmad-plus/swarm/runs/buyer-panel-20261019-2ftt/tally.md
5 of 30 units counted; 25 skipped.
Disclosure: Simulated units are not people. Read rates as an upper bound and confirm with real ones.
$ npx bmad-plus swarm inspect buyer-panel-20261019-2ftt
buyer-panel-20261019-2ftt: tallied (panel, approved by the user)
units 30, briefed 30, valid 5, invalid 0, missing 25
Disclosure: Simulated units are not people. Read rates as an upper bound and confirm with real ones.
```

Ausgabe eines echten Laufs. Quelle: bmad-plus 0.23.0, 2026-10-19

**tally.md (Anfang und Raten-Abschnitt)**

```md
> Simulated units are not people. Read rates as an upper bound and confirm with real ones.

# Simulated buyers see the pitch (run buyer-panel-20261019-2ftt)

5 of 30 units gave a valid answer; 25 skipped: B006 (no answer file), B007 (no answer file), ...

## Rate: buys

| group | yes | of | rate |
|---|---|---|---|
| all | 3 | 5 | 60.0% |
| segment = mid career | 2 | 4 | 50.0% |
| segment = high earner | 1 | 1 | 100.0% |
| segment = early career | 0 | 0 | n/a |
| behaviour = occasional | 1 | 3 | 33.3% |
| behaviour = daily regular | 2 | 2 | 100.0% |
| behaviour = explorer | 0 | 0 | n/a |
```

So liest man es: Die Rate kommt mit ihrem Nenner („3 von 5“, und 5 von 30 Einheiten gezählt), nicht als bloßer Prozentwert. Eine Gruppe ohne gültige Antwort zeigt `n/a`, nicht 0. Derselbe Lauf schreibt außerdem Zählungen je Begründungscode, die ersten zwei Zitate je Gruppe wörtlich sowie Median, Mittelwert, Minimum und Maximum von `price_floor`. Führe `init` mit demselben Profil, `--n 30` und `--seed 7` gegen einen zweiten Pitch erneut aus, um zu vergleichen: Die Datei `cards.json` beider Läufe ist Byte für Byte identisch (`cmp` meldet keinen Unterschied zwischen ihnen).

<a id="recipe-transcript"></a>
## Die Schritte des Abnahmeprotokolls, erneut ausgeführt: 1 gültige Antwort von 30

Das Abnahmeprotokoll von 0.23.0 enthält einen Schwarm-Schritt in einem leeren Projekt, den eine Person durchläuft: Kein Sub-Agent läuft, der Tester ist eine Einheit, legt für B001 eine gültige Antwort ab und versucht eine schlechte. Das Werkzeug zählt genau das und sagt es. Unten dieselbe Abfolge, erneut mit der 0.23.0-CLI ausgeführt (die 30 Pfade von `briefs` sind gekürzt).

**briefs, check, save, tally mit nur einer gültigen Antwort**

```text
$ npx bmad-plus swarm init --definition swarm/buyer-panel.json --profile swarm/profile.json --context pitch=swarm/pitch.md --n 30 --seed 7 --approved
buyer-panel-20261019-9da2: panel of 30 units, budget 26, approval user.
Seed 7 (same seed, same cards).
Next: bmad-plus swarm briefs buyer-panel-20261019-9da2
$ npx bmad-plus swarm briefs buyer-panel-20261019-9da2
buyer-panel-20261019-9da2: 30 of 30 units need a sub-agent, in waves of 10.
Wave 1:
# ... eine Zeile pro Einheit mit dem Briefing-Pfad, drei Wellen ...
Each sub-agent: Read the brief and follow it exactly; it is your whole instruction.
Disclosure: Simulated units are not people. Read rates as an upper bound and confirm with real ones.
# Der Tester schreibt von Hand eine gültige Antwort: answers/B001.json.
$ npx bmad-plus swarm check buyer-panel-20261019-9da2
buyer-panel-20261019-9da2: 1 of 30 valid answers.
  B002  missing: no answer file
# ... B003 bis B030 ebenso.
$ npx bmad-plus swarm save buyer-panel-20261019-9da2 B002 --input swarm/reply-bad.txt
Swarm: Reply of unit B002 refused: field "buys" must be true or false.
# swarm/reply-bad.txt enthält ein Objekt, dessen Feld buys der Text „maybe“ ist. Exit-Code 1.
$ npx bmad-plus swarm tally buyer-panel-20261019-9da2
/work/demo/app/.bmad-plus/swarm/runs/buyer-panel-20261019-9da2/tally.md
1 of 30 units counted; 29 skipped.
Disclosure: Simulated units are not people. Read rates as an upper bound and confirm with real ones.
$ head -n 3 .bmad-plus/swarm/runs/buyer-panel-20261019-9da2/tally.md
> Simulated units are not people. Read rates as an upper bound and confirm with real ones.

# Simulated buyers see the pitch (run buyer-panel-20261019-9da2)
```

Ausgabe eines echten Laufs. Quelle: bmad-plus 0.23.0, 2026-10-19

<a id="jury"></a>
## Eine Jury: drei Blickwinkel auf denselben Pitch

Eine Jury braucht kein Profil, kein `--n` und keinen Seed: Ihre Einheiten stehen in der Definition, je eine Linse. Diese (`swarm/pitch-jury.json`, unten samt Vorlage abgedruckt) liest denselben Pitch durch Preis, Vertrauen und Gewohnheit. Der dritte Juror trägt eine eigene `id` (`J-habit`); die ersten beiden erhalten `J001` und `J002` aus dem Präfix. Ihre Antwort hat nur drei Felder: ein Urteil, die schwächste Behauptung und bis zu zwei Korrekturen; die Auswertung zählt Urteile und behält die ersten drei Zitate.

**swarm/pitch-jury.json (die Definition)**

```json
{
  "schemaVersion": 1,
  "id": "pitch-jury",
  "kind": "jury",
  "title": "Three lenses on the pitch",
  "units": {
    "source": "list",
    "idPrefix": "J",
    "list": [
      { "lens": "price", "stance": "Every claim is a cost the buyer pays." },
      { "lens": "trust", "stance": "Who vouches for this, and why believe them?" },
      { "id": "J-habit", "lens": "habit", "stance": "What has to change in a normal morning?" }
    ]
  },
  "brief": { "template": "briefs/juror.md", "context": ["pitch"] },
  "answer": {
    "required": ["id", "verdict", "weakest_claim"],
    "fields": {
      "verdict": { "type": "enum", "values": ["convincing", "unclear", "weak"] },
      "weakest_claim": { "type": "string", "min": 5, "max": 300 },
      "fixes": { "type": "list", "maxItems": 2 }
    }
  },
  "tally": { "counts": ["verdict"], "quotes": { "weakest_claim": 3 } },
  "disclosure": "A simulated jury is a rehearsal, not a review by the people it imitates."
}
```

**swarm/briefs/juror.md (die Vorlage)**

```md
# Juror {{unit.id}}

Lens: {{card.lens}}. Stance: {{card.stance}}

Read the pitch below through that lens only and write a JSON object to `{{answer.path}}` with
`id` ("{{unit.id}}"), `verdict` (convincing, unclear or weak), `weakest_claim` and optional `fixes`.

{{context.pitch}}

{{disclosure}}
```

**Die Demonstrationsantworten (answers/J001.json, answers/J002.json, answers/J-habit.json)**

```text
{ "id": "J001", "verdict": "unclear", "weakest_claim": "A flat white at 4.20 is stated, but nothing says what it is compared to.", "fixes": ["Compare the price with a nearby chain.", "Show what the loyalty card is worth in euros."] }
{ "id": "J002", "verdict": "weak", "weakest_claim": "No one vouches for the bar: there is no review, no name, no photo.", "fixes": ["Add two customer sentences with a first name."] }
{ "id": "J-habit", "verdict": "convincing", "weakest_claim": "Opening at seven is good; it does not say how long the queue is.", "fixes": ["Say how long a regular order takes."] }
```

**Eine Jury aus drei Einheiten, mit drei von Hand geschriebenen Demonstrationsantworten**

```text
$ npx bmad-plus swarm init --definition swarm/pitch-jury.json --context pitch=swarm/pitch.md
pitch-jury-20261019-3qxm: jury of 3 units, budget 26, approval not-needed.
Units listed, no seed.
Next: bmad-plus swarm briefs pitch-jury-20261019-3qxm
$ npx bmad-plus swarm briefs pitch-jury-20261019-3qxm
pitch-jury-20261019-3qxm: 3 of 3 units need a sub-agent, in waves of 10.
Each sub-agent: Read the brief and follow it exactly; it is your whole instruction.
Disclosure: A simulated jury is a rehearsal, not a review by the people it imitates.
# Drei Antwortdateien werden von Hand in answers/ geschrieben.
$ npx bmad-plus swarm check pitch-jury-20261019-3qxm
pitch-jury-20261019-3qxm: 3 of 3 valid answers.
$ npx bmad-plus swarm tally pitch-jury-20261019-3qxm
3 of 3 units counted; 0 skipped.
Disclosure: A simulated jury is a rehearsal, not a review by the people it imitates.
```

Ausgabe eines echten Laufs. Quelle: bmad-plus 0.23.0, 2026-10-19

**tally.md der Jury**

```md
> A simulated jury is a rehearsal, not a review by the people it imitates.

# Three lenses on the pitch (run pitch-jury-20261019-3qxm)

3 of 3 units gave a valid answer; 0 skipped.

## Counts: verdict

| group | convincing | unclear | weak |
|---|---|---|---|
| all | 1 | 1 | 1 |

## Quotes: weakest_claim (up to 3 per group, verbatim)

**all**
- J001: "A flat white at 4.20 is stated, but nothing says what it is compared to."
- J002: "No one vouches for the bar: there is no review, no name, no photo."
- J-habit: "Opening at seven is good; it does not say how long the queue is."
```

<a id="use-cases"></a>
## Einsatzfälle für Panel und Jury

**Welche Art welche Frage beantwortet**

| Frage | Art | Wie man es startet |
| --- | --- | --- |
| Schlägt der neue Pitch den alten bei denselben Leuten? | `panel` | Gleiches Profil, gleiche `--n` und `--seed`; ändere nur `--context pitch=...`; vergleiche die beiden Auswertungen. |
| Welches Segment wehrt sich gegen den Preis? | `panel` | Lege das Segment in `groupBy`, den Einwand in ein Enum-Feld und lies `counts` je Gruppe. |
| Was ist die schwächste Behauptung dieser Seite? | `jury` | Eine Linse pro Juror (Preis, Vertrauen, Barrierefreiheit, Recht); lies die Zitate je Linse. |
| Übersteht der Plan eine kritische Gegenlesung? | `jury` | Gib jedem Juror eine Haltung wie „nimm an, das scheitert; wo?“ und zähle die Urteile. |
| Lassen sich zwölf Seiten schreiben, ohne sich in die Quere zu kommen? | `fanout` | Eine Einheit pro Seite mit disjunktem `scope`; als Sitzungs-Sub-Agenten ausführen oder mit `swarm plan` für Nexus exportieren. |

<a id="example-swarm-panel-before-after"></a>
### Zwei Pitches mit denselben simulierten Käufern vergleichen

Nutze es, wenn du ein Profil und eine Panel-Definition sowie zwei Textfassungen zum Testen hast. Rechne mit einer Freigabe-Rückfrage, wenn das Panel größer als 26 ist.

**In deinem KI-Assistenten**

```text
Starte den Schwarm buyer-panel mit 30 Einheiten und Seed 7 auf swarm/pitch-v1.md, dann noch einmal mit demselben Seed und Profil auf swarm/pitch-v2.md. Braucht ein Lauf eine Freigabe, frage mich zuerst mit den Zahlen. Starte die Sub-Agenten Welle für Welle und antworte nie für eine Einheit. Berichte nur aus den beiden Auswertungen: zuerst der Offenlegungshinweis, dann die Kaufrate je Segment für jeden Pitch mit Nenner, die Begründungscodes und was sich zwischen beiden geändert hat.
```

**Das solltest du erhalten** Der erste `init` endet mit Exit-Code 2 und der Zeile „needs approval ... 30 sub-agents and the budget is 26“. Nach deinem Ja laufen drei Wellen zu je 10, `check` listet fehlende Einheiten, die Auswertungsdateien werden geschrieben, und der Bericht nennt den Offenlegungshinweis vor jeder Rate. Da beide Läufe Profil, `--n` und Seed teilen, sind ihre `cards.json` identisch, und der Unterschied kommt allein vom Pitch. Lies das Ergebnis als Obergrenze, die mit echten Menschen zu bestätigen ist.

<a id="example-swarm-jury-read"></a>
### Eine Jury vor dem Start eine Seite angreifen lassen

Nutze es mit einer Jury-Definition (eine Linse pro Juror) und dem zu lesenden Text als Kontextdatei. Weder Profil noch Seed sind nötig.

**In deinem KI-Assistenten**

```text
Starte den Schwarm pitch-jury auf swarm/pitch.md. Ein Sub-Agent pro Juror, jeder liest nur sein eigenes Briefing. Lies jede Kontextdatei, bevor du sie übergibst. Berichte nach der Auswertung zuerst den Offenlegungshinweis, dann die Urteilszahlen und die schwächste Behauptung je Linse als Zitat und liste die von den Juroren vorgeschlagenen Korrekturen auf. Schreibe oder ändere selbst keine Antwort.
```

**Das solltest du erhalten** Drei Briefings werden gerendert, drei Sub-Agenten antworten, `check` meldet 3 von 3 gültigen Antworten, und `tally.md` beginnt mit „A simulated jury is a rehearsal, not a review by the people it imitates.“ Danach zeigt es, wie viele Juroren den Pitch überzeugend, unklar oder schwach fanden, und zitiert jede schwächste Behauptung mit der Juror-ID.

<a id="example-swarm-fanout-pages"></a>
### Mehrere Seiten parallel schreiben und prüfen

Nutze es, wenn Einheiten das Repository ändern, je eine Prüfung brauchen oder die Sitzung überleben müssen: exportiere den Fanout als Nexus-Plan.

**In deinem KI-Assistenten**

```text
Initialisiere den Fanout site-pages aus swarm/page-fanout.json und swarm/units.json (about, pricing, contact), exportiere ihn mit swarm plan nach .bmad-plus/swarm/reports/RUN/plan.json und lege daraus den Nexus-Lauf an. Starte auf diesem Host eine Aufgabe nach der anderen, lass mich die Seite prüfen, verifiziere und akzeptiere sie dann. Akzeptiere keine Aufgabe, deren Prüfung fehlschlägt.
```

**Das solltest du erhalten** `swarm plan` meldet „3 tasks“ und schreibt einen Plan, dessen Aufgaben die disjunkten Scopes tragen; `nexus create` zeigt jede Aufgabe als „not started; verification=pending; acceptance=pending“. Pro Aufgabe: `start`, die Seite wird geschrieben, `record`, dann führt `verify` die Prüfung der Einheit aus und `accept` markiert sie als akzeptiert. Eine Aufgabe mit ungültiger Antwortdatei bleibt unakzeptiert.

<a id="run-tree-and-limits"></a>
## Laufstruktur und Grenzen

**.bmad-plus/swarm/runs/<definition-id>-<yyyymmdd>-<4 chars>/**

```text
run.json         kind, pack, hashes of every input, n, seed, wave, budget, approval, status
definition.json  the normalized definition, frozen
template.md      the brief template, frozen
cards.json       the dealt or listed units
context/<name>.md  each context file, frozen
briefs/<unit>.md   rendered by briefs or plan
answers/<unit>.json  written by the sub-agent, or filed by save
tally.json, tally.md
checks/answer.cjs, checks/swarm-validate.cjs, nexus-plan.json   (fanout, written by plan)
```

**Grenzen**

| Grenze | Wert |
| --- | --- |
| Einheiten pro Lauf | 1 bis 1000 |
| `budget`, `wave` | 1 bis 1000 (Standard 26 und 10) |
| Seed | 0 bis 2147483647 |
| Eingabedateien (Definition, Profil, Einheiten, Vorlage, Kontexte, Antworten) | Je höchstens 16 MiB; eine an `save` gegebene Antwort höchstens 1 MiB |
| Profil | 10 Dimensionen mit bis zu 50 Werten, 20 Bereiche, 20 Pools mit bis zu 200 Einträgen |
| Antwortfelder | 50; Enum-Werte 50; Listenelemente bis 200; Obergrenze der Textlänge 20000 |
| `groupBy`-Felder; Zitate pro Gruppe | 5; 1 bis 10 |
| Fanout-Scopes pro Einheit | 20 |
| Export nach Nexus | Eine Aufgabe pro Einheit, `maxParallel` höchstens 32 (Nexus akzeptiert 200 Aufgaben pro Lauf) |

Sicherheitsgrenzen: Die Laufzeit hat keinen Kindprozess, kein Netzwerk und kein `eval`; jede Datei wird atomar und nur unter `.bmad-plus/swarm/` geschrieben; Pfade, die aufsteigen, absolut sind, einem Link folgen oder `.git` erreichen, werden abgelehnt; Eingaben werden bei `init` eingefroren, eine spätere Änderung eines Kontexts ändert für diesen Lauf also nichts.

**Siehe auch**

- [Referenz: bmad-plus swarm](https://bmad-plus.rochetta.fr/de/docs/reference/cli-swarm/)
- [Tutorial: von der Idee zum Schwarm](https://bmad-plus.rochetta.fr/de/docs/guides/idea-to-swarm/)
- [Intake: erst fragen](https://bmad-plus.rochetta.fr/de/docs/concepts/intake/)
- [Nexus, Autopilot und parallele Arbeit](https://bmad-plus.rochetta.fr/de/docs/concepts/nexus-orchestration/)
- [Referenz: config.yaml](https://bmad-plus.rochetta.fr/de/docs/reference/config-yaml/)

[BMAD+ Dokumentation](https://bmad-plus.rochetta.fr/de/docs/) · [Konzepte](https://bmad-plus.rochetta.fr/de/docs/concepts/)

[Quellcode auf GitHub](https://github.com/lrochetta/BMAD-PLUS)
