外观
生产安全规则
目标读者:在生产环境中部署 Claude Code 的团队。独立学习者:请参见入门指南。
速览(30 秒)
生产团队的 6 条不可妥协规则:
- ✅ 端口稳定:绝不更改后端/前端端口
- ✅ 数据库安全:破坏性操作前始终备份
- ✅ 功能完整:绝不发布半成品功能
- ✅ 基础设施锁定:Docker/env 变更需要授权
- ✅ 依赖安全:新依赖需获批准
- ✅ 遵循模式:符合现有代码库规范
何时使用这些规则
| 项目类型 | 使用这些规则? | 原因 |
|---|---|---|
| 学习/教程 | ❌ 否 | 对探索过于限制 |
| 个人原型 | ❌ 否 | 额外开销不值得 |
| 小型团队(2-3 人),测试环境 | ⚠️ 部分 | 仅规则 1、3、6 |
| 生产应用、多开发者团队 | ✅ 是 | 全部 6 条规则 |
| 受监管行业(HIPAA、SOC2) | ✅ 是 + 添加合规规则 | 关键安全 |
规则 1:端口稳定
问题所在
更改端口会破坏:
- 本地开发环境
- Docker Compose 配置
- 已部署服务配置
- 团队成员的设置
真实事故:重构时后端端口从 3000 改为 8080。所有开发者花了一天时间重新配置本地环境。测试环境部署静默失败,因为 nginx 代理仍指向 3000。
规则
未经团队明确许可,绝不修改后端/前端端口。
实现方式
方式 A:在 settings.json 中拒绝权限
JSON
{
"permissions": {
"deny": [
"Edit(docker-compose.yml:*ports*)",
"Edit(package.json:*PORT*)",
"Edit(.env.example:*PORT*)",
"Edit(vite.config.ts:*port*)"
]
}
}方式 B:工具前钩子
Bash
# .claude/hooks/PreToolUse.sh
if [[ "$TOOL" == "Edit" ]]; then
FILE=$(echo "$INPUT" | jq -r '.tool.input.file_path')
CONTENT=$(echo "$INPUT" | jq -r '.tool.input.new_string')
if [[ "$FILE" =~ (docker-compose|vite.config|package.json) ]] && \
[[ "$CONTENT" =~ (port|PORT):[[:space:]]*[0-9] ]]; then
echo "⚠️ 已阻止:检测到 $FILE 中有端口修改"
echo "端口必须保持稳定以便团队协作。请先获得许可。"
exit 2
fi
fi方式 C:CLAUDE.md 约束
Markdown
## 端口配置
**重要**:端口已为团队协作而锁定。
当前端口:
- 前端(Vite):5173
- 后端(Express):3000
- 数据库:5432
更改端口需要:
1. 在 `/docs/rfcs/` 中创建 RFC 文档
2. 获得团队审批(3+ 名审查者)
3. 同时更新所有环境
4. 提前 48 小时通知团队边界情况
| 场景 | 处理方式 |
|---|---|
| 添加新服务 | 允许(不影响现有服务) |
| 更改测试环境端口 | 允许(与开发/生产隔离) |
| 机器上的端口冲突 | 要求用户本地解决(.env.local) |
规则 2:数据库安全
问题所在
生产环境意外删除 = 数据丢失。
真实事故:
DELETE FROM users WHERE id = 123→ 忘记WHERE→ 所有用户被删除- 清理时
DROP TABLE sessions→ 生产表被删除 - 迁移回滚 → 因无备份而丢失数据
规则
破坏性操作前始终备份。
破坏性操作包括:
DELETE FROM(不带LIMIT 1)DROP TABLETRUNCATEALTER TABLE ... DROP COLUMN- 无法回滚的数据库迁移
实现方式
方式 A:带备份强制的工具前钩子
Bash
# .claude/hooks/PreToolUse.sh
#!/bin/bash
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool.name')
if [[ "$TOOL" == "Bash" ]]; then
COMMAND=$(echo "$INPUT" | jq -r '.tool.input.command')
# 检测破坏性数据库操作
if [[ "$COMMAND" =~ (DROP TABLE|DELETE FROM|TRUNCATE|ALTER.*DROP) ]]; then
echo "🚨 已阻止:检测到破坏性数据库操作"
echo ""
echo "必要步骤:"
echo "1. 创建备份:pg_dump -U user dbname > backup_\$(date +%Y%m%d_%H%M%S).sql"
echo "2. 验证备份大小合理"
echo "3. 确认备份后重新运行"
exit 2
fi
fi
exit 0方式 B:迁移安全包装脚本
Bash
# scripts/safe-migrate.sh
#!/bin/bash
set -e
echo "🔍 迁移前检查..."
# 1. 检查环境
if [[ "$NODE_ENV" == "production" ]]; then
echo "❌ 已阻止:生产环境请使用迁移服务"
exit 1
fi
# 2. 创建备份
BACKUP_FILE="backups/pre-migration-$(date +%Y%m%d_%H%M%S).sql"
mkdir -p backups
pg_dump $DATABASE_URL > "$BACKUP_FILE"
echo "✅ 备份已创建:$BACKUP_FILE"
# 3. 运行迁移
echo "🚀 运行迁移..."
npm run prisma:migrate:dev
# 4. 验证
echo "🔍 验证数据库状态..."
npm run prisma:validate
echo "✅ 迁移完成。备份:$BACKUP_FILE"方式 C:CLAUDE.md 协议
Markdown
## 数据库操作
### 破坏性操作协议
**以下操作绝不在没有备份的情况下执行**:
- DELETE、DROP、TRUNCATE、ALTER...DROP
**必要步骤**:
1. 在 Slack #dev-ops 频道公告
2. 创建备份:`./scripts/backup-db.sh`
3. 验证备份:`ls -lh backups/`(大小应 >0 字节)
4. 先在测试环境执行
5. 等待 24 小时观察问题
6. 在值班工程师在场时在生产环境执行
**紧急回滚**:
```bash
psql $DATABASE_URL < backups/[最新备份].sqlPlain
### MCP 数据库安全
如果使用 MCP 数据库服务器(Postgres、MySQL 等):
```json
{
"mcpServers": {
"database": {
"command": "npx",
"args": ["@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_URL": "postgres://readonly:***@dev-db.example.com:5432/appdb"
},
"comment": "仅限只读用户,确保安全"
}
}
}重要:MCP 使用只读数据库用户。参见「数据隐私指南」。
规则 3:功能完整
问题所在
当上下文不足时,Claude Code 有时会"敷衍了事":
- 删除现有功能而不是修复错误
- 为核心功能添加
TODO注释 - 未处理错误状态
- 创建模拟实现
真实事故:
- 支付验证"修复"为完全删除验证
- 错误处理"添加"为
throw new Error("Not implemented") - 功能"完成"为
// TODO: Add actual logic here
规则
绝不发布半成品功能。如果开始了,就必须做到可工作状态。
实现方式
方式 A:CLAUDE.md 约束
Markdown
## 功能实现标准
### 不可妥协
1. **核心功能不允许有 TODO**
- TODO 仅允许用于未来增强
- 核心功能必须完整且可工作
2. **不允许模拟实现**
- 不允许 `throw new Error("Not implemented")`
- 生产代码路径中不允许假数据生成器
3. **完整的错误处理**
- 每个异步调用都有 try/catch
- 每个用户输入都经过验证
- 每个 API 调用都有超时和重试逻辑
4. **降级 = 完全删除该功能**
- 如果无法正确修复,则删除该功能
- 在提交信息中记录原因
- 创建 Issue 以便正确实现
### 验证
接受变更前,验证:
- [ ] 修改的文件中没有 `TODO`(未来增强除外)
- [ ] 没有 `throw new Error("Not implemented")`
- [ ] 没有无注释的注释掉的代码
- [ ] 所有新函数都有错误处理方式 B:pre-commit git 钩子
Bash
# .git/hooks/pre-commit
#!/bin/bash
# 检查暂存文件中的"敷衍了事"模式
STAGED=$(git diff --cached --name-only --diff-filter=ACM)
for FILE in $STAGED; do
if [[ "$FILE" =~ \.(ts|tsx|js|jsx|py)$ ]]; then
# 检查核心逻辑中的 TODO(非测试)
if ! [[ "$FILE" =~ test|spec ]]; then
if git diff --cached "$FILE" | grep -E "^\+.*TODO.*implement|^\+.*Not implemented"; then
echo "❌ 提交已阻止:$FILE 中有 TODO/Not implemented"
echo " 请完成该功能或完全删除它。"
exit 1
fi
fi
# 检查模拟占位符
if git diff --cached "$FILE" | grep -E "^\+.*(MOCK_DATA|fakeData|placeholder)"; then
echo "⚠️ 警告:$FILE 中检测到模拟数据"
echo " 请确认这仅用于测试/开发环境。"
fi
fi
done
exit 0方式 C:输出评估命令
Bash
# 提交前运行
/validate-changes
# 这会运行 output-evaluator 智能体(参见 examples/agents/output-evaluator.md)
# 评分维度:
# - 正确性(10/10)
# - 完整性(10/10) ← 检测敷衍了事
# - 安全性(10/10)规则 4:基础设施锁定
问题所在
Claude 可能在不了解生产影响的情况下修改基础设施配置:
- 更改 Docker Compose 卷 → 数据丢失
- 修改
.env.example→ 破坏入职流程 - 更新 Terraform → 意外的资源变更
- 调整 Kubernetes 清单 → 停机
规则
基础设施修改需要团队明确授权。
需要保护的文件:
docker-compose.yml、Dockerfile.env.example(模板,非个人 .env.local)kubernetes/、k8s/、terraform/、helm/- CI/CD 配置(
.github/workflows/、.gitlab-ci.yml) - 数据库架构(需要迁移审查)
实现方式
方式 A:权限拒绝
JSON
{
"permissions": {
"deny": [
"Edit(docker-compose.yml)",
"Edit(Dockerfile)",
"Edit(.env.example)",
"Edit(terraform/**)",
"Edit(kubernetes/**)",
"Edit(.github/workflows/**)",
"Edit(prisma/schema.prisma)"
]
}
}方式 B:CLAUDE.md 规则
Markdown
## 基础设施变更
**未经明确许可,禁止修改**以下内容:
- `docker-compose.yml`、`Dockerfile`
- `.env.example`(新开发者的模板)
- `terraform/`、`kubernetes/`(基础设施即代码)
- `.github/workflows/`(CI/CD 流水线)
- `prisma/schema.prisma`(数据库架构)
**如果需要基础设施变更**:
1. 询问用户:"这需要基础设施变更。是否创建 RFC?"
2. 在 `docs/rfcs/YYYYMMDD-<title>.md` 中创建 RFC 文档
3. RFC 批准前不要修改文件注意:个人 .env.local 文件可以修改(它们在 gitignore 中)。
规则 5:依赖安全
问题所在
未经团队批准添加依赖会:
- 增加包体积(性能问题)
- 引入安全漏洞
- 造成许可证合规问题
- 增加维护负担
真实事故:
- 已有
date-fns(体积小)的情况下引入了moment.js(200KB) - 项目使用
ramda时安装了lodash - 为专有代码库添加了 GPL 库 → 许可证违规
规则
未经明确批准,不添加新依赖。
实现方式
方式 A:对包管理器使用权限拒绝
JSON
{
"permissions": {
"deny": [
"Bash(npm install *)",
"Bash(npm i *)",
"Bash(pnpm add *)",
"Bash(yarn add *)",
"Bash(pip install *)",
"Bash(poetry add *)"
],
"allow": [
"Bash(npm install)",
"Bash(pnpm install)",
"Bash(pip install -r requirements.txt)"
]
}
}方式 B:CLAUDE.md 协议
Markdown
## 依赖管理
### 不可变技术栈规则
**禁止添加新依赖**(`npm install <包名>`)。
**如果需要新依赖**:
1. 检查现有依赖是否能解决:
- 日期处理?使用现有 `date-fns`
- HTTP 请求?使用现有 `axios`
- 状态管理?使用现有 `zustand`
2. 如果确实需要,请询问:
- "我需要 [包名] 用于 [原因]。现有替代方案:[X、Y]。是否添加?"
3. 等待明确批准
4. 用户将手动运行:`npm install <包名>`
**无需询问即可执行**:
- `npm install`(安装现有 package.json 中的依赖)
- 获批准后的开发依赖(`-D` 标志)方式 C:工具前钩子
Bash
# .claude/hooks/PreToolUse.sh
if [[ "$TOOL" == "Bash" ]]; then
COMMAND=$(echo "$INPUT" | jq -r '.tool.input.command')
# 阻止依赖安装
if [[ "$COMMAND" =~ (npm|pnpm|yarn)[[:space:]]+(install|add|i)[[:space:]]+[a-zA-Z] ]]; then
echo "🚨 已阻止:新依赖安装"
echo ""
echo "依赖必须由技术负责人批准。"
echo "创建 PR 并附上 RFC,说明:"
echo "1. 为什么需要这个依赖"
echo "2. 考虑过的替代方案"
echo "3. 包体积影响"
echo "4. 许可证兼容性"
exit 2
fi
# 允许:npm install(无参数)、npm install -g、pnpm install
if [[ "$COMMAND" =~ ^(npm|pnpm|yarn)[[:space:]]+install$ ]]; then
exit 0
fi
fi规则 6:遵循模式
问题所在
Claude 引入与代码库不一致的新模式:
- 项目使用函数式 React 时使用
class组件 - 项目使用
ramda时导入lodash - 项目是 GraphQL 时编写 REST 端点
- 项目标准化使用
axios时使用fetch
规则
遵循现有代码库规范。实现前先检查。
实现方式
方式 A:CLAUDE.md 规范
Markdown
## 代码规范
### 技术栈(不得偏离)
**前端**:
- React 18 使用**函数组件 + Hooks**(禁止使用 class 组件)
- 状态:Zustand(非 Redux、Context)
- HTTP:axios(非 fetch)
- 样式:Tailwind CSS(非 styled-components、emotion)
- 表单:React Hook Form + Zod
**后端**:
- Node.js + Express
- 数据库:Prisma ORM(非原始 SQL、TypeORM)
- 认证:通过 jose 库实现 JWT
- 验证:Zod schemas
**测试**:
- 单元测试:Vitest(非 Jest)
- E2E 测试:Playwright(非 Cypress)
### 导入模式
**始终使用**:
```typescript
import { useState } from 'react' // ✅ 具名导入
import axios from 'axios' // ✅ 默认导入禁止使用:
TypeScript
import React from 'react' // ❌ 已废弃的模式
import * as axios from 'axios' // ❌ 命名空间导入文件结构
Plain
src/
features/ ← 按功能组织(非按类型)
auth/
components/
hooks/
api/
shared/ ← 共享工具
components/
hooks/设计系统
UI 变更必须使用现有设计系统:
- 在
src/shared/components/中查找现有组件 - 使用
tailwind.config.js中的 Tailwind 工具类 - 仅使用
colors.ts中的颜色 - 使用
typography.config.js中的排版
创建新组件前:
- 搜索:
rg "Button" src/shared/components/ - 如果存在,使用它
- 如果不存在,询问:"是否创建新 Button 组件,还是使用现有基础组件?"
Plain
**方式 B:实现前分析**
```markdown
## 实现前
**始终**运行以下检查:
1. **模式检查**:
```bash
# 代码库如何处理 X?
rg "import.*useState" src/ # 检查 React 模式
rg "axios." src/ # 检查 HTTP 模式
rg "prisma." src/ # 检查数据库模式- 现有组件:
Bash
# 组件是否已存在?
find src/shared/components -name "*Button*"
find src/shared/components -name "*Modal*"不确定时询问用户:
- [x] "我看到项目使用 。是否遵循此模式,还是使用 [Y]?"
Plain
**方式 C:自动化验证**
```bash
# .claude/hooks/PostToolUse.sh
#!/bin/bash
if [[ "$TOOL" == "Write" ]] || [[ "$TOOL" == "Edit" ]]; then
FILE=$(echo "$INPUT" | jq -r '.tool.input.file_path')
# 检查模式违规
if [[ "$FILE" =~ \.(tsx?)$ ]]; then
CONTENT=$(cat "$FILE")
# 违规:React 中的 class 组件
if echo "$CONTENT" | grep -q "class.*extends.*Component"; then
echo "⚠️ 警告:$FILE 中检测到 class 组件"
echo " 项目使用函数组件,请考虑重构。"
fi
# 违规:错误的 HTTP 库
if echo "$CONTENT" | grep -q "import.*fetch\|window.fetch"; then
echo "⚠️ 警告:$FILE 中检测到 fetch()"
echo " 项目使用 axios。请使用:import axios from 'axios'"
fi
fi
fi规则 7:验证悖论
问题所在
当 AI 成功率达到 99% 时,传统的人工验证变得脆弱:
悖论:AI 可靠性越高,人工审查质量越低。
- 警觉性疲劳:当人类潜意识信任通常有效的模式时,罕见错误(1%)会被忽视
- 信任模式行为:随着审查者不再预期错误,人工审查质量下降
- 错误的自信:"已经成功了 50 次"会导致对第 51 次失败的盲点
- 认知负荷:人类无法持续捕捉 1/100 的错误
真实事故:
- 200 次成功交易后支付验证被绕过 → 第 201 次发生欺诈
- "AI 始终做对认证"导致跳过安全检查 → 凭证泄露
- 测试套件 99% 通过 → 来自那 1% 未测试情况的生产 bug
来源:Alan 工程团队(Charles Gorintin、Maxime Le Bras),2026 年 2 月
规则
构建自动化安全系统,而非依赖人工警觉性。
当 AI 可靠性超过约 95% 时,从人工审查转向自动化护栏。
反模式 vs 更好的方法
| 反模式 | 更好的方法 |
|---|---|
| 对每个 AI 输出进行人工审查 | 自动化测试套件 + 选择性审查 |
| 因"上次成功了"而信任 | 验证契约(测试、类型、Lint) |
| 人类作为唯一错误检测者 | 快速失败的护栏(CI/CD 门控) |
| 高频 AI 操作的"抽查"策略 | 全面自动化验证 |
| 审查者疲劳 = 随时间降低标准 | 一致的自动化质量标准 |
实现方式
方式 A:自动化护栏堆栈
YAML
# .github/workflows/ai-safety.yml
name: AI 输出验证
on: [pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: 类型安全
run: npm run typecheck # 捕获 AI 遗漏的类型错误
- name: Lint 规则
run: npm run lint # 强制代码标准
- name: 单元测试
run: npm run test # 验证行为契约
- name: E2E 测试
run: npm run test:e2e # 捕获集成失败
- name: 安全审计
run: npm audit # 检测易受攻击的依赖
- name: 包分析
run: npm run analyze # 捕获体积/性能回归
# 所有自动化通过后才进行人工审查方式 B:CLAUDE.md 中的验证契约
Markdown
## 验证协议
### 绝不仅依赖人工审查
**必须进行自动化验证**:
1. **类型安全**:`npm run typecheck` 必须通过(零错误)
2. **测试**:`npm run test` 新代码覆盖率 ≥ 80%
3. **Lint**:`npm run lint` 必须通过(零警告)
4. **安全**:`npm audit` 必须显示零高危/严重漏洞
5. **性能**:受影响页面的 Lighthouse 评分 ≥ 90
**人工审查用于**:
- 架构决策
- UX/设计选择
- 业务逻辑验证
- 自动化无法捕获的边界情况
**人工审查不用于**:
- 语法错误(使用 Lint 工具)
- 类型错误(使用 TypeScript)
- 性能回归(使用基准测试)
- 安全问题(使用自动化扫描器)方式 C:自动化预合并检查清单
Bash
# .claude/hooks/PreCommit.sh
#!/bin/bash
echo "🔍 运行自动化验证(验证悖论防御)..."
# 1. 类型安全
npm run typecheck || { echo "❌ 检测到类型错误"; exit 1; }
# 2. Lint
npm run lint || { echo "❌ 检测到 Lint 错误"; exit 1; }
# 3. 测试
npm run test || { echo "❌ 测试失败"; exit 1; }
# 4. 安全
npm audit --audit-level=high || { echo "❌ 检测到安全漏洞"; exit 1; }
echo "✅ 所有自动化检查通过"
echo "💡 人工审查现在可以专注于架构/UX/业务逻辑"边界情况
| 场景 | 处理方式 |
|---|---|
| AI 代码质量达 99.9% | 仍要运行自动化(悖论即使在 99.9% 时也适用) |
| 时间压力,"直接发布" | 自动化不可妥协(快速 ≠ 跳过安全) |
| 微小变更(修正错别字) | 运行自动化(错别字可能破坏生产) |
| 紧急热修复 | 自动化必须执行(压力下错误率更高) |
为什么重要
旧模型(前 AI 时代):
- 代码质量 = 人类专业知识 + 仔细审查
- 错误由有经验的开发者捕获
- 审查质量保持一致
新模型(AI 辅助):
- AI 95%+ 的时间产生高质量代码
- 人类变得自满("AI 通常能做对")
- 5% 的错误率通过疲劳的审查漏出
解决方案:自动化枯燥的验证(语法、类型、测试),保留人类注意力用于创造性/战略性审查。
与其他规则的整合
- 规则 3(功能完整):自动化测试验证功能确实完整
- 规则 2(数据库安全):迁移测试捕获破坏性操作
- 规则 6(遵循模式):Lint 工具自动强制项目规范
此悖论的智能体侧对应是 「TDD 工作流」中记录的验证缺口模式。
与现有工作流的集成
与计划模式结合
Bash
# 多文件变更前
/plan
# Claude 进入只读模式,探索代码库
# 识别模式、规范、现有实现
# 提出遵循项目规范的方案
# 您在执行前审查与 Git 钩子结合
这些规则与现有 git 工作流集成:
Bash
# .git/hooks/pre-commit
#!/bin/bash
# 运行安全检查
./.claude/hooks/production-safety-check.sh
# 如果阻止,提交失败
exit $?与 CI/CD 结合
添加验证步骤:
YAML
# .github/workflows/pr-validation.yml
name: PR 验证
on: [pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: 检查半成品功能
run: |
if git diff origin/main...HEAD | grep -E "TODO.*implement|Not implemented"; then
echo "❌ PR 包含未完成的功能"
exit 1
fi
- name: 检查未授权依赖
run: |
git diff origin/main...HEAD -- package.json | grep -E '^\+.*"[^"]+": "[^"]+"' || exit 0
echo "⚠️ 检测到新依赖,需要审查。"故障排除
"这些规则过于严格"
解决方案:根据团队规模和阶段调整。
| 团队规模 | 推荐规则 |
|---|---|
| 1-2 人 | 仅规则 1、3、6 |
| 3-10 人 | 规则 1、3、5、6 |
| 10+ 人或生产环境 | 全部 6 条规则 |
"Claude 一直被阻止"
解决方案:规则正在生效!选项:
授予临时权限:
创建例外:
审查规则是否合适:
- 独立开发者阻止了自己?→ 删除规则
- 团队需要灵活性?→ 使用"询问"而非"拒绝"
"如何在整个团队中强制执行规则?"
解决方案:提交到代码库,而非个人配置。
Bash
# 共享团队规则
/project/.claude/settings.json # 已提交
/project/CLAUDE.md # 已提交
# 个人覆盖
/project/.claude/settings.local.json # 在 gitignore 中
/project/.claude/CLAUDE.md # 在 gitignore 中团队设置优先,但个人可以选择更严格的规则。
另见
- 《Claude Code:从入门到大师》 §9.12 Git 最佳实践 — 提交工作流、计划→执行模式
- 「安全加固指南」 — MCP 安全、密钥保护、钩子堆栈
- 「数据隐私指南」 — MCP 数据库风险、保留策略
- 「企业 AI 治理」 — 组织级治理:使用章程、MCP 审批流程、护栏级别、合规
- 「采用方式」 — 团队设置、共享规范、企业发布
- 计划模式 — 执行前的安全探索
- 权限系统 — 允许/拒绝规则、钩子
快速参考
规则严重级别
| 规则 | 严重级别 | 违反后果 |
|---|---|---|
| 1. 端口稳定 | 🔴 关键 | 团队停机、部署失败 |
| 2. 数据库安全 | 🔴 关键 | 数据丢失、客户影响 |
| 3. 功能完整 | 🟡 高 | 生产 bug、技术债务 |
| 4. 基础设施锁定 | 🟠 高 | 停机、安全问题 |
| 5. 依赖安全 | 🟡 中 | 包体积膨胀、许可证问题 |
| 6. 遵循模式 | 🟢 低 | 代码不一致、维护负担 |
执行方法
| 方法 | 严格程度 | 配置时间 | 最适合 |
|---|---|---|---|
| 权限拒绝 | 100%(阻断) | 2 分钟 | 关键规则(1、2、4) |
| 工具前钩子 | 100%(阻断) | 10 分钟 | 自定义逻辑、团队特定 |
| CLAUDE.md 规则 | ~70%(Claude 遵守) | 5 分钟 | 规范、指导方针 |
| 工具后警告 | ~30%(仅警告) | 5 分钟 | 最佳实践、建议 |
| Git 钩子 | 100%(阻断提交) | 15 分钟 | 推送前最后安全防线 |
常见模式
允许测试环境变更,阻止生产变更:
JSON
{
"permissions": {
"allow": ["Edit(docker-compose.dev.yml)"],
"deny": ["Edit(docker-compose.prod.yml)"]
}
}要求对敏感操作进行确认:
JSON
{
"permissions": {
"ask": ["Bash(rm -rf *)", "Bash(DROP TABLE *)"]
}
}带到期时间的临时覆盖:
Markdown
## 临时覆盖(过期时间:2026-02-01)
允许为迁移项目进行基础设施变更。
过期后:恢复标准规则。规则 6:自主循环安全
问题所在
自主智能体循环——一个无人值守运行数小时、处理队列、监控系统的 Claude 会话——有一种难以调试的失败模式:进程看起来在运行,但实际上已静默停止。没有错误,没有退出码,就是什么都不发生,同时消耗您的 API 预算。
发生这种情况时:
- Claude 进入没有退出条件的推理循环
- 工具调用挂起等待一个已消失的资源
- 会话触及某个不产生输出但也不失败的边界情况
规则
对于任何预计运行时间超过几分钟的自主会话,实施心跳机制。如果心跳停止,则终止整个进程组——而不仅仅是父进程。
为什么是进程组而非父进程:Claude Code 会派生子进程(shell 命令、工具调用)。只杀死父进程会留下孤立的子进程,它们会继续消耗资源并可能在没有监督的情况下采取行动。
实现方式
心跳写入器——在自主循环内作为 PostToolUse 钩子运行:
Bash
#!/bin/bash
# .claude/hooks/autonomous-heartbeat.sh
# PostToolUse 钩子:每次工具调用后写入时间戳
HEARTBEAT_FILE="${CLAUDE_HEARTBEAT_FILE:-/tmp/claude-heartbeat-$$}"
date +%s > "$HEARTBEAT_FILE"死亡开关看门狗——作为独立进程与 Claude 并行运行:
Bash
#!/bin/bash
# scripts/watchdog.sh
# 用法:./scripts/watchdog.sh <超时秒数> <pid>
TIMEOUT="${1:-30}"
TARGET_PID="${2:-}"
HEARTBEAT_FILE="${CLAUDE_HEARTBEAT_FILE:-/tmp/claude-heartbeat-$TARGET_PID}"
if [[ -z "$TARGET_PID" ]]; then
echo "用法:watchdog.sh <超时秒数> <pid>" >&2
exit 1
fi
while true; do
sleep 5
if ! kill -0 "$TARGET_PID" 2>/dev/null; then
echo "看门狗:进程 $TARGET_PID 已正常退出"
exit 0
fi
if [[ -f "$HEARTBEAT_FILE" ]]; then
LAST_BEAT=$(cat "$HEARTBEAT_FILE")
NOW=$(date +%s)
AGE=$(( NOW - LAST_BEAT ))
if [[ "$AGE" -gt "$TIMEOUT" ]]; then
echo "看门狗:${AGE}秒无心跳(限制:${TIMEOUT}秒)——正在终止进程组"
kill -TERM -"$TARGET_PID" 2>/dev/null || kill -TERM "$TARGET_PID"
sleep 2
kill -KILL -"$TARGET_PID" 2>/dev/null || true
rm -f "$HEARTBEAT_FILE"
exit 1
fi
fi
done将它们连接在一起的启动脚本:
Bash
#!/bin/bash
export CLAUDE_HEARTBEAT_FILE="/tmp/claude-heartbeat-$$"
claude --print "处理 tasks.json 中的任务队列" &
CLAUDE_PID=$!
./scripts/watchdog.sh 30 "$CLAUDE_PID" &
WATCHDOG_PID=$!
wait "$CLAUDE_PID"
EXIT_CODE=$?
kill "$WATCHDOG_PID" 2>/dev/null
rm -f "$CLAUDE_HEARTBEAT_FILE"
exit "$EXIT_CODE"超时调整
| 任务类型 | 推荐超时 |
|---|---|
| 简单文件操作 | 15–30 秒 |
| Web 请求、API 调用 | 60 秒 |
| 代码编译、测试运行 | 120 秒 |
| 长时间研究任务 | 300 秒 |
从 30 秒开始,仅在观察到合理暂停时间超过您的超时时才增加。
何时不使用此方法
- 交互式会话(您在观察)——看门狗没有额外价值
- 5 分钟以内的任务——配置开销不值得
- 失败是预期的且由重试逻辑处理的流水线
致谢:自主智能体的心跳死亡开关模式来自 Everything Claude Code 安全指南(Affaan Mustafa)。进程组终止和看门狗分离是他们的贡献。
版本:1.0.0最后更新:2026-01-21变更日志:基于社区验证的生产模式的初始版本
来源:飞书 · AI Spark 知识库 | 原文(最新版):https://lcnniolukk80.feishu.cn/wiki/SkemwywMgiKPD4k7Ov7cOXZgnOh | 归档:2026-06-04