# Teaching Claude Code the Art of Data Engineering: Introducing Altimate Skills

---

Today, we're open-sourcing **Altimate Skills** — a collection of [Claude Code skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) specifically designed for analytics engineers. We are starting with skills for dbt and Snowflake. These encode the workflows and best practices that transform AI from a basic code generator into a capable data engineering assistant.

%[https://youtu.be/kvIo5PmF0Ns] 

**Key Results:**

* **+25% improvement** on model creation tasks (40% → 65%)
    
* **+22% faster execution** (TPC-H 1TB) with 100% logically equivalent queries generated for SQL optimization.
    
* **53% accuracy** on [ADE-bench](https://github.com/dbt-labs/ade-bench) (43 real-world dbt tasks)
    
* Skills that actually **teach Claude *how* to work**, not just *what* to write
    

```bash
# Get started in 30 seconds
/plugin marketplace add AltimateAI/data-engineering-skills
/plugin install dbt-skills@data-engineering-skills
```

**GitHub:** [https://github.com/AltimateAI/data-engineering-skills](https://github.com/AltimateAI/data-engineering-skills) and ⭐ the repo.

---

## Solving the C**ontext and Workflow Issue**

If you've used Claude Code, Cursor, or any AI coding assistant for dbt development, you've experienced the frustration:

**The task:** "Create a staging model for the Stripe payment source."

**What you expect:**

```sql
-- models/staging/stripe/stg_stripe__payments.sql
{{
  config(
    materialized='view',
    schema='staging'
  )
}}

with source as (
    select * from {{ source('stripe', 'payments') }}
),

renamed as (
    select
        id as payment_id,
        amount_cents / 100.0 as amount,
        currency,
        status,
        created_at
    from source
)

select * from renamed
```

**What you get:**

```sql
SELECT * FROM {{ source('stripe', 'payments') }}
```

No `stg_` prefix. No `{{ source() }}` reference. No config block. No CTEs. No understanding of your project's conventions.

### Why This Happens

The core issue isn't that LLMs lack knowledge — Claude knows dbt syntax perfectly well. The problem is **context and workflow**:

1. **No project awareness** — Claude doesn't know your naming conventions, folder structure, or existing patterns
    
2. **No verification loop** — Claude declares "done" after writing code, without running `dbt build`
    
3. **No convention discovery** — Claude guesses at patterns instead of reading existing models first
    
4. **Compile ≠ Success** — `dbt compile` passes, but the model produces the wrong output
    

This leads to a frustrating cycle: AI writes code → You review and fix → AI loses context → Repeat.

---

## What Are Claude Code Skills?

Anthorpic introduced [Claude Skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) in October 2025. Skills are markdown files that teach Claude **how to approach tasks**, not just what syntax to use. Think of them as encoding the workflow an experienced analytics engineer follows.

Skills matter because they make Claude more reliable and specialized: you can standardize repeatable work (like formatting outputs, following internal conventions, or running a known process) and reuse it across projects. Claude can also load Skills progressively, starting with lightweight metadata and pulling in deeper instructions only when needed, giving you targeted behavior without bloating context.

Practically, a Skill is typically packaged as a small folder of structured instructions (and optionally templates, scripts, or reference files) that define *how* Claude should approach a workflow. See our [data-engineering-skills](https://github.com/AltimateAI/data-engineering-skills) repo folders as an example.

A skill has two parts:

**1\. Trigger conditions** — When should this skill activate?

```yaml
---
name: creating-dbt-models
description: |
  Guide for creating dbt models. ALWAYS use this skill when:
  (1) Creating ANY new model (staging, intermediate, mart)
  (2) Task mentions "create", "build", "add" with model/table
  (3) Modifying model logic or columns
---
```

**2\. Workflow instructions** — What steps should Claude follow?

```markdown
# dbt Model Development

**Read before you write. Build after you write. Verify your output.**

## Critical Rules
1. ALWAYS run `dbt build` after creating models - compile is NOT enough
2. ALWAYS verify output after build using `dbt show`
3. If build fails 3+ times, stop and reassess your approach

## Workflow
### 1. Understand Requirements
- What columns are needed?
- What is the grain (one row per what)?
- What calculations are required?

### 2. Discover Project Conventions
cat dbt_project.yml
find models/ -name "*.sql" | head -20
Read 2-3 existing models to learn patterns...
```

When Claude encounters a task that matches the trigger conditions, it automatically applies the skill's workflow.

---

## The Skills We Built

### [dbt Skills](https://github.com/AltimateAI/data-engineering-skills/tree/main/skills/dbt)

| Skill | Purpose | Key Behaviors |
| --- | --- | --- |
| **creating-dbt-models** | Model creation | Convention discovery → Write → Build → Verify output |
| **debugging-dbt-errors** | Error troubleshooting | Read full error → Check upstream → Apply fix → Rebuild |
| **testing-dbt-models** | Schema tests | Study existing test patterns → Match project style |
| **documenting-dbt-models** | Documentation | Analyze model → Generate descriptions |
| **migrating-sql-to-dbt** | Legacy SQL conversion | Parse SQL → Create proper dbt model |
| **refactoring-dbt-models** | Safe restructuring | Track dependencies → Apply changes → Verify downstream |

### [Snowflake Skills](https://github.com/AltimateAI/data-engineering-skills/tree/main/skills/snowflake)

| Skill | Purpose | Key Behaviors |
| --- | --- | --- |
| **optimizing-query-text** | Performance tuning (from SQL) | Profile query → Identify bottlenecks → Apply patterns |
| **optimizing-query-by-id** | Performance tuning (from query ID) | Fetch query from history → Analyze → Optimize |
| **finding-expensive-queries** | Cost analysis | Query ACCOUNT\_USAGE → Identify top spenders |

---

## Deep Dive: How creating-dbt-models Changes Claude's Behavior

Let's trace through a real task from our benchmark to see the difference.

> ### Task: "Create a model called dim\_customer that renames id to customer\_id and makes it a unique primary key."

### Without Skills (Baseline Claude)

**Claude's approach:**

1. Write the SQL immediately:
    

```sql
SELECT
  id AS customer_id,
  *
FROM customers
```

1. Run `dbt compile` → passes
    
2. Declare done
    

**Outcome:** Model compiles, but:

* Wrong table reference (raw table vs staging model)
    
* No config block matching project patterns
    
* No verification that the output is correct
    
* No `unique` test added for primary key
    

### With creating-dbt-models Skill

([See the specific SKILL.md file here](https://github.com/AltimateAI/data-engineering-skills/tree/main/skills/dbt/creating-dbt-models))

**Claude's approach:**

**Step 1: Understand Requirements**

* Columns needed: `customer_id` (renamed from `id`), plus all other columns
    
* Grain: One row per customer
    
* Constraint: Must be unique on `customer_id`
    

**Step 2: Discover Project Conventions**

```bash
$ cat dbt_project.yml
# Shows model-paths, naming conventions

$ find models/ -name "*.sql" | head -10
models/staging/stg_customers.sql
models/staging/stg_products.sql
models/marts/dim_products.sql

$ cat models/marts/dim_products.sql
# Learns: CTEs named 'source' and 'final', config blocks, column naming
```

**Step 3: Find Upstream Models**

```bash
$ cat models/staging/stg_customers.sql
# Discovers the correct source to reference
```

**Step 4: Write Model (following discovered patterns)**

```sql
-- models/marts/dim_customer.sql
{{
  config(
    materialized='table'
  )
}}

with source as (
    select * from {{ ref('stg_customers') }}
),

final as (
    select
        id as customer_id,
        name,
        email,
        created_at
    from source
)

select * from final
```

**Step 5: Update schema.yml with test**

```yaml
models:
  - name: dim_customer
    columns:
      - name: customer_id
        tests:
          - unique
          - not_null
```

**Step 6: Build and Verify**

```bash
$ dbt build --select dim_customer
# Actually runs the model and tests

$ dbt show --select dim_customer --limit 5
# Verifies output looks correct
```

**Outcome:** Model matches project conventions, has proper tests, output verified.

---

## Benchmarking: ADE-bench Results

We evaluated our skills using [ADE-bench](https://github.com/dbt-labs/ade-bench), a framework for evaluating AI agents on analytics engineering tasks created by dbt Labs.

### Test Setup

* **43 tasks** across 5 projects (Airbnb reviews, F1 racing, Asana projects, Analytics engineering, Intercom conversations)
    
* **Task types:** Model creation, bug fixing, debugging, refactoring, data analysis
    
* **Model:** Claude Sonnet 4.5
    
* **Database:** Snowflake
    
* **Evaluation:** Automated tests comparing model output to expected results
    

### Task Difficulty Distribution

| Difficulty | Example Task |
| --- | --- |
| **Easy** | "Fix the surrogate\_key deprecation warning." |
| **Medium** | "Create a dim\_customer model with unique primary key." |
| **Hard** | "Identify which top-N tables have inconsistent results due to tie.s" |

### Overall Results

| Configuration | Accuracy | Tasks Resolved | Avg Runtime | Avg Cost |
| --- | --- | --- | --- | --- |
| Baseline Claude (no skills, no MCP) | 46.5% | 20/43 | 152s | $0.33/task |
| Claude + Skills | 53.5% | 23/43 | 182s | $0.40/task |

### Results by Task Category

| Category | Baseline | With Skills | Improvement |
| --- | --- | --- | --- |
| **Model Creation** | 40% | 65% | **+25 pts** |
| **Bug Fixing** | 60% | 70% | +10 pts |
| **Debugging** | 35% | 50% | +15 pts |
| **Refactoring** | 30% | 35% | +5 pts |
| **Analysis** | 25% | 30% | +5 pts |

### What Worked

**Model creation** saw the biggest improvement. The creating-dbt-models skill's workflow of "discover conventions → write → build → verify" catches errors that baseline Claude misses:

1. **Convention discovery** prevents wrong naming/structure
    
2. **Mandatory** `dbt build` catches runtime errors that `compile` misses
    
3. **Output verification** ensures the model produces correct data
    

**Example success — Task** `analytics_engineering003`:

> "Create a model called 'dim\_customer' that renames id to customer\_id, and makes that row a unique primary key."

* Baseline: Created model but wrong column reference, no test
    
* With skills: Discovered existing staging model, matched project patterns, and added proper unique test
    

### What Didn't Work

**Complex analysis tasks** remain challenging. Tasks requiring deep reasoning about data behavior (like identifying which queries have non-deterministic results due to ties) still need human insight.

**Example failure — Task** `f1003`:

> "Identify which top-N tables have inconsistent results due to ties in the data"

This task requires:

1. Understanding the semantic meaning of "ties"
    
2. Analyzing actual data values across 8 models
    
3. Reasoning about SQL ordering behavior
    

Skills can't encode this kind of domain reasoning — they work best for **workflow guidance**, not **analytical judgment**.

---

## The Overhead Trade-off

Skills add overhead. The "discover conventions" step takes 15-30 seconds of additional LLM calls. Is it worth it?

| Metric | Without Skills | With Skills |
| --- | --- | --- |
| Avg task time | 152 seconds | 182 seconds |
| Success rate | 46.5% | 53.5% |
| Time to first success | ~5-6 min | ~3-4 min |
| Human intervention needed | High | Low |

**Our conclusion:** The 30-second overhead is worth it because:

1. Successful tasks need no human review
    
2. Failed tasks fail faster (3-failure rule)
    
3. Time saved on human review &gt;&gt; time spent on convention discovery
    

## Benchmarking: SQL Query Optimization

We evaluated the `optimizing-query-text` skill on TPC-H SF1000 (1TB dataset).

### Test Setup

* **10 queries** from TPC-H benchmark
    
* **Model:** Claude Sonnet 4.5
    
* **Evaluation:** Automated comparison of query results + execution time
    

### Overall Results

| Configuration | Pass Rate | Avg Time Improvement |
| --- | --- | --- |
| Baseline Claude (no skills) | 80% (8/10) | +25% (on passing queries) |
| Claude + Skills | **100% (10/10)** | +22% |

### What Failed Without Skills

Baseline failed 2 queries by making "optimizations" that changed what the query returned:

* Changed deduplication behavior, returning extra rows
    
* Renamed columns, breaking downstream compatibility
    

---

## Installation & Usage

### Add the Marketplace

```bash
/plugin marketplace add AltimateAI/data-engineering-skills
```

### Install Skills

You can browse and install via the CLI, or directly install plugins:

```bash
# Install dbt skills
/plugin install dbt-skills@data-engineering-skills

# Install Snowflake skills
/plugin install snowflake-skills@data-engineering-skills
```

After installing, skills activate automatically when you mention relevant tasks.

### Available Skills

**dbt Skills:**

* `creating-dbt-models` — Model creation with convention discovery
    
* `debugging-dbt-errors` — Systematic error troubleshooting
    
* `testing-dbt-models` — Schema tests and data quality
    
* `documenting-dbt-models` — Generate descriptions in schema.yml
    
* `migrating-sql-to-dbt` — Convert legacy SQL to dbt models
    
* `refactoring-dbt-models` — Safe restructuring with impact analysis
    

**Snowflake Skills:**

* `optimizing-query-text` — Optimize SQL you provide
    
* `optimizing-query-by-id` — Optimize using query ID from history
    
* `finding-expensive-queries` — Find top cost/time queries
    

### Usage

Skills activate automatically based on your request:

| Your Request | Skill Activated |
| --- | --- |
| "Create a new orders model." | `creating-dbt-models` |
| "Fix this compilation error." | `debugging-dbt-errors` |
| "Add tests to the customers model." | `testing-dbt-models` |
| "Document the revenue metrics". | `documenting-dbt-models` |
| "This query is slow; optimize it." | `optimizing-query-text` |
| "Why is query X expensive?" | `optimizing-query-by-id` |
| "What are our most expensive queries?" | `finding-expensive-queries` |

---

## Combining Skills with Altimate MCP Tools

Skills become even more powerful when combined with [Altimate's MCP server](https://docs.myaltimate.com/). The MCP server provides real-time access to your dbt project and data warehouse:

| MCP Tool | What It Provides |
| --- | --- |
| `dbt_project_info` | Project structure, model list, sources |
| `dbt_model_details` | Column types, dependencies, compiled SQL |
| `dbt_compile` | Compile models without CLI |
| `snowflake_query_history` | Recent query executions and stats |
| `snowflake_table_stats` | Row counts, clustering info |

**Example: Skills + MCP workflow**

User: "The daily\_revenue model is producing wrong numbers."

Claude (with skills + MCP):

1. **debugging-dbt-errors skill activates**
    
2. Uses `dbt_model_details` to get model SQL and dependencies
    
3. Uses `dbt_compile` to check for errors
    
4. Queries upstream models to verify input data
    
5. Identifies the issue (e.g., missing WHERE clause)
    
6. Fixes and rebuilds
    
7. Uses `dbt show` to verify the correct output
    

---

## What We Learned Building This

### 1\. Workflow &gt; Knowledge

The biggest wins came from encoding **workflows**, not facts. Claude already knows dbt syntax — what it lacks is the discipline to:

* Check existing patterns before writing
    
* Run `dbt build` instead of `dbt compile`
    
* Verify output after build
    

### 2\. The 3-Failure Rule

We added this to every skill:

> "If build fails 3+ times, STOP. Step back and reassess your entire approach."

This prevents Claude from making tiny tweaks hoping they work. Instead, it forces a fundamental rethink.

### 3\. Skills Can't Replace Domain Expertise

Skills work best for **procedural tasks** with clear success criteria. They struggle with:

* Tasks requiring business context
    
* Ambiguous requirements ("make this better")
    
* Deep analytical reasoning about data behavior
    

### 4\. Convention Discovery Is Essential

The #1 source of Claude errors was mismatched conventions. Simply adding "read 2-3 existing models first" eliminated most of these.

---

## What's Next

We're actively developing:

* **Airflow skills** — DAG development, debugging, testing
    
* **Cross-platform migration** — dbt ↔ SQL Server, Oracle
    
* **Snowflake cost optimization** — Warehouse sizing, query patterns
    
* **Data quality workflows** — Anomaly detection, freshness checks
    

### Contributing

Altimate Skills is open source (MIT License). We welcome:

* **New skills** for workflows we haven't covered
    
* **Improvements** to existing skills based on your team's patterns
    
* **Benchmark results** on different datasets
    

**GitHub:** [https://github.com/AltimateAI/data-engineering-skills](https://github.com/AltimateAI/data-engineering-skills)

---

## Try It Now

```bash
# Add the marketplace
/plugin marketplace add AltimateAI/altimate-skills

# Install the plugins you need
/plugin install dbt-skills@altimate-skills
/plugin install snowflake-skills@altimate-skills
```

**Resources:**

* [GitHub Repository](https://github.com/AltimateAI/data-engineering-skills) and ⭐ the repo.
    
* [Altimate MCP Server Docs](https://docs.myaltimate.com/)
    
* [ADE-bench Framework](https://github.com/dbt-labs/ade-bench)
    
* [dbt Slack #tools-dbt-power-user](https://app.slack.com/client/T0VLPD22H/C05KPDGRMDW)
    

---

*Built by the team at* [*Altimate AI*](https://altimate.ai/) *— Making data engineering delightful.*
