<!-- title: 接手陌生代码库：Claude Code修首个Bug -->

# Claude Code 入门实战：接手一个陌生代码库并修复第一个 Bug

## 概述

本教程面向**刚装好 Claude Code、却不知道怎么把它真正用到项目里**的零基础开发者。与其再讲一遍安装向导，我们聚焦一个更真实、也更容易翻车的场景：**接手一个你不熟悉的代码库，让 Claude Code 帮你读懂它，并修掉第一个 Bug**。学完你将掌握认证登录、`/init` 生成项目记忆、只读探索、read-before-edit（先读再改）、测试验证与提交闭环。适用人群：有基础 Git/命令行常识、刚拿到一个交接项目或想给开源仓库贡献代码的开发者。

## 前置条件

- 一台已联网的开发机（macOS / Linux / WSL / Windows 均可），有可用终端。
- 已安装 **Node.js ≥ 18**（部分安装方式需要）与 **Git**。
- 一个 Anthropic 账号，二选一：
  - **Claude 订阅账号**（Pro / Max），适合个人长期使用；
  - **Anthropic Console 账号**（按 API Key 计费），适合团队、CI 或想精确控费的场景。
- 一个**你不熟悉的代码库**用于练习——可以是同事交接的项目，也可以是任何小型开源仓库。本教程末尾会提供一个 30 行即可复现的小项目，方便你零成本跟练。

---

## 第一步：安装并完成首次认证

### 操作说明

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

```bash
# macOS / Linux / WSL
curl -fsSL https://claude.ai/install.sh | bash

# Windows PowerShell
irm https://claude.ai/install.ps1 | iex
```

如果你更习惯包管理器，也可以：

```bash
# Homebrew（不会自动更新，需手动 brew upgrade）
brew install --cask claude-code          # 稳定通道，约落后一周
brew install --cask claude-code@latest   # 最新通道

# Windows WinGet
winget install Anthropic.ClaudeCode

# Debian / Fedora / RHEL / Alpine
# apt / dnf / apk 均有官方包，详见官方 setup 文档
```

安装完成后，进入任意项目目录并启动：

```bash
cd your-project
claude
```

首次启动会弹出**登录提示**。这里就是两条认证通道的分流点：

| 认证方式 | 适用场景 | 计费 | 注意事项 |
|---|---|---|---|
| Claude 订阅（Pro/Max） | 个人开发、桌面日常使用 | 订阅费内含额度 | 受订阅速率限制 |
| Anthropic Console API Key | 团队、CI、精确控费 | 按 token 计费 | 需在 console.anthropic.com 充值 |
| 第三方模型供应商 | 想接入非 Claude 模型 | 依供应商 | 终端 CLI 与 VS Code 支持 |

按浏览器引导完成 OAuth 登录后，终端会回到交互界面（REPL），看到输入框即代表就绪。

### 预期结果

终端出现 `>` 提示符，底部状态栏显示当前模型（默认通常是 Sonnet）、上下文用量与所在目录。此时 Claude Code 已经"住进"了你的项目，但**它对你代码库一无所知**——这正是接下来要解决的问题。

### 常见问题

- **`'irm' is not recognized`**：说明你在 CMD 里跑了 PowerShell 命令。看提示符，`PS C:\>` 是 PowerShell，裸 `C:\>` 是 CMD，按对应命令重试。
- **`syntax error near unexpected token '<'` 或 403**：通常是网络代理或 curl 被劫持，参考官方 troubleshoot-install 文档逐项排查。
- **登录后立刻报限流**：订阅账号在高峰期可能触发速率限制；若需稳定，改用 Console API Key 并在 `~/.claude/settings.json` 配置好 key 来源。

---

## 第二步：为什么"陌生代码库"是另一道题

很多人在新建项目时觉得 Claude Code 好用，一接手老项目就翻车。原因不是模型变笨了，而是**上下文的性质变了**。

一个 5 万行的老项目里藏着大量"代码本身看不出来"的隐性知识：

- **被迁移掉的旧模式**：半年前从 Redux 换成了 Zustand，但旧文件还散落各处；
- **看起来活着、其实没人调用的死代码**；
- **不在 import 里的隐藏依赖**：环境变量、数据库触发器、第三方 webhook 约定的数据结构；
- **业务词汇的精确含义**："Order" 到底指购物车还是已成单的订单？

没有这些上下文，Claude 会写出**能编译、但不合身**的代码——套用你早已弃用的模式，或忽略某个关键的副作用。所以接手项目的第一原则是：**把模型当成一个刚入职的新同事，给它一份"入职文档"**，而这份文档就是 `CLAUDE.md`。

---

## 第三步：用 `/init` 给项目生成"入职文档"草稿

### 操作说明

在 REPL 里输入：

```
/init
```

Claude Code 会读取项目结构（`package.json`、目录树、README、常见约定），生成一份**初始版** `CLAUDE.md`。注意三个关键点：

1. **它是草稿，不是成品**。能抓到"这是一个 Next.js + TypeScript + Prisma 的项目"这类客观事实，但抓不到你团队的约定。
2. **你需要人工补全**——这是把项目"教"给模型的核心环节。
3. **它跨平台生效**：终端、VS Code、桌面端、Web 共享同一份 `CLAUDE.md`，写一次到处用。

一份对老项目真正有用的 `CLAUDE.md`，至少要包含这几节：

```markdown
## 架构与决策
- Next.js App Router，能用 Server Component 就用
- 所有写操作走 Server Actions，不写 REST 接口（2025 Q1 已迁移）
- 数据库访问统一用 Prisma；仅 /lib/db/queries.ts 允许裸 SQL 做复杂聚合
- 不用 Redux：全局 UI 状态用 Zustand，服务端状态用 TanStack Query

## 当前状态
- 鉴权：已全量迁移到 Clerk（旧 next-auth 代码在 /archive/old-auth，请忽略）
- 邮件：Resend，模板在 /emails/，禁止使用 nodemailer（遗留）

## 禁止修改
- /lib/generated/ —— Prisma 自动生成，下次 db push 会被覆盖
- /public/static/ —— 市场团队管理，不在部署流水线内

## 业务词汇表
- Order：orders 表中的成单记录（不是购物车）
- Cart：会话内的临购买态，不落库
- Processing：订单"已下单"与"已发货"之间的状态，触发仓库通知
```

经验之谈：**"禁止修改"这一节往往是最有价值的**。Claude 出于好心会去碰不该碰的东西，明确的禁区能挡掉大半麻烦。

### 预期结果

项目根目录多出 `CLAUDE.md`。之后每次会话启动，Claude 都会自动加载它，省去重复解释架构的口舌。

### 常见问题

- **生成的 CLAUDE.md 太泛泛**：正常。`/init` 只能描述"是什么"，"为什么这么干"必须你来补。把它当模板，往里填团队决策。
- **CLAUDE.md 越写越长**：这是好事也是隐患。当它逼近几千字时，参考官方 memory 文档做分层（项目根 + 子目录）与压缩，保持高信号密度。

---

## 第四步：先用 3 个"只读任务"建立上下文

### 操作说明

**千万不要**一上来就让它"重构鉴权系统"。先用低风险、高信息量的只读任务，让模型把真实代码读进去。推荐三句话：

```
读取 /lib/actions/ 目录，描述每个 action 的职责。不要修改任何文件，只做映射。
```

```
看一个 /components/ui/ 下的现有组件，按同样的模式新写一个同类组件，保存前先把产物展示给我看。
```

```
读取 Prisma schema，解释数据模型，并指出字段名看不出来的隐含关系。
```

这些任务"低风险"是因为不碰生产代码，"高信息量"是因为模型读的是**你项目里真实的代码**，而非泛泛的 Next.js 模板。两三轮之后，你就能验证它是否真的吃透了你的约定。

对于大文件，**读摘要而非全文**，省上下文：

```
读取 src/services/UserService.ts，给我 5 句话的概述和它的公开接口签名，不要展示完整实现。
```

### 预期结果

Claude 返回一段结构化总结。把它和你的心智模型对照——**如果对得上，就不必把全文喂进去**；只在实际要改某几行时才拉取完整文件。

### 常见问题

- **它编造了不存在的函数**：说明上下文不足。用 `/clear` 清空后重新指定精确路径，或把关键文件直接 `@` 进来。
- **上下文塞满了还没开始写代码**：在自然停顿点用 `/compact` 压缩。它会保留学到的结论，丢弃原始文件原文，是长任务的关键卫生习惯。

---

## 第五步：挑选一个独立小 Bug，完成修复闭环

### 操作说明

在让模型动生产代码之前，先建立一条铁律——**先读再改（read-before-edit）**。在每个改动型 prompt 里加上这句：

> 改动前，先读取 [目标文件] 和 [相关文件]，并总结你的理解供我核对。

这条习惯看似拖慢节奏，实则能省下"基于文件名臆测、改了半天发现根本没读过文件"那种两小时的 debug。

模型切换（视任务复杂度）：简单改动用 Sonnet，复杂重构用 `/model` 切到 Opus，验证型小任务用 Haiku 省额度。

权限模式上，新项目建议先用**计划模式 / 逐项确认**（按 `Shift+Tab` 在默认、计划、自动接受编辑等模式间循环），等信任建立后再放权。

### 实战案例：一个 30 行的 Todo CLI，修掉一个 off-by-one

下面是一个**完整可运行**的小项目，你可以在本地复刻。它有一个真实的 Bug，正好用来走完整闭环。

新建目录 `todo-cli`，创建 `todo.py`：

```python
# todo.py — 一个故意藏了 Bug 的极简待办 CLI
import sys, json, pathlib

DB = pathlib.Path("todos.json")

def load():
    return json.loads(DB.read_text()) if DB.exists() else []

def save(items):
    DB.write_text(json.dumps(items, indent=2))

def main():
    cmd = sys.argv[1] if len(sys.argv) > 1 else "list"
    items = load()

    if cmd == "add":
        items.append({"text": sys.argv[2], "done": False})
        save(items)
        print(f"added: {sys.argv[2]}")
    elif cmd == "done":
        # 用户从 1 开始计数，这里直接用下标 —— 经典 off-by-one
        idx = int(sys.argv[2])
        items[idx]["done"] = True          # <- Bug: 应为 idx - 1
        save(items)
        print(f"done: {items[idx]['text']}")
    elif cmd == "list":
        for i, it in enumerate(items, 1):
            mark = "x" if it["done"] else " "
            print(f"{i}. [{mark}] {it['text']}")

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

现在让 Claude Code 接手。在项目目录启动 `claude`，按顺序：

**① 只读探索**
```
读取 todo.py，概述它支持的命令和数据结构，不要修改。
```
预期：它指出这是一个支持 add/done/list、用 todos.json 持久化的 CLI。

**② 定位 Bug**
```
假设用户执行 python todo.py add 买牛奶、python todo.py add 写报告、
然后 python todo.py done 2 想标记第二条完成。逐行走读 done 分支，
找出与用户预期不符的行为并说明原因。
```
预期：它会发现 `items[idx]` 用了 1 起点的下标，`done 2` 会改到第 3 项或越界，正确写法是 `items[idx - 1]`。

**③ 先读再改**
```
改动前先重新读取 todo.py 的 done 分支，确认你理解后再修改：
把用户输入的 1 起点序号正确映射为 0 起点下标，并对越界输入给出友好提示。
改完写一个最小验证：add 三条，done 2，再 list 确认只有第二条被勾选。
```

**④ 运行验证**

```bash
python todo.py add 买牛奶
python todo.py add 写报告
python todo.py add 健身
python todo.py done 2
python todo.py list
```

预期输出：

```
1. [ ] 买牛奶
2. [x] 写报告
3. [ ] 健身
```

只有第 2 条被勾选，Bug 修复成功。

**⑤ 审查 diff 并手动提交**

不要让模型在第一天就自主 commit。看一眼改动：

```bash
git diff todo.py
git add todo.py && git commit -m "fix(done): map 1-based index to 0-based, guard out-of-range"
```

**⑥ 把教训写回 CLAUDE.md**

发现"用户序号是 1 起点、内部是 0 起点"这一约定后，补进 `CLAUDE.md`：

```markdown
## 约定
- 所有面向用户的序号均为 1 起点；内部数组下标 0 起点，转换在入口层统一处理
- 越界输入一律返回友好提示，不抛裸异常
```

这个六步小闭环，就是接手任何陌生项目时的**最小可信单元**。把它放大到真实仓库，逻辑完全一致：`/init` → 补记忆 → 只读探索 → 先读再改 → 测试验证 → 手动提交 → 回写经验。

---

## 整体工作流程

```mermaid
flowchart TD
    A[安装 Claude Code] --> B[首次认证<br/>订阅 或 API Key]
    B --> C[cd 进入陌生项目目录]
    C --> D["运行 /init 生成 CLAUDE.md 草稿"]
    D --> E[人工补全<br/>架构/现状/禁区/词汇表]
    E --> F[3 个只读探索任务]
    F --> G{理解准确?}
    G -- 否 --> E
    G -- 是 --> H[选定一个独立小 Bug]
    H --> I[先读再改 read-before-edit]
    I --> J[运行测试验证]
    J --> K{测试通过?}
    K -- 否 --> I
    K -- 是 --> L[审查 diff 并手动提交]
    L --> M[把教训写回 CLAUDE.md]
    M --> N[逐步放权 循环迭代]
```

---

## 信任的建立是渐进的

第一天别让模型自主提交。用一个 review 循环起步：模型提改动 → 你在终端或编辑器里审 diff → 你手动 commit。一两周后，你会摸清它在你**这个项目**上哪类任务靠谱、哪类需要盯。这并非不信任，而是搞清楚模型对你代码库的边界——这份判断，是任何通用文档都给不了你的。

之后你可以逐步引入更高级的能力：用 `/review-pr` 做提交前自审、用 hooks 在每次文件编辑后自动格式化、用子智能体（sub-agents）让多个 Claude 并行啃不同模块。但这一切的前提，都是先有一份**靠谱的 CLAUDE.md** 和一个**经过验证的理解基线**。

---

## 延伸阅读

- **Anthropic 官方 Quickstart**：`https://docs.anthropic.com/en/docs/claude-code/quickstart` —— 从探索代码库到提交修复的首个完整任务，官方手把手版本。
- **CLAUDE.md 记忆机制**：`https://docs.anthropic.com/en/docs/claude-code/memory` —— CLAUDE.md 的加载规则、分层与自动记忆。
- **官方 Overview（安装与多端）**：`https://docs.anthropic.com/en/docs/claude-code/overview` —— 终端、VS Code、桌面端、Web 的安装与互通。
- **CLI Reference**：`https://docs.anthropic.com/en/docs/claude-code/cli-reference` —— 全部命令与 flags 速查。

---

## 训练营适用性评估

- **适合类型**：Claude Code 入门营 / 企业 AI 编程提效营 / 开源贡献新手营。门槛低、闭环完整，是最佳"第一次真实产出"课题。
- **不适合**：纯 Agent 自动化营、MCP 开发营——本篇不涉及 SDK 与服务器开发。
- **预计教学时长**：2.5–3.5 小时。其中安装认证 30 分钟、`/init` 与 CLAUDE.md 撰写 60 分钟、只读探索 45 分钟、Bug 修复实战与提交 60–90 分钟。
- **考核建议**：学员提交一个 PR，diff 必须满足"修复一个真实问题 + 附带把经验回写进 CLAUDE.md"两项，缺一不可——这正是工程化而非祈祷的关键分水岭。

---

## 参考来源

1. [Bringing Claude Code Into an Existing Codebase (2026)](https://stacknotice.com/blog/claude-code-existing-codebase-guide-2026) — `/init`、为遗留代码撰写 CLAUDE.md、先读再改与渐进信任的实操指南。
2. [Claude Code Overview — Anthropic 官方文档](https://docs.anthropic.com/en/docs/claude-code/overview) — 原生安装命令、订阅/API 双认证、多端互通与 CLI 互操作的权威说明。
3. [Claude Code Quickstart — Anthropic 官方文档](https://docs.anthropic.com/en/docs/claude-code/quickstart) — 从探索代码库到提交修复的首个官方完整任务 walkthrough。
4. [The Complete Guide to CLAUDE.md (Medium)](https://medium.com/@bijit211987/the-complete-guide-to-claude-md-memory-rules-loading-and-cross-tool-compression-97cc12ed037b) — CLAUDE.md 的设计、维护与压缩，构建高信号指令层。

---

> 本文由微信公众号 **「51学通信」** 原创整理，站长 **爱卫生**（微信：gprshome201101）运营。专注通信与 AI 工程化的实战内容，欢迎关注获取更多 Claude Code、5G/6G 核心网与协议深度解析。

> [!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)
