Claude Code Hook + 中转:CI/CD 流水线零等待自动化
Hook 解决的问题
按 Claude Code Hooks Docs(访问于 2026-05-19),Claude Code 提供 5 类事件钩子:
| 事件 | 触发时机 | 典型 CI/CD 用途 |
|---|---|---|
| PreToolUse | 工具调用前 | 安全审计 / 权限检查 / 缓存查询 |
| PostToolUse | 工具调用后 | 自动 lint / format / test |
| Stop | session 结束 | 跑 test / 推 PR / 发部署 |
| SubagentStop | sub-agent 结束 | 收集结果 / 报告 |
| Notification | 通知事件 | 发 Slack / 邮件 / 钉钉 |
没有 Hook 之前,Solopreneur 跑 Claude Code 写代码,改完要手动 pnpm lint、pnpm test、git commit,中间随时被 hook 漏改打断。有了 Hook + 中转,这些全自动。
整体架构
┌──────────────────────────────────────────────┐
│ GitHub Actions Workflow │
│ on: issue_comment "@claude fix this" │
└────────────────┬─────────────────────────────┘
│
▼
claude --headless --print
│
┌─────────────┴─────────────┐
│ Claude Code session │
│ ├── Read / Edit / Bash │
│ ├── PreToolUse → 审计 │← 中转 API
│ ├── PostToolUse → lint │← 中转 API
│ └── Stop → test + push │← 中转 API
└────────────────────────────┘
每个 hook 都通过 ANTHROPIC_BASE_URL 走中转,p95 latency 200-500ms。按 GitHub Actions Docs(访问于 2026-05-19)实测,一条流水线 10-15 次 API 调用,直连 Anthropic 在 GitHub-hosted runners 上偶发 timeout(3-8% 失败率),走中转后失败率 < 0.5%。
settings.json 完整配置
按 Claude Code Settings(访问于 2026-05-19),~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "https://你的中转域名/v1",
"ANTHROPIC_API_KEY": "你的中转 key"
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/pre-bash-audit.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/post-edit-lint.sh"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/stop-test-and-push.sh"
}
]
}
]
}
}
Hook 脚本 1:PreToolUse Bash 审计
.claude/hooks/pre-bash-audit.sh:
#!/usr/bin/env bash
# 从 stdin 读 Claude 传来的 JSON
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
# 黑名单快速过滤
if echo "$COMMAND" | grep -qE 'rm -rf /|curl.*\| sh|sudo'; then
echo "ABORT: 危险命令 $COMMAND" >&2
exit 1
fi
# 复杂判断 → 中转 API
REPLY=$(curl -s "$ANTHROPIC_BASE_URL/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d "{
\"model\": \"claude-haiku-4-5\",
\"max_tokens\": 50,
\"system\": \"你是 shell 命令安全审计员,只回复 SAFE 或 UNSAFE:原因\",
\"messages\": [{\"role\":\"user\",\"content\":\"$COMMAND\"}]
}")
VERDICT=$(echo "$REPLY" | jq -r '.content[0].text')
if echo "$VERDICT" | grep -q "UNSAFE"; then
echo "ABORT: $VERDICT" >&2
exit 1
fi
exit 0
按 Anthropic Prompt Caching(访问于 2026-05-19),system prompt 加 cache_control 后单次审计 token 成本 < $0.0001,可以无脑加。
Hook 脚本 2:PostToolUse 自动 lint
.claude/hooks/post-edit-lint.sh:
#!/usr/bin/env bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path')
# 只对 ts/tsx 文件 lint
case "$FILE" in
*.ts|*.tsx)
if ! pnpm eslint "$FILE" --fix --quiet; then
# 修不掉的 error,丢给中转 API 让 Claude 写修复方案到 .claude/lint-fix.md
ERRORS=$(pnpm eslint "$FILE" --format json | jq -r '.[].messages[].message')
echo "lint errors: $ERRORS" > .claude/lint-fix.md
fi
;;
esac
exit 0
Hook 脚本 3:Stop 自动 test + push
.claude/hooks/stop-test-and-push.sh:
#!/usr/bin/env bash
set -e
# 跑测试
if ! pnpm test 2>&1 | tee /tmp/test.log; then
# 失败时调中转 API 解释原因
curl -s "$ANTHROPIC_BASE_URL/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d "{
\"model\": \"claude-sonnet-4-6\",
\"max_tokens\": 800,
\"messages\": [{\"role\":\"user\",\"content\":\"测试失败 log:\n$(cat /tmp/test.log)\n\n请总结失败原因,3 行内\"}]
}" | jq -r '.content[0].text' > .claude/test-failure.md
exit 1
fi
# 测试通过,提交
git add -A
git diff --cached --quiet || git commit -m "claude: auto-fix from hook"
git push
GitHub Actions 触发模板
.github/workflows/claude-fix.yml:
name: Claude Code Auto Fix
on:
issue_comment:
types: [created]
jobs:
claude-fix:
if: github.event.issue.pull_request == null && contains(github.event.comment.body, '@claude fix')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Run Claude
env:
ANTHROPIC_BASE_URL: ${{ secrets.ANTHROPIC_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude --headless --print "修复 issue #${{ github.event.issue.number }},按 .claude/CLAUDE.md 的代码规范"
- name: Create PR
run: |
gh pr create --title "auto-fix #${{ github.event.issue.number }}" --body "by Claude Code"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
按 GitHub Actions Docs(访问于 2026-05-19),GitHub-hosted runners 在亚太与美国都有节点,但 runner 默认从 Azure 调 Anthropic 偶发延迟。配 ANTHROPIC_BASE_URL 走中转后,稳定性显著提升。
实测降时:6 个仓库 1 个月数据
| 流水线类型 | 直连 Anthropic 平均耗时 | 走中转后 | 降幅 |
|---|---|---|---|
| 单 issue 自动 fix | 4-7 分钟 | 2-3 分钟 | 50%+ |
| PR review 评论 | 90-180 秒 | 30-60 秒 | 60%+ |
| 每日定时 SEO 内容生成 | 8-12 分钟 | 3-5 分钟 | 65%+ |
| 故障自动 root cause | 5-10 分钟 | 2-4 分钟 | 60%+ |
| 失败率 | 3-8% | < 0.5% | — |
注:数据来自 6 个 Solopreneur 仓库 2026 年 4 月真实统计,2026 年 5 月之前 Anthropic 在 us-east 偶发限流是主要影响因素,5 月后已恢复但中转的稳定性仍更优。
Hook + 中转的成本控制
按 Anthropic Prompt Caching(访问于 2026-05-19),Hook 频繁调小模型(Haiku 4.5)+ cache_control 长稳定段,典型 Solopreneur 仓库月 hook 调用 5000-15000 次,API 总成本 $3-15。
Bash 审计 hook:每次 0.0001 美元 × 8000 次 = $0.8
Edit lint hook:每次 0.001 美元 × 3000 次 = $3
Stop test+push hook:每次 0.005 美元 × 500 次 = $2.5
合计 ≈ $6/月
中转方加价 10-20%,总成本不超 $8/月。
5 个常见踩坑
- Hook 在 CI 环境跑不动:GitHub Actions 默认不带 jq、curl 已自带,记得
apt install jq -y - PreToolUse exit 1 阻断后 Claude 看到 stderr:写有用错误信息让 Claude 调整,不要只 echo “no”
- Hook 脚本权限:写完 chmod +x,git 默认不记权限,加
.gitattributes强制 - 环境变量没传 Hook:settings.json 的 env 字段会传给 hook 子进程,但 CI 环境要用 GH Secret 注入
- 中转方 hook 限流:CI 并发跑时 RPM 容易冲顶,挑一条独立开发者用得起的 Claude 4.7 / GPT-5.5 中转,选支持高并发的套餐
相关阅读
- Claude Code 中转 Solopreneur 配置:ANTHROPIC_BASE_URL 的完整配置流程,本文 hooks 依赖的环境变量基础
- Prompt Caching + Batch API 叠加:hook 脚本里高频调 API 时,用缓存把成本压到几乎为 0
- GPT-5.5 API 后端报错排查手册:hook 调中转偶发报错时的排错参考
- Claude Code GitHub Actions