Alle Skills

composition-patterns (vercel-labs/agent-skills)

Refaktoriert React-Komponenten zu Compound-Komponenten und wiederverwendbaren APIs, statt Boolean-Props zu häufen.

vercel-composition-patterns: Verschiebt eine React-Komponente mit Boolean-Props zu einer Compound-Component-API (Kontrolle 3.7, Skill 4.4), ohne zusätzliche Tokens, aber ein Ein-Satz-Prompt mit demselben Rat erzielt 4.7

SituativSicher

Codex CLI · gpt-6-astra

25.1 / 30

Lift gegenüber ohne Skill: +0.68 · Situativ · 18 Läufe

Situativ: der Lift +0.68 liegt unter +1.0. Für „Empfohlen“ sind insgesamt 22/30, eine Ausgabequalität von 3.5 und ein Lift von +1.0 nötig.

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
2.7
Ausgabequalität
4.4
Token- und Zeitkosten
5.0
Installation und Portabilität
4.0
Sicherheit
4.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 vercel-labs/agent-skills --skill composition-patterns

Quelle

Fixierter Commit: 1a2c79d4e6c4a2283dc2c614b6538cbe1ed5ca62

Getestet: 2026-11-02

Was wir getestet haben

  • Boolean-Props durch Komposition ersetzen — Composer.tsx hat einen Haufen Boolean-Props angesammelt. In eine flexible Komponenten-API refaktorieren, die sie nicht braucht. In der einzelnen Datei Composer.tsx bleiben und das Verhalten erhalten.
  • Eine Variante ohne zusätzliche Props hinzufügen — Einen „Quick Reply“-Composer hinzufügen: ein einzeiliges Eingabefeld, das bei Enter sendet, ohne Anhänge oder Emoji-Button. Keine weiteren Boolean-Props zu Composer hinzufügen. Composer.tsx bearbeiten.
  • Eine Komponenten-API reviewen — Die Komponenten-API von Composer.tsx reviewen: Was ist daran falsch und was wäre zu ändern? Keine Dateien ändern.

Vorteile

  • Hebt den Mittelwert von 3.71 auf 4.39 gegenüber ohne Skill (+0.68).
  • Der Skill wurde erkannt, ohne genannt zu werden: Skill-Datei in 6/6 Treatment-Läufen gelesen.
  • Kein Token-Overhead: 1.03x die Tokens von ohne Skill.

Nachteile

  • Ein Ein-Satz-Prompt erzielte 4.7 gegenüber 4.39 mit dem Skill (-0.31).
  • 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 dedizierten Windows-Test-PC, 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). Eine Chat-Composer-Komponente (Composer.tsx) mit einem Haufen Boolean-Props. Aufgaben: sie in eine flexible API refaktorieren und das Verhalten erhalten, einen einzeiligen „Quick Reply“-Composer hinzufügen, ohne weitere Booleans einzuführen, und die Komponenten-API reviewen (keine Änderungen). Die Prompts nennen kein Muster. Der One-Liner nennt die Muster (explizite Varianten aus Compound-Teilen, gemeinsamer Context mit State/Actions, children statt renderX, State in einen Provider gehoben).

Drei-Arm-Vergleich

VarianteDurchschnittsnote (0-5)Tokens pro Lauf
Ohne Skill3.71103k
Ein-Satz-Prompt4.7105k
Mit Skill4.39105k

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

Urteil: Situationsabhängig (25.1 / 30). Quelle: vercel-labs/agent-skills, skills/composition-patterns, festgeschrieben auf Commit 1a2c79d. Installation: npx skills@latest add vercel-labs/agent-skills --skill composition-patterns. Lizenz: MIT (LICENSE im Repo).

Was es ist

Der Skill vercel-composition-patterns (vercel-labs/agent-skills) ist ein React-Kompositionsleitfaden: Boolean-Prop-Wildwuchs vermeiden, Compound Components bauen, die Zustand über Context teilen (eine generische State/Actions-Schnittstelle), explizite Variantenkomponenten erstellen, children statt renderX-Props bevorzugen, Zustand in Provider heben; enthält Hinweise zu React 19. Eine SKILL.md plus ein Regeln-Ordner.

Wie wir getestet haben

Codex CLI 0.166 (gpt-6-astra, niedriges Reasoning) auf einem dedizierten Windows-Test-PC, pro Lauf ein frisches temporäres Projekt sowie temporäre HOME/TMPDIR/Caches, Skill installiert (Treatment) oder nicht vorhanden (Kontrolle) oder nicht vorhanden 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 (außer der unten erwähnten Formulierung).

Eine Chat-Composer-Komponente (Composer.tsx) mit einer Vielzahl von Boolean-Props. Aufgaben: sie in eine flexible API refaktorieren, ohne das Verhalten zu ändern; einen einzeiligen „Quick Reply“-Composer hinzufügen, ohne weitere Booleans einzuführen; und die Komponenten-API reviewen (keine Änderungen). Die Prompts nennen kein Muster. Der Ein-Satz-Prompt nennt die Muster (explizite Varianten aus Compound-Teilen, geteilter Context mit State/Actions, children statt renderX, Zustand in einen Provider gehoben).

  1. Boolean-Props durch Komposition ersetzen — Composer.tsx hat einen Haufen Boolean-Props angesammelt. Refaktoriere sie in eine flexible Komponenten-API, die diese nicht braucht. Behalte alles in der einen Datei Composer.tsx und erhalte das Verhalten.
  2. Eine Variante ohne zusätzliche Props hinzufügen — Füge einen „Quick Reply“-Composer hinzu: ein einzeiliges Eingabefeld, das mit Enter sendet, ohne Anhänge oder Emoji-Button. Füge Composer keine weiteren Boolean-Props hinzu. Bearbeite Composer.tsx.
  3. Eine Komponenten-API reviewen — Reviewe die Komponenten-API von Composer.tsx: Was ist daran falsch, und was würdest du ändern? Ändere keine Dateien.

Die Bewertung erfolgt programmatisch (versteckte Tests / Erkennung eingepflanzter Fehler / Constraint-Checks / Rendering+OCR, wo relevant), 0–5 pro Lauf. Kein LLM-Judge hat eine Bewertung entschieden.

Ergebnisse

Der Ein-Satz-Prompt für die dritte Gruppe: "Vermeide Boolean-Prop-Wildwuchs: teile Modi in explizite Variantenkomponenten auf, die aus Compound-Teilen mit einem gemeinsamen Context und einer generischen State/Actions-Schnittstelle gebaut sind, verwende children statt renderX-Props und hebe den Zustand in einen Provider."

AufgabeKontrollwertEin-SatzMit SkillKontroll-TokenEin-Satz-TokenMit-Skill-TokenSkill gelesen
t1-refactor3.04.54.0126k127k144k2/2
t2-add-variant4.385.05.099k106k100k2/2
t3-review3.754.584.1781k80k70k2/2

Durchschnittswert: 3.71 ohne vs. 4.39 mit dem Skill (Delta +0.68). Token pro Lauf: 103k vs. 105k (1.03x); Zeit 53s vs. 49s. Ein-Satz-Gruppe: 4.7 (Gewinn des Skills gegenüber dem Ein-Satz-Prompt: -0.31; Gewinn des Ein-Satz-Prompts gegenüber ohne Skill: +0.99); Ein-Satz-Token 105k pro Lauf, der Skill kostet also 1.00x so viel wie der Ein-Satz-Prompt.

Was passiert ist

  • Kontrolle 3.71, Skill 4.39, Ein-Satz 4.70 (je n=6). Ohne Anleitung verwendeten die Refactorings der Kontrolle zwar Compound-Teile, aber in beiden Läufen gab der geteilte Context keine State/Actions-Schnittstelle frei, und in beiden Quick-Reply-Läufen sendete der neue Composer nicht mit Enter.
  • Die Refactorings mit dem Skill hatten den Context mit State und Actions (2/2), und ihr Quick-Reply-Composer sendete mit Enter (2/2). Aber beide Treatment-Refactorings erzeugten, wie die Kontrolle, keine expliziten Variantenkomponenten (die Ein-Satz-Läufe taten das in 2/2), und bei der Review-Aufgabe verfehlten beide Treatment-Läufe und beide Kontroll-Läufe den Punkt „Boolean-Prop-Wildwuchs“ (ein schwaches Prüfmuster: Reviewer können es anders formulieren).
  • Die Token sind bei Skill, Ein-Satz und Kontrolle gleich (105k, 105k, 103k): Der Skill wurde in 6/6 Treatment-Läufen gelesen, ohne genannt zu werden, und kostet nichts extra.
  • Treatment-Läufe kopieren den Regeln-Ordner ins Projekt (14.7 neue Dateien pro Lauf).

Dimensionswerte

DimensionWertBegründung
1_output_quality4.39

Durchschnittswert 4.39/5 mit dem Skill (programmatische Checks, siehe Tabelle pro Aufgabe).

2_lift_vs_no_skill2.68

+0.68 Punkte gegenüber 3.71 ohne den Skill (n=2 pro Aufgabe; unter ~1 Punkt ist Rauschen).

3_trigger5.0Skill-Datei in 6/6 Treatment-Läufen gelesen.
4_instructions_portability4SKILL.md plus ein AGENTS.md-Index und ein Regeln-Ordner; nur Dokumentation.
5_efficiency5

1.03x Token (105k vs. 103k pro Lauf) und 0.93x Zeit (49s vs. 53s).

6_safety_hygiene4Nur Prosa; siehe security.md.

Grenzen dieses Tests

  • Regelbasierte Checks am Code-Text (Context-/Provider-Muster, Variantenkomponenten, Key-Props); das TypeScript wurde nicht kompiliert oder gerendert (React ist in der Sandbox nicht installiert).
  • Ein Check für die Review-Aufgabe ist schwach: Er sucht nach der wörtlichen Formulierung „boolean prop“, die Reviewer auch anders ausdrücken können.
  • Ein einziges Komponenten-Fixture; n=2 pro Zelle.
  • n = 2 pro Gruppe und Aufgabe: Abweichungen unter etwa 1 Punkt sind Rauschen.
  • Regelbasierte Bewertung misst, was die Checks sehen können; sie kann weder Geschmack beurteilen noch, 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

Ein ordentlicher Musterleitfaden: Die Compound-Component-Struktur erscheint mit dem Skill zuverlässig und ohne ihn selten, und das kostenlos. Ein einzelner Satz, der die Muster nennt, war hier besser; der Nutzen des Skills liegt also in Bequemlichkeit und Breite, nicht in einer Qualitätsobergrenze.

Transkript

Laufprotokoll: composition-patterns (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-refactor control-1: Punkte 3.0, Tokens 130032, Sek. 72.5, Prüfungen 3/5, nichts geöffnet
t1-refactor control-2: Punkte 3.0, Tokens 123317, Sek. 64.3, Prüfungen 3/5, nichts geöffnet
t1-refactor oneliner-1: Punkte 4.0, Tokens 127545, Sek. 101.8, Prüfungen 4/5, nichts geöffnet
t1-refactor oneliner-2: Punkte 5.0, Tokens 127024, Sek. 89.6, Prüfungen 5/5, nichts geöffnet
t1-refactor treatment-1: Punkte 4.0, Tokens 158276, Sek. 67.7, Prüfungen 4/5, geöffnet composition-patterns
t1-refactor treatment-2: Punkte 4.0, Tokens 130234, Sek. 59.2, Prüfungen 4/5, geöffnet composition-patterns
t2-add-variant control-1: Punkte 4.38, Tokens 99946, Sek. 40.3, Prüfungen 3/4, nichts geöffnet
t2-add-variant control-2: Punkte 4.38, Tokens 100013, Sek. 39.2, Prüfungen 3/4, nichts geöffnet
t2-add-variant oneliner-1: Punkte 5.0, Tokens 106946, Sek. 70.9, Prüfungen 4/4, nichts geöffnet

18 Läufe, 3 Artefakte

Beispielausgabe

SOTA · With the skill: Composer.tsx (t1-refactor, run 1, Codex)

import React, { createContext, use, useState } from "react"; type ComposerProps = { initialText?: string; onSubmit: (text: string) => void; children?: React.ReactNode; }; type ComposerContextValue = { state: { text: string }; actions: { setText: (text: string) => void; submit: () => void; }; }; const ComposerContext = createContext<ComposerContextValue | null>(null); export function useComposer() { const context = use(ComposerContext); if (!context) { throw new Error("Composer components must be inside Composer.Provider or Composer."); } return context; } function ComposerProvider({ initialText = "", onSubmit, children }: ComposerProps) { const [text, setText] = useState(initialText); function submit() { onSubmit(text); setText(""); } return ( <ComposerContext value={{ state: { text }, actions: { setText, submit } }}> {children} </ComposerContext> ); } function ComposerFrame({ children }: { children: React.ReactNode }) { const { actions } = useComposer(); return ( <form onSubmit={(event) => { event.preventDefault(); actions.submit(); }}> {children} </form> ); } function ComposerInput({ placeholder = "Message" }: { placeholder?: string }) { const { state, actions } = useComposer(); return ( <textarea value={state.text} onChange={(event) => actions.setText(event.target.value)} placeholder={placeholder} /> ); } function ComposerFormatting() { return ( <div className="toolbar"> <button type="button">B</button> <button type="button">I</button> </div> ); } function ComposerAttachments() { return <button type="button">Attach</button>; } function ComposerEmojis() { return <button type="button">😀</button>; } function ComposerSubmit({ children = "Send" }: { children?: React.ReactNode }) { return <button type="submit">{children}</button>; } function ComposerRoot({ children, ...props }: ComposerProps) { return ( <ComposerProvider {...props}> <ComposerFrame> {children === undefined ? <><ComposerInput /><ComposerSubmit /></> : children} </ComposerFrame> </ComposerProvider> ); } /** * Compose controls in their display order; footer content is ordinary children: * * <Composer initialText="Draft" onSubmit={send}> * <Composer.Formatting /> * <Composer.Input placeholder="Reply in thread" /> * <Composer.Attachments /> * <Composer.Emojis /> * <Composer.Submit /> * <CustomFooter /> * </Composer> * * Message: use the default input placeholder and submit label. * Thread: use "Reply in thread" and "Send". * Forward: use "Add a note" and "Forward". * Edit: use "Edit message" and "Save", and omit Attachments. * When migrating overlapping modes, edit takes precedence over forward, then thread. * Include Formatting, Attachments, and Emojis only where needed. * Provider and Frame can also be composed separately to share state with siblings. */ export const Composer = Object.assign(ComposerRoot, { Provider: ComposerProvider, Frame: ComposerFrame, Input: ComposerInput, Formatting: ComposerFormatting, Attachments: ComposerAttachments, Emojis: [... excerpt: first 3200 of 3247 characters]

Pro ansehen