第 09 期 | 精准的 Prompt Scoping(作用域边界控制)
🎯 学习目标
学完本期你将掌握:
- 为什么 Claude 有时会"越界"修改不相关的代码
- 如何通过文件路径、目录限定来约束修改范围
- Subagent 作用域隔离的进阶用法
--allowedTools/--disallowedTools的精确控制
📖 核心概念讲解
9.1 问题:Claude 为什么会"越界"?
当你说"修复这个 bug",Claude 可能:
- ✅ 修改了目标文件 ← 期望行为
- ❌ 顺手"优化"了其他无关文件 ← 越界
- ❌ 重构了你没提到的模块 ← 过度自信
这是因为 Claude 默认拥有对整个项目的读写权限。没有明确的边界指令时,它可能"好心办坏事"。
9.2 Scoping 三层控制法
┌─ Layer 1: Prompt 级别 ─────────────────────────┐
│ "只修改 src/auth/login.ts,不要动其他文件" │
│ → 最简单,适合一次性指令 │
├─ Layer 2: Settings 级别 ──────────────────────── │
│ .claude/settings.json → permissions.deny │
│ → 持久化保护,适合团队共享 │
├─ Layer 3: CLI 级别 ───────────────────────────── │
│ --allowedTools "Read" "Edit(src/auth/**)" │
│ → 启动时限定,适合脚本化 │
└──────────────────────────────────────────────────┘
💻 模拟 Claude TUI 交互
场景 1:未限定作用域 — Claude 越界
> 修复用户登录时密码验证的 bug
╭─ Claude ─────────────────────────────────────────────╮
│ │
│ 🔍 Tool: Grep ("password" across src/**) │
│ 🔍 Tool: Read (src/auth/login.ts) │
│ 🔍 Tool: Read (src/auth/register.ts) │
│ 🔍 Tool: Read (src/utils/validation.ts) │
│ │
│ 找到了 bug!密码比对时缺少 await。 │
│ │
│ ⚙️ Tool: Edit → src/auth/login.ts │
│ ╭─ DIFF ─────────────────────────────────────╮ │
│ │ - if (bcrypt.compare(password, user.hash)) │ │
│ │ + if (await bcrypt.compare(password, │ │
│ │ + user.hash)) │ │
│ ╰─────────────────────────────────────────────╯ │
│ ✅ 这是正确的修复! │
│ │
│ ⚙️ Tool: Edit → src/utils/validation.ts │
│ ╭─ DIFF ─────────────────────────────────────╮ │
│ │ - // TODO: add password strength check │ │
│ │ + export function checkPasswordStrength( │ │
│ │ + password: string): PasswordStrength { │ │
│ │ + // ... 40 行新代码 ... │ │
│ │ + } │ │
│ ╰─────────────────────────────────────────────╯ │
│ ⚠️ 这个修改超出了你的请求范围! │
│ │
│ ⚙️ Tool: Edit → src/auth/register.ts │
│ ╭─ DIFF ─────────────────────────────────────╮ │
│ │ + import { checkPasswordStrength } │ │
│ │ + from '../utils/validation'; │ │
│ │ + // 注册时检查密码强度 │ │
│ │ + if (checkPasswordStrength(pw) │ │
│ │ + === 'weak') { ... } │ │
│ ╰─────────────────────────────────────────────╯ │
│ ⚠️ 又改了一个文件! │
│ │
╰──────────────────────────────────────────────────────╯
场景 2:精确限定作用域 — 只动目标文件
> 修复 src/auth/login.ts 中密码验证的 bug。
只修改这一个文件,不要触碰其他任何文件。
╭─ Claude ─────────────────────────────────────────────╮
│ │
│ 🔍 Tool: Read (src/auth/login.ts) │
│ │
│ 找到问题:第 34 行 bcrypt.compare 缺少 await。 │
│ │
│ ⚙️ Tool: Edit → src/auth/login.ts │
│ ╭─ DIFF ─────────────────────────────────────╮ │
│ │ - if (bcrypt.compare(password, user.hash)) │ │
│ │ + if (await bcrypt.compare(password, │ │
│ │ + user.hash)) │ │
│ ╰─────────────────────────────────────────────╯ │
│ │
│ ✅ 修复完成。只修改了 src/auth/login.ts。 │
│ │
│ 💡 另外我注意到 validation.ts 中有一个 │
│ TODO 关于密码强度检查,要不要我另起一个 │
│ 会话来处理? │
│ │
╰──────────────────────────────────────────────────────╯
💻 代码演示:CLI 级别的精确控制
# 只允许读取和编辑 src/auth/ 目录
claude --allowedTools "Read" "Glob" "Grep" "Edit(src/auth/**)"
# 禁止执行任何 bash 命令(纯编辑模式)
claude --disallowedTools "Bash"
# 限制工具 + 限制轮次(CI/CD 中的安全运行)
claude -p \
--allowedTools "Read" "Glob" "Grep" \
--max-turns 5 \
"审查 src/payment/ 目录的安全性"
# 只允许执行特定 bash 命令
claude --allowedTools \
"Read" "Glob" "Grep" \
"Bash(npm test *)" \
"Bash(npm run lint)"
Settings 文件级别的保护
// .claude/settings.json — 项目级
{
"permissions": {
"deny": [
"Write(.env*)",
"Edit(.env*)",
"Write(prisma/migrations/**)",
"Edit(prisma/migrations/**)",
"Bash(rm -rf *)",
"Bash(DROP *)",
"Bash(sudo *)"
]
}
}
💡 Prompt Scoping 技巧速查
❌ 模糊指令(容易越界):
"修复登录 bug"
"优化性能"
"添加错误处理"
✅ 精确指令(作用域明确):
"修复 src/auth/login.ts 第 34 行的 bcrypt.compare 缺少 await"
"只优化 src/api/search.ts 的数据库查询性能,不改其他文件"
"给 src/routes/payment.ts 的 createOrder 函数添加 try-catch"
🔧 涉及的 CLI Flags
| Flag | 作用 | 示例 |
|---|---|---|
--allowedTools |
白名单限制可用工具 | "Read" "Edit(src/**)" |
--disallowedTools |
黑名单禁用工具 | "Bash" "Write" |
--max-turns |
限制最大执行轮次 | --max-turns 3 |
--add-dir |
添加额外目录访问 | --add-dir ../shared |
📝 本期要点回顾
- Claude 默认对整个项目有读写权限,需要 主动限制作用域
- Prompt 级别:直接在指令中说明"只修改 X 文件"
- Settings 级别:用
permissions.deny保护敏感文件 - CLI 级别:用
--allowedTools做白名单限制 - 好 Prompt 的核心:具体文件名 + 具体行为 + 明确边界