找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2085

积分

0

好友

273

主题
发表于 1 小时前 | 查看: 2| 回复: 0

自动化代码审查系统概念图

编写完代码后,通常还有一大堆琐事等着:跑 Lint、执行测试、检查类型、扫描安全漏洞、确认格式规范…… 手动执行这些步骤不仅耗时,而且极易被忽略。尤其是在赶工时,一句“下次再说”可能就让 Bug 溜进了生产环境。

Claude Code 的 Hook 系统 正是为解决此痛点而生。它允许你在代码编写、文件保存、提交前后等关键节点,自动触发预设的检查脚本。无论是类型检查、Lint、安全扫描还是格式化审计,全部实现自动化。你再也不用记着去运行这些命令,即便想跳过,系统也会自动拦截。这不仅关乎效率,更是一种代码质量的文化。在 云栈社区 的技术讨论中,自动化流程的构建也是提升研发效能的热门话题。

本文将从 Hook 的原理入手,逐步讲解脚本的具体实现,并延伸至 CI/CD 集成与企业级审计方案,所有代码均可直接复用。

Hook 是什么?如何工作?

Claude Code Hook 是用户在工作流程特定节点执行的自定义脚本。其概念类似于 Git Hook,但专门为 Claude 的 AI 编码工作流进行了优化。

执行流程 大致如下:Claude 任务开始 → Pre Hook 执行 → 若通过则继续任务,失败则中断 → 任务完成 → Post Hook 执行 → 若通过则完成,失败则回滚或发出警告。

Hook 通过 退出码 来控制 Claude 的行为:

exit 0   # 成功(继续任务)
exit 1   # 失败(中断任务)
exit 2   # 警告(继续但显示警告)

目录结构 通常如下所示:

.claude/
└── hooks/
    ├── pre-file-write.sh      # 文件保存前执行
    ├── post-file-write.py     # 文件保存后执行
    ├── pre-commit.sh          # 提交前执行
    ├── post-commit.py         # 提交后执行
    └── code-review.js         # 自定义审查 Hook

Claude 会以 JSON 格式向 Hook 脚本传递上下文信息:

{
  "file_path": "src/components/Button.tsx",
  "operation": "write",
  "content": "...",
  "metadata": {
    "timestamp": "2025-10-29T10:30:00Z",
    "user": "developer@example.com"
  }
}

第一个 Hook:保护敏感文件

让我们从最简单的 Hook 开始——防止 AI 意外修改 .env 或包含 credentials 字样的敏感文件:

#!/bin/bash
# .claude/hooks/pre-file-write.sh

input=$(cat)
file_path=$(echo "$input" | jq -r '.file_path')

echo "Checking file: $file_path"

# 保护敏感文件
if [[ "$file_path" == *".env"* ]] || [[ "$file_path" == *"credentials"* ]]; then
    echo "Error: Cannot modify sensitive files"
    exit 1
fi

exit 0

创建脚本后,别忘了为其添加执行权限:

chmod +x .claude/hooks/*.sh
chmod +x .claude/hooks/*.py

编码规则自动验证

TypeScript 类型检查

#!/bin/bash
# .claude/hooks/typescript-check.sh

input=$(cat)
file_path=$(echo "$input" | jq -r '.file_path')

# 仅检查 TypeScript 文件
if [[ "$file_path" != *.ts ]] && [[ "$file_path" != *.tsx ]]; then
    exit 0
fi

echo "Running TypeScript type check..."
npx tsc --noEmit "$file_path" 2>&1 | tee /tmp/tsc-output.txt

if [ ${PIPESTATUS[0]} -ne 0 ]; then
    echo "❌ Type check failed"
    cat /tmp/tsc-output.txt
    exit 1
fi

echo "✅ Type check passed"
exit 0

ESLint 检查(Python 版)

#!/usr/bin/env python3
# .claude/hooks/eslint-check.py

import sys
import json
import subprocess

def main():
    input_data = json.loads(sys.stdin.read())
    file_path = input_data.get('file_path', '')

    if not (file_path.endswith('.js') or file_path.endswith('.ts') or
            file_path.endswith('.jsx') or file_path.endswith('.tsx')):
        sys.exit(0)

    print(f"Running ESLint on {file_path}...")

    result = subprocess.run(
        ['npx', 'eslint', file_path, '--format', 'json'],
        capture_output=True, text=True
    )

    if result.returncode != 0:
        lint_results = json.loads(result.stdout)
        for file_result in lint_results:
            for message in file_result.get('messages', []):
                severity = 'Error' if message['severity'] == 2 else 'Warning'
                print(f"{severity}: {message['message']} "
                      f"(line {message['line']}, col {message['column']})")
        sys.exit(1)

    print("✅ ESLint passed")
    sys.exit(0)

if __name__ == '__main__':
    main()

保存后自动格式化

#!/bin/bash
# .claude/hooks/post-file-write.sh

input=$(cat)
file_path=$(echo "$input" | jq -r '.file_path')

if [[ "$file_path" =~ \.(js|ts|jsx|tsx|json|css|scss)$ ]]; then
    echo "Auto-formatting $file_path with Prettier..."
    npx prettier --write "$file_path"
    if [ $? -eq 0 ]; then
        echo "✅ Formatted successfully"
    else
        echo "⚠️  Formatting failed, but continuing..."
    fi
fi

exit 0

综合代码审查 Hook

我们可以创建一个功能更强大的 Hook,在一个脚本中集成安全扫描、类型检查、Lint、测试覆盖和文档检查:

#!/bin/bash
# .claude/hooks/comprehensive-review.sh

set -e
input=$(cat)
file_path=$(echo "$input" | jq -r '.file_path')

echo "🔍 Starting comprehensive code review for $file_path"

# 1. 安全扫描
echo "🔒 Security scan..."
if command -v semgrep &> /dev/null; then
    semgrep --config=auto "$file_path" --quiet
fi

# 2. 类型检查
echo "📝 Type checking..."
if [[ "$file_path" =~ \.(ts|tsx)$ ]]; then
    npx tsc --noEmit "$file_path"
fi

# 3. Linting
echo "✨ Linting..."
if [[ "$file_path" =~ \.(js|ts|jsx|tsx)$ ]]; then
    npx eslint "$file_path"
fi

# 4. 测试覆盖率
echo "🧪 Test coverage..."
test_file="${file_path/src/tests}"
test_file="${test_file/.ts/.test.ts}"
if [ ! -f "$test_file" ]; then
    echo "⚠️  Warning: No test file found at $test_file"
fi

# 5. 文档检查
echo "📚 Documentation check..."
if [[ "$file_path" =~ \.(ts|tsx|js|jsx)$ ]]; then
    if ! grep -q "/\*\*" "$file_path"; then
        echo "⚠️  Warning: No JSDoc comments found"
    fi
fi

echo "✅ Code review completed successfully"
exit 0

SOX/SOC2 审计追踪

对于合规要求较高的企业级项目,每次代码变更都需要留下清晰的审计痕迹。这个Hook将自动记录变更信息:

#!/usr/bin/env python3
# .claude/hooks/audit-trail.py

import sys, json, hashlib, os
from datetime import datetime

AUDIT_LOG = '.claude/audit/trail.jsonl'

def main():
    input_data = json.loads(sys.stdin.read())
    os.makedirs(os.path.dirname(AUDIT_LOG), exist_ok=True)

    audit_entry = {
        'timestamp': datetime.utcnow().isoformat(),
        'operation': input_data.get('operation', 'unknown'),
        'file_path': input_data.get('file_path', ''),
        'user': os.environ.get('USER', 'unknown'),
        'content_hash': hashlib.sha256(
            input_data.get('content', '').encode()
        ).hexdigest(),
        'metadata': input_data.get('metadata', {})
    }

    with open(AUDIT_LOG, 'a') as f:
        f.write(json.dumps(audit_entry) + '\n')

    print(f"✅ Audit trail recorded: {audit_entry['timestamp']}")
    sys.exit(0)

if __name__ == '__main__':
    main()

每次 AI 对代码进行修改后,该脚本会自动在 JSONL 格式的文件中记录时间戳、操作类型、文件路径、内容哈希值和操作者等信息,为后续的合规审计提供完整依据。

CI/CD 集成

GitHub Actions 集成

将这些审查 Hook 无缝集成到你的 CI/CD 流程中,可以确保代码质量门禁在自动化流水线中得到严格执行。这是很多专业团队在 运维/DevOps 实践中采用的方法。

# .github/workflows/claude-hooks.yml
name: Claude Code Hooks

on:
  pull_request:
    types: [opened, synchronized]

jobs:
  run-hooks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Install dependencies
        run: npm ci
      - name: Make hooks executable
        run: chmod +x .claude/hooks/*.sh
      - name: Run code review hook
        run: |
          for file in $(git diff --name-only origin/main); do
            if [ -f ".claude/hooks/code-review.sh" ]; then
              echo "{\"file_path\": \"$file\"}" | .claude/hooks/code-review.sh
            fi
          done

Telegram 通知

#!/usr/bin/env python3
# .claude/hooks/telegram-notify.py

import sys, json, os, requests

def send_telegram_message(message):
    bot_token = os.environ.get('TELEGRAM_BOT_TOKEN')
    chat_id = os.environ.get('TELEGRAM_CHAT_ID')
    if not bot_token or not chat_id:
        return
    url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
    requests.post(url, json={'chat_id': chat_id, 'text': message,
                             'parse_mode': 'Markdown'}, timeout=5)

def main():
    input_data = json.loads(sys.stdin.read())
    file_path = input_data.get('file_path', 'unknown')
    message = f"🔍 *Code Review Completed*\n📁 File: `{file_path}`\n✅ All checks passed"
    send_telegram_message(message)
    sys.exit(0)

if __name__ == '__main__':
    main()

渐进式引入策略

一次性启用所有阻塞性 Hook 可能会严重干扰现有的工作流。更明智的做法是分阶段、渐进式地引入:

阶段 1:非破坏性监控(第 1~2 周)
这个阶段 Hook 只提供信息反馈,绝不阻塞操作,让团队习惯它的存在。

# 只提供信息,永远 exit 0
echo "ℹ️  Code formatting applied"
echo "ℹ️  Audit trail recorded"
exit 0

阶段 2:警告级别(第 3~4 周)
发现问题时会给出警告,但允许操作继续,让开发者开始关注并修复问题。

# 发现问题但不阻塞,exit 2
npx eslint "$file_path" || echo "⚠️  Linting issues found"
exit 2

阶段 3:阻塞性检查(第 5 周起)
在团队充分适应后,将关键检查(如类型安全)升级为阻塞级别,从根本上杜绝问题代码入库。

# 检查不过直接中断,exit 1
npx tsc --noEmit "$file_path"
if [ $? -ne 0 ]; then
    echo "❌ Type check failed - blocking operation"
    exit 1
fi
exit 0

性能优化技巧

并行执行

将多个独立的检查任务并行执行,可以显著减少总体等待时间。

# 设置超时 5 秒,并行跑
TIMEOUT=5
(
    timeout $TIMEOUT npx eslint "$file_path" &
    timeout $TIMEOUT npx prettier --check "$file_path" &
    wait
) 2>/dev/null

使用缓存避免重复检查

对内容未变化的文件跳过重复检查,利用缓存提升效率。

content_hash=$(echo "$content" | sha256sum | cut -d' ' -f1)
cache_file=".claude/cache/$content_hash"

if [ -f "$cache_file" ]; then
    echo "✅ Using cached result"
    exit 0
fi

# 执行实际检查...
echo "passed" > "$cache_file"

条件执行:按文件类型分流

根据文件类型调用不同的专用检查脚本,实现精准分流。

case "$file_path" in
    *.ts|*.tsx) .claude/hooks/typescript-check.sh <<< "$input" ;;
    *.py)       .claude/hooks/python-check.sh <<< "$input" ;;
    *.md)       .claude/hooks/markdown-lint.sh <<< "$input" ;;
    *)          echo "No specific checks for this file type" ;;
esac

安全注意事项

在编写 Hook 脚本时,必须考虑安全性,防止恶意输入或操作。

# 1. 验证 JSON 输入
if ! echo "$input" | jq empty 2>/dev/null; then
    echo "Error: Invalid JSON input"
    exit 1
fi

# 2. 防止路径注入攻击
if [[ "$file_path" =~ \.\. ]]; then
    echo "Error: Path traversal detected"
    exit 1
fi

# 3. 安全处理临时文件
temp_file=$(mktemp)
trap "rm -f $temp_file" EXIT

Claude Code 简介

Claude Code 是 Anthropic 推出的终端 AI 编程助手。其 Hook 系统是核心能力之一,让你能够在 AI 编码工作流的各个节点插入自定义逻辑,从而实现代码审查、测试、安全扫描等流程的完全自动化。

除了 Hook,Claude Code 还支持 MCP 服务器扩展、自定义斜杠命令、并行代理和子代理系统等功能。使用需要订阅 Anthropic 官方套餐。

套餐 月费 说明
Claude Pro $20/月 日常使用足够
Claude Max $200/月 完整功能,包含 Agent Teams、Extended Thinking

官方订阅需要海外信用卡和支付环境。对于国内开发者,也可以考虑使用一些提供 Claude API 中转服务的平台来降低使用门槛。

常见问题

Q: Hook 脚本可以用什么语言编写?
A: 任何能够从标准输入读取 JSON、并能通过退出码返回结果的编程语言都可以使用。Bash、Python、Node.js、Go 都是不错的选择。文中示例主要使用了 Bash 和 Python,你可以选择自己最熟悉的语言。

Q: Hook 会不会拖慢开发速度?
A: 如果设计不当,确实可能影响效率。解决方案有三个:一是将多个检查并行执行;二是利用内容哈希缓存避免对未变更内容进行重复检查;三是为每个检查设置合理的超时时间。文中的“性能优化技巧”部分提供了具体代码。此外,强烈推荐采用“渐进式引入”策略。

Q: Hook 和 Git Hook 有什么区别?
A: 核心概念相似,但 Claude Code Hook 专门针对 AI 编码工作流设计。它的触发点不仅限于 Git 提交,还包括文件保存前后、AI 任务开始与结束等。更重要的是,Claude 会以结构化的 JSON 格式向脚本传递丰富的上下文信息(文件路径、内容、元数据等),这比传统 Git Hook 的信息量要大得多。

Q: 可以在 CI/CD 流水线中复用这些 Hook 吗?
A: 完全可以。文中提供了完整的 GitHub Actions YAML 配置示例。其思路是遍历拉取请求中所有变更的文件,然后将每个文件的信息依次喂给相同的 Hook 脚本执行。这确保了本地开发环境和 CI/CD 流水线使用完全相同的质量检查标准。

总结

通过 Claude Code 的 Hook 系统,我们可以将AI编程从随意的“提示词对话”升级为严谨的“工程化流程”。它不仅仅是自动化了几个命令,更是将代码质量保障内嵌到了开发工作流的每一个环节。

从保护敏感文件的基础检查,到集成安全扫描、代码风格、测试覆盖的全面审查,再到满足企业合规要求的审计追踪,Hook 提供了极高的灵活性和强大的能力。结合渐进式引入策略和性能优化技巧,这套系统可以平滑地融入现有团队,在不显著增加开发负担的前提下,持续守护代码质量。如果你对这类自动化脚本开发与集成感兴趣,也可以在 开源实战 板块找到更多灵感。




上一篇:FPGA可重构测试架构如何应对CPO与AI芯片的验证挑战?
下一篇:聊聊OpenClaw爆火背后:一场被制造的AI焦虑与冷静思考
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-10 09:26 , Processed in 0.434082 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表