supabase-postgres-best-practices (supabase/agent-skills)
Leitet Postgres-Schemadesign, Migrationen, RLS, Indizes und Abfrageperformance mit Supabase-Best-Practices an.
Supabase Postgres best practices: Kein Gewinn gegenüber einfachem Codex bei Schema-, Review- und Index-Aufgaben (4.48 vs. 4.54)
Codex CLI · gpt-6-astra
24.4 / 30
Lift gegenüber ohne Skill: -0.06 · Situativ · 18 Läufe
Situativ: der Lift -0.06 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
BestandenGetestet 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
- 1.9
- Ausgabequalität
- 4.5
- Token- und Zeitkosten
- 4.0
- Installation und Portabilität
- 4.0
- Sicherheit
- 5.0
Sicherheitsprüfung
SicherStatischer Scan: 0 CRITICAL / 4 HIGH / 0 MEDIUM. Manuelle Prüfung: Sicher in einer Sandbox ohne Netzwerk auszuführen (Scanner-Befunde erklärt). Ein sauberer Scan beweist nicht, dass ein Skill sicher ist.
Installieren
npx skills@latest add supabase/agent-skills --skill supabase-postgres-best-practices
Fixierter Commit: c9be0e931b7930f7d02126d04774d904c381e7d7
Getestet: 2026-11-02
Was wir getestet haben
- Multi-Tenant-Schema mit RLS — schema.sql für einen Supabase-(Postgres-)Multi-Tenant-Projekttracker schreiben: Organisationen, Mitgliedschaften (ein Supabase-Auth-Benutzer gehört mit einer Rolle zu einer Organisation), Projekte, Aufgaben (Zuständiger, Status, Fälligkeitsdatum) und Kommentare zu Aufgaben. Ein Benutzer darf nur seine eigenen sehen und änd…
- Ein Schema, Queries und einen Worker reviewen — schema.sql, queries.sql und worker.py reviewen (eine Supabase/Postgres-Support-Ticket-App). Die Probleme auflisten, schwerwiegendstes zuerst, jeweils mit dem Fix. Keine Dateien ändern. Die Liste in der letzten Antwort ausgeben.
- Indizes für drei langsame Abfragen — Die drei Abfragen in slow_queries.md sind auf der Tabelle in schema.sql (120 Mio. Zeilen) langsam. migration.sql mit den Indexänderungen schreiben (und nichts anderes) sowie notes.md (höchstens 120 Wörter), die sagen, welcher Index welche Abfrage bedient und welche Einschränkungen gelten. (Keine Datenbank…
Vorteile
- Der Skill wurde erkannt, ohne genannt zu werden: Skill-Datei in 6/6 Treatment-Läufen gelesen.
Nachteile
- Kein messbarer Lift gegenüber ohne Skill (-0.06, im Rauschen).
- Ein Ein-Satz-Prompt erzielte 4.75 gegenüber 4.48 mit dem Skill (-0.27).
- 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). Drei Aufgaben: ein Multi-Tenant-Supabase-Schema mit RLS schreiben (Prüfungen: RLS auf jeder Tabelle, auth.uid() in einem select eingebettet, jeder Foreign Key indiziert, timestamptz, Identity- oder UUID-Schlüssel, Constraints, Kleinbuchstaben-Namen), ein fehlerhaftes Schema/Queries/Worker auf 11 eingebaute Probleme prüfen und Index-Migrationen plus Notizen für drei langsame Abfragen auf einer Tabelle mit 120 Mio. Zeilen schreiben (zusammengesetzter Index, partieller Index, CONCURRENTLY, höchstens 4 Indizes).
Drei-Arm-Vergleich
| Variante | Durchschnittsnote (0-5) | Tokens pro Lauf |
|---|---|---|
| Ohne Skill | 4.54 | 77k |
| Ein-Satz-Prompt | 4.75 | 80k |
| Mit Skill | 4.48 | 93k |
Gemessen mit Codex CLI über 18 Läufe, bewertet durch regelbasierte Prüfungen ohne LLM-Richter. Gesamt 24.4 / 30, Urteil Situativ.
Urteil: Situativ (24.4 / 30). Quelle: supabase/agent-skills, skills/supabase-postgres-best-practices, gepinnt auf Commit c9be0e9. Installation: npx skills@latest add supabase/agent-skills --skill supabase-postgres-best-practices. Lizenz: MIT (Repo-LICENSE).
Was es ist
Der Skill supabase-postgres-best-practices aus supabase/agent-skills: Postgres-Performance- und Schema-Hinweise für Supabase-Projekte in etwa 35 Referenzdateien (Query-Performance und Indizes, Verbindungsverwaltung, Sicherheit und RLS, Schema-Design, Nebenläufigkeit und Locking, Datenzugriffsmuster, Monitoring), mit einer 440 Wörter langen SKILL.md, die sie indexiert. Nur Markdown, keine Skripte.
So haben wir getestet
Codex CLI 0.166 (gpt-6-astra, low reasoning) auf einem Mac-Testgerät, pro Lauf ein frisches temporäres Projekt und temporäre HOME/TMPDIR/Caches, Skill installiert (Mit-Skill-Gruppe) oder 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 (außer der unten genannten Formulierung).
Drei Aufgaben: ein Multi-Tenant-Supabase-Schema mit RLS schreiben (Prüfungen: RLS auf jeder Tabelle, auth.uid() in ein select verpackt, jeder Fremdschlüssel indiziert, timestamptz, Identity- oder UUID-Schlüssel, Constraints, kleingeschriebene Namen), ein fehlerhaftes Schema/Queries/Worker auf 11 eingebaute Probleme prüfen und Index-Migrationen plus Notizen für drei langsame Queries auf einer Tabelle mit 120M Zeilen schreiben (zusammengesetzter Index, partieller Index, CONCURRENTLY, höchstens 4 Indizes).
- Multi-Tenant-Schema mit RLS — Schreibe schema.sql für einen Multi-Tenant-Projekttracker auf Supabase (Postgres): Organizations, Memberships (ein Supabase-Auth-Nutzer gehört mit einer Rolle zu einer Organization), Projects, Tasks (Assignee, Status, Fälligkeitsdatum) und Comments zu Tasks. Ein Nutzer darf nur sehen und änder…
- Schema, Queries und einen Worker prüfen — Prüfe schema.sql, queries.sql und worker.py (eine Supabase/Postgres-Support-Ticket-App). Liste die Probleme auf, das schwerwiegendste zuerst, jeweils mit der Lösung. Ändere keine Dateien. Schreibe die Liste in deine letzte Antwort.
- Indizes für drei langsame Queries — Die drei Queries in slow_queries.md sind auf der Tabelle in schema.sql langsam (120M Zeilen). Schreibe migration.sql mit den Indexänderungen, die du vornehmen würdest (und nichts anderes), sowie notes.md (höchstens 120 Wörter), die sagt, welcher Index welcher Query dient und welche Einschränkung gilt. (Keine Datenbank…
Die Bewertung erfolgt programmatisch (versteckte Tests / Trefferquote bei eingebauten Problemen / Constraint-Prüfungen / Rendern+OCR, wo relevant), 0–5 pro Lauf. Kein LLM-Richter hat eine Punktzahl entschieden.
Ergebnisse
Der Ein-Satz-Prompt für die dritte Gruppe: "Wende Postgres-Best-Practices an: indiziere jeden Fremdschlüssel und jede in WHERE/ORDER BY verwendete Spalte (zusammengesetzte Indizes mit Gleichheitsspalten zuerst, partielle Indizes für seltene Status, CREATE INDEX CONCURRENTLY auf großen Tabellen), aktiviere RLS auf jeder exponierten Tabelle und verpacke auth.uid() in (select auth.uid()), verwende timestamptz, Identity- oder UUID-Schlüssel und kleingeschriebene snake_case-Namen, paginiere per Keyset statt Offset und halte Transaktionen kurz (keine externen Aufrufe darin)."
| Aufgabe | Punktzahl Kontrolle | Ein-Satz | Mit Skill | Token Kontrolle | Token Ein-Satz | Token mit Skill | Skill gelesen |
|---|---|---|---|---|---|---|---|
| t1-schema | 4.52 | 4.79 | 4.16 | 104k | 121k | 124k | 2/2 |
| t2-review | 4.09 | 4.46 | 4.28 | 64k | 56k | 70k | 2/2 |
| t3-indexes | 5.0 | 5.0 | 5.0 | 60k | 61k | 84k | 2/2 |
Durchschnitt: 4.54 ohne vs. 4.48 mit Skill (Delta -0.06). Token pro Lauf: 77k vs. 93k (1.21x); Zeit 78s vs. 73s. Ein-Satz-Gruppe: 4.75 (Zuwachs des Skills gegenüber dem Ein-Satz-Prompt: -0.27; Zuwachs des Ein-Satz-Prompts gegenüber ohne Skill: +0.21); Token des Ein-Satz-Prompts 80k pro Lauf, der Skill kostet also 1.16x so viel wie der Ein-Satz-Prompt.
Was dabei herauskam
- Kein Unterschied: Durchschnitt 4.54 Kontrolle, 4.75 Ein-Satz, 4.48 Skill. Der Skill liegt bei 93k Token pro Lauf gegenüber 77k (1.2x) um -0.06 unter der Kontrolle.
- Die Index-Aufgabe wird von jeder Gruppe in jedem Lauf gelöst (alle sechs Index-Prüfungen bestehen 6/6 in allen Gruppen, einschließlich CONCURRENTLY und Einhaltung von 4 Indizes): Reines Codex kennt diese Grundlagen bereits.
- Bei der Schema-Aufgabe indizierte jede Gruppe alle Fremdschlüssel, aktivierte RLS auf allen Tabellen und verwendete UUID-/Identity-Schlüssel. Das Verpacken von auth.uid() in (select auth.uid()) geschah in jeder Gruppe nur für einen Teil der Policies: 3 von 5–6 Vorkommen in Kontroll- und Skill-Läufen, 5 von 5 in einem Ein-Satz-Lauf. Die Ein-Satz-Gruppe war bei dieser Regel am besten (1.6 von 2 gegenüber 1.1 bei Kontrolle und Skill). Ein Skill-Lauf verwendete eine einfache timestamp-Spalte (3.86), die niedrigste Punktzahl aller Läufe.
- Bei der Review-Aufgabe fanden alle Gruppen 8–9 der 11 eingebauten Probleme (1.5–1.7 von 2 Prüfungen); der Skill fand nicht mehr.
- Der Test wurde für die Index-Aufgabe einmal wiederholt: Der erste Durchlauf gab ihr wegen eines Spezifikationsfehlers keine Eingabedateien (die Fixture-Liste war leer), sodass alle 6 Läufe meldeten, die Dateien fehlten. Wir haben die Spezifikation korrigiert und diese 6 Läufe erneut ausgeführt; die früheren zählen nicht.
Bewertung nach Dimensionen
| Dimension | Punktzahl | Begründung |
|---|---|---|
| 1_output_quality | 4.48 | Durchschnitt 4.48/5 mit Skill (programmatische Prüfungen, siehe Tabelle pro Aufgabe). |
| 2_lift_vs_no_skill | 1.94 | -0.06 Punkte gegenüber 4.54 ohne Skill (n=2 pro Aufgabe; unter etwa 1 Punkt ist Rauschen). |
| 3_trigger | 5.0 | Skill-Datei in 6/6 Mit-Skill-Läufen gelesen. |
| 4_instructions_portability | 4 | Reine Markdown-Regeldateien; folgt dem offenen Skills-Layout. |
| 5_efficiency | 4 | 1.21x Token (93k vs. 77k pro Lauf) und 0.93x Zeit (73s vs. 78s). |
| 6_safety_hygiene | 5 | Nur Markdown; die vier HIGH-Treffer des Scanners betreffen den
Tabellennamen
|
Grenzen dieses Tests
- Lehrbuchprobleme in kleinen Dateien; Supabase-spezifische Punkte über RLS hinaus (Connection Pooling, Realtime, Storage) wurden nicht getestet.
- Punkte werden per Regex abgeglichen, ein anders formulierter Fix zählt also als verfehlt.
- Die Regeln des Skills zu Locking, Monitoring und Datenzugriffsmustern wurden nicht ausgeführt.
- n = 2 pro Gruppe und Aufgabe: Unterschiede unter etwa 1 Punkt sind Rauschen.
- Regelbasierte Bewertung misst nur, was die Prüfungen sehen können; Geschmack oder ob ein Ergebnis das bestmögliche ist, lässt sich so nicht beurteilen.
Sicherheit
Siehe security.md. Scan: 0 CRITICAL / 4 HIGH / 0 MEDIUM. Urteil: sicher ausführbar (Sandbox ohne Netzwerk). Ein sauberer Scan beweist nicht, dass ein Skill sicher ist.
Fazit
Bei Schema-Design, Review- und Index-Aufgaben wendet reines Codex die Praktiken, die dieser Skill auflistet, bereits an, und der Skill verbesserte die Punktzahl nicht, während er etwa 20% mehr Token kostete. Als Referenz für seltenere Supabase-Themen, die diese Tests nicht berührten, kann er trotzdem nützlich sein.
Transkript
Laufprotokoll: supabase-postgres-best-practices (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-schema control-1: Punkte 4.57, Tokens 105331, Sek. 124.5, Prüfungen 6/7, nichts geöffnet t1-schema control-2: Punkte 4.46, Tokens 104624, Sek. 130.1, Prüfungen 6/7, nichts geöffnet t1-schema oneliner-1: Punkte 5.0, Tokens 111153, Sek. 140.4, Prüfungen 7/7, nichts geöffnet t1-schema oneliner-2: Punkte 4.57, Tokens 132693, Sek. 145.1, Prüfungen 6/7, nichts geöffnet t1-schema treatment-1: Punkte 3.86, Tokens 123861, Sek. 108.3, Prüfungen 5/7, geöffnet supabase-postgres-best-practices t1-schema treatment-2: Punkte 4.46, Tokens 124377, Sek. 129.6, Prüfungen 6/7, geöffnet supabase-postgres-best-practices t2-review control-1: Punkte 4.27, Tokens 64780, Sek. 65.4, Prüfungen 2/2, nichts geöffnet t2-review control-2: Punkte 3.91, Tokens 64695, Sek. 71.5, Prüfungen 2/2, nichts geöffnet t2-review oneliner-1: Punkte 3.91, Tokens 45381, Sek. 57.3, Prüfungen 2/2, nichts geöffnet
18 Läufe, 3 Artefakte
Beispielausgabe
SOTA · With the skill: schema.sql (t1-schema, run 1, Codex)
-- Fresh Supabase database: run once as postgres (trusted BYPASSRLS owner). -- Members manage tenant content; admins also manage settings and memberships. -- service_role bypasses RLS: keep its credentials exclusively on the backend. begin; create schema if not exists private; revoke all on schema private from public, anon; grant usage on schema private to authenticated; -- Keep private out of the Data API's exposed schemas. create table public.organizations ( id uuid primary key default gen_random_uuid(), name text not null check (length(btrim(name)) between 1 and 200), created_at timestamptz not null default now(), updated_at timestamptz not null default now() ); create table public.memberships ( organization_id uuid not null references public.organizations(id) on delete cascade, user_id uuid not null references auth.users(id) on delete cascade, role text not null default 'member' check (role in ('admin', 'member')), created_at timestamptz not null default now(), primary key (organization_id, user_id) ); -- Reverse lookup for the caller's tenants, RLS, and auth user deletion. create index memberships_user_idx on public.memberships (user_id, organization_id) include (role); create table public.projects ( id uuid primary key default gen_random_uuid(), organization_id uuid not null references public.organizations(id) on delete cascade, name text not null check (length(btrim(name)) between 1 and 200), description text not null default '', created_at timestamptz not null default now(), updated_at timestamptz not null default now(), unique (organization_id, id) ); create index projects_list_idx on public.projects (organization_id, created_at desc, id desc); create table public.tasks ( id uuid primary key default gen_random_uuid(), organization_id uuid not null references public.organizations(id) on delete cascade, project_id uuid not null, title text not null check (length(btrim(title)) between 1 and 500), description text not null default '', assignee_id uuid, status text not null default 'todo' check (status in ('todo', 'in_progress', 'done', 'cancelled')), due_date date, created_at timestamptz not null default now(), updated_at timestamptz not null default now(), unique (organization_id, id), foreign key (organization_id, project_id) references public.projects (organization_id, id) on delete cascade, -- Unassign tasks before deleting a membership/auth user. Deferred checking -- permits deleting an entire organization and all its children atomically. foreign key (organization_id, assignee_id) references public.memberships (organization_id, user_id) on delete no action deferrable initially deferred ); create index tasks_project_list_idx on public.tasks (organization_id, project_id, created_at desc, id desc); create index tasks_board_idx on public.tasks (organization_id, project_id, status, created_at desc, id desc); create index tasks_assignee_idx on public.tasks (organization_id, assignee_id, status, due_date, id) where assignee_id is not null; create index tasks_open_due_idx on public.tasks (organization_id, due_date, id) where status in ('todo', 'in_progress') [... excerpt: first 3200 of 11674 characters]