第一次代码变更
当你第一次让 Claude 修改代码时,你会看到一个独特的交互画面:Claude 不会直接写入文件,而是先展示一份 diff,然后停下来问你"是否批准"。这个看似简单的停顿,正是 Claude Code 安全架构的核心设计——人类在环(Human-in-the-Loop)。
本章将带你完整体验从提出需求到确认修改的全过程,深入理解 Claude Code 的权限模型,并掌握审查修改、撤销变更的实用技巧。
1. 第一次代码变更的完整流程
1.1 发起请求
在 Claude Code 中输入你的第一个代码修改请求。建议从简单、低风险的任务开始:
在 src/utils.js 中添加一个计算数组平均值的函数 calculateAverage
Claude 会立即开始工作,经历以下阶段:
- 读取文件:Claude 先读取
src/utils.js的当前内容,了解现有代码风格和结构 - 分析上下文:检查是否有同名函数、确认导出方式、判断最佳插入位置
- 生成修改方案:在脑中构建具体的代码变更
- 展示 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 会确认文件已更新。此时你应该:
- 查看文件:用
cat src/utils.js或编辑器确认修改内容 - 运行测试:如果有相关测试,让 Claude 运行验证
- 检查副作用:确认修改没有破坏其他功能
[你] 运行相关测试验证这个函数
[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 命令前询问。
额外自动批准的命令:mkdir、touch、rm、rmdir、mv、cp、sed(限于工作目录内)。
适用场景:
- 你信任 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 不支持
分类器的三层决策:
- 第一层:内置安全工具白名单 + 用户设置
- 只读工具(文件读取、搜索等)直接通过
- 用户配置的 always-allow 规则直接通过
- 进入 Auto Mode 时,会丢弃已知可任意执行代码的权限规则(如 blanket shell 访问、通配脚本解释器)
- 第二层:项目内文件操作
- 工作目录内的文件写入和编辑直接通过
- 无需分类器判断,因为可通过版本控制审查
- 第三层:转录分类器
- 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:查看 diffe:在编辑器中打开文件y:接受修改n:拒绝修改
5. 常见的第一代码变更场景
5.1 场景一:添加新函数
请求:
在 src/utils.js 中添加一个防抖函数 debounce
Claude 的思考过程:
- 读取
src/utils.js确认文件存在 - 检查是否已有同名函数
- 确定插入位置(通常放在相关函数附近或文件末尾)
- 遵循现有代码风格(ES modules vs CommonJS、JSDoc 注释习惯等)
- 生成修改并展示 diff
你的审查重点:
- 函数签名是否符合项目约定
- 是否有 JSDoc 注释
- 边界条件处理(如 delay 为负数的情况)
- 是否导出了函数
5.2 场景二:修复 Bug
请求:
修复 src/calculator.js 中除零错误
Claude 的思考过程:
- 读取
src/calculator.js定位除法相关代码 - 识别所有可能的除零场景
- 确定修复策略(返回 Infinity?抛出错误?返回 0?)
- 检查是否有相关测试需要更新
- 生成修改
你的审查重点:
- 修复是否覆盖了所有除零场景
- 错误处理方式是否符合项目约定
- 是否引入了新的问题
- 测试是否同步更新
5.3 场景三:重构代码
请求:
将 src/components/Button.js 中的内联样式提取为 CSS 模块
Claude 的思考过程:
- 读取
src/components/Button.js识别所有内联样式 - 检查项目是否已使用 CSS 模块
- 创建新的
.module.css文件 - 修改组件文件导入样式
- 确保类名映射正确
你的审查重点:
- 样式提取是否完整
- 类名命名是否符合 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.txt、sed -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 包含以下防护:
- 权限系统:敏感操作需要显式批准
- 上下文感知分析:通过分析完整请求检测潜在有害指令
- 输入清理:处理用户输入以防止命令注入
- 命令黑名单:默认阻止
curl、wget等从网络获取任意内容的命令 - 网络请求批准:默认需要用户批准
- 隔离上下文窗口:WebFetch 使用单独的上下文窗口
最佳实践:
- 批准前审查建议的命令
- 避免将不受信任的内容直接管道传输给 Claude
- 验证对关键文件的提议变更
- 使用虚拟机运行脚本和工具调用
- 发现可疑行为时用
/feedback报告
8. 总结
Claude Code 的"修改前请求许可"机制不是障碍,而是保护。它确保你始终掌握代码库的主动权,同时享受 AI 辅助编程的效率。
核心要点回顾:
- Default 模式是新手最好的朋友——每个修改都经过你的审查
- Accept Edits 模式适合信任的迭代场景——提高速度但不放弃安全
- Plan Mode是复杂任务的必备——先看地图再出发
- Auto Mode是高级用户的效率工具——智能分类器在后台守护
- Checkpoint是你的后悔药——
/rewind随时回滚 - Git是最终安全网——重要修改前先提交
随着你对 Claude Code 的信任逐渐建立,可以从 Default 模式逐步过渡到更宽松的模式。但记住 Anthropic 的忠告:
"权限系统不是不信任 Claude——而是让你始终坐在驾驶座上。Claude 非常能干,而这种能力应该始终在你的控制之下。"
选择匹配你信心和上下文的模式。不确定时,保守一点。建立信任后,再放松。并且永远记住:Ctrl+C 就在手边,随时可以停止。
参考来源
- Claude Code 官方文档 - 权限模式
- Claude Code 官方文档 - 配置权限
- Claude Code 官方文档 - Checkpointing
- Claude Code 官方文档 - 安全
- Claude Code 官方文档 - 工作原理
- Anthropic 工程博客 - Claude Code Auto Mode
- Claude Code Handbook - 权限模式
- Pete Freitag - Claude Code 权限深度解析
- Vincent Qiao - Claude Code /rewind 详解
- Builder.io - Claude Code 初学者指南
- ClaudeFast - Diff 审查快捷键