<!-- title: 装通Claude Code造首个数据看板 -->
# 装通 Claude Code 造首个本地数据看板

## 概述

本教程面向零基础读者，从安装 Claude Code、完成首次认证，到理解它的"对话循环"与权限机制，最终用一句自然语言指令驱动它生成一个**纯标准库的 CSV 数据看板生成器**——读 CSV、自动识别数值列、产出可在浏览器打开的自包含 HTML 看板（内联 SVG 柱状图 + 汇总卡片 + 明细表）。学完你将掌握安装、认证、CLAUDE.md 项目记忆、斜杠命令与最小可运行项目，适合从未写过命令行工具的入门者。

## 前置条件

- 一台 macOS / Linux / Windows 机器，能联网
- 终端基础：会复制粘贴命令、能 `cd` 进入目录即可，**不要求会写代码**
- 二选一的认证凭据：
  - **订阅方式**：Claude Pro（约 $17/月起）或 Max（$100/月）账号
  - **API 方式**：Anthropic Console 的 API Key（按量付费）
- 若走 npm 安装路线，需要 Node.js 18 及以上

> 本文示例在 Linux + Python 3 环境下演示，Windows 用户把 `python3` 换成 `python` 即可。

---

## 正文

### 第 1 步：安装 Claude Code

Anthropic 官方推荐用**原生安装器**（native installer），它会在后台自动更新，省去手动升级的麻烦。

macOS / Linux：

```bash
curl -fsSL https://claude.ai/install.sh | bash
```

Windows（PowerShell）：

```powershell
irm https://claude.ai/install.ps1 | iex
```

也可以用包管理器：mac 的 `brew install claude-code`、Windows 的 `winget install Anthropic.ClaudeCode`；或走 npm：

```bash
npm install -g @anthropic-ai/claude-code
```

安装完，验证版本：

```bash
claude --version
```

**预期结果**：打印一串版本号，例如 `1.x.x`，说明可执行文件已在 PATH 中。

**常见问题**：

| 现象 | 原因与解决 |
|---|---|
| `command not found: claude` | 安装后没重开终端，PATH 未刷新；重开一个终端窗口，或 `source ~/.zshrc` / `source ~/.bashrc` |
| npm 报 `engine` 不兼容 | Node 版本低于 18，升级 Node 后重装 |
| 公司网络下载失败 | 换 npm 镜像或给 curl 设代理 `https_proxy=... curl ...` |

### 第 2 步：首次登录与认证

在任意目录输入：

```bash
claude
```

首次启动会让你选界面风格（颜色/字体），随后进入登录。Claude Code 支持三种身份：

1. **Claude Pro / Max 订阅**：选浏览器登录，会自动打开网页完成授权——这是最省事的路子。
2. **Anthropic Console API 账号**：在 [console.anthropic.com](https://console.anthropic.com) 生成 API Key，用环境变量注入：

   ```bash
   export ANTHROPIC_API_KEY="sk-ant-xxxxxxxx"
   claude
   ```

3. **第三方平台**：如 Amazon Bedrock / Google Vertex，企业用户常用。

**预期结果**：登录成功后，终端出现输入框，光标闪烁，可以开始打字对话。

**常见问题**：

- **在 SSH / 远程服务器上登录卡住**：浏览器无法弹出。改用 API Key 方式（`export ANTHROPIC_API_KEY=...`），无需浏览器。
- **想切换账号**：在交互界面输入 `/login` 重新选择身份。
- **怀疑环境有问题**：输入 `/doctor`，它会自检 Node、网络、认证、磁盘等并给出诊断。

### 第 3 步：理解"对话循环"与权限

Claude Code 不是一次问答，而是一个**代理循环（agentic loop）**：你给目标 → 它读文件/想方案 → 调工具（读写文件、跑命令）→ 看结果 → 继续推进，直到完成或停下来征求你同意。

关键是**权限**：默认情况下，它要改文件、跑命令前都会弹出确认，你可以逐条 `y` 同意、`n` 拒绝。这让零基础用户也始终握有控制权。

几个高频斜杠命令，现在就记住：

| 命令 | 作用 |
|---|---|
| `/help` | 查看所有命令 |
| `/clear` | 清空当前对话上下文，重新开始 |
| `/context` | 看当前塞进了哪些文件/上下文 |
| `/compact` | 压缩历史，省 token、延长会话 |
| `/model` | 切换模型（如 Opus / Sonnet） |
| `/doctor` | 自检环境与配置 |
| `/permissions` | 管理工具白名单/黑名单 |

两个命令行参数同样好用：

```bash
claude --continue      # 继续上一次会话
claude -p "列出当前目录文件"   # 一次性模式，问完即退，适合脚本
```

### 第 4 步：建立项目与 CLAUDE.md

CLAUDE.md 是**项目记忆**：放在项目根目录，每次启动 Claude Code 会自动读它，等于一开始就把"这是个什么项目、用什么技术、怎么跑"告诉它。

新建项目目录并进入：

```bash
mkdir csv-dashboard && cd csv-dashboard
claude
```

在交互界面直接说：

> 帮我在当前目录创建一个 CLAUDE.md，写明：项目目标是用纯 Python 标准库把任意 CSV 转成自包含 HTML 看板；约定只用标准库、不引第三方包；输出文件固定叫 dashboard.html；注释用中文；运行方式是 `python3 dashboard.py <csv> [数值列]`。

它会生成类似这样的文件：

```markdown
# CSV 数据看板项目

## 目标
用纯 Python 标准库把任意 CSV 转成自包含 HTML 看板（内联 SVG，无第三方依赖）。

## 约定
- 仅用标准库，禁止引入 pandas / matplotlib
- 输出文件名固定为 dashboard.html
- 代码注释用中文

## 运行
- 生成看板：`python3 dashboard.py <csv路径> [数值列名]`
- 验证方式：生成后用浏览器打开 dashboard.html 目检
```

如果想减少权限弹窗，再加一个项目级 `.claude/settings.json`（让它自动放行安全的运行命令）：

```json
{
  "permissions": {
    "allow": ["Bash(python3 dashboard.py:*)", "Bash(python3 -c:*)", "Bash(ls:*)"],
    "deny": ["Bash(rm -rf:*)"]
  }
}
```

### 第 5 步：第一个项目——让 Claude Code 造数据看板

CLAUDE.md 立好后，把需求用一句自然语言抛给它：

> 按 CLAUDE.md 的约定写 dashboard.py：读任意 CSV，自动识别第一个数值列做柱状图、第一列做标签，生成自包含 dashboard.html（内联 SVG 柱状图 + 汇总卡片 + 明细表），终端打印摘要并尝试用浏览器打开。再准备一个示例 sales.csv。

接下来你会看到完整的代理循环：它创建 `dashboard.py`、`sales.csv` → 弹权限让你确认 → 跑 `python3 dashboard.py sales.csv` → 看到 `✅ 已生成看板` → 用浏览器打开 `dashboard.html` 检查效果 → 如有瑕疵继续改。

**预期结果**：目录里多出 `dashboard.py`、`sales.csv`、`dashboard.html`，浏览器弹出一个带柱状图和统计卡片的页面。

**常见问题**：

- **看板数值列选错了**：CSV 里有多列数字时它可能挑错。手动指定：`python3 dashboard.py sales.csv 订单数`。
- **中文标签变方块**：HTML 已声明 `charset=utf-8`，一般是 CSV 本身编码问题；脚本用 `utf-8-sig` 读取可兼容带 BOM 的文件。
- **浏览器没自动弹**：服务器环境无图形界面属正常，手动把 `dashboard.html` 下载到本地打开即可。

---

## 实战案例：完整可运行示例

**示例数据 `sales.csv`**：

```csv
月份,销售额,订单数
1月,12500,120
2月,9800,98
3月,15600,150
4月,18200,175
5月,16400,158
6月,21300,205
```

**生成器 `dashboard.py`**（纯标准库，可直接复制运行）：

```python
#!/usr/bin/env python3
# CSV -> 自包含 HTML 数据看板（纯标准库，无第三方依赖）
import csv, sys, html, os, webbrowser

def to_num(s):
    s = (s or "").replace(",", "").replace("¥", "").replace("$", "").strip()
    try:
        return float(s)
    except ValueError:
        return None

def load_rows(path):
    with open(path, newline="", encoding="utf-8-sig") as f:
        return list(csv.DictReader(f))

def pick_numeric_col(rows, cols, hint=None):
    if hint:
        return hint
    for c in cols:                       # 自动猜：多数行能转成数字的列
        nums = [to_num(r.get(c)) for r in rows]
        if sum(1 for v in nums if v is not None) >= max(2, len(rows) * 0.6):
            return c
    return None

def bar_chart(labels, values, width=720, height=320, color="#4f46e5"):
    n, max_v = len(values), (max(values) if values else 1) or 1
    pad_l, pad_b, pad_t, pad_r = 48, 48, 24, 16
    cw, ch = width - pad_l - pad_r, height - pad_b - pad_t
    step = cw / max(n, 1); bw = step * 0.7
    p = [f'<svg viewBox="0 0 {width} {height}" class="chart">']
    p.append(f'<line x1="{pad_l}" y1="{pad_t+ch}" x2="{pad_l+cw}" y2="{pad_t+ch}" stroke="#cbd5e1"/>')
    for i, (lab, val) in enumerate(zip(labels, values)):
        h = (val / max_v) * ch
        x = pad_l + i * step + (step - bw) / 2
        y = pad_t + ch - h
        p.append(f'<rect x="{x:.1f}" y="{y:.1f}" width="{bw:.1f}" height="{h:.1f}" rx="4" fill="{color}"/>')
        p.append(f'<text x="{x+bw/2:.1f}" y="{y-6:.1f}" text-anchor="middle" class="v">{val:g}</text>')
        p.append(f'<text x="{x+bw/2:.1f}" y="{pad_t+ch+18:.1f}" text-anchor="middle" class="l">{html.escape(str(lab))}</text>')
    p.append("</svg>")
    return "".join(p)

def build_html(title, labels, values, c_label, c_value, rows):
    total, mx = sum(values), (max(values) if values else 0)
    avg = total / len(values) if values else 0
    cards = "".join(
        f'<div class="card"><div class="k">{k}</div><div class="v">{v}</div></div>'
        for k, v in [("记录数", str(len(rows))), ("合计", f"{total:,.2f}"),
                     ("平均", f"{avg:,.2f}"), ("峰值", f"{mx:,.2f}")]
    )
    body = "".join(
        f"<tr><td>{html.escape(str(r.get(c_label,'')))}</td><td>{html.escape(str(r.get(c_value,'')))}</td></tr>"
        for r in rows
    )
    return f"""<!doctype html><html lang="zh"><head><meta charset="utf-8">
<title>{html.escape(title)}</title><style>
*{{font-family:-apple-system,'Segoe UI',sans-serif}}
body{{margin:0;background:#f8fafc;color:#0f172a;padding:24px}}
h1{{font-size:22px;margin:0 0 16px}}
.cards{{display:flex;gap:12px;margin-bottom:20px;flex-wrap:wrap}}
.card{{background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:14px 18px;min-width:120px}}
.card .k{{color:#64748b;font-size:12px}}.card .v{{font-size:22px;font-weight:700;margin-top:4px}}
.panel{{background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:16px}}
.chart{{width:100%;height:auto}}.chart .v{{font-size:11px;fill:#475569}}.chart .l{{font-size:11px;fill:#64748b}}
table{{border-collapse:collapse;width:100%;margin-top:8px}}
th,td{{text-align:left;padding:8px 10px;border-bottom:1px solid #eef2f7;font-size:14px}}
th{{color:#64748b;font-weight:600}}
</style></head><body>
<h1>📊 {html.escape(title)}</h1>
<div class="cards">{cards}</div>
<div class="panel">{bar_chart(labels, values)}</div>
<div class="panel" style="margin-top:16px"><table><thead><tr><th>{html.escape(c_label)}</th><th>{html.escape(c_value)}</th></tr></thead><tbody>{body}</tbody></table></div>
</body></html>"""

def main():
    if len(sys.argv) < 2:
        print("用法: python3 dashboard.py <data.csv> [数值列名]"); sys.exit(1)
    path = sys.argv[1]
    hint = sys.argv[2] if len(sys.argv) > 2 else None
    rows = load_rows(path)
    if not rows:
        print("错误: CSV 为空或没有数据行"); sys.exit(1)
    cols = list(rows[0].keys())
    num_col = pick_numeric_col(rows, cols, hint)
    if not num_col:
        print(f"错误: 未找到数值列，列名: {cols}"); print("请手动指定: python3 dashboard.py data.csv 列名"); sys.exit(1)
    label_col = cols[0]
    labels = [r[label_col] for r in rows]
    values = [to_num(r[num_col]) or 0 for r in rows]
    out = os.path.join(os.path.dirname(os.path.abspath(path)) or ".", "dashboard.html")
    with open(out, "w", encoding="utf-8") as f:
        f.write(build_html(os.path.basename(path), labels, values, label_col, num_col, rows))
    print(f"✅ 已生成看板: {out}")
    print(f"   标签列: {label_col}  数值列: {num_col}  记录数: {len(rows)}")
    try:
        webbrowser.open("file://" + os.path.abspath(out))
    except Exception:
        pass

if __name__ == "__main__":
    main()
```

**运行与输出**：

```bash
$ python3 dashboard.py sales.csv
✅ 已生成看板: /home/you/csv-dashboard/dashboard.html
   标签列: 月份  数值列: 销售额  记录数: 6
```

浏览器自动打开 `dashboard.html`：顶部四张卡片（记录数 6 / 合计 94,800.00 / 平均 15,800.00 / 峰值 21,300.00），下方紫色柱状图横跨 1–6 月，再下方是明细表。想看"订单数"趋势就加个参数：`python3 dashboard.py sales.csv 订单数`。

这套脚本零依赖、单文件，扔给同事也能直接跑——这正是 CLAUDE.md 里"只用标准库"约定带来的好处。

---

## 工作流程图

```mermaid
flowchart TD
    A[安装 Claude Code<br/>原生安装器 / npm] --> B[首次认证<br/>订阅登录 或 API Key]
    B --> C[理解代理循环 + 权限确认<br/>/help /clear /context /compact]
    C --> D[建项目目录 + CLAUDE.md<br/>项目记忆]
    D --> E[.claude/settings.json<br/>放行安全命令]
    E --> F[一句自然语言下需求<br/>造 CSV 数据看板]
    F --> G{代理循环}
    G --> G1[读 CLAUDE.md / CSV]
    G1 --> G2[写 dashboard.py + sales.csv]
    G2 --> G3[跑 python3 dashboard.py]
    G3 --> G4[浏览器目检 dashboard.html]
    G4 -->|有瑕疵| G2
    G4 -->|通过| H[✅ 完成首个可视化项目]
```

---

## 延伸阅读

- 把看板升级为**多图表**：让 Claude Code 再加折线图、饼图（仍用内联 SVG），练习多轮迭代与 `/compact` 上下文管理。
- 体验 **`-p` 一次性模式**：`claude -p "把 sales.csv 的销售额列求和"`，把 Claude Code 当 Unix 管道的一环。
- 给项目加 **Stop 钩子**：每次生成完看板自动用 `python3 -m http.server` 起本地预览，体会自动化。
- 学会 **`/permissions` 与 settings.json** 的分层（用户级 vs 项目级），为团队协作打基础。

---

## 训练营适用性评估

- **适合类型**：零基础编程入门营、数据可视化启蒙营、AI 工具上手营、产品经理"用 AI 做原型"工作坊。
- **教学时长**：约 2–3 小时。安装认证 30 分钟、对话循环与权限 30 分钟、CLAUDE.md 与项目搭建 30 分钟、造看板并调优 60–90 分钟。
- **难度曲线**：平缓。前半段是"装好就能用"，后半段从一句需求到看到可视化成品，反馈即时，成就感强。
- **可考核点**：能否独立生成 `dashboard.html` 并正确指定数值列；能否解释代理循环中"权限确认"的作用；能否写出最小 CLAUDE.md。
- **延伸作业**：换一份自己的真实 CSV（记账、健身、销售）生成看板，并写一段 100 字的项目说明放进 CLAUDE.md。

---

## 参考来源

1. [Claude Code 官方快速上手（Quickstart）](https://code.claude.com/docs/en/quickstart) — 安装、登录、首个项目的权威步骤
2. [Claude Code Tutorial for Beginners 2026（dev.to）](https://dev.to/ayyazzafar/claude-code-tutorial-for-beginners-2026-from-installation-to-building-your-first-project-1lma) — 从安装到首个项目的完整入门视频图文版
3. [Claude Code Tutorial for Beginners - Complete 2026 Guide（CodeWithMukesh）](https://codewithmukesh.com/blog/claude-code-for-beginners/) — 涵盖安装、CLAUDE.md、斜杠命令的入门指南
4. [Claude Code: Complete Guide From Beginner to Power User 2026（The Neuron）](https://www.theneuron.ai/explainer-articles/claude-code-guide-how-to-use-it%20/) — 从入门到进阶的上下文管理与工作流
5. [Anthropic 官方文档主站](https://docs.anthropic.com/en/docs/claude-code) — 认证、配置、settings.json 与权限的官方说明

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
