
在 CI 里跑 Claude Code 这件事我折腾了整整两天才跑通。把过程中踩过的坑、验证过的配置、还有实际生产环境中跑了一个多月的经验整理出来希望能帮你少走弯路。1. 为什么要用 claude-code-action先说清楚这个东西解决什么问题。claude-code-action是一个 GitHub Action让 Claude Code CLI 直接跑在 GitHub Actions 的 runner 上。核心用途是两大类一是自动给 PR 做 code review二是让 Claude 在 CI 环境里自动改代码、跑测试、提交 PR。我最初的需求很简单团队代码 review 人手不够希望有个 AI 能先过一遍把明显的问题挑出来但不需要它真的改代码。后来加了一个更进阶的用法让它自动修 lint 错误、自动补测试跑完直接开一个 PR。为什么不是本地跑本地跑有一个致命问题——不可复现。Claude 在本地改了什么、什么时候跑的、用的什么模型版本这些都没有记录。放到 CI 里就不一样了每一次执行都有日志、有时间戳、有可追溯的上下文。这在团队协作里非常重要尤其是多个开发者共用同一个 GitHub 仓库时你总得知道这个 AI 到底干了什么。再说一下为什么这个 action 比自己在 workflow 里裸调 CLI 更靠谱。直接写claude -p review this diff这种命令会遇到几个坑认证 token 怎么传、工作目录怎么切、JSON 输出怎么接、失败重试怎么办。这些 claude-code-action 已经都处理好了有输入参数可以控制有输出可以直接后续步骤复用。省掉的这些时间足够你多配三个 workflow。2. 环境准备与前置条件2.1 必要的权限与密钥用这个 action 之前先把 GitHub 侧的权限理清楚。第一件事是确保 workflow 有权限。在 repository settings 里Actions General Workflow permissions需要设置为Read and write permissions否则 action 即使启动了也没法创建 PR、没法提交 code review comment。这个权限设置是很隐蔽的一个坑我见过不少人配置完全正确就是跑起来之后 GitHub API 返回 403排查到最后发现是仓库本身的 workflow 权限没开。第二件事是 API key。如果你用的是 Claude API你需要一个ANTHROPIC_API_KEY存在 GitHub Secrets 里。如果你用的是 Claude Code 的订阅账号比如 Pro 或者 Max那你需要CLAUDE_CODE_OAUTH_TOKEN这个 token 可以通过在本地登录 Claude Code 后从~/.claude/credentials.json里找到。两者在生产环境里我建议都用 API key因为 OAuth token 有设备绑定和有效期跑一跑突然失效会让你欲哭无泪。2.2 最小配置示例一个最简的 workflow 长这样name: Claude Code Review on: pull_request: types: [opened, synchronize] jobs: review: runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - uses: actions/checkoutv4 with: fetch-depth: 0 - uses: anthropics/claude-code-actionv1 with: claude-code-auth-token: ${{ secrets.ANTHROPIC_API_KEY }} prompt: Review this pull request. Identify bugs, security issues, and style problems. Return results as a JSON object with a comments array.这里有两个细节值得注意。fetch-depth: 0很重要它让 checkout 拿到完整的 git 历史这样 Claude 才能正确理解 diff 的上下文。如果不加这一行Claude Code 看到的可能只有最新的一个 commitreview 质量会大打折扣。permissions块也要显式声明GitHub 默认的权限是只读不写这一块就只能看不能写。2.3 模型选择与参数配置claude-code-action本身不直接暴露模型参数但你可以通过环境变量控制。最常用的是ANTHROPIC_MODEL比如设成claude-sonnet-4-20250514。经验之谈review 任务用默认模型就够因为 review 是一次性的分析任务token 用量可控但自动修代码、开 PR 这类多轮 agentic 任务建议显式指定更强的模型并加上max-think-tokens这类参数。我自己在项目里跑自动修 bug 任务时发现默认配置的模型有时候在复杂代码路径上会“偷懒”给定一个看似合理但根本没修对的方案。换成指定模型并给了更大的思考空间之后正确率明显提升。参数层面的调优后面详述先把 workflow 跑起来。3. 核心玩法三种典型场景3.1 场景一PR 自动 Code Review这是最简单的用法也是我认为价值密度最高的用法。让 Claude 在每次 PR 变更时自动分析代码然后把意见作为 review comment 提交到 PR 上。- uses: anthropics/claude-code-actionv1 with: claude-code-auth-token: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | You are a senior software engineer. Review this PR carefully. Focus on: 1. Logic errors and edge cases 2. Security vulnerabilities 3. Performance issues 4. Code style consistency For each issue, provide: - File path and line number - Severity (critical / major / minor) - Explanation of the problem - Suggested fix Format the output as YAML for easy parsing.直接跑这个配置Claude 的分析结果会出现在 workflow 的日志输出里不会自动变成 PR comment。如果你想要它直接发到 PR 上需要加一个后续步骤来处理输出。- uses: anthropics/claude-code-actionv1 id: review with: claude-code-auth-token: ${{ secrets.ANTHROPIC_API_KEY }} prompt: Review the PR and provide a summary of issues. output: review-result.md - name: Post Review Comment run: | gh pr comment ${{ github.event.pull_request.number }} --body-file review-result.md env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}这里用到了 action 的output参数它会把 Claude 的输出写入一个文件后面的步骤直接读取这个文件。一开始我没发现这个参数走了一个弯路用${{ steps.review.outputs.output }}去拿结果发现拿到的只是文件名不是内容。后来看了源码才知道这个 action 会把内容写进指定的文件你需要自己再读出来。3.2 场景二自动修代码并开 PR这个玩法的核心思路是给 Claude 一个明确的任务让它直接改代码、跑测试可选、然后提交到一个新分支并开 PR。name: Auto Fix Lint Issues on: schedule: - cron: 0 2 * * * # 每天凌晨两点 workflow_dispatch: # 支持手动触发 jobs: autofix: runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - uses: actions/checkoutv4 with: fetch-depth: 0 - name: Run Claude Code Auto Fix uses: anthropics/claude-code-actionv1 with: claude-code-auth-token: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | Run the linter with: npm run lint If there are lint errors, fix them. Then commit and push the changes to a new branch called autofix/lint. Finally, open a pull request against the main branch with title chore: auto-fix lint issues.这个赛季的关键是你必须给 Claude 的权限足够大。除了之前提到的contents: write还需要注意actions: write权限用于触发一些后续 action而且 Claude 在 CI 里默认是交互模式你必须在 prompt 后面给它加一个明确的指示比如 Do not ask the user for confirmation, just do it。否则 workflow 会挂在那里等输入。在实际项目中跑这个方案最大的痛点是 Claude 改完代码后提交到 GitHub 的过程容易出问题。正常的做法是把 GitHub CLIgh预装在 runner 上但 Claude 有时候会因为 git 用户没有配置而报错。在 prompt 里提前告诉它“先配置git config user.name和user.email然后再 commit”可以避免大部分这种问题。跑这个任务我踩过一个具体的坑Claude 改完代码后执行git push时仓库的状态不是预期的于是它自作聪明地做了git pull --rebase结果产生了大量冲突。原因是 main 分支在任务执行期间被其他人更新了。后来我在 prompt 里加了“dont pull or mergeonly push to a fresh branch”并且让 action 可以拿到浅克隆shallow clone分支创建后直接强推force push问题就消失了。3.3 场景三接收外部输入做定向任务这个更适合团队内部构建“AI 自动化流水线”比如把 GitHub Issue 作为任务源让 Claude 去处理。name: Issue Auto-Responder on: issues: types: [opened] jobs: respond: runs-on: ubuntu-latest permissions: issues: write steps: - uses: actions/checkoutv4 - uses: anthropics/claude-code-actionv1 with: claude-code-auth-token: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | A new issue has been opened: ${{ github.event.issue.title }} The issue body is: ${{ github.event.issue.body }} 1. Analyze the issue and determine if its a bug report, feature request, or question. 2. If its a bug report, check if the codebase has code related to the issue description. 3. Output a response with: - Classification - Initial analysis - Suggested next steps Do not modify any files. Just output the analysis.这个玩法适合给开源项目搭建自动化的 Issue triage 机器人。我自己在一个组织内部用过类似配置效果是Issue 一开几分钟内就有一个初步的分析报告包括问题分类、疑似相关代码位置、建议的修复方向。维护者拿到这个报告后再决定要不要深入处理效率提升非常明显。4. 输入输出机制与数据复用4.1 输入参数详解我扒了一遍 claude-code-action 的源码把常用的输入参数整理成表参数名作用备注claude-code-auth-token认证 tokenAPI Key 或 OAuth Tokenprompt给 Claude 的任务描述支持多行字符串output将输出保存到指定文件为空时输出到 stdoutworking-directory指定 Claude 的工作路径默认为仓库根目录args传给claude命令的额外参数用逗号分隔github-token用于 GitHub API 操作默认使用GITHUB_TOKENdebug是否输出调试信息选true时会有详细走查args这个参数是通往高级玩法的钥匙。我需要给 Claude 指定模型时就是用args: --model,claude-sonnet-4-20250514这样传的。查看当前支持的所有模型可以用claude model命令在本地查看。实际使用中working-directory也很实用。如果你想在 monorepo 里只处理某个子项目把工作目录指进去Claude 就只会看到那个子目录不会被其他无关代码干扰。这在上下文窗口有限的情况下很有意义。4.2 输出复用技巧Claude Code CLI 有一个 JSON 输出模式这在做自动化时特别好用。你可以在 prompt 里要求它输出 JSON然后把产出文件交给后续步骤处理。- name: Generate Test Report uses: anthropics/claude-code-actionv1 id: gen_tests with: claude-code-auth-token: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | Look at the file src/utils/string.ts. Generate unit tests for all functions in this file. Use vitest syntax. Write the tests to tests/string.test.ts. output: tests-created.txt - name: Verify Tests Pass run: npm test - name: Commit Tests run: | git add tests/ git diff --cached --stat这里有一个小技巧不一定非要用output参数生成的文件也可以直接在后一步读 stdout——但 stdout 也可能包含其他信息比如 Claude 的辅助话语不适合直接当结构化数据用。我把output参数学到的规范用起来后后续步骤可靠了许多。5. 实际项目中的参数调优与成本控制5.1 控制 Token 消耗的实战经验AI 自动化的一个隐性问题就是成本。让 Claude Code 在 CI 里自主干活如果不做任何约束同一个任务可能吃掉几百 k 的 token费用对小型团队来说并不轻。我的控制策略有两种第一在 prompt 里限制范围。比如“只 review 这个 PR 中新增的代码跳过已有逻辑”直接把分析范围压缩到 diff 而不是整个仓库。这个简单的一句话能让 token 消耗下降 50% 以上。第二利用args参数限制输出长度和思考预算with: claude-code-auth-token: ${{ secrets.ANTHROPIC_API_KEY }} args: --max-turns,8,--max-output-tokens,1024 prompt: Fix all lint errors in src/ directory. Do not ask questions. Just do it.max-turns限制 Claude 在任务中可以执行的工具调用次数max-output-tokens限制每次回复的长度。这两个参数加上之后就算任务规划失控也不会无限消耗下去。这里我个人的实测数据跑一个 200 行变更的 PR review不限制时平均消耗约 45k token加上--max-turns,6和--max-output-tokens,1024后基本稳定在 28k 左右而且 review 质量没有明显下降。如果你的场景是“每天定时修复”再加一个条件判断只有在 diff 文件数大于某个阈值时才执行 Claude进一步降低空跑的成本。5.2 并发与超时设置Claude Code 执行任务不是瞬间完成的复杂任务可能在几分钟到十几分钟之间。GitHub Actions 默认 job 超时是 6 小时但对 AI 任务不要给这么长。并非所有人都意识到任务挂住时你也是在烧 token 的。我的做法是设置timeout-minutes: 30。如果 30 分钟没有跑完基本可以断定任务设计或者 prompt 描述出了问题把整个 job 杀掉更合理。并发控制上限制条件是同一个仓库同一时间只能有一个 AI 任务在跑否则两个 Claude 同时改代码会产生 git 冲突。在 workflow 里加 concurrency 块concurrency: group: claude-code-${{ github.ref }} cancel-in-progress: true为简便起见我把cancel-in-progress关掉了因为取消进行中的任务实际上会造成 token 的浪费——已经烧掉的 API 费用是不会退的。如果希望后来的任务等待而不是取消前面不要设置这个字段即可。5.3 失败重试策略AI 执行任务本身就带不确定性同一个 prompt 跑 10 次可能会有 1 次跑偏。不要让 workflow 因为一次失败就报红。我给一万步的 workflow 配置了continue-on-error: true让主流程继续跑但在最后加一个“判断 Claude 任务是否成功”的步骤仅在该步骤输出警告而不是让整个 CI 失败。这样主要目的让 AI 完成大部分工作依然成立剩下的边缘情况再人工处理。对于自动开 PR 的任务因为 push 失败需要重新跑我会用更保守的策略。要是那次跑的结果没有达到预期我宁可人工重跑也不想让 workflow 自动疯狂重试——因为重试一次就是一笔 API 费用。6. 常见错误与排查手册6.1 认证失败401 / 403这个坑出现频率最高。配置正确的前提下最常见的原因是 Secrets 名字打错了。我建议先去仓库的 Actions 日志里看具体报错信息如果看到Authentication failed检查 secrets 是否以正确名字存在。如果看到403 Forbidden大概率是 workflow 权限设置成了 read-only。在 Actions 设置里把Workflow permissions改为读写权限是最快的解决方案。另外如果你的 API Key 是在 Anthropic Console 创建的确认它有正确的预算和权限。免费额度用完了也会出现认证失败这个报错很具有迷惑性。6.2 Claude 执行过程中卡住不动在日志里如果看到 Claude 输出停在某个工具调用没有后续进展可能有三个原因模型在做长思考需要更长轮次。加大max-turns或者直接提高timeout-minutes。任务的 prompt 里带有“ask me if you need help”之类的语句导致 Claude 在等待输入。使用非交互模式时在 prompt 里同时加上 “You should not ask the user for additional input. Make reasonable assumptions and complete the task.”。仓库 checkout 不完整导致 Claude 找不到文件。确认fetch-depth: 0。6.3 Push 失败 / 无法写入分支这类问题比较直白多做几个检查是否给了 action 对仓库的写权限contents: write。是否设置了GITHUB_TOKEN或者自定义的 token。切记如果使用默认的GITHUB_TOKEN这个 token 只在当前 job 内有效并且仓库的 Actions 权限须为允许写。如果仓库启用了 branch protection默认的GITHUB_TOKEN无法直接 push 到受保护的 main 分支。这种情况最常见且最易误导人解决方案是创建一个带 push 权限的 Personal Access Token把它存在 Secrets 里再在 workflow 的 env 中引用。6.4 生成的代码质量不稳定我的体感是这个不稳定并不是模型能力的问题更多是任务描述不清晰导致的。有一次我让它“写一个函数判断字符串是否是回文”它写出了递归 栈 正则去特殊字符的版本明显过度包装了。此后我在所有 prompt 开头都会加上“Write the simplest possible production code. Do not over-engineer. Do not add extra features.”这类限制定语代码质量稳定很多。还有一个实用技巧是在 prompt 里规定“只改目标问题不要重构其他代码”。否则你能看到它顺手帮你把文件里 10 年前的旧写法全换了一遍——让你胆战心惊。7. 生产环境的实战经验总结这套配置在我们团队已经稳定跑了一个半月每天凌晨自动修 lint、自动补测试、自动清理 TODO 注释。从我观察到的产出看收益有几个方面一是 PR review 的覆盖率大幅提升。以前人工 review 很容易漏掉小问题现在 Claude 在代码合并之前总能先抓住几处逻辑问题。虽然质量比不上顶级工程师但是“永不休眠”这一点是人力无法替代的。二是自动化修 lint 这类重复劳动确实释放了我不少时间。每天醒来看到 auto-fix PR 已经开好commit 清晰描述明确只需花五分钟看下 diff 就能合并。但你也要清楚它的边界。Claude Code Action 目前不适合做需要强领域知识的任务比如“这个第三方 SDK 的最佳实践是什么”这类问题它的回答质量浮动较大。对大型仓库的全局重构也不推荐让它在 CI 里自主行动上下文和代码库的边界把握很容易失控。最后给一个我在使用中沉淀下来的配置清单仅供参考- uses: anthropics/claude-code-actionv1 with: claude-code-auth-token: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | You are working in a production codebase. 1. Read the provided context carefully. 2. Make the minimal changes to satisfy the request. 3. Do not ask for confirmation. 4. Check your work with git diff. 5. Only commit if the change is complete. output: result.md args: --max-turns,10,--max-output-tokens,2048 working-directory: src/svc这个动作配合一个“通知 Slack 或者飞书群”的后续步骤就是一套完整的 AI 自动化闭环。配置不复杂做到稳定运行靠的是耐心调试和不断的 prompt 迭代。实际上往后加一步——用gh pr create --title AI autofix: 日期 --body 由 Claude Code Action 自动提交创建 PR这套 CI 的能力就圆满了。跑起来之后你会发现不只是 review很多以前想做的自动化又多了另一种可能性。