Communitygithub.com

exmergo/dex

Dexは、エージェントネイティブな分析エンジニアリングツールキットです。ウェアハウスとdbtプロジェクトを指定するだけで、スキーマを学習し、変換を自動生成し、スキーマがずれた際に修正すべき箇所を正確に指示します。コーディングエージェントを最大限に活用したい分析エンジニアやデータエンジニアのために構築されました。

dex とは?

Dexは、AIエージェント向けに設計された分析エンジニアリングツールキットであり、データウェアハウスやDuckDBデータベースを探索し、スキーマをマッピングし、dbtプロジェクトを管理するための完全に読み取り専用のスキルです。このスキルは、BigQuery、Snowflake、Databricks、Postgres、Redshift、DuckDBをサポートしており、`claude_code` や `cursor` などのエージェント環境で動作します。主な機能には、テーブルとカラムのプロファイリング、外部キー関係の推論、ER図の生成、カラム値のクラスタリング、dbtセマンティックレイヤーへのクエリなどが含まれます。これらの機能はすべて読み取り専用であり、データを変更することはありません。Dexは、クエリファイアウォールによる安全なSQL実行、課金対象コネクタのコスト見積もりと予算確認、機密データ(PII)の自動検出とマスキングを提供します。キャッシュ機能により、再実行時のコストを最小限に抑え、`uv run` コマンドを使用して制御される単一のサブコマンド駆動のインターフェースを提供します。

対応✓Claude Code~Codex CLI~Cursor
npx skills add exmergo/dex

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

探索

アナリティクスエンジニアと同じように、ウェアハウスまたはローカルのDuckDBデータベースを理解します。つまり、重要なものをランク付けし、選択的にドリルダウンし、ドラフトマップを永続化します。これは代表的な、完全に読み取り専用のスキルです。プロファイリングとリレーションシップ推論を機能として取り込みます。これらは別のスキルではありません。

操作方法

ラッパーを通じてエンジンを実行します。ラッパーは1つのサニタイズされたJSONエンベロープだけを出力します。そのエンベロープを読み取り、次のステップを決定します。

uv run "${CLAUDE_SKILL_DIR}/scripts/run.py" <サブコマンド> [フラグ]

サブコマンド(一般的な順序):

  1. connect test --path <file.duckdb> 読み取り専用接続を確認し、機能を報告します。
  2. explore inventory --rank ランク付けされたオブジェクトの要約(行数とサイズ、行そのものは含みません)を返します。
  3. explore profile <objects> (スペースまたはカンマ区切り)カラムプロファイル、PIIフラグ(カラム、カテゴリ、信頼度として記録され、値の例は含みません)、候補キー、推定される粒度、およびデータ品質の警告(例:結合時にファンアウトする非一意なID)を返します。一般的な *_name フラグの信頼度は、同じスキャンからの値形状の証拠によって精緻化されます。両方向について:人物形状の値はそれを裏付け、閉じた参照語彙や長いラベルはファイアウォールのブロックしきい値を下回るように評価を下げ、証拠がない場合は何も変更しません(フラグ自体は決して削除されません)。個別カウントはスケールのために近似値ですが、近似ノイズ内で一意に見えるカラムは正確なCOUNT(DISTINCT)にエスカレーションされます(distinct_count_exact: true)。そのため、一意性と粒度の判定は証明に基づきます。警告内の ~ プレフィックスは、まだ近似値であるカウントを示します。要求されたオブジェクトのキャッシュされたプロファイルがまだ新鮮な場合(同じコネクタ、スキーマ変更なし、profile_freshness_hours(デフォルト24時間)以内)、再スキャンではなくキャッシュから提供されます(cache_hit_count)。そのため、map が書き込んだばかりのテーブルをプロファイリングするコストはかかりません。無料のメタデータチェックでは確認できない方法でソースが変更された場合は、--refresh を渡して強制的に再スキャンします。
  4. explore relationships 推論された結合と宣言された結合を信頼度とともに返し、さらに推論が何を調査したかを説明するメモを返します(そのため、空のリストにも意味があります)。--verify を追加すると、各推論された結合を集約オーバーラッププローブ(孤立フラクション、調整された信頼度)で測定します。
  5. explore map は .dex/ キャッシュに書き込むか更新し、要約を出力します(--verify もここで機能します)。50オブジェクトを超える場合、ランク上位25のみをプロファイリングし、その旨を notes に記述します(skipped_count 付き)。--full を渡すとすべてをプロファイリングします。再マップ時、今回スキップされたオブジェクトは以前のプロファイルを保持します(carried_forward_count)。各オブジェクトには独自の profiled_at がスタンプされ、列の詳細が静かに消えるのではなく、古さが可視化されます。選択されたオブジェクトのキャッシュされたプロファイルがまだ新鮮な場合(同じコネクタ、スキーマ変更なし、profile_freshness_hours(デフォルト24時間)以内にプロファイリング済み)、再スキャンなしで再利用されます(cache_hit_count)。そのため、再実行のコストはかかりません。無料のメタデータチェックでは確認できない方法でソースが変更された場合(例:行は変更されたがスキーマは変更されていない)、--refresh を渡して強制的に完全な再プロファイリングを実行します。explore relationships とスタンドアロンの explore profile も同じ方法で新鮮なプロファイルを再利用します。
  6. explore diagram [--full] キャッシュされたマップを data.mermaid 内のMermaid ER図としてレンダリングします。無料で接続不要(キャッシュを読み取るだけで、ウェアハウスにはアクセスしません)のため、画像を調整する際に安全に再実行できます。文字列をフェンス付きの ```mermaid ブロック内にそのまま再現して人間が見られるようにし、ユーザーがディスク上に保存したい場合は .mmd ファイルまたはマークダウンファイルに書き込みます。エンジンは意図的にファイルを書き込みません。 図を手動で再描画したり「整理」したりしないでください。グリフはエンジンが証拠から導き出した主張であり、あなたが提供したもっともらしいカーディナリティは、まさにこのコマンドが防止しようとしている過剰主張です。宣言された結合は実線、推論された結合は点線であり、未検証の推論が「正確に1つ」と述べることはありません。図を提示する前に notes を読んでください。省略されたオブジェクトや列が記載されています。--full はデフォルト(プロファイリングされ、結合されたオブジェクトとその粒度、キー、結合、PIIカラム)から、資格のあるすべてのものに拡大します。
  7. explore query "<SELECT ...>" ["<SELECT ...>" ...] 固定コマンドではカバーされないアドホックな質問に答えます。あなたがSQLを書き、エンジンのクエリファイアウォールがそれを拒否または制限します。ステートメントごとに1つの引数を渡すか、より長いリストの場合は --sql-file <path> を渡し、1回の呼び出しで質問の連鎖全体を(1回の呼び出しで1つずつではなく)行います。各ステートメントは個別に判断および回答されるため、1つのステートメントの拒否が他のステートメントに影響することはなく、data.results はステートメントごとに1つのエントリを保持します。プロファイリングしていないテーブル(構築したばかりのモデルを含む)は、プロファイリングされてからステートメントが実行されるため、新しいものをプローブするのは3回の呼び出しではなく1回で済みます。エンベロープは何をプロファイリングしたかを示し、従量課金コネクタではそのプロファイルはステートメントと同じ確認に価格設定されます。結果は行優先で返され、上限があります。拒否があった場合は、問題のカラムと修正方法が示されるため、1回の書き直しで十分です。プローブを書く前に ${CLAUDE_SKILL_DIR}/references/probe-playbook.md を読んでください。一般的な質問を効果的なプローブ形状にマッピングします。
  8. explore cluster <object> [--features a,b,c] [-k N] オブジェクトの数値カラムの制限付きサンプルに対してk-meansを実行し、セグメント構造(クラスターごとのサイズと割合、重心(各座標はその特徴のクラスター平均、集計値)、シルエットスコア)を返します。-k を省略した場合、選択したkと、それが選択されたシルエットスイープも返します。.dex/ キャッシュが必要です(最初に map/profile を実行)。これにより、プロファイリングされた数値、非PII、非キーカラムから特徴量を自動選択できます。--features を渡すと自分で選択できます(PIIカラムまたはキーに名前を付けると意図的にオプトインされ、その平均のみが報告されます)。キーは決して特徴量にはなりません。その平均は無意味であり、ファクトテーブルはほとんどがキーと少数のメジャーであるため、それらをクラスタリングするとサロゲート範囲が分割されるだけです。キーは、一意のカラム、結合するカラム(map が推論した結合から)、およびそのように名付けられたカラムです。ここでは生の profile よりも map を優先してください。推論された結合がないと、外部キーは名前でわかる場合にのみ捕捉されます。メモは除外されたすべてのカラムに名前を付けるため、結果を信頼する前に確認してください。シルエットだけではわからないことが2つあり、どちらもメモに記載されています。サンプルの1%未満を保持するクラスターは外れ値ポケットであり、セグメントではありません。スコアを押し上げるのは、まさにそれが非常に遠くにあるからです。それを外れ値検出として報告するか、-k を指定して再実行して大部分を分割します。また、サンプルをシードできないコネクタでは、ドローが実行ごとに変化するため、2回の実行でkが一致しない可能性があります。エンベロープの sample_repeatable はどちらのケースかを示し、異なるドローにわたる実行を比較することは無意味です。集計値のみが境界を越えます。サンプル行はプロセス内でクラスタリングされ、コンテキストに入ることはありません。従量課金コネクタでは、以下のスキャンコマンドと同じコストハンドシェイクがかかります(特徴量カラムのみがスキャンされ、ダイアレクト対応のサンプル句が一部を読み取ります)。そのため、見積もりを提示し、まず予算を取得してください。[cluster] エクストラ(scikit-learn)が必要です。ラッパーはこのサブコマンドのために自動的にインストールします。
  9. explore semantic list および explore semantic query は、dbtセマンティックレイヤー(メトリクス、ディメンション、エンティティ)にアクセスします。list は発見用:どのメトリクスが存在し、それぞれをどのディメンションでグループ化できるかを示します。query は、明示的なモードの後ろに位置引数としてメトリクスをとり(互換性のために --metric も保持)、--group-by <entity__dim> (およびオプションで --where、--grain、--limit)を指定して、メトリクスの値を上限のある列形式の結果として返します。名前フラグはカンマ区切りのリストまたは繰り返しフラグを受け入れます(--group-by a,b は --group-by a --group-by b と同じ)。--where は決して分割されません。これらに答える2つのバックエンドがあり、.dex/config.yml の semantic.backend で選択され、--local / --api で上書き可能です。--local はMetricFlowでSQLをレンダリングし、dex自身のコネクタとコストハンドシェイクを通じて実行します。そのため、支出前にコストが明示されます(dbtプロジェクトが必要であり、query の場合は [semantic] エクストラも必要。list はマニフェストの読み取りビューであり、どちらも必要ありません)。--api はクエリをホスト型dbt Cloudデプロイメントに送信します(ホスト、環境ID、DBT_SL_TOKEN のみが必要。[semantic-api] エクストラも必要。ローカルプロジェクトは不要)。ホスト型バックエンドはコストガードが適用できない唯一の場所です。dbt Cloudはサーバーサイドで実行されるため、結果には支出がそこで管理され、dexでは管理されないという明示的な警告が含まれ、--confirm は要求されません。どちらの場合も、PII形状のグループ化またはフィルタリングされたディメンション(例:user__email)は、クエリ実行前に拒否されます。これはレイヤーにクエリを実行します。オーサリングは transform の仕事です。

query の行動規則:質問に答えられる場合は固定コマンドを優先してください。1つのプローブは1つの質問に答えます。関連する測定値を多数発行するのではなく、1つのクエリにまとめてください。PIIフラグが付いたカラムの集計は、測定(COUNT、APPROX_COUNT_DISTINCT、AVG(LENGTH(...)))である必要があり、値を持つ(MIN、ANY_VALUE、STRING_AGG)ものであってはなりません。FROM句は、コネクタのネイティブイディオムでJSONおよび配列カラムをアンネストできます。これはスキーマレスデータを探索する正しい方法です(例:「このJSONカラムのすべての行にどのキーが出現するか」)。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)。アンネストされた値は、クエリ内のテーブルのカラムから(直接、またはJSON/配列関数を介して)取得する必要があります。サブクエリ、別のテーブル、リテラル、またはジェネレータをアンネストすることは拒否され、アンネストの出力はソースカラムのPIIフラグを継承します。フラグが0.5のブロックしきい値を下回るように評価が下げられたカラムは、名前を挙げたエンベロープの警告とともに通常どおりに投影されます。警告はユーザーへの情報として扱い、修正すべきエラーとして扱わないでください。ユーザーが拒否されたカラムは個人データではないと言った場合は、.dex/config.yml に pii_overrides エントリ(完全修飾カラム名、オプションの理由)を推奨してください。これによりクエリが即座にブロック解除され、再プロファイル後も存続し、gitでレビュー可能になります。フラグをクリアするために .dex/cache.json を手動で編集しないでください。SQLを実行するために生のPythonやデータベースCLIにフォールバックしないでください。ファイアウォールパスが唯一の承認されたパスです。

クラウドおよびデータベースターゲット(BigQuery、Snowflake、Databricks、Postgres、Redshift)

リモートのウェアハウスまたはデータベースは、--path をコネクタ設定に置き換えます。connect test --connector <name> から開始するか、.dex/config.yml に connector: と対応するブロックを設定します:bigquery: には project と datasets 許可リスト、snowflake: には固定された warehouse と databases 許可リスト、databricks: には固定されたSQL warehouse と catalogs 許可リスト、postgres: には schemas 許可リスト、redshift: にはServerless workgroup と schemas 許可リスト。認証情報は自動検出され、要求されることはありません。エンベロープが認証情報の欠落または有効期限切れを報告した場合は、それが指定する修正方法を中継してください(BigQueryの場合は gcloud auth application-default login、Snowflakeの場合は connections.toml エントリまたは SNOWFLAKE_* 環境変数、Databricksの場合は databricks auth login または DATABRICKS_* 環境変数、Postgresの場合は DATABASE_URL、PG* 環境変数、または pg_service.conf エントリ、Redshiftの場合はAWS認証情報チェーン(aws configure、AWS_* 環境変数)または REDSHIFT_* 環境変数)。ユーザーにキー、トークン、パスワードを貼り付けさせないでください。

従量課金コネクタでは、スキャンコマンド(profile、map、relationships、query)は2段階のハンドシェイクを実行します。最初の呼び出しは、needs_confirmation を cost.estimate 内の見積もり(および該当する場合はテーブルごとの内訳)とともに返します。BigQueryでは正確なドライランバイト数、Snowflakeではヒューリスティックでラベル estimate_quality: "heuristic" のウェアハウス秒数(クレジットも併記)、Databricksではラベル estimate_quality: "low" のウェアハウス秒数(DBUも併記、確認された予算内で自己調整します)、Redshiftではコンピュート秒数のヒューリスティック(RPU時間も併記、Serverlessの見積もりには60秒のウェイク最小値が1回含まれます)、Postgresではデータベース秒数(ドルはなし、保護される数量は運用データベースへの負荷です)。見積もりを人間が理解できる単位でユーザーに提示し、明示的な予算を取得してから、同じコマンドを --confirm と --budget <magnitude> をパラダイムの単位で指定して再発行してください。ユーザーが同意していない予算を決して発明したり、上限超過の拒否に対してユーザーに確認せずに予算を上げて再試行したりしないでください。メタデータは無料です(connect test、inventory は即座に実行されます)。OKエンベロープは data.spend の下で実際の支出を報告します。

BigQueryでは、プロファイリングの見積もりには、プロファイルが集計スキャン後に発行する可能性のある各エスカレーションクエリに対して、テーブルごとに10 MBのフロアが保持されます。そのため、多数の小さなテーブルがあるウェアハウスでは、数値の大部分が発生しない作業のために予約される可能性があります。ハンドシェイクと上限超過の拒否の両方がその分割を報告します(reserved_bytes と reserved_queries、および文章内)。見積もりを提示する際にそれを伝えてください。数値がスキャンか予約かによって、予算を上げることが作業を購入することになるのか、ヘッドルームを購入することになるのかが変わります。

見積もりが作業の価値よりも大きい場合は、予算を上げるのではなく、スコープを絞ってください。--scope(繰り返し可能)は、コマンドを設定されたソース許可リストの一部に制限します。コネクタ独自の語彙を使用します。BigQueryではデータセット、Snowflakeでは schema または database.schema、Databricksでは catalog.schema、PostgresまたはRedshiftではスキーマ。解決は無料で、オブジェクトリストを制限することしかできず、拡張することはできません。ソース許可リストにないものに名前を付けると、エラーになります。異なるコネクタ上の同じ名前のスコープは、それぞれ独自のコンテキストで評価されます。そのため、データベースをまたがるスコープは、跨ぐことのできない境界を越えようとしている場合に明確に失敗します。見積もりを形状化するためにのみ使用してください。--scope は、サブコマンドがコマンドラインで識別されるオブジェクトを受け入れるかどうかには影響しません。map を --scope dataset1,dataset2 で実行すると、それらのデータセット内のオブジェクトのみがマッピングおよびプロファイリングされます。

関連スキル