首页 › tutorials › 构建只读沙箱的变更影响面技能

本教程面向已跑通首个 Claude Code 项目、想系统掌握自定义 Skill 开发的工程师。学完后你将独立构建一个只读、可复用、带内置规则库的"代码变更影响面分析 Skill",并真正理解 allowed-tools 沙箱、model/effort 分级、${CLAUDE_SKILL_DIR} 资源定位与渐进式披露四项核心机制。


一、为什么要专门做一个"变更影响面分析"Skill

在日常开发里,最危险的往往不是写新代码,而是改一行老代码却不知道波及了谁。一次看似无害的重命名、一次签名调整、一次常量改动,可能悄悄打断了十公里外的调用方,而单元测试又恰好没覆盖到那条路径。

把"分析这次改动会影响什么"这件事固化成一个 Skill,而不是每次都靠人工提示词"祈祷",有三个工程价值:

  1. 可复用:团队成员输入 /blast-radius HEAD~1 即可得到一份结构化影响面报告,无需每人重写提示词。
  2. 可约束:通过 allowed-tools 把这个 Skill 关进只读笼子——它只能读、只能搜、只能跑只读 git 命令,绝不会误删或误改代码。分析类任务本就该只读。
  3. 可分级:通过 model + effort 给"读代码+追踪调用"这种中等难度任务匹配合适的算力,避免动辄用最贵模型烧钱。

本教程与"渐进式披露构建分层 Skill""触发优先"等已有主题不重叠——它的核心是把一个真实的高频开发痛点,用 Skill 的安全沙箱机制工程化解决,并顺带讲透几项官方文档里零散、社区里常被误用的 frontmatter 字段。


二、前置条件

项目 要求
Claude Code 版本 v2.1.154 或更高(支持当前 allowed-tools/effort 语义)
操作环境 已能正常启动 claude 交互会话
示例代码库 任意一个 git 仓库(有若干次提交、有 import/调用关系即可,Node 或 Python 项目最佳)
基础概念 知道 .claude/ 目录的作用,会读 YAML frontmatter

如果你还没有合适仓库,临时建一个:

mkdir demo-svc && cd demo-svc && git init -q
echo 'export function calcTax(base){ return base*0.13 }' > tax.js
echo 'import {calcTax} from "./tax.js"; export function checkout(items){ return items.reduce((s,i)=>s+calcTax(i.price),0) }' > cart.js
git add -A && git commit -qm "init demo service"

三、Skill 目录骨架

Claude Code 的 Skill 存放路径有三层,优先级从高到低:

我们做的是团队共享工具,放项目级。一个完整的 Skill 不只有一个文件,而是"瘦入口 + 胖参考库"的目录:

.claude/skills/blast-radius/
├── SKILL.md                       # 瘦入口:frontmatter + 何时用 + 工作流骨架
└── references/
    └── impact-heuristics.md       # 胖参考库:追踪启发式规则,按需加载

预期结果:目录创建好后,在 claude 会话里输入 / 应能看到 blast-radius 出现在补全列表中(前提是 disable-model-invocation 没开,且 description 非空)。

常见问题:


四、动手写 SKILL.md:四个关键字段

步骤 1:frontmatter 配置

---
name: blast-radius
description: 分析一次代码变更(git diff/commit 或指定文件)的影响面,列出受影响的文件、函数、调用方与回归测试。只读,绝不修改代码。当用户问"这次改动会影响什么/波及哪些模块/要不要补测试"时使用。
argument-hint: "[commit范围或文件路径,如 HEAD~1 / src/foo.js]"
allowed-tools: Read, Grep, Glob, Bash
model: sonnet
effort: medium
---

逐字段解释(这是本教程的核心知识):

① allowed-tools: Read, Grep, Glob, Bash —— 只读沙箱

这是整个 Skill 安全性的基石。它是一个白名单:Skill 处于激活状态时,模型只能调用这四个工具。

关键认知:allowed-tools 是 Skill 级别的收窄,不会扩大你在 settings.json 里的总权限。也就是说,即使你全局允许了 Edit,这个 Skill 在它生命周期内依然写不了文件——这正是我们想要的"最小权限原则"。

② model: sonnet —— 给中等任务配中等算力

模型别名的官方语义:sonnet 对应当前最新的 Sonnet(API 上即 Sonnet 4.6),适合日常编码任务。读代码、追调用链、写影响面报告这类任务,sonnet 的速度与成本远优于 opus,而质量足够。

何时改用 opus(最强推理,对应 Opus 4.8)?只有当你的代码库跨多语言、调用链极深、需要强逻辑推断时才值得。何时用 haiku?纯机械的"列出 diff 文件名"可降级,但影响面分析通常需要推理,不建议。

模型解析优先级(高→低):会话内指定 > Skill 的 model frontmatter > 主会话模型。所以 Skill 里写 model: sonnet 会覆盖主会话设置,专门为这个任务降档省钱。

③ effort: medium —— 推理深度旋钮

取值 low|medium|high|max(max 仅 Opus 可用)。medium 让模型在"够用"的思考预算内完成,避免对每个调用关系都做 max 级深挖。这是除 model 之外第二根成本杠杆。

④ argument-hint —— 补全友好性

斜杠补全时会显示 /blast-radius [commit范围或文件路径],让调用者一眼知道该传什么。配合正文里的 $ARGUMENTS 接收参数。

预期结果:保存后,/blast-radius 在补全里带有参数提示;调用 /blast-radius HEAD~1 时,$ARGUMENTS 即为字符串 HEAD~1。

常见问题:


步骤 2:写正文——瘦入口与资源定位

SKILL.md 正文应保持精炼(建议 500 行以内),它每次激活都会被读进上下文,所以越短越省 token。详细规则下沉到 bundled 参考文件。

# 变更影响面分析(Blast Radius)

## 何时使用
用户给出一次改动(git 范围、commit、文件路径),想知道它会波及哪些模块、
哪些函数、哪些测试可能回归。本技能**只读**,绝不修改任何代码。

## 输入
- `$ARGUMENTS`:commit 范围(如 `HEAD~1`、`main..feature`)或文件路径。
- 若 `$ARGUMENTS` 为空,先用 `git diff --name-only` 列出工作区改动,
  再询问用户确认范围。

## 工作流
1. 用 Bash 跑 `git show --stat $ARGUMENTS` / `git diff $ARGUMENTS`,
   拿到**变更文件清单**与**变更行**。
2. 用 Read 读取每个变更文件,识别**被改动的符号**(函数、类、导出常量、类型)。
3. 用 Grep 反向追踪:对每个被改符号,搜索整个仓库的引用与调用方,
   构建"变更 → 直接依赖 → 间接依赖"两层波及图。
   详细追踪启发式见 `references/impact-heuristics.md`,务必先读它再追踪。
4. 用 Glob + Grep 定位**回归测试**:按 `*.test.*`/`*.spec.*`/`test_*` 模式,
   找到覆盖了被改符号或其调用方的测试文件,标记"已覆盖/未覆盖"。
5. 输出**结构化影响面报告**(见下文模板)。

## 报告模板
## 影响面报告:$ARGUMENTS
- 变更摘要:<文件数>个文件,<符号数>个符号
- 直接受影响:<文件:符号> 列表
- 间接波及:<调用链>
- 回归测试:已覆盖 N 个 / **缺口** M 个(标红)
- 风险评级:低/中/高(依据:是否有未覆盖测试 + 波及面大小)

## 资源定位
- 追踪规则库:`${CLAUDE_SKILL_DIR}/references/impact-heuristics.md`
- 资源定位符 `${CLAUDE_SKILL_DIR}` 在运行时展开为本 SKILL.md 所在目录的绝对路径,
  因此**写死路径或用相对路径都不可靠**——一律用 `${CLAUDE_SKILL_DIR}` 拼接。

两个要点:

动态变量 ${CLAUDE_SKILL_DIR}:运行时被替换为 Skill 目录绝对路径,是访问 bundled 文件的唯一可靠方式。此外还有 $ARGUMENTS(全部入参)、$N/$ARGUMENTS[N](第 N 个位置参数,0 基)、${CLAUDE_SESSION_ID}(当前会话 ID)可用。

渐进式披露:正文只写"做什么",把"怎么精确追踪调用方"这种大段细节放进 references/impact-heuristics.md,并明确指示"务必先读它再追踪"。这样 99% 的简短分析只需瘦入口进上下文,复杂分析才加载胖参考库,token 消耗随难度自适应。

预期结果:调用 /blast-radius HEAD~1,模型会先读 references/impact-heuristics.md,再执行五步工作流。

常见问题:


五、写 bundled 参考库:把"专家经验"固化

在 .claude/skills/blast-radius/references/impact-heuristics.md 写入追踪启发式。这是整个 Skill 的"大脑"——它把"高级工程师如何判断影响面"的经验编码下来:

# 影响面追踪启发式

## 1. 识别被改符号(按语言)
- JS/TS:`export (function|const|class)`、`function name(`、`class Name`
- Python:`^def name`、`^class Name`、模块级赋值(可能是常量/配置)
- 提取符号名后,进入第 2 步用 Grep 反查。

## 2. 反向追踪调用方(两层)
- 第一层(直接):`grep -rn "符号名"` 找到所有引用点。
- 第二层(间接):对第一层结果中的函数,再 `grep` 其函数名,
  判断是否被更上层调用。**通常两层足够**,更深需人工判断。
- 注意区分**定义点**与**引用点**:用 `def|function|class` 前缀排除定义。

## 3. 测试覆盖判定
- 用 Glob 找 `**/*.test.{js,ts}`、`**/*.spec.{js,ts}`、`**/test_*.py`、`**/*_test.go`。
- 对每个测试文件 Grep 被改符号:命中=已覆盖,未命中=缺口。
- **缺口处的调用方**是最高风险点,优先在报告中标红。

## 4. 风险评级规则
- 高:被改符号是公共 API/导出,且存在未覆盖测试的调用方。
- 中:被改符号有内部调用方,测试基本覆盖。
- 低:仅私有实现改动,且测试全覆盖。

设计哲学:把易变的"规则"与稳定的"流程"分离。SKILL.md 的五步工作流很少变,而追踪规则会随团队语言栈演进——分文件后,更新规则不必动入口文件,版本可追溯。


六、可选进阶:用 context: fork 做隔离分析

当仓库巨大、分析耗时较长,你不想让大段 grep 结果污染主对话上下文时,可在 frontmatter 加两行:

context: fork        # 在隔离的子智能体上下文里运行
agent: Explore       # 复用 Explore(只读搜索)子代理类型

context: fork 让 Skill 在一个独立子智能体里执行,结束后只把最终报告返回主会话——中间成百上千行 grep 输出不占用主上下文窗口。配合 agent: Explore(只读搜索专用子代理),既隔离又复用现成的搜索型系统提示。

注意:fork 模式下子智能体无法写文件、无法推进主会话状态,纯产出文本。这对"只读分析报告"场景是完美匹配,但对需要落盘改文件的任务则不适用——本教程的影响面分析正好契合。


七、端到端实战:跑通一次真实分析

在你的 demo-svc 里制造一次"危险改动":

# 故意改动一个被多处依赖的公共函数签名
cat > tax.js <<'EOF'
export function calcTax(base, region = 'CN'){ return base * (region==='CN' ? 0.13 : 0.0) }
EOF
git add -A && git commit -qm "tax: support multi-region"

现在在 claude 会话里:

/blast-radius HEAD~1

预期输出(影响面报告,节选):

## 影响面报告:HEAD~1
- 变更摘要:1 个文件,1 个符号(calcTax)
- 变更内容:calcTax 签名新增可选参数 region,逻辑变更
- 直接受影响:cart.js:checkout —— 调用 calcTax(i.price),签名兼容(可选参数)
- 间接波及:任何调用 checkout 的上层(本次仓库内无)
- 回归测试:仓库内无 *.test.* 文件 —— **测试缺口:checkout 未被覆盖**
- 风险评级:中(签名向后兼容,但关键路径无测试保护)
- 建议:为 checkout 补单测,覆盖多 region 税率场景

注意模型全程只用 Read/Grep/Glob/Bash,没有尝试"顺手帮你改代码或建测试文件"——这就是 allowed-tools 沙箱在起作用。它给出了判断与建议,但把"要不要补测试、怎么补"的决定权交还给你。

常见问题:


八、整体工作流架构

flowchart TD
    A["用户: /blast-radius HEAD~1"] --> B["激活 Skill"]
    B --> C{"allowed-tools 沙箱生效\n只读: Read/Grep/Glob/Bash"}
    C --> D["Bash: git diff 拿变更文件与行"]
    D --> E["Read: 读取变更文件\n识别被改符号"]
    E --> F["加载 references/impact-heuristics.md\n按需: 渐进式披露"]
    F --> G["Grep: 反向追踪调用方\n两层波及图"]
    G --> H["Glob+Grep: 定位回归测试\n标记覆盖/缺口"]
    H --> I["输出结构化影响面报告\n风险评级"]
    I --> J{"context: fork?"}
    J -- 是 --> K["仅报告回传主会话\n中间结果隔离"]
    J -- 否 --> L["直接呈现在主会话"]
    K --> M["用户决策: 是否补测试/回滚"]
    L --> M
    style C fill:#ffe4e1,stroke:#c44
    style F fill:#e6f3ff,stroke:#36c

九、调试与迭代清单


十、延伸阅读


参考来源

  1. Claude Code Skill Frontmatter: Every YAML Option Explained — 15 个 frontmatter 字段逐一详解(含 allowed-tools/model/effort/context: fork)
  2. Claude Code Frontmatter Reference (GitHub) — 基于 code.claude.com 官方文档整理的 Skills/Agents/Commands frontmatter 与 $ARGUMENTS/${CLAUDE_SKILL_DIR} 变量速查
  3. Model configuration — Claude Code Docs — model 别名(sonnet/opus/haiku/best/fable)与 effort 取值的官方语义与解析优先级
  4. SKILL.md Frontmatter Reference — AgentPatterns.ai — allowed-tools 收窄语义、context: fork 隔离执行与 agent 子代理类型搭配
  5. Claude Code Permissions (2026) — Skill 级 allowed-tools 与全局权限/沙箱的边界关系

训练营适用性评估

掌握 allowed-tools 把 Skill 关进只读笼子、用 ${CLAUDE_SKILL_DIR} 定位内置资源、以 model/effort 调节算力,你便拥有了构建安全、可复用、成本可控的团队级 Skill 的全部基础。

[!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学通信知识星球海报-扫码加入