跳到正文

生产安全规则

目标读者:在生产环境中部署 Claude Code 的团队。独立学习者:请参见入门指南。


速览(30 秒)

生产团队的 6 条不可妥协规则

  1. 端口稳定:绝不更改后端/前端端口
  2. 数据库安全:破坏性操作前始终备份
  3. 功能完整:绝不发布半成品功能
  4. 基础设施锁定:Docker/env 变更需要授权
  5. 依赖安全:新依赖需获批准
  6. 遵循模式:符合现有代码库规范

何时使用这些规则

项目类型使用这些规则?原因
学习/教程❌ 否对探索过于限制
个人原型❌ 否额外开销不值得
小型团队(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 TABLE
  • TRUNCATE
  • ALTER 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/[最新备份].sql
Plain

### 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.ymlDockerfile
  • .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 中的排版

创建新组件前

  1. 搜索:rg "Button" src/shared/components/
  2. 如果存在,使用它
  3. 如果不存在,询问:"是否创建新 Button 组件,还是使用现有基础组件?"
Plain

**方式 B:实现前分析**

```markdown
## 实现前

**始终**运行以下检查:

1. **模式检查**:
```bash
# 代码库如何处理 X?
rg "import.*useState" src/  # 检查 React 模式
rg "axios." src/           # 检查 HTTP 模式
rg "prisma." src/          # 检查数据库模式
  1. 现有组件
Bash
# 组件是否已存在?
find src/shared/components -name "*Button*"
find src/shared/components -name "*Modal*"
  1. 不确定时询问用户

    • [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 一直被阻止"

解决方案:规则正在生效!选项:

  1. 授予临时权限

  2. 创建例外

  3. 审查规则是否合适

    • 独立开发者阻止了自己?→ 删除规则
    • 团队需要灵活性?→ 使用"询问"而非"拒绝"

"如何在整个团队中强制执行规则?"

解决方案:提交到代码库,而非个人配置。

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