Communitygithub.com

exmergo/dex

Dex ist das agent-native Toolkit für Analytics Engineering. Richten Sie es auf Ihr Data Warehouse und Ihr dbt-Projekt aus. Es lernt die Datenlandschaft, schreibt Ihre Transformationen und sagt Ihnen genau, was zu reparieren ist, wenn das Schema driftet. Entwickelt für Analytics Engineers und Data Engineers, die mehr aus ihrem Coding-Agenten herausholen möchten.

Was ist dex?

Dex ist ein agent-natives Toolkit für Analytics Engineering, das als Skill für KI-Coding-Agenten wie Claude Code, Cursor oder Codex konzipiert ist. Es analysiert Data Warehouses (z. B. BigQuery, Snowflake, Databricks, Postgres, Redshift) oder lokale DuckDB-Datenbanken und dbt-Projekte, um Datenprofile, Beziehungen und Metriken zu verstehen. Der Skill bietet eine Reihe von schreibgeschützten `explore`-Subkommandos, darunter `connect test` zur Verbindungsprüfung, `explore inventory` für eine priorisierte Objektübersicht, `explore profile` für detaillierte Spaltenprofile mit PII-Erkennung, `explore relationships` für abgeleitete und deklarierte Joins, `explore map` zum Caching der analysierten Struktur, `explore diagram` zur Erstellung von Mermaid-ER-Diagrammen aus dem Cache, `explore query` für benutzerdefinierte SQL-Abfragen mit einer Firewall, `explore cluster` für k-Means-Clustering numerischer Spalten und `explore semantic query` für dbt Semantic Layer Abfragen. Entscheidend ist, dass Dex die Ausgaben in einem einzigen JSON-Envelope ausgibt, den der Agent interpretieren muss, um die nächsten Schritte zu planen. Es implementiert ein zweistufiges Kostenmodell für kostenpflichtige Connectors, bei dem vor der Ausführung eine Kostenschätzung eingeholt und eine explizite Budgetgenehmigung des Benutzers eingeholt werden muss. Der Skill ist darauf ausgelegt, dem Agenten zu helfen, die Datenlandschaft zu verstehen, Schema-Drift zu erkennen und qualitativ hochwertige Datenmodellierungsentscheidungen zu treffen.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add exmergo/dex

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Erkunden

Machen Sie ein Warehouse oder eine lokale DuckDB-Datenbank so verständlich, wie es ein Analytics Engineer tun würde: bewerten Sie, was wichtig ist, bohren Sie selektiv nach und speichern Sie einen Entwurf der Landkarte. Dies ist der Flaggschiff-Skill, vollständig schreibgeschützt. Es absorbiert Profilerstellung und Beziehungsinferenz als Fähigkeiten; sie sind keine separaten Skills.

Wie man es nutzt

Führen Sie die Engine über den Wrapper aus. Er gibt ein einziges bereinigtes JSON-Envelope aus und sonst nichts; lesen Sie das Envelope und entscheiden Sie den nächsten Schritt.

uv run "${CLAUDE_SKILL_DIR}/scripts/run.py" <Befehl> [Flags]

Unterbefehle, in der üblichen Reihenfolge:

  1. connect test --path <datei.duckdb> bestätigt eine schreibgeschützte Verbindung und meldet die Fähigkeiten.
  2. explore inventory --rank gibt eine bewertete Objektzusammenfassung zurück (Anzahl und Größen, niemals Zeilen).
  3. explore profile <objekte> (durch Leerzeichen oder Kommas getrennt) gibt Spaltenprofile zurück, PII-Flags, aufgezeichnet als (Spalte, Kategorie, Konfidenz) und niemals Beispielwerte, plus Kandidatenschlüssel, die wahrscheinliche Körnung und Datenqualitätswarnungen (z. B. eine nicht-eindeutige ID, die bei Joins aufbläht). Ein generisches *_name-Flag wird durch Wertform-Hinweise aus demselben Scan in beide Richtungen verfeinert: personenförmige Werte bestätigen es, ein geschlossenes Referenzvokabular oder lange Labels bewerten es unter die Blockierungsschwelle der Firewall, und fehlende Hinweise ändern nichts (das Flag selbst wird niemals entfernt). Eindeutige Zählungen sind für die Skalierung approximativ, aber jede Spalte, die innerhalb des Approximationsrauschens eindeutig erscheint, wird auf eine exakte COUNT(DISTINCT) hochgestuft (distinct_count_exact: true), sodass Eindeutigkeits- und Körnungsurteile auf Beweisen beruhen; ein ~-Präfix in einer Warnung markiert eine Zählung, die noch approximativ ist. Ein angefordertes Objekt, dessen gecachtes Profil noch frisch ist (gleicher Connector, unverändertes Schema, innerhalb von profile_freshness_hours, Standard 24), wird aus dem Cache bedient (cache_hit_count) anstatt erneut gescannt zu werden. Das Profilieren einer Tabelle, die map gerade geschrieben hat, kostet also nichts; übergeben Sie --refresh, um einen erneuten Scan zu erzwingen, wenn sich die Quelle auf eine Weise geändert hat, die der kostenlose Metadaten-Check nicht sehen kann.
  4. explore relationships gibt abgeleitete und deklarierte Joins mit Konfidenzen zurück, plus Notizen, die erklären, was die Inferenz untersucht hat (sodass eine leere Liste aussagekräftig ist). Fügen Sie --verify hinzu, um jeden abgeleiteten Join mit einer aggregierten Überlappungssonde (Anteil an verwaisten Datensätzen, angepasste Konfidenz) zu messen.
  5. explore map schreibt oder aktualisiert den .dex/-Cache und gibt eine Zusammenfassung aus (--verify funktioniert auch hier). Bei mehr als 50 Objekten profiliert es nur die obersten 25 nach Rang und gibt dies in notes an (mit skipped_count); übergeben Sie --full, um alles zu profilieren. Bei einer Neukartierung behalten übersprungene Objekte dieses Laufs ihre vorherigen Profile (carried_forward_count), jedes mit seinem eigenen profiled_at-Stempel, sodass die Veralterung sichtbar ist, anstatt dass Spaltendetails stillschweigend verschwinden. Ein ausgewähltes Objekt, dessen gecachtes Profil noch frisch ist (gleicher Connector, unverändertes Schema, profiliert innerhalb von profile_freshness_hours, Standard 24), wird ohne erneuten Scan wiederverwendet (cache_hit_count), sodass Wiederholungsläufe nichts kosten; übergeben Sie --refresh, um eine vollständige Neuprofilierung zu erzwingen, wenn sich die Quelle auf eine Weise geändert hat, die der kostenlose Metadaten-Check nicht sehen kann (z. B. Zeilen geändert, aber das Schema nicht). explore relationships und das eigenständige explore profile verwenden frische Profile auf dieselbe Weise.
  6. explore diagram [--full] rendert die gecachte Karte als Mermaid-ER-Diagramm in data.mermaid. Kostenlos und verbindungslos (es liest den Cache, niemals das Warehouse), daher ist es sicher, es während der Bildgestaltung erneut auszuführen. Geben Sie die Zeichenfolge wörtlich in einem fenced ```mermaid-Block wieder, damit der Mensch sie sehen kann, und schreiben Sie sie in eine .mmd- oder eine Markdown-Datei, wenn er eine auf der Festplatte haben möchte: die Engine schreibt absichtlich keine Datei. Zeichnen Sie das Diagramm niemals von Hand neu oder „ordnen Sie es auf“. Die Glyphen sind Behauptungen, die die Engine aus Beweisen abgeleitet hat, und eine plausibel aussehende Kardinalität, die Sie geliefert haben, ist genau die Überbehauptung, die dieser Befehl verhindern soll: deklarierte Joins sind durchgezogen, abgeleitete gepunktet, und eine unverifizierte Inferenz sagt niemals „genau eins“. Lesen Sie notes, bevor Sie es präsentieren, da es alle Objekte oder Spalten angibt, die ausgelassen wurden; --full erweitert die Auswahl vom Standard (profilierte, gejoinete Objekte und deren Körnung, Schlüssel, Join- und PII-Spalten) auf alles, was in Frage kommt.
  7. explore query "<SELECT ...>" ["<SELECT ...>" ...] beantwortet Ad-hoc-Fragen, die die festen Befehle nicht abdecken: Sie schreiben das SQL, die Abfrage-Firewall der Engine lehnt es ab oder begrenzt es. Übergeben Sie eine Anweisung pro Argument oder --sql-file <pfad> für eine längere Liste, und stellen Sie eine ganze Kette von Fragen in einem Aufruf, anstatt einen Aufruf pro Frage; jede Anweisung wird einzeln beurteilt und beantwortet, sodass eine Ablehnung bei einer nicht die anderen kostet, und data.results enthält einen Eintrag pro Anweisung. Eine Tabelle, die Sie nicht profiliert haben, einschließlich eines Modells, das Sie gerade erstellt haben, wird für Sie profiliert, und die Anweisung wird dann ausgeführt, sodass das Sondieren von Neuem ein Aufruf ist und nicht drei; das Envelope sagt, was es profiliert hat, und bei einem gemessenen Connector wird dieses Profil in dieselbe Bestätigung wie die Anweisungen eingepreist. Ergebnisse werden zeilenweise und begrenzt zurückgegeben; eine Ablehnung nennt die beanstandete Spalte und die Behebung, sodass eine Neuschreibung ausreicht. Lesen Sie ${CLAUDE_SKILL_DIR}/references/probe-playbook.md, bevor Sie eine Sonde schreiben: es bildet häufige Fragen auf effektive Sondenformen ab.
  8. explore cluster <objekt> [--features a,b,c] [-k N] führt k-Means über eine begrenzte Stichprobe der numerischen Spalten des Objekts aus und gibt die Segmentstruktur zurück: Größen und Anteile pro Cluster, Zentroide (jede Koordinate ist der Mittelwert dieses Merkmals im Cluster, ein Aggregat), den Silhouetten-Score und, wenn -k weggelassen wird, das gewählte k plus den Silhouetten-Durchlauf, aus dem es wählte. Erfordert den .dex/-Cache (führen Sie zuerst map/profile aus), damit Merkmale automatisch aus profilierten numerischen, Nicht-PII-, Nicht-Schlüssel-Spalten ausgewählt werden können; übergeben Sie --features, um sie selbst zu wählen (das Benennen einer PII-Spalte oder eines Schlüssels entscheidet sich bewusst dafür, und nur ihr Mittelwert wird jemals gemeldet). Ein Schlüssel ist niemals ein Merkmal: sein Mittelwert ist bedeutungslos, und eine Fakten-Tabelle besteht größtenteils aus Schlüsseln plus einer Handvoll Metriken, sodass das Clustering darauf nur Ersatzbereiche partitioniert. Schlüssel sind die eindeutigen Spalten, die Spalten, die ausjoinieren (aus den Joins, die map abgeleitet hat), und die Spalten, die wie solche benannt sind; bevorzugen Sie map gegenüber einem bloßen profile hier, denn ohne abgeleitete Joins wird ein Fremdschlüssel nur abgefangen, wenn sein Name ihn verrät. Die Notizen nennen jede ausgeschlossene Spalte, also überprüfen Sie sie, bevor Sie einem Ergebnis vertrauen. Zwei Dinge, die die Silhouette allein Ihnen nicht sagen wird, die aber die Notizen sagen werden. Ein Cluster, der weniger als 1 % der Stichprobe enthält, ist eine Ausreißertasche, kein Segment, und er treibt den Score genau deshalb nach oben, weil er so weit draußen sitzt: melden Sie das als Ausreißererkennung oder führen Sie es mit -k erneut aus, um die Masse aufzuteilen. Und bei Connectors, die keine Stichprobe seeden können, ändert sich die Ziehung pro Lauf, sodass zwei Läufe sich bei k unterscheiden können; das sample_repeatable des Envelopes sagt, in welchem Fall Sie sich befinden, und das Vergleichen von Läufen über verschiedene Ziehungen hinweg ist bedeutungslos. Nur Aggregate überqueren die Grenze: die Stichprobenzeilen werden prozessintern geclustert und gelangen nie in den Kontext. Bei einem gemessenen Connector erfordert es denselben Kosten-Handshake wie die Scan-Befehle unten (nur die Merkmalsspalten werden gescannt, und eine dialektbewusste Stichprobenklausel liest einen Bruchteil), also zeigen Sie die Schätzung an und holen Sie zuerst ein Budget ein. Benötigt die [cluster]-Erweiterung (scikit-learn); der Wrapper installiert sie automatisch für diesen Unterbefehl.
  9. explore semantic list und explore semantic query erreichen die dbt Semantic Layer (Metriken, Dimensionen, Entitäten). list ist die Entdeckung: welche Metriken existieren und nach welchen Dimensionen jede gruppiert werden kann. query nimmt eine positionale Metrik nach dem expliziten Modus (mit --metric aus Kompatibilitätsgründen beibehalten) und ein --group-by <entity__dim> (plus optional --where, --grain und --limit) und gibt die Werte einer Metrik als begrenztes, spaltenweises Ergebnis zurück. Namens-Flags nehmen eine kommagetrennte Liste oder ein wiederholtes Flag (--group-by a,b ist --group-by a --group-by b); --where wird niemals geteilt. Zwei Backends beantworten diese, ausgewählt durch .dex/config.yml semantic.backend und überschreibbar mit --local / --api. --local rendert das SQL mit MetricFlow und führt es durch den eigenen Connector und Kosten-Handshake von dex aus, sodass die Kosten vor der Ausgabe aufgedeckt werden (benötigt ein dbt-Projekt und für query die [semantic]-Erweiterung; list ist eine manifeste Leseansicht, die keines benötigt). --api sendet die Abfrage an eine gehostete dbt Cloud-Bereitstellung (benötigt nur einen Host, eine Umgebungs-ID und einen DBT_SL_TOKEN, plus die [semantic-api]-Erweiterung, kein lokales Projekt). Das gehostete Backend ist der eine Ort, an dem die Kostenwache nicht greift: dbt Cloud führt serverseitig aus, sodass das Ergebnis eine explizite Warnung enthält, dass die Ausgaben dort geregelt werden, nicht von dex, und es wird kein --confirm verlangt. In beiden Fällen wird eine PII-förmige gruppierte oder gefilterte Dimension (z. B. user__email) abgelehnt, bevor die Abfrage ausgeführt wird. Dies fragt die Schicht ab; das Erstellen ist die Aufgabe von transform.

Verhaltensregeln für query: bevorzugen Sie die festen Befehle, wenn sie die Frage beantworten; eine Sonde beantwortet eine Frage; bündeln Sie verwandte Maße in eine einzige Abfrage, anstatt viele auszugeben; Aggregate über PII-gekennzeichnete Spalten müssen messend (COUNT, APPROX_COUNT_DISTINCT, AVG(LENGTH(...))), niemals wertetragend (MIN, ANY_VALUE, STRING_AGG) sein. Die FROM-Klausel kann JSON- und Array-Spalten im natives Idiom des Connectors entpacken, was die richtige Art ist, schemalose Daten zu erkunden (z. B. „welche Schlüssel erscheinen in jeder Zeile dieser JSON-Spalte“): BigQuery t, UNNEST(JSON_KEYS(doc)) AS k, Snowflake t, LATERAL FLATTEN(input => doc) f, Databricks t LATERAL VIEW EXPLODE(json_object_keys(doc)) x AS k, Postgres t, jsonb_object_keys(doc) AS k, Redshift t, UNPIVOT t.doc AS v AT k, DuckDB t, UNNEST(json_keys(doc)) AS u(k). Der entpackte Wert muss aus einer Spalte einer Tabelle in der Abfrage stammen (direkt oder durch eine JSON-/Array-Funktion); das Entpacken einer Unterabfrage, einer anderen Tabelle, eines Literals oder eines Generators wird abgelehnt, und die Ausgaben des Entpackens erben die PII-Flags der Quellspalte. Eine Spalte, deren Flag unter die 0,5er-Blockierungsschwelle herabgestuft wurde, projiziert normal, mit einer Envelope-Warnung, die sie benennt; behandeln Sie die Warnung als Information für den Benutzer, nicht als zu behebenden Fehler. Wenn der Benutzer sagt, eine abgelehnte Spalte sei keine persönlichen Daten, empfehlen Sie einen pii_overrides-Eintrag in .dex/config.yml (vollqualifizierte Spalte, optionaler Grund): er entsperrt das Abfragen sofort, überlebt Neuprofilierungen und ist in Git überprüfbar. Bearbeiten Sie niemals .dex/cache.json von Hand, um ein Flag zu löschen. Verwenden Sie niemals rohes Python oder ein datenbank-CLI, um SQL auszuführen; der Firewall-Pfad ist der einzig zulässige.

Cloud- und Datenbank-Ziele (BigQuery, Snowflake, Databricks, Postgres, Redshift)

Ein entferntes Warehouse oder eine entfernte Datenbank ersetzt --path durch die Connector-Konfiguration. Beginnen Sie mit connect test --connector <name> (oder setzen Sie connector: plus den passenden Block in .dex/config.yml: bigquery: mit project und einer datasets-Whitelist, snowflake: mit dem festgelegten warehouse und einer databases-Whitelist, databricks: mit dem festgelegten SQL warehouse und einer catalogs-Whitelist, postgres: mit einer schemas-Whitelist, redshift: mit dem Serverless workgroup und einer schemas-Whitelist). Anmeldeinformationen werden erkannt, niemals erfragt: wenn das Envelope fehlende oder abgelaufene Anmeldeinformationen meldet, leiten Sie die von ihm genannte Behebung weiter (für BigQuery gcloud auth application-default login; für Snowflake einen connections.toml-Eintrag oder SNOWFLAKE_*-Umgebungsvariablen; für Databricks databricks auth login oder DATABRICKS_*-Umgebungsvariablen; für Postgres DATABASE_URL, PG*-Umgebungsvariablen oder einen pg_service.conf-Eintrag; für Redshift die AWS-Anmeldeinformationskette (aws configure, AWS_*-Umgebungsvariablen) oder REDSHIFT_*-Umgebungsvariablen) und bitten Sie den Benutzer niemals, einen Schlüssel, ein Token oder ein Passwort einzufügen.

Bei einem gemessenen Connector führen Scan-Befehle (profile, map, relationships, query) einen zweistufigen Handshake durch. Der erste Aufruf gibt needs_confirmation mit einer Schätzung in cost.estimate zurück (und einer pro-Tabelle-Aufschlüsselung, wo relevant): einen genauen Dry-Run-Byte-Wert auf BigQuery, einen heuristischen Wert mit der Bezeichnung estimate_quality: "heuristic" in Warehouse-Sekunden auf Snowflake (Credits daneben), einen Basiswert mit der Bezeichnung estimate_quality: "low" in Warehouse-Sekunden auf Databricks (DBUs daneben; er schärft sich innerhalb des bestätigten Budgets), einen heuristischen Wert in Compute-Sekunden auf Redshift (RPU-Stunden daneben; Serverless-Schätzungen enthalten das 60-Sekunden-Aufwärmminimum einmal), und Datenbank-Sekunden auf Postgres (keine Dollars; die geschützte Größe ist die Last auf der operativen Datenbank). Zeigen Sie die Schätzung dem Benutzer in menschlichen Einheiten an, holen Sie ein explizites Budget von ihnen ein, und geben Sie denselben Befehl mit --confirm und --budget <größe> in der Paradigmen-Einheit erneut aus. Erfinden Sie niemals ein Budget, dem der Benutzer nicht zugestimmt hat, und versuchen Sie niemals mit einem erhöhten Budget bei einer Überschreitungsablehnung erneut, ohne zu fragen. Metadaten sind kostenlos (connect test, inventory werden sofort ausgeführt), und OK-Envelopes melden die tatsächlichen Ausgaben unter data.spend.

Bei BigQuery enthält eine Profilierungsschätzung eine 10-MB-Reserve pro Tabelle für jede Hochstufungsabfrage, die ein Profil nach seinem Aggregat-Scan noch ausgeben kann. Bei einem Warehouse mit vielen kleinen Tabellen kann der Großteil der Zahl also Reserve für Arbeit sein, die nie stattfindet. Sowohl der Handshake als auch die Überschreitungsablehnung melden diese Aufteilung (reserved_bytes und reserved_queries, sowie im Prosa-Text). Geben Sie dies weiter, wenn Sie die Schätzung präsentieren: ob eine Zahl Scan oder Reserve ist, ändert, ob das Erhöhen des Budgets Arbeit oder Spielraum kauft.

Wenn eine Schätzung größer ist, als die Arbeit verdient, grenzen Sie den Umfang ein, anstatt das Budget zu erhöhen. --scope (wiederholbar) begrenzt einen Befehl auf einen Teil der konfigurierten Quellen-Whitelist, im eigenen Vokabular des Connectors: ein Dataset auf BigQuery, ein schema oder database.schema auf Snowflake, ein catalog.schema auf Databricks, ein Schema auf Postgres oder Redshift. Es ist kostenlos aufzulösen, es kann nur na…

…[für die Übersetzung gekürzt]

Verwandte Skills