Alle Skills

test-driven-development (obra/superpowers)

Implementiert Features und Bugfixes testgetrieben: erst der fehlschlagende Test, dann der Produktivcode.

superpowers test-driven-development: Bringt den Agenten dazu, zuerst den Test zu schreiben, und kostet etwa 1.6x die Tokens

EmpfohlenSicher

Codex CLI · gpt-6-astra

24.0 / 30

Lift gegenüber ohne Skill: +1.00 · Empfohlen · 18 Läufe

Empfohlen: Die Gesamtpunktzahl 24.0/30 liegt bei mindestens 22, die Ausgabequalität 5.0 bei mindestens 3.5 und der Lift +1.00 bei mindestens +1.0.

SOTA

Bestanden

Getestet mit Codex.

Gilt für Codex, Claude Code

Codex CLI 0.166 (SOTA-Stufe): 18 bewertete Läufe. Ein Bestehen hier deckt gemäß unserer Stufenregel auch Claude Code ab; über die zweite Stufe sagt es nichts aus.

Punktzahlen

Jede Dimension reicht von 0 bis 5, und die sechs ergeben zusammen die Gesamtpunktzahl von 30. 5 ist in jeder Dimension besser. Kosten 5 bedeutet günstig und schnell. Installation 5 bedeutet einfach.

Trigger-Zuverlässigkeit
5.0
Lift gegenüber ohne Skill
3.0
Ausgabequalität
5.0
Token- und Zeitkosten
2.0
Installation und Portabilität
4.0
Sicherheit
5.0

Sicherheitsprüfung

Sicher

Statischer Scan: 0 CRITICAL / 0 HIGH / 0 MEDIUM. Manuelle Prüfung: Sicher in einer Sandbox ohne Netzwerk auszuführen (keine Befunde). Ein sauberer Scan beweist nicht, dass ein Skill sicher ist.

Installieren

npx skills@latest add obra/superpowers --skill test-driven-development

Quelle

Fixierter Commit: 2ce8aa15d05bd57213e6f746f953aafb7ded7a8b

Getestet: 2026-11-02

Was wir getestet haben

  • Eine Funktion nach einer präzisen Spezifikation implementieren — slugify(text, max_length=None) in slug.py implementieren (Python 3, nur Standardbibliothek). Spezifikation: Text kleinschreiben; jede Folge von Zeichen, die keine ASCII-Buchstaben oder -Ziffern sind, durch ein einzelnes '-' ersetzen; führende und abschließende '-' entfernen; ein leeres Ergebnis wird 'n…
  • Eine kleine zustandsbehaftete Klasse implementieren — ratelimiter.py schreiben (Python 3, nur Standardbibliothek) mit class RateLimiter(limit, window_seconds, clock=time.monotonic): ein Sliding-Window-Limiter pro Schlüssel. allow(key) gibt True zurück und zeichnet den Aufruf auf, wenn in den letzten…
  • Einen Rundungsfehler beheben — Kunden sagen, cart_total in cart.py sei manchmal einen Cent daneben im Vergleich zu unserem Buchhaltungssystem, das bei jedem Schritt kaufmännisch auf den Cent rundet (jede Zeilensumme, die rabattierte Zwischensumme und die Steuer). Beispiel: cart_total([(1.005, 1)]) sollte 1.09 zurückgeben und…

Vorteile

  • Hebt den Mittelwert von 4.0 auf 5.0 gegenüber ohne Skill (+1.00).
  • Der Skill wurde erkannt, ohne genannt zu werden: Skill-Datei in 6/6 Treatment-Läufen gelesen.
  • Schlägt eine Ein-Satz-Version seiner eigenen Regel um +0.33.
  • Hohe absolute Qualität mit dem Skill: 5.0 von 5.

Nachteile

  • Verbraucht 1.65x die Tokens von ohne Skill.
  • Testhinweis: Der Ein-Satz-Arm (6 Läufe) wurde später auf einem anderen Rechner als Kontroll- und Treatment-Arm ergänzt.
  • n=2 pro Aufgabe und Variante; Unterschiede unter etwa 1 Punkt sind Rauschen.

Bewertung

Codex CLI 0.166 (gpt-6-astra, niedriges Reasoning) auf einem Mac-Testrechner, einem frischen temporären Projekt und temporären HOME/TMPDIR/Caches pro Lauf; Skill installiert (Treatment) oder nicht vorhanden (Kontrolle) oder nicht vorhanden mit der Kernanforderung des Skills in einem an den Prompt angehängten Satz (One-Liner-Gruppe); 2 Läufe pro Gruppe und Aufgabe; Netzwerk aus; Schreiben nach /tmp blockiert. Die Prompts nennen den Skill nie (außer der unten genannten Formulierung). Die Prompts nennen den Skill nie. Die Bewertung ist programmatisch (versteckte Tests / Trefferquote eingebauter Probleme / Constraint-Prüfungen / Rendern+OCR wo relevant), 0–5 pro Lauf. Keine Punktzahl wurde von einem LLM-Richter vergeben.

Drei-Arm-Vergleich

VarianteDurchschnittsnote (0-5)Tokens pro Lauf
Ohne Skill4.065k
Ein-Satz-Prompt4.67127k
Mit Skill5.0108k

Gemessen mit Codex CLI über 18 Läufe, bewertet durch regelbasierte Prüfungen ohne LLM-Richter. Gesamt 24.0 / 30, Urteil Empfohlen.

Offenlegung: Der Ein-Satz-Arm (6 Läufe) wurde später auf einem anderen Rechner als Kontroll- und Treatment-Arm ergänzt.

Urteil: Empfohlen (24.0 / 30). Quelle: obra/superpowers, skills/test-driven-development, gepinnt auf Commit 2ce8aa1. Installation: npx skills@latest add obra/superpowers --skill test-driven-development. Lizenz: MIT (Repo-LICENSE).

Worum es geht

Der Skill test-driven-development aus obra/superpowers. Seine Beschreibung lautet: „Verwende ihn bei der Implementierung eines Features oder Bugfixes, bevor du Implementierungscode schreibst.“ Rund 1,500 Wörter Markdown (das „eherne Gesetz“ von Red-Green-Refactor, eine Tabelle mit Ausreden für das Überspringen des Tests, eine Verifikationscheckliste) plus eine zusätzliche Datei über das Schreiben guter Tests. Keine Skripte.

So haben wir getestet

Codex CLI 0.166 (gpt-6-astra, niedriges Reasoning) auf einem Mac-Testgerät, pro Lauf ein frisches temporäres Projekt und temporäre HOME/TMPDIR/Caches, Skill installiert (Skill-Gruppe), nicht vorhanden (Kontrollgruppe) oder nicht vorhanden, aber mit der Kernanforderung des Skills als einem an den Prompt angehängten Satz (Ein-Satz-Gruppe), 2 Läufe pro Gruppe und Aufgabe, Netzwerk aus, Schreibzugriffe auf /tmp blockiert. Die Prompts nennen den Skill nie.

  1. Eine Funktion nach einer präzisen Spezifikation implementieren — Implementiere slugify(text, max_length=None) in slug.py (Python 3, nur Standardbibliothek). Spezifikation: Den Text in Kleinbuchstaben umwandeln; jeden Lauf von Zeichen, die keine ASCII-Buchstaben oder -Ziffern sind, durch einen einzelnen „-“ ersetzen; führende und nachfolgende „-“ entfernen; ein leeres Ergebnis wird zu „n…“
  2. Eine kleine zustandsbehaftete Klasse implementieren — Schreibe ratelimiter.py (Python 3, nur Standardbibliothek) mit der Klasse RateLimiter(limit, window_seconds, clock=time.monotonic): ein Sliding-Window-Limiter pro Schlüssel. allow(key) gibt True zurück und zeichnet den Aufruf auf, wenn in den letzten … weniger als limit Aufrufe verzeichnet wurden …
  3. Einen Rundungsfehler beheben — Kunden sagen, dass cart_total in cart.py manchmal um einen Cent vom Buchhaltungssystem abweicht, das bei jedem Schritt kaufmännisch auf den Cent rundet (jede Zeilensumme, die rabattierte Zwischensumme und die Steuer). Zum Beispiel sollte cart_total([(1.005, 1)]) 1.09 ergeben, und …

Die Bewertung ist programmatisch (versteckte Tests / Erkennung eingebauter Probleme / Constraint-Checks / Rendern+OCR, wo relevant), 0–5 pro Lauf. Kein LLM-Richter hat einen Score vergeben.

Ergebnisse

Der Ein-Satz-Prompt für die dritte Gruppe: „Befolge ein striktes Red-Green-Refactor: Schreibe zuerst einen fehlschlagenden Test und sieh zu, wie er aus dem richtigen Grund fehlschlägt, schreibe dann die minimale Implementierung, die ihn besteht, und refaktoriere anschließend; kein Produktionscode ohne vorher fehlschlagenden Test.“

AufgabeScore KontrolleEin-SatzMit SkillTokens KontrolleTokens Ein-SatzTokens mit SkillSkill gelesen
t1-slugify4.05.05.062k134k108k2/2
t2-ratelimiter4.05.05.063k147k97k2/2
t3-cart-bugfix4.04.05.069k97k116k2/2

Durchschnittsscore: 4.0 ohne vs. 5.0 mit dem Skill (Delta +1.0). Tokens pro Lauf: 65k vs. 108k (1.65x); Zeit 55s vs. 51s. Ein-Satz-Gruppe: 4.67 (Gewinn des Skills gegenüber der Ein-Satz-Version: +0.33; Gewinn der Ein-Satz-Version gegenüber ohne Skill: +0.67); Ein-Satz-Version 127k Tokens pro Lauf, der Skill kostet also 0.85x so viel wie die Ein-Satz-Version.

Was passiert ist

  • Korrektheit war identisch: Die versteckten Testsuiten bestanden in allen 12 Läufen beider Gruppen (12/12, 10/10 und 11/11 Tests). Bei diesen kleinen Aufgaben ändert der Skill nichts daran, ob der Code funktioniert.
  • Was er ändert, ist die Reihenfolge der Arbeit. In allen 6 Skill-Läufen wurde die Testdatei in einem früheren Schritt geschrieben als die Implementierung; in allen 6 Kontroll-Läufen schrieb der Agent Tests und Implementierung im selben Patch (oder behob zuerst den Bug und ergänzte den Test danach in der Warenkorb-Aufgabe). In dem Skill-Lauf, den wir durchlasen (slugify), schrieb der Agent den Test, führte ihn aus, um ihn scheitern zu sehen, und schrieb dann den Code.
  • Er löst allein über die Beschreibung aus: Die Skill-Datei wurde in 6/6 Skill-Läufen gelesen, obwohl kein Prompt TDD nannte.
  • Er kostet mehr: etwa 1.65x die Tokens pro Lauf (107k vs. 65k) bei ähnlicher Laufzeit (51 s vs. 55 s), weil der Agent den Skill und seine Begleitdatei liest und die Schleife mehrmals durchläuft.
  • Ein-Satz-Version (strenges Red-Green-Refactor, kein Produktionscode ohne fehlschlagenden Test): Mittelwert 4.67, zwischen Kontrolle (4.0) und Skill (5.0), bei 127k Tokens pro Lauf gegenüber 65k für die Kontrolle (2.0x) und 108k für den Skill (1.2x des Skills).
  • Tests wurden vor der Implementierung geschrieben in 0 von 6 Kontroll-Läufen, 4 von 6 Ein-Satz-Läufen und 6 von 6 Skill-Läufen; die fehlenden zwei Ein-Satz-Läufe betreffen die Warenkorb-Bugfix-Aufgabe. Der Skill ist die einzige Gruppe, die es jedes Mal tat, und er tat es mit weniger Befehlen (10 pro Lauf) als die Ein-Satz-Version (19).

Dimensionsbewertungen

DimensionScoreBegründung
1_output_quality5.0

Durchschnittsscore 5.00/5 mit dem Skill (programmatische Prüfungen, siehe Tabelle pro Aufgabe).

2_lift_vs_no_skill3.0

+1.00 Punkte gegenüber 4.00 ohne den Skill (n=2 pro Aufgabe; unter etwa 1 Punkt ist Rauschen).

3_trigger5.0Skill-Datei in 6/6 Skill-Läufen gelesen.
4_instructions_portability4
5_efficiency21.65x Tokens (108k vs. 65k pro Lauf) und 0.93x Zeit (51s vs. 55s).
6_safety_hygiene5

Grenzen dieses Tests

  • Die versteckten Tests bestehen in beiden Gruppen vollständig (Deckeneffekt), daher ist der gemessene Gewinn die Prozessprüfung (Test vor der Implementierung geschrieben), die wir aus dem Event-Log berechnen, kein Ergebnisunterschied.
  • Die Aufgaben sind kleine Python-Übungen in einer Datei; größere Repos, andere Sprachen und Testqualität (zum Beispiel Mutation Testing) wurden nicht getestet.
  • n = 2 pro Gruppe und Aufgabe: Unterschiede unter etwa 1 Punkt sind Rauschen.
  • Regelbasierte Bewertung misst, was die Prüfungen sehen können; sie kann keinen Geschmack beurteilen oder ob ein Ergebnis das bestmögliche ist.

Sicherheit

Siehe security.md. Scan: 0 CRITICAL / 0 HIGH / 0 MEDIUM. Urteil: sicher ausführbar (Sandbox ohne Netzwerk). Ein sauberer Scan beweist nicht, dass ein Skill sicher ist.

Fazit

Tut, was er verspricht: Er ist die einzige Gruppe, die in jedem Lauf zuerst den fehlschlagenden Test schrieb (6/6, gegenüber 0/6 bei der Kontrolle und 4/6 bei der Ein-Satz-Version), mit 1.7x so vielen Tokens wie die Kontrolle und 0.85x so vielen wie die Ein-Satz-Version. Die endgültige Korrektheit war bei diesen kleinen Aufgaben in allen Gruppen gleich, der Gewinn liegt also im Prozess, nicht im Code.

Transkript

Laufprotokoll: test-driven-development (Codex CLI, network off, per-run temp HOME/TMPDIR, one row per graded run.)
Spalten: Aufgabe, Gruppe-Lauf, Punktzahl (0-5), Tokens, Sekunden, bestandene Prüfungen, vom Agenten geöffnete Skill-Dateien.

t1-slugify control-1: Punkte 4.0, Tokens 62017, Sek. 55.5, Prüfungen 2/3, nichts geöffnet
t1-slugify control-2: Punkte 4.0, Tokens 62139, Sek. 53.8, Prüfungen 2/3, nichts geöffnet
t1-slugify oneliner-1: Punkte 5.0, Tokens 135535, Sek. 52.9, Prüfungen 3/3, nichts geöffnet
t1-slugify oneliner-2: Punkte 5.0, Tokens 134448, Sek. 46.7, Prüfungen 3/3, nichts geöffnet
t1-slugify treatment-1: Punkte 5.0, Tokens 118034, Sek. 56.3, Prüfungen 3/3, geöffnet test-driven-development
t1-slugify treatment-2: Punkte 5.0, Tokens 97974, Sek. 48.3, Prüfungen 3/3, geöffnet test-driven-development
t2-ratelimiter control-1: Punkte 4.0, Tokens 63363, Sek. 46.1, Prüfungen 2/3, nichts geöffnet
t2-ratelimiter control-2: Punkte 4.0, Tokens 63431, Sek. 98.9, Prüfungen 2/3, nichts geöffnet
t2-ratelimiter oneliner-1: Punkte 5.0, Tokens 140042, Sek. 60.8, Prüfungen 3/3, nichts geöffnet

18 Läufe, 3 Artefakte

Beispielausgabe

SOTA · With the skill: test_slug.py (t1-slugify, run 1, Codex)

import unittest from slug import slugify class SlugifyTests(unittest.TestCase): def test_normalizes_text(self): cases = [ ('Hello, World!', 'hello-world'), (' --ABC__123\t\nxyz!! ', 'abc-123-xyz'), ('café déjà vu 12٣', 'caf-d-j-vu'), ('İ X', 'i-x'), ('already-a-slug', 'already-a-slug'), ] for text, expected in cases: with self.subTest(text=text): self.assertEqual(slugify(text), expected) def test_empty_result_uses_fallback(self): for text in ('', '--- !\t', '中文', '😀'): with self.subTest(text=text): self.assertEqual(slugify(text), 'n-a') def test_length_limits_respect_word_boundaries(self): cases = [ ('Hello, World!', 8, 'hello'), ('Hello, World!', 11, 'hello-world'), ('Hello, World!', 20, 'hello-world'), ('Hello, World!', 5, 'hello'), ('Hello, World!', 6, 'hello'), ('one two three', 7, 'one-two'), ('one two three', 9, 'one-two'), ('Supercalifragilistic', 5, 'super'), ('Supercalifragilistic next', 5, 'super'), ('abc', 1, 'a'), ('abc', 0, ''), ('!!!', 1, 'n'), ('!!!', 2, 'n'), ('!!!', 3, 'n-a'), ] for text, limit, expected in cases: with self.subTest(text=text, limit=limit): self.assertEqual(slugify(text, limit), expected) def test_explicit_none_leaves_length_unlimited(self): self.assertEqual(slugify('Hello, World!', None), 'hello-world') if __name__ == '__main__': unittest.main()

Pro ansehen