16 KiB
第十一章:自动化与 CI 集成 —— 把 Claude 嵌入流水线
不想每次都手动对话?让 Claude 在脚本、CI 和容器里自动干活。
Pipe 模式:一句话调用,拿结果就走
Pipe 模式(也叫 headless / print 模式)是 Claude Code 最直接的自动化入口。不需要 TTY,不需要交互,传入提示词,拿回结果,进程退出。它在 src/main.tsx 里注册为 -p, --print 选项,描述原文是 "Print response and exit (useful for pipes)"。
最基本的用法:
# 把结果直接输出到终端
claude -p "解释当前目录的 package.json 依赖关系"
# 管道传入提示词
echo "列出 src/ 下所有 .ts 文件" | claude -p
# 把结果存到文件
claude -p "给 src/utils/hash.ts 写单元测试" > hash.test.ts
Pipe 模式有几个值得注意的行为。第一,信任对话框被跳过——命令行帮助文本明确写了 "The workspace trust dialog is skipped when Claude is run with the -p mode. Only use this flag in directories you trust." 意味着 Claude 会直接在当前目录操作文件,不会先问你是否信任它。所以只在可信目录用 -p。
第二,支持结构化输出。配合 --output-format json 可以拿到 JSON 格式的结果,方便脚本解析:
claude -p "列出 3 个最常见的 TypeScript 性能问题" --output-format json
第三,支持流式 JSON 输出(--output-format stream-json),适合需要实时处理中间结果的场景。
第四,可以限制工具白名单。在 CI 环境中,你可能不想让 Claude 随意执行任意命令。通过 --allowed-tools 参数可以精确控制:
claude -p "检查 package.json 里有没有废弃依赖" \
--allowed-tools Bash(npm audit:*) Bash(cat:*) Read
--allowed-tools 的值支持 glob 风格匹配,比如 Bash(git:*) 匹配所有 git 命令,Bash(npm install:*) 只允许 npm install 相关命令。
Headless 模式的环境差异
Pipe 模式的底层走的是 headless 路径。在 src/main.tsx 中,headless 模式会在启动时创建一个轻量级的 headlessStore(Zustand store),跳过 Ink UI 渲染、MCP 交互式认证等需要 TTY 的步骤。
在无 TTY 的环境(CI runner、Docker 容器、cron 任务)下,Claude Code 会自动检测并进入 headless 行为。但有一个常见坑:嵌套 bun 启动时 TTY 检测可能出错。比如你的脚本用 bun 调用另一个 bun 进程时,子进程可能误判自己有 TTY。
解决方案是设置环境变量 CLAUDE_CODE_FORCE_INTERACTIVE:
# 在 CI 脚本中,如果 Claude 意外进入了交互模式(卡住等待输入),
# 反过来设置这个变量让 stdin/stdout/stderr 的 isTTY 被强制标记为 true
CLAUDE_CODE_FORCE_INTERACTIVE=1 claude -p "你的提示词"
这个环境变量的处理逻辑在 src/entrypoints/cli.tsx 的顶层,在 main() 函数之前就生效。它会把 process.stdin、process.stdout、process.stderr 的 isTTY 属性强行覆写为 true。代码注释说这是 "Best-effort dev-only override for nested bun launch on Windows",但实际上在任何嵌套场景都可能用到。
--bare 模式是更激进的 headless 变体。它设置 CLAUDE_CODE_SIMPLE=1,跳过 hooks、LSP、plugin sync、attribution、auto-memory、background prefetches、keychain reads 和 CLAUDE.md 自动发现。适合只需要最原始能力的 CI 场景:
claude --bare -p "解释这个函数的作用" --system-prompt "你是一个代码审查助手"
注意 --bare 模式下 OAuth 和 keychain 认证不会被读取,只能通过 ANTHROPIC_API_KEY 环境变量或 --settings 参数提供凭证。
容器环境与 CLAUDE_CODE_REMOTE
在 Docker 容器或远程 CI 环境里跑 Claude Code 时,内存管理是个实际问题。Bun/JSC 的内存行为和 Node.js/V8 不同(详见设计篇),在大代码库上可能消耗较多内存。
src/entrypoints/cli.tsx 顶层有一段专门处理容器环境的逻辑:
if (process.env.CLAUDE_CODE_REMOTE === 'true') {
const existing = process.env.NODE_OPTIONS || '';
process.env.NODE_OPTIONS = existing
? `${existing} --max-old-space-size=8192`
: '--max-old-space-size=8192';
}
设置 CLAUDE_CODE_REMOTE=true 后,会自动给 NODE_OPTIONS 追加 --max-old-space-size=8192(8GB 上限)。这对 Node.js 运行时的构建产物生效——V8 引擎会尊重这个限制。容器通常有 16GB 内存配额,8GB 上限留足余量。
在 Docker Compose 或 CI 配置中这样用:
# docker-compose.yml
services:
claude-worker:
image: your-claude-image
environment:
- CLAUDE_CODE_REMOTE=true
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
working_dir: /app
command: ["node", "dist/cli.js", "-p", "运行测试并报告结果"]
# GitHub Actions workflow
env:
CLAUDE_CODE_REMOTE: true
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GitHub Actions 集成:install-github-app
Claude Code 内置了一套完整的 GitHub Actions 自动配置流程,通过 /install-github-app 命令触发。这个命令是 local-jsx 类型(交互式 React 组件),会引导你一步步完成配置。
整个流程大致如下:
- 检查 GitHub CLI (
gh) 是否安装 - 选择目标仓库(默认检测当前 git 仓库)
- 选择 API Key 认证方式(已有 key / 新建 key / OAuth)
- 选择要安装的 workflow(PR 助手
claude.yml/ 代码审查claude-code-review.yml,可多选) - 自动创建分支、写入 workflow 文件、设置 secret、打开浏览器创建 PR
安装完成后,你的仓库里会多两个 workflow 文件。
PR 助手 workflow (.github/workflows/claude.yml):监听 PR/Issue 评论中包含 @claude 的事件,自动触发 Claude 执行任务:
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
...
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
配置成功后,在 PR 评论中 @claude 修复这个测试失败,Claude 就会在 GitHub Actions runner 里自动分析、修改代码、提交。
代码审查 workflow (.github/workflows/claude-code-review.yml):在 PR 创建或更新时自动触发代码审查,使用 code-review 插件生成结构化的审查报告。
前置条件:
- 安装 GitHub CLI:
brew install gh(macOS)或参考 cli.github.com gh已登录并有目标仓库的 admin 权限- 准备好 Anthropic API Key(OAuth token 也支持)
如果不想用交互式命令,setupGitHubActions.ts 里暴露了完整的 API 级流程。install-github-app 命令本质上就是对这个 API 的 UI 包装。
/commit-push-pr:一键提交、推送、开 PR
/commit-push-pr 是一个 prompt 类型命令(不是交互式命令),适合在 CI 或自动化流程中调用。它会分析当前分支相对于默认分支的所有变更(不是只看最新 commit),自动生成 commit message、推送到远程、创建 PR。
它内置了一个允许工具白名单,严格限制只能执行 git 和 gh 命令:
const ALLOWED_TOOLS = [
'Bash(git checkout --branch:*)',
'Bash(git checkout -b:*)',
'Bash(git add:*)',
'Bash(git status:*)',
'Bash(git push:*)',
'Bash(git commit:*)',
'Bash(gh pr create:*)',
'Bash(gh pr edit:*)',
'Bash(gh pr view:*)',
'Bash(gh pr merge:*)',
'SearchExtraTools',
'mcp__slack__send_message',
'mcp__claude_ai_Slack__slack_send_message',
]
在交互式 REPL 中直接输入:
/commit-push-pr
或者带上额外指令:
/commit-push-pr 重点说明新增了缓存层来优化查询性能
Claude 会自动查看 git status、git diff、git branch --show-current,分析所有相关提交,生成 commit message,推送到远程,并通过 gh pr create 创建 PR。如果 CLAUDE.md 里配置了 Slack 通知,还会尝试搜索 Slack 工具并发送 PR 链接。
Git 安全协议被硬编码在 prompt 里:不更新 git config、不跑破坏性命令(push --force、hard reset)、不跳 hooks、不提交含密钥的文件。
/subscribe-pr:订阅 PR 事件
/subscribe-pr 命令让你关注某个 PR 的动态——新评论、CI 状态变化、review 等。它把订阅信息存在本地的 ~/.claude/pr-subscriptions.json 文件里。
使用方式:
# 通过完整 URL 订阅
/subscribe-pr https://github.com/owner/repo/pull/123
# 通过短引用
/subscribe-pr owner/repo#123
# 如果在 git 仓库内,直接用 PR 编号
/subscribe-pr 123
# 查看当前订阅列表
/subscribe-pr --list
# 取消订阅
/subscribe-pr --remove 123
订阅数据结构很简单——每条记录包含仓库、PR 编号和订阅时间。这个功能在 Bridge 模式下特别有用,Bridge 层的 useReplBridge 和 webhookSanitizer 会根据订阅过滤入站事件,只推送你关心的 PR 通知。
Pipe 多会话与 /pipe-status
Claude Code 支持主从 pipe 架构——一个主会话可以连接多个子会话,通过 pipe IPC 机制传递消息和任务。/pipe-status 命令查看当前连接状态。
有三种角色:
- Main 模式:未连接任何子会话的默认状态
- Slave(被控)模式:被主会话控制,所有数据上报给 master
- Master(主控)模式:已连接子会话,可以向子会话派发任务
在 master 模式下,/pipe-status 会显示每个子会话的状态、连接时间、历史记录数,并列出可用操作:
/pipe-status
# Master mode — 2 sub session(s) connected:
#
# worker-1
# Status: idle (connected)
# Connected: 14:32:05
# History: 12 entries
#
# worker-2
# Status: busy (connected)
# Connected: 14:33:12
# History: 8 entries
#
# Commands:
# /send <name> <msg> — Send a task to a sub session
# /history <name> — View sub session transcript
# /detach [name] — Disconnect from a sub session (or all)
BYOC Runner:environment-runner 与 self-hosted-runner
BYOC(Bring Your Own Compute)Runner 是两种 headless 长驻运行模式,设计目标是在你自己的基础设施上运行 Claude Code 任务。它们都在 src/entrypoints/cli.tsx 中注册为独立的 fast-path,避免加载完整 CLI。
claude environment-runner:
claude environment-runner <args...>
这是一个 BYOC(自带计算环境)的 headless runner。入口在 src/environment-runner/main.ts,受 BYOC_ENVIRONMENT_RUNNER feature flag 控制。
claude self-hosted-runner:
claude self-hosted-runner <args...>
这是一个自托管 runner,对接 SelfHostedRunnerWorkerService API(register + poll,poll 同时充当 heartbeat)。入口在 src/self-hosted-runner/main.ts,受 SELF_HOSTED_RUNNER feature flag 控制。
注意:这两个 runner 的当前实现是 stub(占位),main.ts 里只有 Promise.resolve()。它们是 feature-gated 的,需要在构建时启用对应 feature 才能使用。实际的 BYOC 能力目前更多通过 Bridge 模式(BRIDGE_MODE)和 ACP 协议(ACP)实现。
如果你想在自己的服务器上长驻运行 Claude 任务,当前可用的替代方案是:
- Bridge 模式:
claude remote-control启动后,外部客户端通过 WebSocket 连接 - ACP 协议:
claude --acp把 Claude 暴露为 ACP agent - 自托管 RCS:
bun run rcs启动 Remote Control Server,包含 Web UI
定时任务:cron + pipe 实现巡检
自动化不只是"跑一次",很多时候你需要定期巡检。有两种方式:
方式一:cron 调用 pipe 模式
最简单的方式是用系统 crontab 定时调用 claude -p:
# 每 30 分钟检查一次主分支是否有新的 CI 失败
*/30 * * * * cd /path/to/repo && claude --bare -p "检查 CI 是否有失败,如果有则列出失败原因" >> /var/log/claude-ci-check.log 2>&1
# 每天早上 9 点生成一份代码变更摘要
0 9 * * * cd /path/to/repo && claude --bare -p "总结过去 24 小时 main 分支的所有变更" | mail -s "日报" team@example.com
方式二:/schedule 远程 cron 触发器
/schedule 命令创建远程 cron 触发器,由服务端按计划触发(需要认证)。这种方式不依赖本机在线:
# 创建一个每小时触发一次的巡检任务
/schedule create "检查依赖安全漏洞" --cron "0 * * * *" --prompt "运行 npm audit 并报告高危漏洞"
更详细的内容见第七章(Daemon、Background Sessions、Schedule)。
退出码与脚本判断
在脚本里调用 Claude 时,判断成功失败很重要。Pipe 模式下,Claude Code 的退出码取决于执行结果:
0:正常完成- 非
0:出错或被拒绝
结合 shell 的 && / || 可以实现条件执行:
# 只有 Claude 确认代码正确才执行部署
claude -p "审查这个 PR 的代码质量,如果有问题就说 FAIL" && ./deploy.sh
# Claude 分析失败时发送告警
claude -p "分析错误日志 /var/log/app.log" || echo "分析失败,需要人工介入" | mail -s "告警" ops@example.com
src/entrypoints/cli.tsx 中,各个 fast-path 在出错时通过 process.exitCode = 1 或 process.exit(1) 设置退出码。主流程的退出码由 src/main.tsx 中的 action handler 决定。
一个实用的 CI 脚本模板:
#!/bin/bash
set -euo pipefail
# 环境准备
export ANTHROPIC_API_KEY="${API_KEY}"
export CLAUDE_CODE_REMOTE=true # 容器环境内存优化
# 运行 Claude 分析
if claude --bare -p "检查 src/ 下是否有明显的 bug 或安全问题" --allowed-tools "Read Grep Glob"; then
echo "检查通过"
exit 0
else
echo "发现问题,检查输出"
exit 1
fi
CLAUDE_CODE_ABLATION_BASELINE:消融实验基线
CLAUDE_CODE_ABLATION_BASELINE 是一个用于 harness-science L0 消融实验的环境变量。当同时满足 feature('ABLATION_BASELINE') 和设置了该环境变量时,cli.tsx 顶层会批量设置一组简化开关:
CLAUDE_CODE_SIMPLE=1 # 简化模式
CLAUDE_CODE_DISABLE_THINKING=1 # 禁用 thinking
DISABLE_INTERLEAVED_THINKING=1 # 禁用交错 thinking
DISABLE_COMPACT=1 # 禁用 compact
DISABLE_AUTO_COMPACT=1 # 禁用自动 compact
CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 # 禁用自动记忆
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 # 禁用后台任务
这个逻辑被特意放在 cli.tsx 的顶层(不在 init.ts 里),因为 BashTool、AgentTool、PowerShellTool 在 import 时就把 DISABLE_BACKGROUND_TASKS 等环境变量捕获进模块级常量——如果放在 init() 里就太晚了。
普通用户不需要关心这个环境变量。它是给做模型能力消融实验的研究者用的。
下一步
- 想在 PR 评论中自动触发 Claude,回到本章"GitHub Actions 集成"部分,参考
setupGitHubActions的自动配置流程 - 想了解
@claude在 GitHub 中的完整配置,看 claude-code-action 仓库 的使用文档 - 想让 Claude 定时自动执行任务(不依赖本机 crontab),看 第七章:Daemon、Background Sessions、Schedule
- 想把 Claude 暴露给外部客户端调用,看 第八章:Bridge、Remote Control、ACP
- 想限制 Claude 在 CI 中的权限,看 第九章:权限规则配置指南 中的
allow/deny规则部分