GitHub Actions:让 Claude Code 自动 Review PR、分类 Issue、修小 Bug

TL;DR: GitHub Actions 把 Claude Code 接入团队协作流程。第一批场景应该是 review、triage、摘要和低风险修复,不是自动合并。配置关键是:触发条件过滤、权限最小化、提示词精确、输出格式约束。
问题
团队协作的核心流程在 PR 和 issue 里。如果 Claude Code 只在本地终端使用,它的分析结果需要人工复制粘贴到 PR 评论里,这是一个断点。GitHub Actions 能把这个环节接上——当 PR 创建或 issue 提交时,自动触发 Claude Code 分析,把结果直接写回 PR/issue。

但这不是简单加一个 Action 就完事。CI 环境有独特约束:token 权限、secrets 暴露、外部贡献者、触发频率、成本控制。每个约束都需要在设计时明确处理。
更深层的问题是定位问题。Claude Code 在 CI 里的角色应该是什么?是自动审批者?代码质量检查器?还是辅助 review 工具?这个定位决定了整个配置策略。我们的建议是:把 CI 里的 Claude Code 定位为第一道防线——它负责捕获明显的 bug 和安全问题,让人类 reviewer 把精力集中在架构、业务逻辑和用户体验上。它不是最终审批者,而是一个不知疲倦的初级 reviewer。
核心架构
Claude Code 在 GitHub Actions 中有两种使用方式:

方式一:claude-code-action(官方 Action)
Anthropic 提供了官方 GitHub Action,封装了 Claude Code 调用、权限管理和结果输出。
PR 事件 → GitHub Action 触发 → claude-code-action → Claude Code 分析 → PR 评论
方式二:Headless 调用(自定义 Workflow)
直接在 workflow 中用 claude -p 调用,灵活但需要自己处理权限和输出。
PR 事件 → 自定义 Workflow → claude -p → 结果解析 → 下游动作
选择原则:标准 review/triage 场景用官方 Action,需要自定义输出格式或复杂逻辑时用 Headless 调用。
真实 Workflow 配置
PR Review(推荐起步场景)

name: Claude PR Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
# 关键:只处理同仓库 PR,排除外部 fork
if: github.event.pull_request.head.repo.full_name == github.repository
permissions:
contents: read # 读代码
pull-requests: write # 写评论
# 注意:没有 write 到 contents,不能改代码
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # 需要完整历史来理解 diff
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
max_turns: 8
claude_args: |
You are reviewing a pull request.
Focus ONLY on:
- Correctness bugs (logic errors, off-by-one, null dereference)
- Missing error handling
- Security issues (injection, auth bypass, data exposure)
- Missing or incorrect tests
Do NOT comment on:
- Code style preferences
- Naming conventions (unless genuinely confusing)
- Minor optimizations without measurable impact
Format each finding as:
**[SEVERITY]** file:line — description
Severity: critical | high | medium | low | info
If no significant issues found, say "No significant issues found" and stop.
关键配置决策:
Issue Triage
name: Claude Issue Triage
on:
issues:
types: [opened, edited]
jobs:
triage:
runs-on: ubuntu-latest
if: github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'COLLABORATOR'
permissions:
issues: write
steps:
- uses: actions/checkout@v4
- name: Classify Issue
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
RESULT=$(claude -p "Classify this GitHub issue.
Title: ${{ github.event.issue.title }}
Body: ${{ github.event.issue.body }}
Output JSON only: {\"labels\": [\"bug\"|\"feature\"|\"docs\"|\"question\"], \"priority\": \"high\"|\"medium\"|\"low\", \"summary\": \"one line\"}" \
--output-format json \
--max-turns 1 \
--disallowedTools "Edit,Write,Bash")
LABELS=$(echo "$RESULT" | jq -r '.labels[]' | tr '\n' ',' | sed 's/,$//')
PRIORITY=$(echo "$RESULT" | jq -r '.priority')
# 应用标签
gh issue edit ${{ github.event.issue.number }} \
--add-label "$LABELS" \
--add-label "priority:$PRIORITY"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
关键配置决策:
CI 失败分析
name: Claude Failure Analysis
on:
workflow_run:
workflows: ["CI"]
types: [completed]
branches: [main]
jobs:
analyze:
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'failure'
permissions:
contents: read
issues: write
steps:
- uses: actions/checkout@v4
- name: Fetch Failure Log
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# 获取失败 job 的日志
RUN_ID=${{ github.event.workflow_run.id }}
gh run view $RUN_ID --log-failed > failure-log.txt 2>/dev/null || echo "No log available" > failure-log.txt
- name: Analyze with Claude
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "Analyze this CI failure and identify root cause.
Branch: ${{ github.event.workflow_run.head_branch }}
Commit: ${{ github.event.workflow_run.head_sha }}
Failure log:
$(head -200 failure-log.txt)
Output JSON: {\"root_cause\": \"...\", \"confidence\": 0.0-1.0, \"suggested_fix\": \"...\", \"is_flaky\": bool, \"files_to_check\": [\"...\"]}" \
--output-format json \
--max-turns 3 \
--allowedTools "Read,Grep,Glob" \
> analysis.json
- name: Post Analysis Comment
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# 找到对应的 commit 关联的 PR(如果有)
PR_NUMBER=$(gh pr list --state open --head ${{ github.event.workflow_run.head_branch }} --json number -q '.[0].number' 2>/dev/null || echo "")
ROOT_CAUSE=$(jq -r '.root_cause' analysis.json)
SUGGESTED_FIX=$(jq -r '.suggested_fix' analysis.json)
IS_FLAKY=$(jq -r '.is_flaky' analysis.json)
COMMENT="## CI Failure Analysis
**Root Cause**: $ROOT_CAUSE
**Suggested Fix**: $SUGGESTED_FIX
**Flaky Test**: $IS_FLAKY
_Generated by Claude Code_"
if [ -n "$PR_NUMBER" ]; then
gh pr comment $PR_NUMBER --body "$COMMENT"
fi
claude_args 提示词调优
claude_args 不是随便写一段描述。它是 CI 环境下的系统级提示词,需要精确控制模型的关注点和输出格式。
提示词设计原则
常见反模式
# 反模式一:提示词太开放
claude_args: "Review this PR thoroughly" # 模型会尝试分析所有方面,消耗大量 tokens
# 反模式二:没有输出格式约束
claude_args: "Find bugs in this PR" # 输出是自然语言段落,无法被下游解析
# 反模式三:过度期望
claude_args: "Review this PR and fix all issues" # CI 环境不应该让模型修改代码
修正后
# 精确、有限、可解析
claude_args: |
Review this PR for correctness bugs only.
Report max 5 most significant findings.
Format: [SEVERITY] file:line — description
If no bugs found, output "No significant bugs found" and stop.
触发条件设计
触发条件直接决定成本和安全性。过度触发会快速消耗 API 额度。
|
触发事件
|
适用场景
|
频率控制
|
| — | — | — |
| pull_request: opened |
新 PR review
|
每个 PR 一次
|
| pull_request: synchronize |
PR 更新后重新 review
|
每次 push 都触发,注意成本
|
| issues: opened |
新 issue 分类
|
每个 issue 一次
|
| workflow_run: completed |
CI 失败分析
|
仅 failure 时
|
| schedule: cron |
定期巡检
|
控制频率,建议每日一次
|
| issue_comment: created | /claude
命令触发
|
按需,最省成本
|
成本估算:以一个活跃仓库为例,每天约 10 个 PR、20 个 issue。
-
• PR Review(每次 ~$0.05):10 × $0.05 = $0.50/天
-
• Issue Triage(每次 ~$0.01):20 × $0.01 = $0.20/天
-
• 失败分析(平均 2 次/天,每次 ~$0.03):2 × $0.03 = $0.06/天
-
• 总计:$0.76/天,$23/月
如果 PR 频率更高(比如 50 个/天),月成本会到 $100+。这时需要评估每个 PR 是否都需要自动 review,还是只在特定条件下触发。
按需触发模式
用 issue_comment 实现 /claude 命令触发,成本更低:
name: Claude on Demand
on:
issue_comment:
types: [created]
jobs:
on-demand:
runs-on: ubuntu-latest
# 只处理 PR 评论中的 /claude 命令
if: |
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '/claude') &&
(github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR')
steps:
- uses: actions/checkout@v4
- name: Parse Command
id: parse
run: |
COMMENT="${{ github.event.comment.body }}"
# 提取 /claude 后面的参数
COMMAND=$(echo "$COMMENT" | sed 's|^/claude[[:space:]]*||')
echo "command=$COMMAND" >> $GITHUB_OUTPUT
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_args: ${{ steps.parse.outputs.command }}
这种模式的好处是:只有团队成员明确请求时才触发,成本完全可控。
权限策略矩阵
|
场景
|
读取代码
|
写评论
|
创建分支
|
推送代码
|
部署
|
| — | — | — | — | — | — |
|
PR Review
|
yes
|
yes
|
no
|
no
|
no
|
|
Issue Triage
|
no
|
yes (标签)
|
no
|
no
|
no
|
|
简单修复
|
yes
|
yes
|
yes
|
no
|
no
|
|
自动合并
|
yes
|
yes
|
yes
|
yes
|
no
|
|
部署
|
-
|
-
|
-
|
-
|
-
|

关键原则:
Review 质量优化
Claude Code 在 CI 里的 review 质量直接决定了团队对它的信任度。如果噪声太多,开发者会忽略所有 AI 评论;如果漏报太多,安全问题会被放行。以下是从实践中总结的质量优化策略。
提示词优化
review 提示词的质量是输出质量的最大变量。一个好的 review 提示词应该具备四个特征:
聚焦:只关注特定类型的缺陷。不要让模型同时检查 bug、性能、安全、风格、架构——每个领域都需要不同的分析框架。推荐的做法是分多个独立 job,每个 job 只关注一个维度。
# 拆分为多个聚焦的 review job
jobs:
bug-review:
claude_args: "只检查逻辑错误:空指针、越界、条件判断、类型错误"
security-review:
claude_args: "只检查安全问题:注入、认证绕过、数据暴露"
test-review:
claude_args: "只检查测试覆盖:新增代码是否有对应测试、测试是否有效"
有界:设定 findings 的数量上限。不要让模型输出 30 条 findings——太多 findings 等于没有 findings。推荐上限是 5 条最重要的发现。模型被迫选择最重要的 5 条时,输出质量反而更高。
可验证:每条 finding 必须包含文件路径和行号。没有位置的 finding 是不可操作的——开发者不知道该看哪里。如果模型无法定位到具体行号,至少应该指向具体文件。
有停止条件:如果没有显著问题,明确告诉模型输出"无显著问题"并停止。这避免了模型为了"提供价值"而编造低质量 findings。
信号噪声比监控
部署后需要持续监控 review 的信号噪声比。定义如下:
信号噪声比 = (被开发者采纳的 findings) / (总 findings)
目标:> 30%
低于 15%:团队会开始忽略 AI 评论
低于 10%:AI review 失去价值
监控方法:在每个 AI 评论中加一个反应按钮(emoji)。开发者如果觉得 finding 有用就点赞,没用就点踩。每周统计比例。
如果信号噪声比下降,按以下步骤排查:
与人类 Reviewer 的协作
AI review 不应该替代人类 review,而应该互补。推荐的工作流:
PR 创建
→ AI review(自动触发,5 分钟内完成)
→ AI 评论标记明显的 bug 和安全问题
→ 人类 reviewer 重点看架构、业务逻辑、用户体验
→ 人类 reviewer 可以引用 AI 的 finding 来支持自己的观点
关键:在 AI 评论中明确标注"这是自动 review,不是最终审批"。避免开发者看到 AI 标注了 approved 就认为可以合并。
多仓库统一配置
当一个组织有多个仓库时,每个仓库单独配置 Claude Code Action 效率很低。推荐的做法是创建共享的 workflow 模板。
可复用 Workflow
# .github/workflows/claude-review-template.yml(放在模板仓库中)
name: Claude Review Template
on:
workflow_call:
inputs:
review_focus:
required: false
type: string
default: "bugs and security issues"
max_turns:
required: false
type: number
default: 5
allowed_paths:
required: false
type: string
default: ""
jobs:
review:
runs-on: ubuntu-latest
if: github.event.pull_request.head.repo.full_name == github.repository
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
max_turns: ${{ inputs.max_turns }}
claude_args: |
Review this PR for ${{ inputs.review_focus }}.
Report max 5 most significant findings.
Format: [SEVERITY] file:line — description
If no significant issues, say "No significant issues found."
各仓库引用模板
# 各仓库的 .github/workflows/claude-review.yml
name: PR Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
uses: org/review-templates/.github/workflows/claude-review-template.yml@main
with:
review_focus: "correctness bugs, auth issues, missing tests"
max_turns: 8
secrets:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
统一模板的好处:一处修改,所有仓库同步更新。策略调整(比如收紧提示词范围、增加 findings 上限)只需要改模板仓库,不需要逐个仓库修改。
按仓库定制
不同仓库有不同的关注点。前端仓库关注组件逻辑和状态管理,后端仓库关注数据一致性和 API 安全。通过 inputs 参数让各仓库传递自定义 focus:
# 前端仓库
with:
review_focus: "React 状态管理错误、内存泄漏、可访问性问题、未处理的 Promise rejection"
# 后端仓库
with:
review_focus: "SQL 注入、认证绕过、竞态条件、未处理的异常、数据泄露"
成本治理
GitHub Actions 中的 Claude Code 调用会产生两方面的成本:GitHub Actions 运行时间和 Anthropic API 调用费用。两者都需要治理。
运行时间控制
jobs:
review:
runs-on: ubuntu-latest
timeout-minutes: 5 # 硬性超时,防止失控
steps:
# ...
timeout-minutes 是安全兜底。正常 review 应该在 2 分钟内完成。超过 5 分钟说明提示词范围过大或模型在无效探索。
API 成本控制
# 方法一:通过路径过滤减少触发频率
paths:
- 'src/**' # 只在源码变更时触发
- '!**/*.md' # 排除文档变更
- '!**/*.css' # 排除样式变更
# 方法二:跳过自动生成的 PR
if: |
github.event.pull_request.head.repo.full_name == github.repository &&
github.event.pull_request.user.login != 'dependabot[bot]' &&
github.event.pull_request.user.login != 'renovate[bot]'
成本报告
建议每周生成成本报告:
# 统计 Anthropic API 使用量(通过 Anthropic 控制台或 API)
# 结合 GitHub Actions 运行次数
# 计算每仓库、每任务类型的平均成本
# 示例输出:
# 仓库 A: 45 次 review × $0.05 = $2.25
# 仓库 B: 12 次 review × $0.05 = $0.60
# 仓库 C: 8 次 review × $0.05 = $0.40
# 总计: $3.25/周
如果某个仓库的成本异常高,检查是否有过多的 synchronize 触发(每次 push 都重新 review),或者提示词范围是否过大。
失败案例:外部 PR 泄露内部上下文
场景:团队配置了 Claude Code PR Review Action,对所有 PR 运行。
原始配置:
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
# 没有 if 条件过滤
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
发生什么:一个外部贡献者 fork 了仓库,提交了 PR。Action 在内部仓库的上下文中运行——模型能读到内部代码结构、命名约定、甚至 CLAUDE.md 中的内部决策。Review 评论被发到公开 PR 上,内部上下文随之暴露。
更严重的情况:如果 CLAUDE.md 中包含了内部服务名称、API endpoint、团队联系人等敏感信息,这些信息会通过模型的回复间接泄露到公开 PR 的评论中。
根因:
修正后:
jobs:
review:
runs-on: ubuntu-latest
if: github.event.pull_request.head.repo.full_name == github.repository
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
更进一步,对外部 PR 可以用不同的处理方式:
jobs:
# 内部 PR:完整 review
review-internal:
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_args: "Review this PR for bugs and security issues."
# 外部 PR:只做基本检查,不暴露内部上下文
review-external:
if: github.event.pull_request.head.repo.full_name != github.repository
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: |
package.json
README.md
- name: Basic diff check
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# 只看 diff,不加载完整仓库上下文
DIFF=$(gh pr diff ${{ github.event.pull_request.number }})
claude -p "Review this diff for obvious bugs only. Do NOT reference any internal code.
Diff: $DIFF" --max-turns 1 --output-format text
ActionResult 处理
在自定义 workflow 中解析 Claude Code 的输出,需要处理几种情况:
# 健壮的结果处理流程
RESULT=$(claude -p "..." --output-format json --max-turns 5) || {
echo "::warning::Claude Code execution failed with exit code $?"
exit 0 # 不阻塞 CI
}
# 验证 JSON
if ! echo "$RESULT" | jq empty 2>/dev/null; then
echo "::warning::Invalid JSON output from Claude Code"
echo "::group::Raw output"
echo "$RESULT"
echo "::endgroup::"
exit 0 # 不阻塞 CI
fi
# 验证必要字段
STATUS=$(echo "$RESULT" | jq -r '.status // empty')
if [ -z "$STATUS" ]; then
echo "::warning::Missing 'status' field in output"
exit 0
fi
# 按状态执行不同动作
case "$STATUS" in
approved)
echo "Review passed"
;;
changes_requested)
echo "::error::Review requested changes"
# 发通知但不要阻塞 CI(除非你有信心让 AI 阻塞)
;;
needs_review)
echo "::warning::AI recommends human review"
;;
*)
echo "::warning::Unknown status: $STATUS"
;;
esac
落地练习
第一步,部署一个最简单的 PR Review Action:
第二步,运行一周后评估:
-
• 评论的信号噪声比如何?有效发现 vs 无关评论的比例。
-
• 每次执行的平均成本。
-
• 是否有误报导致开发者忽略 AI 评论。
第三步,根据评估调整:
-
• 误报多 → 收窄提示词范围。
-
• 成本高 → 减少
max_turns或只对特定路径触发。 -
• 信号强 → 考虑增加 issue triage 等场景。
权衡
CI 里的 Agent 输出会被团队当成"半正式意见"。这意味着两个风险:
正确的定位:Claude Code 的 CI review 是第一道防线,不是最后一道。它负责捕获明显的 bug 和安全问题,让人类 reviewer 把精力集中在架构和业务逻辑上。
分阶段部署策略
团队对 CI 里 AI 的信任是逐步建立的。不应该第一天就全面部署——这会导致两种极端反应:要么过度信任(“AI 说没问题那就没问题”),要么完全忽视(“AI 说的都是废话”)。正确的方式是分三个阶段逐步展开。
阶段一:观察模式(第 1-2 周)
部署 Action,但 只输出评论,不影响 CI 状态。设置 continue-on-error: true,确保即使 Action 失败也不阻塞 CI。这个阶段的目标是收集数据:观察 AI 评论的质量、频率、信号噪声比。
jobs:
review:
runs-on: ubuntu-latest
continue-on-error: true # 关键:不阻塞 CI
steps:
- uses: anthropics/claude-code-action@v1
# 即使 review 失败,CI 仍然通过
每周统计以下数据:
-
• 评论总数。
-
• 被开发者回复或采纳的评论数(信号)。
-
• 被开发者忽略的评论数(噪声)。
-
• 开发者的主观反馈(“AI 评论有用吗?”)。
阶段二:辅助模式(第 3-4 周)
如果阶段一的数据显示信号噪声比 > 30%,进入辅助模式。AI 评论开始影响 CI 的视觉状态(比如加 ai-reviewed 标签),但仍然不阻塞合并。这个阶段的目标是让团队习惯 AI review 的存在。
- name: Add review label
if: success()
run: gh pr edit ${{ github.event.pull_request.number }} --add-label "ai-reviewed"
阶段三:门禁模式(第 5 周起)
只有当阶段二的数据持续显示高质量,且团队明确同意后,才考虑让 AI review 影响 CI 门禁。即使在这个阶段,也只阻塞 critical 级别的 findings,不要让所有 findings 都阻塞合并。
- name: Check critical findings
run: |
CRITICAL=$(jq '[.findings[] | select(.severity == "critical")] | length' review.json)
if [ "$CRITICAL" -gt 0 ]; then
echo "Critical findings found — blocking merge"
exit 1
fi
退出条件
如果任何阶段的数据不达标,退回上一阶段。比如阶段二的信号噪声比降到 20% 以下,退回观察模式,调整提示词后重新开始。不要在没有数据支撑的情况下推进到下一阶段。
常见配置错误
以下是实际项目中观察到的配置错误,按严重程度排序。
错误一:无条件信任 AI 输出
# 错误:直接让 AI 输出决定 CI 是否通过
- name: Check AI verdict
run: |
STATUS=$(jq -r '.status' review.json)
if [ "$STATUS" != "approved" ]; then
exit 1 # 直接阻塞 CI
fi
问题:AI 可能因为误判而阻塞正常的 PR,或者因为漏判而放过有问题的 PR。在信任 AI 输出之前,至少运行两周的观察模式来评估质量。
修正:先用观察模式收集数据,确认假阳性率和假阴性率都在可接受范围内,再考虑让 AI 输出影响 CI 状态。
错误二:对外部 PR 暴露完整仓库上下文
# 错误:对外部 PR 运行完整 review
if: github.event_name == 'pull_request' # 没有过滤外部 fork
问题:外部 PR 的描述可能包含提示注入,完整仓库上下文可能包含内部信息。详见 29 — CI 安全边界[1]。
修正:添加 if: github.event.pull_request.head.repo.full_name == github.repository。
错误三:不限制执行轮数
# 错误:无轮数限制
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
# 没有 max_turns
问题:复杂 PR 可能导致模型执行几十轮工具调用,消耗大量 tokens 和时间。
修正:始终设置 max_turns,推荐 5-8 轮。
错误四:用同一个提示词处理所有类型的变更
# 错误:通用 review 提示词
claude_args: "Review this PR"
问题:前端样式变更和后端 API 变更的关注点完全不同。通用提示词会产生大量无关评论。
修正:按变更路径选择不同的 review 策略,或者至少在提示词中明确当前 PR 的变更类型。
错误五:不处理 API 失败
# 错误:没有错误处理
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
问题:Anthropic API 可能因为限流、网络问题或额度耗尽而失败。失败时 CI 的行为是什么?如果默认是失败,会阻塞所有 PR。
修正:
- uses: anthropics/claude-code-action@v1
continue-on-error: true # Action 失败不阻塞 CI
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Check review status
if: failure()
run: echo "::warning::AI review failed — human review required"
claude_args 参数调优指南
claude_args 的质量直接决定 CI 中 Claude Code 的输出质量。以下是经过生产验证的调优框架。
参数矩阵
参数 推荐值 作用 调优方向
──────────────────────────────────────────────────────────────────
max_turns 3-8 限制工具调用轮数 增大→更全面但更贵
值越小,AI 探索越少 减小→更快但可能遗漏
output-format json 结构化输出 保持 json
便于下游解析
allowedTools 按场景限定 白名单工具集 精确限定
review 只需 Read/Grep
disallowedTools 按场景限定 黑名单工具集 CI 中必须禁用
Edit/Write/Bash
timeout 5 分钟 硬性超时 不建议超过 10 分钟
按 PR 大小动态调整
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Determine review depth
id: depth
run: |
# 统计 PR 变更行数
LINES=$(gh pr diff ${{ github.event.pull_request.number }} | wc -l)
if [ "$LINES" -lt 100 ]; then
echo "max_turns=3" >> $GITHUB_OUTPUT
echo "focus=basic" >> $GITHUB_OUTPUT
elif [ "$LINES" -lt 500 ]; then
echo "max_turns=6" >> $GITHUB_OUTPUT
echo "focus=standard" >> $GITHUB_OUTPUT
else
echo "max_turns=10" >> $GITHUB_OUTPUT
echo "focus=comprehensive" >> $GITHUB_OUTPUT
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
max_turns: ${{ steps.depth.outputs.max_turns }}
claude_args: |
Review this PR.
Depth: ${{ steps.depth.outputs.focus }}
${{
steps.depth.outputs.focus == 'basic' &&
'Focus on correctness bugs only. Report max 3 findings.' ||
steps.depth.outputs.focus == 'standard' &&
'Focus on correctness, security, and missing tests. Report max 5 findings.' ||
'Focus on correctness, security, tests, and architectural concerns. Report max 8 findings. Suggest splitting if PR is too large.'
}}
提示词模板库
模板一:安全审查
只检查安全问题:注入、认证绕过、数据暴露、不安全的依赖。
忽略:代码风格、命名约定、性能优化建议。
格式:[SEVERITY] file:line — description
Severity: critical | high | medium
如果没有安全问题,输出 "No security issues found" 并停止。
模板二:测试覆盖审查
检查 PR 中新增或修改的代码是否有对应的测试。
忽略:纯文档变更、配置文件变更、样式变更。
对于每个缺少测试的变更,说明应该测试什么。
格式:[MISSING TEST] file:line — what to test
模板三:Bug 分类
将 findings 按严重程度分类,并给出是否阻塞合并的建议。
Format: JSON { "blockers": [...], "warnings": [...], "suggestions": [...] }
blockers → 应该在合并前修复
warnings → 建议修复但不阻塞
suggestions → 改进建议
模板四:变更摘要
用 3-5 句话总结这个 PR 做了什么。
不要评论代码质量,只描述变更内容。
列出受影响的主要模块和文件。
成本分析:不同配置的运行成本
场景配置对比(基于 Sonnet 模型定价估算):
配置 max_turns 平均 tokens 单次成本 月成本(50 PR/月)
─────────────────────────────────────────────────────────────────────
基础 review 3 ~8,000 $0.03 $1.50
标准 review 6 ~15,000 $0.06 $3.00
深度 review 10 ~30,000 $0.12 $6.00
安全专项审查 5 ~12,000 $0.05 $2.50
Issue 分类 1 ~2,000 $0.008 $0.16
CI 失败分析 3 ~10,000 $0.04 $0.80
按需触发(/claude) 5 ~12,000 $0.05 $1.00*
* 按需触发假设每月 20 次手动请求
月总成本估算(标准配置):
PR review(标准):50 × $0.06 = $3.00
Issue 分类:100 × $0.008 = $0.80
CI 失败分析:10 × $0.04 = $0.40
按需触发:20 × $0.05 = $1.00
──────────────────────────────
总计:~$5.20/月
月总成本估算(高活跃仓库):
PR review(深度):200 × $0.12 = $24.00
Issue 分类:300 × $0.008 = $2.40
CI 失败分析:30 × $0.04 = $1.20
──────────────────────────────
总计:~$27.60/月
成本优化建议:
1. 小 PR 用基础 review(max_turns=3),大 PR 自动升级
2. Issue 分类用 max_turns=1,不需要多轮
3. 排除 dependabot 和 renovate PR
4. 路径过滤:只在 src/ 变更时触发 review
5. 考虑按需触发替代自动触发
自动修复 Workflow
在独立分支上创建自动修复 PR 的配置,需要额外的安全措施:
name: Claude Auto-fix
on:
issue_comment:
types: [created]
jobs:
autofix:
runs-on: ubuntu-latest
# 只有成员可以触发自动修复
if: |
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '/claude fix') &&
github.event.comment.author_association == 'MEMBER'
permissions:
contents: write # 需要创建分支
pull-requests: write # 需要创建 PR
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create fix branch
run: |
BRANCH="claude-fix-$(date +%s)"
git checkout -b "$BRANCH"
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
- name: Parse fix command
id: parse
run: |
# 提取 /claude fix 后面的描述
COMMAND="${{ github.event.comment.body }}"
FIX_DESC=$(echo "$COMMAND" | sed 's|^/claude fix[[:space:]]*||')
echo "description=$FIX_DESC" >> $GITHUB_OUTPUT
- name: Run Claude fix
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "Fix the following issue in this PR:
${{ steps.parse.outputs.description }}
Rules:
- Make minimal changes to fix the described issue
- Do NOT modify .github/workflows/ files
- Do NOT modify package.json or lock files
- Run relevant tests after making changes
- Output JSON: { \"files_modified\": [...], \"tests_passed\": bool, \"summary\": \"...\" }" \
--output-format json \
--max-turns 10 \
--allowedTools "Read,Grep,Glob,Edit,Write,Bash" \
--disallowedTools ""
- name: Commit and create PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config user.name "Claude Code [bot]"
git config user.email "claude-code[bot]@users.noreply.github.com"
git add -A
git diff --staged --quiet || git commit -m "fix: ${{ steps.parse.outputs.description }}"
git push origin "$BRANCH"
gh pr create \
--title "fix: ${{ steps.parse.outputs.description }}" \
--body "Auto-generated fix by Claude Code.
Triggered by @${{ github.event.comment.user.login }}'s comment.
Please review before merging." \
--base "${{ github.base_ref }}" \
--head "$BRANCH"
关键安全措施:
相关文章
-
• 27 — Headless 模式[2]:GitHub Actions 内部调用的底层机制
-
• 29 — CI 安全边界[1]:token 权限、secrets 和外部 PR 的安全设计
-
• 30 — 结构化输出[3]:CI 输出的格式化和验证方法
-
• 21 — MCP 风险[4]:工具越权和提示注入的风险分析
-
• 23 — PreToolUse[5]:工具调用前的门禁机制
引用链接
[1] 29 — CI 安全边界: ./29-ci-security-boundaries.md[2] 27 — Headless 模式: ./27-headless-mode.md[3] 30 — 结构化输出: ./30-structured-output.md[4] 21 — MCP 风险: ./21-mcp-risks.md[5] 23 — PreToolUse: ./23-pretooluse-guardrails.md
更多推荐




所有评论(0)