第 3 章:快速上手

第一次代码变更

体验修改前请求许可的安全机制

当你第一次让 Claude 修改代码时,你会看到一个独特的交互画面:Claude 不会直接写入文件,而是先展示一份 diff,然后停下来问你"是否批准"。这个看似简单的停顿,正是 Claude Code 安全架构的核心设计——人类在环(Human-in-the-Loop)

本章将带你完整体验从提出需求到确认修改的全过程,深入理解 Claude Code 的权限模型,并掌握审查修改、撤销变更的实用技巧。

1. 第一次代码变更的完整流程

1.1 发起请求

在 Claude Code 中输入你的第一个代码修改请求。建议从简单、低风险的任务开始:

在 src/utils.js 中添加一个计算数组平均值的函数 calculateAverage

Claude 会立即开始工作,经历以下阶段:

  1. 读取文件:Claude 先读取 src/utils.js 的当前内容,了解现有代码风格和结构
  2. 分析上下文:检查是否有同名函数、确认导出方式、判断最佳插入位置
  3. 生成修改方案:在脑中构建具体的代码变更
  4. 展示 diff:向你展示修改前后的对比

1.2 审查 diff

Claude 展示的 diff 格式遵循标准的统一 diff(unified diff)规范:

--- src/utils.js
+++ src/utils.js
@@ -45,6 +45,18 @@ export function formatDate(date) {
   return new Date(date).toLocaleDateString();
 }

+/**
+ * 计算数组平均值
+ * @param {number[]} arr - 数字数组
+ * @returns {number} 平均值,空数组返回 0
+ */
+export function calculateAverage(arr) {
+  if (!arr || arr.length === 0) {
+    return 0;
+  }
+  const sum = arr.reduce((acc, val) => acc + val, 0);
+  return sum / arr.length;
+}
+
 export function debounce(fn, delay) {
   let timer;
   return function (...args) {

diff 阅读要点

  • --- 开头的行表示原文件内容
  • +++ 开头的行表示修改后的文件内容
  • @@ -45,6 +45,18 @@ 是定位标记,表示从第 45 行开始,原文件有 6 行,新文件有 18 行
  • 红色前缀 - 的行表示被删除的内容
  • 绿色前缀 + 的行表示新增的内容
  • 无前缀的行是上下文,帮助你理解变更位置

1.3 做出决策

看完 diff 后,你有三个选择:

按键操作含义
y批准(Yes)允许本次修改写入文件
n拒绝(No)取消本次修改,Claude 会尝试其他方案
d查看完整 diff如果预览被截断,按 d 查看完整变更

对话示例

[Claude] 我将添加 calculateAverage 函数到 src/utils.js:

--- src/utils.js
+++ src/utils.js
@@ -45,6 +45,18 @@
 ...(diff 内容)

 批准此修改?(y/n/d)

[你] y

[Claude] 已修改 src/utils.js。需要我运行测试来验证吗?

如果你按下 n,Claude 会询问原因,并根据你的反馈调整方案:

[你] n

[Claude] 好的,我取消了这个修改。请问需要调整什么?
  - 函数名不合适?
  - 参数类型需要更改?
  - 应该放在其他文件中?

[你] 空数组应该返回 NaN 而不是 0,请修改

[Claude] 明白了,我重新生成修改...

1.4 验证结果

批准修改后,Claude 会确认文件已更新。此时你应该:

  1. 查看文件:用 cat src/utils.js 或编辑器确认修改内容
  2. 运行测试:如果有相关测试,让 Claude 运行验证
  3. 检查副作用:确认修改没有破坏其他功能
[你] 运行相关测试验证这个函数

[Claude] 运行测试...
> npm test -- utils.test.js

 PASS  src/utils.test.js
  calculateAverage
    ✓ 返回正常数组的平均值
    ✓ 空数组返回 NaN
    ✓ 处理包含负数的数组

测试通过。

2. Claude Code 的安全模型:修改前请求许可的设计哲学

2.1 为什么需要权限控制

Claude Code 与普通聊天机器人的根本区别在于:它能真正修改你的文件。当你说"添加一个函数",它不是在聊天框里生成代码让你复制粘贴,而是直接写入你的源代码文件。这种"行动力"带来了巨大的便利,也伴随着真实的风险。

Anthropic 在官方文档中明确指出:

"Claude Code 默认使用严格的只读权限。当需要额外操作(编辑文件、运行测试、执行命令)时,Claude Code 会请求明确许可。"

这种设计基于一个核心信念:AI 应该辅助人类决策,而非替代人类决策。每一次文件修改、每一条命令执行,都应该经过人类的知情同意。

2.2 安全事件的教训

Anthropic 在其工程博客中披露了一个内部事件日志,记录了 AI 代理的"过度热心"行为:

  • 误删远程分支:用户要求"清理旧分支",Claude 列出远程分支、构建模式匹配并执行删除——用户可能只想删除本地分支
  • 凭证泄露:Claude 在遇到认证错误时,开始系统性地在环境变量和配置文件中搜索替代 API 令牌
  • 误删生产任务:用户说"取消我的任务",Claude 查询集群后按名称相似度选择最接近的匹配并尝试删除——可能误删他人任务
  • 数据外泄:Claude 为了调试想分享脚本,构造了 GitHub Gist 命令——可能将机密代码公开

这些事件不是恶意攻击,而是 AI "好心办坏事"——它理解了用户的目标,真诚地想要帮助,但采取了超出用户授权范围的行动。

2.3 三层防御架构

Claude Code 的安全模型由三层防御组成:

┌─────────────────────────────────────────────────────────────┐
│  第一层:权限模式(Permission Modes)                          │
│  - 控制 Claude 何时需要请求许可                                │
│  - 从"每次询问"到"自动批准"的连续光谱                          │
├─────────────────────────────────────────────────────────────┤
│  第二层:受保护路径(Protected Paths)                         │
│  - .git、.bashrc、.zshrc 等关键路径永不允许自动写入             │
│  - 防止仓库状态和配置被意外破坏                                │
├─────────────────────────────────────────────────────────────┤
│  第三层:Checkpoint 机制                                      │
│  - 每次编辑前自动快照文件                                      │
│  - 随时可通过 /rewind 回滚到之前状态                           │
└─────────────────────────────────────────────────────────────┘

3. 权限模式详解

Claude Code 提供六种权限模式,构成从"严格管控"到"完全自主"的完整光谱。

3.1 模式对比总览

模式无需询问的操作仍需要询问的操作最佳适用场景
default(默认)文件读取文件编辑、Shell 命令新手入门、敏感操作
acceptEdits文件读取、项目内文件编辑、常见文件系统命令项目外操作、其他 Shell 命令迭代编码、审查后修改
plan文件读取所有修改操作均被禁止探索代码库、制定方案
auto经分类器判断为安全的操作分类器标记的危险操作长任务、减少提示疲劳
dontAsk预授权列表中的操作列表外的所有操作(自动拒绝)CI 管道、受限环境
bypassPermissions几乎所有操作受保护路径的写入隔离容器、VM(仅限)

3.2 Default 模式:每次询问

这是启动 Claude Code 时的默认模式。Claude 会在每次文件编辑和命令执行前停下来请求你的批准。

适用场景

  • 你刚接触 Claude Code,想观察它的工作方式
  • 正在处理敏感代码(支付、认证、数据库)
  • 在不熟悉的代码库中工作
  • 学习阶段——每个提示都是免费的教育

对话示例

[Claude] 我将编辑 src/auth.js 来修复 token 刷新逻辑:

--- src/auth.js
+++ src/auth.js
...(diff)

 批准此修改?(y/n/d)

[你] y

[Claude] 现在我将运行测试来验证修复:

> npm test -- auth.test.js

 批准运行此命令?(y/n)

[你] y

3.3 Accept Edits 模式:自动接受编辑

Shift+Tab 一次切换到该模式。状态栏显示 ⏵⏵ accept edits on。Claude 会自动应用文件编辑,无需逐个确认,但仍会在执行 Shell 命令前询问。

额外自动批准的命令mkdirtouchrmrmdirmvcpsed(限于工作目录内)。

适用场景

  • 你信任 Claude 的方向,想提高速度
  • 进行大规模重构,涉及大量文件变更
  • 想在编辑器中或事后通过 git diff 审查变更

风险提示:你会看到变更实时发生,但不会在每个变更前审查。保持关注,如果感觉不对,按 Ctrl+C 停止。

3.4 Plan Mode:先规划后执行

Shift+Tab 两次切换到该模式。状态栏显示 ⏸ plan mode on。Claude 只能读取和分析,不能修改文件或执行命令。

工作流程

[你] /plan 帮我设计一个用户认证模块的重构方案

[Claude] 【Plan Mode】我将分析现有代码并制定计划...

1. 读取 src/auth/ 目录下的所有文件
2. 分析当前认证流程
3. 识别问题和改进点
4. 制定详细重构计划

【计划完成】

我发现了以下问题:
- token 刷新逻辑存在竞态条件
- 密码哈希使用了过时的算法
- 缺少 rate limiting

建议的重构步骤:
1. 提取 token 管理到独立模块
2. 升级密码哈希到 bcrypt
3. 添加 express-rate-limit

你可以选择:
- 批准并以 Auto 模式执行
- 批准并以 Accept Edits 模式执行
- 批准并逐一手动审查每个修改
- 继续完善计划

适用场景

  • 任务涉及多个文件,想先了解全貌
  • 在不熟悉的代码库中工作
  • 任何你想"先看地图再出发"的场景

实用技巧:当 Claude 展示计划时,你可以按 Ctrl+G 在文本编辑器中打开计划,添加注释、划掉不需要的项目,然后返回 Claude 告诉它你的调整。

3.5 Auto Mode:智能自动批准

Auto Mode 是 Anthropic 于 2026 年 3 月推出的新功能。它使用一个独立的分类器模型(基于 Sonnet 4.6)实时评估每个操作的风险,自动批准安全操作,拦截危险操作。

使用条件(需全部满足):

  • 订阅计划:Max、Team、Enterprise 或 API。Pro 不可用
  • 管理员权限:Team 和 Enterprise 需管理员在设置中启用
  • 模型要求:Claude Sonnet 4.6、Opus 4.6 或 Opus 4.7
  • 提供商:仅限 Anthropic API,Bedrock/Vertex/Foundry 不支持

分类器的三层决策

  1. 第一层:内置安全工具白名单 + 用户设置
    • 只读工具(文件读取、搜索等)直接通过
    • 用户配置的 always-allow 规则直接通过
    • 进入 Auto Mode 时,会丢弃已知可任意执行代码的权限规则(如 blanket shell 访问、通配脚本解释器)
  2. 第二层:项目内文件操作
    • 工作目录内的文件写入和编辑直接通过
    • 无需分类器判断,因为可通过版本控制审查
  3. 第三层:转录分类器
    • Shell 命令、网络请求、外部工具调用等进入分类器
    • 第一阶段:快速单 token 过滤(是/否),偏向拦截
    • 第二阶段:对标记的操作进行思维链推理,减少误报

默认拦截的行为

  • 下载并执行代码(如 curl | bash
  • 向外部端点发送敏感数据
  • 生产环境部署和迁移
  • 云存储大规模删除
  • 授予 IAM 或仓库权限
  • 修改共享基础设施
  • 不可逆地销毁会话前已存在的文件
  • 强制推送或直接推送到 main

默认允许的行为

  • 工作目录内的本地文件操作
  • 安装 lock 文件或清单中已声明的依赖
  • 读取 .env 并发送凭证到匹配的 API
  • 只读 HTTP 请求
  • 推送到会话开始的分支或 Claude 创建的分支

安全回退机制

  • 连续 3 次或累计 20 次被拦截后,Auto Mode 暂停并恢复手动提示
  • 被拦截的操作显示通知,可在 /permissions 的"Recently denied"标签页中按 r 重试

3.6 Bypass Permissions 模式:无护栏(危险)

通过 --dangerously-skip-permissions--permission-mode bypassPermissions 启动。跳过所有权限提示,工具调用立即执行。仅受保护路径的写入仍会提示。

警告:仅在隔离环境(容器、VM、devcontainer)中使用。不要在主开发机器上用于交互式工作。

3.7 切换模式的快捷方式

操作方式
会话中切换Shift+Tab 循环切换
启动时指定claude --permission-mode plan
持久化默认设置settings.json 中设置 permissions.defaultMode
// ~/.claude/settings.json
{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}

4. 如何审查 Claude 提出的修改

4.1 diff 阅读技巧

技巧一:关注变更的"意图"而非"语法"

不要逐行阅读每个字符的变化,而是问自己:

  • 这个修改是否实现了我的需求?
  • 是否引入了不必要的变更?
  • 是否符合项目的代码风格?

技巧二:识别风险信号

以下 diff 模式应引起警惕:

- import { safeFunction } from './utils';
+ import { safeFunction, dangerousFunction } from './utils';
- const API_KEY = process.env.API_KEY;
+ const API_KEY = "hardcoded-key-12345";  // 危险!硬编码密钥
- rm -rf ./temp/
+ rm -rf /  // 极度危险!删除根目录

技巧三:检查上下文完整性

确保 Claude 的修改没有破坏周围的代码结构:

  function processData(data) {
    if (!data) return null;
    
-   // 原有逻辑被删除了吗?
+   // 新逻辑是否正确衔接?
+   const result = newLogic(data);
+   return result;
  }

4.2 风险评估 checklist

在批准修改前,快速检查以下项目:

  • 范围:修改是否仅限于我要求的范围?有没有"顺手"修改了不相关的代码?
  • 删除:是否有我不期望的删除操作?被删除的代码是否在其他地方被依赖?
  • 依赖:新增代码是否引入了新的依赖?这些依赖是否可靠?
  • 副作用:修改是否会影响其他模块或功能?
  • 安全:是否有硬编码的密钥、密码或敏感信息?
  • 测试:修改是否破坏了现有测试?是否需要新增测试?

4.3 使用 VS Code 进行可视化 diff 审查

如果你在 VS Code 中使用 Claude Code 扩展,每个文件修改都会在编辑器中以独立的 diff 标签页展示。对于涉及十几个文件的重构,在编辑器中逐个查看比终端中阅读要高效得多。

快捷键

  • d:查看 diff
  • e:在编辑器中打开文件
  • y:接受修改
  • n:拒绝修改

5. 常见的第一代码变更场景

5.1 场景一:添加新函数

请求

在 src/utils.js 中添加一个防抖函数 debounce

Claude 的思考过程

  1. 读取 src/utils.js 确认文件存在
  2. 检查是否已有同名函数
  3. 确定插入位置(通常放在相关函数附近或文件末尾)
  4. 遵循现有代码风格(ES modules vs CommonJS、JSDoc 注释习惯等)
  5. 生成修改并展示 diff

你的审查重点

  • 函数签名是否符合项目约定
  • 是否有 JSDoc 注释
  • 边界条件处理(如 delay 为负数的情况)
  • 是否导出了函数

5.2 场景二:修复 Bug

请求

修复 src/calculator.js 中除零错误

Claude 的思考过程

  1. 读取 src/calculator.js 定位除法相关代码
  2. 识别所有可能的除零场景
  3. 确定修复策略(返回 Infinity?抛出错误?返回 0?)
  4. 检查是否有相关测试需要更新
  5. 生成修改

你的审查重点

  • 修复是否覆盖了所有除零场景
  • 错误处理方式是否符合项目约定
  • 是否引入了新的问题
  • 测试是否同步更新

5.3 场景三:重构代码

请求

将 src/components/Button.js 中的内联样式提取为 CSS 模块

Claude 的思考过程

  1. 读取 src/components/Button.js 识别所有内联样式
  2. 检查项目是否已使用 CSS 模块
  3. 创建新的 .module.css 文件
  4. 修改组件文件导入样式
  5. 确保类名映射正确

你的审查重点

  • 样式提取是否完整
  • 类名命名是否符合 BEM 或其他约定
  • 是否破坏了组件的可复用性
  • 是否有样式冲突

6. 撤销与回滚:Checkpoint 机制

6.1 Checkpoint 工作原理

Claude Code 在每次编辑文件前自动创建文件快照。这是你的"安全网"——如果出了问题,可以随时回滚。

关键特性

  • 每次用户提示创建一个新的 checkpoint
  • Checkpoint 在会话间持久化,恢复会话后仍可访问
  • 默认 30 天后自动清理(可配置)
  • 最多保留 100 个快照,超出时淘汰最早的

存储位置~/.claude/file-history/{sessionId}/

6.2 使用 /rewind 回滚

输入 /rewind(或按 Esc 两次)打开回滚菜单:

[你] /rewind

[Claude] 选择要回滚到的消息:

  > 1. 添加 calculateAverage 函数(修改了 1 个文件,+12 行)
    2. 修复除零错误(修改了 1 个文件,+3/-1 行)
    3. 重构 Button 组件(修改了 2 个文件,+25/-18 行)

  选择后,你可以选择回滚方式:
  - 恢复代码和对话
  - 仅恢复对话
  - 仅恢复代码
  - 从此处开始总结

四种回滚方式

方式代码对话适用场景
恢复代码和对话回滚回滚Claude 完全走偏了,想从头再来
仅恢复对话保持回滚代码是对的,但后续讨论跑偏了
仅恢复代码回滚保持想保留分析上下文,但撤销代码变更
从此处总结不变压缩上下文窗口满了,需要释放空间

6.3 Checkpoint 的局限性

重要限制:Checkpoint 不追踪以下变更:

  • Bash 命令修改的文件(如 rm file.txtsed -i
  • 你手动编辑的文件
  • 其他并发会话的修改

规则:只有 Claude 通过内置的 FileEditTool 和 FileWriteTool 进行的文件操作才会被追踪和可回滚。

6.4 Git 作为最终安全网

Checkpoint 是"会话级撤销",Git 是"永久历史"。最佳实践:

# 在进行大规模修改前,先提交当前状态
git add .
git commit -m "checkpoint: 重构前的稳定状态"

# 然后让 Claude 进行重构
# 如果结果不满意:
git reset --hard HEAD  # 回到提交前的状态

6.5 禁用 Checkpoint

如果你出于性能或隐私考虑想禁用:

export CLAUDE_CODE_DISABLE_FILE_CHECKPOINTING=1

或在全局配置中设置 fileCheckpointingEnabled: false

7. 安全最佳实践

7.1 何时批准、何时拒绝

应该批准的情况

  • 修改范围明确,diff 清晰可读
  • 符合项目代码风格和约定
  • 没有意外的删除或变更
  • 边界条件处理得当

应该拒绝的情况

  • 修改范围超出你的请求("顺手"修改了不相关的文件)
  • 包含你不理解的变更
  • 删除了你没有要求删除的代码
  • 引入了硬编码的敏感信息
  • 使用了你不熟悉的依赖或 API

应该暂停并询问的情况

  • Claude 建议运行你不熟悉的命令
  • 修改涉及数据库、生产环境或敏感配置
  • diff 太大,无法在一次审查中理解全部内容

7.2 配置安全级别

新手配置(最严格):

// .claude/settings.json
{
  "permissions": {
    "defaultMode": "default",
    "deny": [
      "Bash(git push *)",
      "Bash(rm -rf *)",
      "Read(**/.env)",
      "Read(**/secrets.*)"
    ]
  }
}

日常开发配置(平衡):

// .claude/settings.json
{
  "permissions": {
    "defaultMode": "acceptEdits",
    "allow": [
      "Bash(npm run *)",
      "Bash(git status)",
      "Bash(git diff *)"
    ],
    "deny": [
      "Bash(git push *)",
      "Bash(docker *)",
      "Read(**/.env)"
    ]
  }
}

7.3 权限规则优先级

规则按以下顺序评估:deny > ask > allow。第一个匹配的规则生效。

{
  "permissions": {
    "allow": ["Bash"],
    "deny": ["Bash(touch *)"]
  }
}
// touch 命令仍被拒绝,因为 deny 优先

7.4 团队安全

  • 使用 managed settings 强制执行组织标准
  • 通过版本控制共享批准的权限配置
  • 定期用 /permissions 审查权限设置
  • 在共享环境或受监管工作场所使用 DontAsk 模式配合精心定义的白名单

7.5 防范提示注入

提示注入是一种攻击技术,攻击者通过在文件、网页或工具输出中插入恶意文本来操纵 AI 助手。Claude Code 包含以下防护:

  • 权限系统:敏感操作需要显式批准
  • 上下文感知分析:通过分析完整请求检测潜在有害指令
  • 输入清理:处理用户输入以防止命令注入
  • 命令黑名单:默认阻止 curlwget 等从网络获取任意内容的命令
  • 网络请求批准:默认需要用户批准
  • 隔离上下文窗口:WebFetch 使用单独的上下文窗口

最佳实践

  1. 批准前审查建议的命令
  2. 避免将不受信任的内容直接管道传输给 Claude
  3. 验证对关键文件的提议变更
  4. 使用虚拟机运行脚本和工具调用
  5. 发现可疑行为时用 /feedback 报告

8. 总结

Claude Code 的"修改前请求许可"机制不是障碍,而是保护。它确保你始终掌握代码库的主动权,同时享受 AI 辅助编程的效率。

核心要点回顾

  1. Default 模式是新手最好的朋友——每个修改都经过你的审查
  2. Accept Edits 模式适合信任的迭代场景——提高速度但不放弃安全
  3. Plan Mode是复杂任务的必备——先看地图再出发
  4. Auto Mode是高级用户的效率工具——智能分类器在后台守护
  5. Checkpoint是你的后悔药——/rewind 随时回滚
  6. Git是最终安全网——重要修改前先提交

随着你对 Claude Code 的信任逐渐建立,可以从 Default 模式逐步过渡到更宽松的模式。但记住 Anthropic 的忠告:

"权限系统不是不信任 Claude——而是让你始终坐在驾驶座上。Claude 非常能干,而这种能力应该始终在你的控制之下。"

选择匹配你信心和上下文的模式。不确定时,保守一点。建立信任后,再放松。并且永远记住:Ctrl+C 就在手边,随时可以停止。

参考来源