跳到主要內容

【2026 最新】Claude Code × dbt Charts 教學:CSV 變成可審查、可重跑的 YAML 儀表板

最後更新: ·
dbt Charts 教學:Claude Code 將 CSV 變成可審查、可重跑的 YAML 儀表板

這篇 dbt Charts 教學要解決一個很實際的 AI 開發問題:Claude Code 可以很快做出儀表板,但如果交付物是一大包 HTML/React,你很難只靠 Git diff 判斷 SQL、指標、版面與互動到底改了什麼。

2026 年 9 月 14 日的 Hacker News 討論很快聚集了實際使用回報,也出現對 SQL 正確性、權限治理、互動性與替代方案的追問;但留言沒有提供可重跑的共同資料集或評分規準。它適合拿來找問題,不足以證明 YAML 一定比自由式網頁更正確。本文會從固定 CSV 開始,帶你做出能驗證、能輸出、能在 CI 重跑的最小專案,並把限制一起說清楚。

先記住這條公式:可靠儀表板 = 固定資料 + 可讀 YAML/SQL 規格 + 會失敗的驗證門。Claude Code 是施工者;規格、測試與 Git 才是驗收。

dbt Charts 教學先說結論:誰適合用?

  • 適合:資料來源已有 SQL/CSV/DuckDB,想把常見 KPI、折線圖、長條圖、表格與說明文字納入 Git review 的團隊。
  • 適合:希望 AI 先產生規格,再由 dct validate、實際 render 與 CI 決定能不能合併,而不是相信聊天回答。
  • 不一定適合:需求核心是高度客製動畫、任意 JavaScript、特殊互動或產品級前端;自由式 React/Observable/Streamlit 類工具會更直接。
  • 不是完整 BI 治理替代品:官方 FAQ 明確說開源 dct serve 沒有內建 access control;身分、權限、資料列政策與稽核仍要由外部系統或託管服務處理。

截至 2026 年 9 月 16 日,最新版本是 dbt Charts 0.8.0。官方 README 稱它是 beta/pre-1.0,套件 metadata 則標成 Alpha;所以本教學會固定版本,不把快速變動的語法假裝成穩定標準。

dbt Charts 教學的 CSV、YAML、驗證與輸出流程
先把資料、規格與驗證拆開;圖表只是最後一段輸出。

先懂四層:SQL、YAML、Markdown、變數各管什麼?

官方 YAML reference把一塊 board 拆成幾個可審查區域:queries 決定資料列與聚合;charts 把查詢欄位映射到視覺通道;rowscolsgrid 決定版面;text 放 Markdown 說明。這比「請做一個好看的 dashboard」多了一組邊界,也少了很多隱藏決策。

變數也不會自動過濾資料。你必須在 SQL 中明確寫入 {{ filter('region', region) }};dbt Charts 才會把使用者選值綁成查詢參數。換句話說,控制元件存在,不等於查詢已接線。想理解「模型讀檔、改檔、跑命令」和完整 agent 系統的差別,可先讀什麼是 AI Agent Harness

dbt Charts 教學:從 CSV 做出第一份 YAML board

步驟 1:固定版本並建立專案

dbt Charts 0.8.0 的官方 Python 範圍是 3.10–3.13。先依 uv 官方安裝頁裝好 uv;使用 uv tool install 會建立隔離環境,避免它目前的 dbt-core<2 相依套件改動你既有的 dbt v2 環境。以下 shell 指令以 macOS/Linux/WSL 為例。

mkdir yaml-dashboard && cd yaml-dashboard
git init
uv tool install --python 3.13 dbt-charts==0.8.0
export PATH="$(uv tool dir --bin):$PATH"
dct --version
dct init --yes
dct skills intro

dct init --yes 不只建立 dbt_charts.ymlcharts/:v0.8.0 也可能把 agent skills 寫進 .agents/skills/.claude/skills/,並依偵測到的 client 提示 MCP 設定。先看 git status,確認這些新增檔是否符合你的 repo 規範,再一起提交。

這條路不要求既有 dbt 專案;CSV、JSON、Parquet、SQLite 與 DuckDB 都可直接開始。若你本來就在比較 coding agent,可搭配Claude Code vs Codex 完整比較;這裡只使用 Claude Code 一般的讀檔、改檔與執行命令能力,不把它描述成「原生支援 dbt Charts」。

步驟 2:加入固定 CSV 與來源設定

建立 data/sales.csv,至少放入月份、地區、營收與訂單數。固定測試資料要一起進 Git,否則兩次 render 讀到不同輸入,snapshot 沒有比較意義。

month,region,revenue,orders
2026-01-01,North,125000,430
2026-01-01,South,98000,350
2026-02-01,North,132000,451
2026-02-01,South,103000,364
2026-03-01,North,141000,478
2026-03-01,South,109000,382
2026-04-01,North,138000,466
2026-04-01,South,116000,401
2026-05-01,North,149000,502
2026-05-01,South,121000,419
2026-06-01,North,158000,526
2026-06-01,South,128000,438

接著把 dbt_charts.yml 簡化成:

sources:
  sales_csv:
    type: csv
    files:
      sales: data/sales.csv

步驟 3:讓 Claude Code 先規劃,再寫 board

目前 Claude Code 的互動預設會依方案、平台與設定而異,不要假設它每次改檔前一定詢問。第一次先明確開 Plan mode:

claude --permission-mode plan

把需求寫成可驗收任務,而不是只說「做一個漂亮圖表」:

先讀 dbt_charts.yml、data/sales.csv 與官方 dct skills 說明,目前不要修改檔案。請規劃 charts/sales-review.yml:包含總營收、總訂單、月營收折線、地區營收長條、月明細表與 region 多選變數。所有查詢都必須使用同一個 sales_csv source;規劃最後列出 validate、render 與 snapshot 驗收命令。

確認計畫後,在核准畫面選擇「Approve and review each edit manually」;若已離開該提示,可用 Shift+Tab 切到 default,或另開 session 執行 claude --permission-mode default。這符合 Claude Code 官方 permission modes 的目前行為,也保留你對每次修改的控制。完整 board 可以長成這樣:

title: CSV sales review
notes: A small review board built from a fixed CSV fixture.
source: sales_csv

style:
  timestamp:
    visible: false

variables:
  region:
    input: multiselect
    column: sales.region

queries:
  monthly: |
    SELECT month,
      SUM(revenue) AS revenue,
      SUM(orders) AS orders
    FROM sales
    WHERE {{ filter('region', region) }}
    GROUP BY month
    ORDER BY month

  regions: |
    SELECT region,
      SUM(revenue) AS revenue,
      SUM(orders) AS orders
    FROM sales
    WHERE {{ filter('region', region) }}
    GROUP BY region
    ORDER BY revenue DESC

  totals: |
    SELECT SUM(revenue) AS revenue,
      SUM(orders) AS orders
    FROM sales
    WHERE {{ filter('region', region) }}

charts:
  revenue_kpi:
    type: kpi
    query: totals
    label: Total revenue
    value: revenue
    style:
      value:
        format: currency_whole

  orders_kpi:
    type: kpi
    query: totals
    label: Total orders
    value: orders
    style:
      value:
        format: integer

  revenue_trend:
    type: line
    query: monthly
    title: Monthly revenue
    x: month
    y: revenue
    style:
      number_format: currency

  regional_mix:
    type: bar
    query: regions
    title: Revenue by region
    x: region
    y: revenue
    style:
      number_format: currency

  monthly_detail:
    type: table
    query: monthly
    title: Monthly detail
    style:
      columns:
        revenue:
          format: currency_whole
        orders:
          format: integer

rows:
  - text: |
      Filter: {{ region or 'All regions' }}. The CSV fixture stays in Git so
      reviewers and CI read the same input.
  - cols: [revenue_kpi, orders_kpi]
  - cols: [revenue_trend, regional_mix]
  - monthly_detail

這份規格把查詢、指標、圖表與版面拆成不同區塊。Reviewer 可以先核對 SUM(revenue) 是否是正確商業定義,再看 revenue 欄位是否接到對的圖,最後才審視雙欄 layout;不必從生成後的 DOM 反推意圖。

驗證與輸出:不要把 validate 當成 SQL 已跑過

dct validate 官方說明指出,預設模式檢查 YAML schema、交叉引用與結構,不會執行所有 SQL。CSV/DuckDB 範例應再加 --warehouse 檢查查詢結果 schema 與 chart 欄位綁定,最後用 render 真正執行查詢:

dct validate charts/sales-review.yml --strict
dct validate charts/sales-review.yml --strict --warehouse

mkdir -p dist
dct render charts/sales-review.yml --format svg  --output dist/sales.svg
dct render charts/sales-review.yml --format html --output dist/sales.html
dct render charts/sales-review.yml --format png  --output dist/sales.png
dct render charts/sales-review.yml --format pdf  --output dist/sales.pdf

本教學展示的 12 列 CSV 與完整 board 已在 v0.8.0 依序通過 strict、warehouse validation 與四種 render。SVG、PNG、PDF 是靜態 snapshot;依 官方變數與 export 邊界,HTML 可保留 hover;若 board 本身設定連結,或資料量/設定觸發分頁,standalone HTML 也會把這些行為與已渲染資料一起帶入,但沒有後端替變數重新查詢。要讓控制元件重跑 SQL,使用 dct serve 或具備 host 的服務。

固定 12 列 CSV 經 dbt Charts 0.8.0 渲染的月營收趨勢
從完整 board 裁出的月營收圖:同一份 fixture 也產生 KPI、地區拆分與明細,畫面仍要和 golden totals 一起驗收。

把 snapshot 與 GitHub CI 變成真的失敗條件

只把 PNG 上傳成 artifact 不叫 regression test;CI 必須在輸出改變時回傳 non-zero。先在你確認過的基準版本建立 snapshot:

mkdir -p build tests/snapshots
dct render charts/sales-review.yml --format svg --output build/sales.svg
sed -E 's/data-rendered-at="[^"]+"/data-rendered-at="NORMALIZED"/' \
  build/sales.svg > tests/snapshots/sales-review.svg
git add data dbt_charts.yml charts tests/snapshots

即使關掉可見 timestamp,v0.8.0 的 SVG root 仍含 data-rendered-at;不先正規化,每次渲染都會出現假差異。接著建立 .github/workflows/dbt-charts.yml

name: dbt Charts
on: [push, pull_request]

jobs:
  validate-and-render:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v6
      - name: Install pinned CLI
        run: |
          uv tool install --python 3.13 dbt-charts==0.8.0
          echo "$(uv tool dir --bin)" >> "$GITHUB_PATH"
      - run: dct validate charts/sales-review.yml --strict --warehouse
      - run: mkdir -p build
      - run: dct render charts/sales-review.yml --format svg --output build/sales.svg
      - run: |
          sed -E 's/data-rendered-at="[^"]+"/data-rendered-at="NORMALIZED"/' \
            build/sales.svg > build/sales.normalized.svg
          diff -u tests/snapshots/sales-review.svg build/sales.normalized.svg

第一次 baseline 必須由你審過,而且要在和 CI 相同的 OS、字型與工具鏈建立;不要讓 workflow 自動接受新 snapshot。上面固定了 Ubuntu 24.04、Python 3.13 與 dbt Charts 0.8.0,但 transitive dependencies 仍未形成完整 lockfile,所以這是一個正規化 regression signal,不是跨平台 byte-for-byte 永遠一致的保證。要求更強時,改用固定 container image 或 lockfile。

這個 gate 能抓 schema、欄位綁定、SQL 執行與渲染差異,但不能證明「營收定義符合公司共識」。目前 v0.8.0 的官方 overview仍寫著「SQL today, dbt metrics next」;指標 SQL 因此仍可能被重複定義。你可以把這套 review/test/CI 思路接到AI Agent Harness 實作流程,但 metric owner 的人工核准不能省。

自由式 HTML vs dbt Charts:真正差在複雜度放哪裡

自由式 HTML React 與 dbt Charts YAML SQL 的中立比較
YAML 不會自動帶來正確性;它把常見儀表板的審查面集中,代價是受 DSL 邊界限制。

「HTML diff 很亂」不是 Web 技術的必然缺陷;良好拆分的 React component 也能有乾淨 diff。反過來,YAML 可讀也不代表 SQL 正確。dbt Charts 的優勢是把常見 board 的查詢、視覺 mapping、layout 和輸出命令收斂到固定 grammar;自由式框架則把責任交給你選擇元件、狀態、權限、測試、可及性與部署。

可攜性也要講精確:YAML/SQL 可留在自己的 Git,OSS renderer 可在本機跑;但它仍是 dbt Charts 專用 DSL。官方把 SVG/PDF/PNG/HTML 描述為 exports,沒有承諾能匯入另一套 BI authoring tool 後繼續來回編輯。這叫「原始碼可自存」,不等於零 switching cost。

pre-1.0 的 5 個邊界,現在就要寫進流程

  1. 固定版本:CI 使用 dbt-charts==0.8.0,升級另開 PR,不讓最新套件在背景改語法。
  2. 先 dry-run migration:依照官方 migration 流程,升級時依序跑 dct migrate --dry-rundct migrategit diffdct validate
  3. 分開三種互動:靜態 HTML 的 hover/連結,不等於 dct serve 的重新查詢,也不等於任意 Web App 行為。
  4. 權限另設:官方 FAQ 明列 dct serve 沒有 access control;不要把它直接暴露在公開網路。託管 Cloud 的 ACL 也是服務端狀態,不會跟 board YAML 一起攜帶。
  5. 理解開源治理:引擎以 Apache-2.0 開源,但官方 CONTRIBUTING 說公開 GitHub repo 是 private upstream 的 read-only mirror,目前接受 issue、不接受 pull request。可以 fork,不代表上游治理已開放。

四個最常見的失敗,該看哪一層?

  1. YAML 過了,render 卻失敗:schema 只知道欄位與引用是否合法,不知道你的 SQL dialect、資料型別或執行權限。先跑 --warehouse,再看 render 的 query error;不要要求 Claude 直接「換一種寫法直到不報錯」,否則可能只是把商業邏輯改掉。
  2. 下拉選單有出現,數字卻沒變:回到每一段 SQL,確認都有 {{ filter('region', region) }}。變數宣告只建立 control,不會偷偷改查詢;這種顯式接線正是 review 應該看的地方。
  3. snapshot 每次都紅:先確認輸入檔、版本、runner、字型和 theme 是否一致,再檢查 data-rendered-at 是否已正規化。若換 OS 才出現差異,重新建立同 runner 的候選 artifact 給人審,不要在 CI 自動覆寫 expected。
  4. 畫面很合理,總數卻錯:先用另一段簡單 SQL 或手算建立 golden totals,再故意放入 duplicate join、NULL、缺月與高基數類別。視覺 snapshot 只能告訴你「畫面變了」,不能告訴你聚合是否符合業務定義。

靜態、self-hosted、managed:先選同一個部署層級

  • 只要審查附件或定期報告:CI 產生 SVG/PNG/PDF/HTML artifact,流程最短,也不需要長駐 query server。
  • 要變數即時重跑 SQL:使用 dct serve,但放在公司既有的 authentication proxy 後面,並使用唯讀資料庫角色;不要把本機 preview server 當成公開權限層。
  • 要分享、分支 review 與服務端 ACL:再評估 dbt Charts Cloud,並把平台權限和 Git 中的 board 規格當成兩份不同狀態管理。

比較工具時也要同層對同層:靜態 export 對 Observable/Evidence 類靜態站;self-hosted 服務對 Streamlit/Dash 等 runtime;managed Cloud 再對 managed BI。若拿一張 SVG 去比較企業 BI 的 IAM、cache 與 audit log,結論一開始就失真。

所以我的判斷很簡單:若 80% 需求是標準 KPI、趨勢、拆分、表格與說明,先用 dbt Charts,把例外需求單獨評估;若核心價值正是自訂互動與產品 UX,就不要為了 YAML 而硬塞進 DSL。

dbt Charts 教學 FAQ

1. 沒有 dbt 專案也能用嗎?

可以。官方支援直接讀 CSV、JSON、Parquet、SQLite 與 DuckDB;本教學就是從固定 CSV 開始。

2. dbt Charts 免費嗎?

開源引擎與 CLI 可以免費自架。它們採 Apache-2.0;dbtCharts.com 託管平台是另一個產品層,功能與方案不要和 OSS license 混為一談。

3. 一定要用 Claude Code 嗎?

不需要。你可以手寫 YAML,或讓任何能讀檔、改檔、跑 CLI 的 agent 協助。Claude Code 只是本文選擇的施工介面。

4. dct validate 通過就代表 SQL 正確嗎?

不代表。預設 validate 偏向結構檢查;--warehouse 的能力也依 adapter 而異。至少再 render 一次,並用人工確認的 golden totals 驗證商業定義。

5. 輸出的 HTML 是完整互動式 dashboard 嗎?

不是完整 live app。它可保留 snapshot 上的 hover;若 board 本身設定連結或表格分頁,這些行為也能隨 export 帶入,但沒有 backend 重新查詢變數;即時重跑要用 dct serve 或託管 host。

6. dbt Charts 能取代公司現有 BI 嗎?

不一定。先列出你需要的 IAM、row-level policy、Semantic Layer、audit log、排程、cache 與自訂圖表,再比較同一部署層級;不要拿靜態 export 對打完整 managed BI。

7. SVG snapshot 一定每次相同嗎?

不一定。必須固定資料、套件、字型、環境與主題,關閉可見 timestamp,並正規化 data-rendered-at;即使文字 diff 相同,仍應抽查實際畫面。

8. pre-1.0 升級最安全的順序是什麼?

先分支、再 dry-run。dct migrate --dry-run,確認改寫範圍後才執行 migrate,接著看 Git diff、validate、render 與 snapshot;不要直接改 CI 的 floating latest。

給新手的 7 個重點

  1. Claude Code 產生的是候選變更,不是正確性證明。
  2. 固定 CSV 和 package version,才能談可重跑。
  3. SQL 管資料,YAML 管呈現,Markdown 管敘事,變數要明確接進 SQL。
  4. validate--warehouserender 是三個強度不同的 gate。
  5. snapshot 要正規化時間欄位,CI 的 diff 必須真的能失敗。
  6. Git review 是治理的一部分,不是身分權限或 semantic metric 的替代品。
  7. 標準 dashboard 優先用 DSL;高度客製體驗保留自由式 Web stack。

接著閱讀

左右滑動查看更多推薦

結語:先讓錯誤會被擋下,再追求一鍵生成

dbt Charts 最值得學的不是「AI 幫你畫圖」,而是把交付物縮成可讀規格,讓錯誤能在 review、validate、render 或 snapshot 任一層被擋下。今天先用 12 列 CSV 跑通完整鏈;下一步不是加入更多花俏圖表,而是放入一個已由人手算對的 golden total,故意改錯欄名與聚合,確認 CI 真的會紅。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週最多三封:一封 Weekly 週報與最多兩封關鍵 Alpha Signal。

我們不會 spam,隨時可退訂。