12.6 案例一:文档改写后的自动测试与风险拦截
面向经管学生、研究者与从业者的 AI 智能体设计教材

场景设定:你要让 Claude Code 批量改写项目里的 Markdown 文档,统一结构和语言风格,同时保持链接、标题层级和引用格式不被破坏。
如果只靠提示词提醒——“不要改到允许目录之外”“改完检查格式和链接”——仍可能漏掉。于是把它拆成两个 Hook。
写前拦截:PreToolUse 做路径与命令拦截
当 Claude Code 准备执行 Write、Edit 或 Bash 命令时,PreToolUse 先检查目标路径和操作类型:是否写到了允许目录之外、是否出现高风险命令、是否违反当前任务边界。如果检测到违规,立刻阻断操作并把原因回灌给当前会话。
在 .claude/settings.json 中配置:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit|Bash",
"hooks": [
{
"type": "command",
"command": "bash scripts/check_path_safety.sh"
}
]
}
]
}
}scripts/check_path_safety.sh 的核心逻辑是解析工具输入中的目标路径,检查是否落在允许范围内:
#!/usr/bin/env bash
# check_path_safety.sh — 拦截越界写入和高风险命令
ALLOWED_DIRS=("docs/" "content/" "outputs/")
BLOCKED_CMDS=("rm -rf" "sudo" "chmod 777")
INPUT="$CLAUDE_TOOL_INPUT"
for cmd in "${BLOCKED_CMDS[@]}"; do
if echo "$INPUT" | grep -q "$cmd"; then
echo "BLOCKED: 检测到高风险命令 '$cmd'" >&2
exit 2
fi
done
TARGET_PATH=$(echo "$INPUT" | sed -n 's/.*"file_path" *: *"\([^"]*\)".*/\1/p')
if [ -n "$TARGET_PATH" ]; then
ALLOWED=false
for dir in "${ALLOWED_DIRS[@]}"; do
if [[ "$TARGET_PATH" == "$dir"* ]]; then
ALLOWED=true
break
fi
done
if [ "$ALLOWED" = false ]; then
echo "BLOCKED: 路径 '$TARGET_PATH' 不在允许目录内" >&2
exit 2
fi
fi
写后检查:PostToolUse 做文档格式验证
如果写入顺利执行,PostToolUse 立刻触发文档检查脚本——检查标题层级是否跳跃、相对链接是否失效、是否引入格式错误。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash scripts/check_doc_format.sh"
}
]
}
]
}
}写后检查不阻断流程,而是把问题回灌给模型,由模型决定是否修补。重点不是检查脚本多复杂,而是它在正确的时间点稳定触发。
四类机制的配合
| 机制 | 在本案例中的角色 |
|---|---|
| 提示层约束 | 说明改写目标、风格、禁改范围 |
| Skill | 组织”读取素材 -> 重组结构 -> 改写正文”的流程 |
| Hooks | 在写前拦截风险,在写后自动检查 |
| 测试闭环 | 根据检查结果决定是否进入修订 |
案例启发
判断一个 Hook 是否合格,看它有没有同时满足三点:触发点明确、责任单一、输出能立刻被当前工作流消费。