【AI编程实战】让AI在凌晨三点替你干活:Claude Code Headless模式接入CI/CD的配置清单

发布时间:2026/10/2 20:38:19
【AI编程实战】让AI在凌晨三点替你干活:Claude Code Headless模式接入CI/CD的配置清单 1. 凌晨三点被 PR 卡住Headless 模式到底解决什么问题你有没有遇到过这种场景周五晚上十一点推完最后一个 commit想着周一早上来收尾结果周一打开 GitHub 发现三个 PR 全挂着reviewer 一个都没动。不是他们不想看是没人愿意在周末盯着一堆 diff 逐行读。代码审查这件事本质上很反人类——它要求你理解别人的逻辑、找出潜在问题、给出具体建议还要在代码风格和业务逻辑之间反复切换。而这些动作往往发生在人最不想动脑的时候。Claude Code 的 Headless 模式就是冲着这个场景来的。简单说它把 Claude Code 从你一句我一句的交互式终端里解放出来变成一条可以塞进脚本、塞进 CI/CD 流水线的命令。你给它一段 prompt它跑完把结果写到 stdout然后退出。没有交互界面但代码分析能力、工具调用能力、推理能力一个不少。适合谁适合那些想让 AI 在无人值守时段替自己干活的团队——比如凌晨跑代码审查、pre-commit 自动检查、定时生成报告。我试过把这套东西接进 GitHub Actions第一次跑通的时候是凌晨两点多看着 Actions 日志里 Claude 输出的审查意见那种它真的在替我干活的感觉挺实在的。下面我把从环境准备到流水线配置的完整链路拆开讲包括我踩过的坑。2. 前置准备TaoToken 接入 Claude Code 的配置清单Headless 模式要跑起来第一件事是让 Claude Code 能正常调用模型。这里我用 TaoToken 做接入层它的 API 地址是https://taotoken.net/api兼容 Anthropic 的接口格式Claude Code 可以直接指过去。你需要准备三样东西Base URL、API Key、Model ID。这三件套在后面的 CI 配置里会反复出现先记牢。Base URL 就是https://taotoken.net/api。API Key 去控制台生成地址是https://taotoken.net/console登录后在 API Keys 页面创建一个复制出来存好别硬编码到代码里。Model ID 根据你用的模型填比如claude-sonnet-4-20250514这类具体以文档为准文档在https://taotoken.net/doc。本地验证的时候我习惯先设环境变量再跑命令export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEY你的Key export ANTHROPIC_MODELclaude-sonnet-4-20250514然后跑一条最简单的 Headless 命令试试水claude -p 用一句话解释什么是幂等性 --output-format text如果终端直接打印出一句话然后退出说明链路通了。如果报 401多半是 Key 没设对或者环境变量没生效如果报连接错误检查 Base URL 有没有写错注意结尾不要多加斜杠。这里有个细节Claude Code 读取的是ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY这两个环境变量不是随便起的名字。你在 CI 里配置 secrets 的时候注入的变量名必须和这两个一致否则 Claude Code 找不到。另外如果你用的是 Claude Code 的配置文件方式可以在~/.claude/settings.json里写{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: 你的Key, ANTHROPIC_MODEL: claude-sonnet-4-20250514 } }这个文件在本地开发时方便但 CI 环境里更推荐用环境变量注入避免把 Key 写进仓库。settings.json 的路径在不同系统下略有差异Linux/macOS 是~/.claude/settings.jsonWindows 是%USERPROFILE%\.claude\settings.json配的时候注意一下。前置准备做完接下来就是核心的 Headless 启动参数和流水线配置。3. 可复制的 Headless 启动参数与流水线配置片段Headless 模式的关键是-p也就是--print标志它告诉 Claude Code别开交互界面跑完就退出。但光有-p不够在 CI 环境里你还得控制它能用什么工具、最多跑几轮否则一个失控的 Agent 可能把你的流水线拖垮。先看核心参数。--allowedTools限制 AI 能调用的工具代码审查场景只需要读操作claude -p 审查这段代码的安全问题 \ --allowedTools Read,Grep,Glob \ --max-turns 3 \ --output-format json--max-turns控制最大推理轮次快速检查设 3深度审查设 10复杂任务最多 20再高就要谨慎了。--output-format有三种text适合人读json适合脚本解析包含耗时、费用、token 用量stream-json适合实时监控。现在把它塞进 GitHub Actions。下面这个配置是 PR 自动审查的完整片段可以直接复制name: Claude PR Review on: pull_request: types: [opened, synchronize, reopened] paths: - src/** concurrency: group: claude-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: review: runs-on: ubuntu-latest permissions: contents: read pull-requests: write steps: - name: Checkout uses: actions/checkoutv4 with: fetch-depth: 0 - name: Get changed files id: changed run: | FILES$(git diff --name-only origin/${{ github.base_ref }}...HEAD) echo files$(echo $FILES | tr \n ) $GITHUB_OUTPUT - name: Run Claude Review env: ANTHROPIC_BASE_URL: https://taotoken.net/api ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} ANTHROPIC_MODEL: claude-sonnet-4-20250514 run: | claude -p Review this PR for code quality, bugs, security issues. Changed files: ${{ steps.changed.outputs.files }}. Provide specific feedback with file:line references. \ --output-format json \ --max-turns 10 \ --allowedTools Read,Grep,Glob review.json - name: Post Review Comment uses: actions/github-scriptv7 with: script: | const fs require(fs); const review JSON.parse(fs.readFileSync(review.json, utf8)); const comment ## Claude Code Review\n\n${review.result}\n\n---\n*Automated review*; await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: comment });几个设计点值得说。fetch-depth: 0必须加否则 git 历史不完整算不出正确的 diff。concurrency配置保证同一个 PR 不会同时跑多个审查快速推送时旧任务会被取消。--allowedTools Read,Grep,Glob只给读权限AI 改不了代码安全。如果你用 Cline 或者 Codex 这类工具配置逻辑类似核心还是 Base URL、Key、Model ID 三件套。Cline 的 MCP 配置里把 provider 指向 TaoToken 的 API 地址Key 填进去模型选对应的 ID 就行。Codex 的auth.json里也是同样的三要素格式略有差异但本质一样。Pre-commit hook 也是 Headless 的典型场景跑在本地提交前给反馈#!/bin/bash STAGED_FILES$(git diff --cached --name-only --diff-filterACM) if [ -z $STAGED_FILES ]; then exit 0; fi RESULT$(claude -p Quick review these staged files: $STAGED_FILES. Focus on syntax errors, security issues, obvious bugs. Reply OK if no issues. \ --output-format text \ --max-turns 3 \ --allowedTools Read,Grep) if echo $RESULT | grep -qi OK; then exit 0 else echo $RESULT exit 1 fi存到.git/hooks/pre-commit然后chmod x给执行权限。注意 hook 要快所以--max-turns设 3只给读工具。4. 本地触发验证与日志核对确认它真的跑通了配置写完不能直接推先在本地模拟一遍。我习惯用act工具在本地跑 GitHub Actions或者干脆手动执行那条 claude 命令看输出对不对。手动验证最简单export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEY你的Key export ANTHROPIC_MODELclaude-sonnet-4-20250514 claude -p Review the file src/user_controller.ts for SQL injection risks. Provide file:line references. \ --output-format json \ --max-turns 5 \ --allowedTools Read,Grep,Glob /tmp/review.json cat /tmp/review.json | python3 -m json.tool跑完看/tmp/review.json里面应该有result字段是审查意见正文还有duration_ms、total_cost_usd、usage这些元数据。如果result是空的或者is_error为 true说明有问题。日志核对有几个关键点。第一看usage.input_tokens和output_tokens确认 token 消耗在预期范围。第二看duration_ms如果超过 60 秒可能是--max-turns设太高或者 diff 太大。第三看total_cost_usd单次审查一般几分钱如果飙到几毛检查是不是把整个仓库都塞进去了。在 GitHub Actions 里日志在 Actions 页面的 job 详情里看。重点看 Run Claude Review 这一步的 stdout以及 Post Review Comment 有没有成功创建评论。如果评论没出现多半是permissions没给pull-requests: write。我踩过的一个坑第一次跑的时候忘了设fetch-depth: 0结果git diff算出来是空的Claude 收到一个空文件列表输出了一句没有变更需要审查。排查了半天才发现是 checkout 的问题。所以验证的时候先确认steps.changed.outputs.files有内容再往下走。还有一个验证技巧故意在一个测试 PR 里塞一段有 SQL 注入风险的代码看 Claude 能不能指出来。如果能准确报出user_controller.ts:47这种行号说明工具调用和上下文理解都正常。5. 常见报错排查401、local proxy failed、reading choices、OAuth跑 Headless 最容易撞上的几类错误我按出现频率排一下。401 Unauthorized。这是最常见的基本是 Key 的问题。检查三处环境变量名是不是ANTHROPIC_API_KEY值有没有多余空格Key 有没有过期。在 CI 里还要确认 secrets 注入的变量名和代码里读的一致。如果本地能跑 CI 不能跑多半是 secrets 没配或者名字写错。local proxy failed / connection refused。这个通常是 Base URL 写错或者网络层有问题。确认ANTHROPIC_BASE_URL是https://taotoken.net/api结尾不要加斜杠不要写成http。如果公司网络有出口限制检查一下能不能访问这个域名。reading choices / unexpected response format。这个报错说明返回的数据结构不是 Claude Code 预期的。常见原因是 Model ID 填错了或者 API 返回了错误信息但被当成正常响应解析。检查ANTHROPIC_MODEL是不是有效的模型 ID去文档页核对一下当前可用的模型列表。OAuth / authentication failed。如果你之前用 Claude Code 登录过官方账号本地可能残留了 OAuth 凭证和 API Key 模式冲突。解决办法是清掉旧的凭证文件通常在~/.claude/目录下然后重新用环境变量方式配置。在 CI 环境里一般不会有这个问题因为每次都是干净的环境。max turns exceeded。这个不是错误是提示。说明任务在限定轮次内没完成。要么提高--max-turns要么把任务拆小。代码审查场景一般 10 轮够用如果经常超检查 prompt 是不是太模糊导致 AI 反复试探。输出为空但退出码为 0。这种情况最隐蔽。可能是 prompt 里的文件路径不对AI 读不到文件也可能是--allowedTools限制太死AI 想读文件但没权限。排查方法是把--output-format改成stream-json看中间过程有没有tool_use和tool_result能定位到卡在哪一步。对照这些报错大部分问题都能自己解决。核心思路是先确认三件套Base URL、Key、Model ID对不对再看工具权限和轮次限制最后看输入数据diff、文件路径有没有问题。6. 把 AI 审查接进日常从只读观察到逐步放权Headless 模式跑通之后别急着让它自动改代码。我的建议是分阶段来。第一周只做只读审查AI 输出意见但不碰代码你观察它的判断质量。第二周让它的修改建议需要人工批准才能应用。第三周把低风险修改格式、注释放开自动合并。第四周根据团队反馈调整策略。成本也要盯着。每次 CI 运行都消耗 token一个典型审查大概 5000 输入 token 加 2000 输出 token按 Sonnet 的定价算单次几分钱。但如果团队每天 100 个 PR一个月下来也是一笔钱。控制手段有几个on.pull_request.types只设opened别加synchronize避免每次推送都触发paths限定只监控src/**concurrency加cancel-in-progress取消旧任务。审计日志也要留。记录哪个 PR 触发了审查、发现了什么问题、最终有没有被采纳。这些数据能帮你判断 AI 审查的实际价值也能在出问题时回溯。Headless 模式的价值是减少等待时间不是跳过人类判断。AI 能帮你查命名规范、发现潜在的 SQL 注入、提醒你加单元测试但架构是否合理、业务逻辑是否正确这些还是得人来定。把它当成一个不知疲倦的初级审查员而不是替代品。如果你还没试过从本地一条claude -p命令开始跑通了再往 CI 里搬。接入文档在https://taotoken.net/docAPI Key 在https://taotoken.net/api-keys生成模型对话调试可以用https://taotoken.net/chat。长期跑编码任务的话Coding Plan 在https://taotoken.net/coding-plan按需选。