跳转到内容

Headless 模式

交互模式像和 Claude 面对面聊天——你一言我一语,它边想边写。但脚本和 CI 不需要「聊天」,它们需要的是一个调用即返回的函数。Headless 模式就是 Claude Code 的「无人值守模式」:拉起来、跑完、吐结果、退场。没有 UI,没有 prompt 等你输入,没有「你确定要继续吗」的确认。

这一页讲清楚怎么开 headless、配什么参数、读什么输出,以及怎么把它稳稳嵌进流水线。

--print / -p 是 headless 模式的总开关。带上它,Claude 就不进交互界面,而是把 prompt 跑完直接打印结果退出。

Terminal window
claude -p "Stage my changes and write a set of commits for them" \
--allowedTools "Bash,Read" \
--permission-mode acceptEdits

不带 -p 调用 claude "做某事" 会进入交互模式——这在脚本里是事故现场。headless 必带 -p

Headless 复用 Claude Code 的全部 CLI 选项,自动化场景下最常用的几个:

Flag 作用
--print / -p 非交互模式,跑完即退
--output-format 输出格式:text / json / stream-json
--resume / -r 按 session ID 恢复会话
--continue / -c 续上当前目录里最近一次会话
--verbose 打开详细日志,看 turn-by-turn 输出
--append-system-prompt 追加到默认 system prompt(仅 -p 模式)
--allowedTools 工具白名单(空格或逗号分隔)
--disallowedTools 工具黑名单
--mcp-config 从 JSON 文件加载 MCP 服务器
--permission-prompt-tool 用 MCP 工具接管权限提示(仅 -p 模式)
Terminal window
# 只允许 Bash 和读,禁掉 commit
claude -p "查一下这个 PR 的风险" \
--allowedTools "Bash,Read" \
--disallowedTools "Bash(git commit)"
# 用自定义 MCP 处理权限
claude -p "..." --permission-prompt-tool mcp__auth__prompt

--allowedTools 既支持空格分隔的多个参数,也支持逗号串成单个字符串,还能写带括号的工具规则,例如 "Bash(npm install),mcp__filesystem"

Headless 不是只能一锤子买卖。Claude Code 把会话存到磁盘,你可以接续上次的上下文继续聊。

Terminal window
# 续上最近一次会话
claude --continue "现在把它重构得更高效一点"
# 按 session ID 恢复,再追加指令
claude --resume 550e8400-e29b-41d4-a716-446655440000 "更新一下测试"
# 在 headless 里恢复
claude --resume 550e8400-e29b-41d4-a716-446655440000 "修掉所有 lint 问题"

把第一次跑得到的 session_id 存下来,后续用 --resume 接着跑——比每次从头喂一遍上下文省钱、省时、省心。

--output-format 决定 Claude 怎么把结果吐出来。

Terminal window
# text:默认,给人看
claude -p "Explain file src/components/Header.tsx"
# json:一次性结构化,含 cost/session_id 等元信息
claude -p "How does the data layer work?" --output-format json
# stream-json:流式逐条 JSON,每行一个事件
claude -p "Build an application" --output-format stream-json

--output-format json 跑完会输出一个完整 JSON 对象,包含结果和元信息:

{
"type": "result",
"subtype": "success",
"total_cost_usd": 0.003,
"is_error": false,
"duration_ms": 1234,
"duration_api_ms": 800,
"num_turns": 6,
"result": "The response text here...",
"session_id": "abc123"
}
字段 含义
type 消息类型,最终结果为 result
subtype 结果子类型,success 表示成功
total_cost_usd 本次花费(美元)
is_error 是否出错
duration_ms 总耗时
duration_api_ms API 耗时
num_turns agentic 轮数
result 最终回答文本
session_id 会话 ID,可用于后续 -r 接续

session_id 是后续 --resume 的钥匙——存下来下次接着用。

stream-json 输出多个 JSON 对象,每行一个,对应一个事件:助手消息、工具调用、工具结果、最终结果。每段对话以一条 init 系统消息开始,以一条带统计信息的 result 系统消息收尾。

Terminal window
claude -p "修这个 Bug" --output-format stream-json | jq 'select(.type=="tool_use")'

把 Claude 嵌进告警流水线,让它接到 incident 自动排查:

#!/bin/bash
# 自动化事件响应 agent
investigate_incident() {
local incident_description="$1"
local severity="${2:-medium}"
claude -p "Incident: $incident_description (Severity: $severity)" \
--append-system-prompt "You are an SRE expert. Diagnose the issue, assess impact, and provide immediate action items." \
--output-format json \
--allowedTools "Bash,Read,WebSearch,mcp__datadog" \
--mcp-config monitoring-tools.json
}
# 用法
investigate_incident "Payment API returning 500 errors" "high"

每个 PR 自动跑一遍安全审查,结果存档:

Terminal window
# PR 安全审计 agent
audit_pr() {
local pr_number="$1"
gh pr diff "$pr_number" | claude -p \
--append-system-prompt "You are a security engineer. Review this PR for vulnerabilities, insecure patterns, and compliance issues." \
--output-format json \
--allowedTools "Read,Grep,WebSearch"
}
# 用法,结果落盘
audit_pr 123 > security-report.json

跨多轮保留上下文的合同审查——靠 session_id 把多步串起来:

Terminal window
# 开启一个法律审查会话
session_id=$(claude -p "Start legal review session" --output-format json | jq -r '.session_id')
# 多轮审查
claude -p --resume "$session_id" "Review contract.pdf for liability clauses"
claude -p --resume "$session_id" "Check compliance with GDPR requirements"
claude -p --resume "$session_id" "Generate executive summary of risks"

把 Claude 嵌进脚本/CI,稳是第一要务。

Terminal window
result=$(claude -p "Generate code" --output-format json)
code=$(echo "$result" | jq -r '.result')
cost=$(echo "$result" | jq -r '.total_cost_usd')

不要假设一定成功——检查 is_error 或退出码与 stderr:

Terminal window
if ! claude -p "$prompt" 2>error.log; then
echo "Error occurred:" >&2
cat error.log >&2
exit 1
fi

长任务用 --name 起名、失败用 --resume 接续,别从头跑:

Terminal window
claude --name ci-build -p "构建并测试"
claude -r ci-build -p "继续上次的修复"

Claude 可能跑很久,加 timeout 防卡死:

Terminal window
timeout 300 claude -p "$complex_prompt" || echo "Timed out after 5 minutes"

并发请求时在调用之间加延时,尊重 API rate limit;CI 里务必加 --max-budget-usd 限钱、--max-turns 限轮数。

Terminal window
claude -p "修 Bug" \
--max-budget-usd 5 \
--max-turns 30 \
--output-format json

headless 场景下,Claude 不是聊天对象,而是一个会吐 JSON 的函数。-p 是入口,--output-format json 是出口,session_id 是接续的钥匙,timeout 是保险丝——把这四件配齐,Claude 就能稳稳嵌进任何流水线。

下一篇看 Unix 管道哲学,看 Claude 怎么和 cattailgh 这些老朋友串成流水线。🚀