以编程方式运行 Claude Code¶
通过 Agent SDK,你可以在 CLI、Python 或 TypeScript 中以编程方式调用 Claude Code。
Agent SDK 提供了与 Claude Code 相同的工具、Agent 循环和上下文管理能力。你可以通过 CLI 在脚本和 CI/CD 中使用它,也可以通过 Python 和 TypeScript 包获得完整的编程控制。
在非交互模式下运行 Claude Code,只需传入 -p 加上你的 Prompt,再搭配任意 CLI 选项:
claude -p "Find and fix the bug in auth.py" --allowedTools "Read,Edit,Bash"
本文介绍如何通过 CLI(claude -p)使用 Agent SDK。如果你需要结构化输出、工具审批回调和原生消息对象,请参阅完整的 Agent SDK 文档。
基本用法¶
添加 -p(或 --print)标志即可以非交互模式运行任何 claude 命令。 所有 CLI 选项 都支持与 -p 配合使用,包括:
下面这个例子会让 Claude 回答关于代码库的问题并打印结果:
claude -p "What does the auth module do?"
使用 bare 模式加速启动¶
添加 --bare 可跳过钩子、技能、插件、MCP 服务器、自动记忆和 CLAUDE.md 的自动加载,从而缩短启动时间。 不加 --bare 时,claude -p 会加载与交互式会话相同的上下文,包括工作目录或 ~/.claude 中配置的所有内容。
bare 模式适用于 CI 和脚本场景——保证每台机器上得到相同的结果。同时 ~/.claude 里的钩子或项目 .mcp.json 中的 MCP 服务器都不会执行,因为 bare 模式不会读取它们。只有你显式传入的标志才会生效。
下面这个例子在 bare 模式下运行一次性摘要任务,并预授权 Read 工具以避免权限提示:
claude --bare -p "Summarize this file" --allowedTools "Read"
在 bare 模式下,Claude 默认可以使用 Bash、文件读取和文件编辑工具。 如果需要加载额外的上下文,使用以下标志:
| 需要加载的内容 | 使用的标志 |
|---|---|
| 系统 Prompt 追加内容 | --append-system-prompt、--append-system-prompt-file |
| 配置 | --settings <file-or-json> |
| MCP 服务器 | --mcp-config <file-or-json> |
| 自定义 Agent | --agents <json> |
| 插件 | --plugin-dir <path>、--plugin-url <url> |
bare 模式会跳过 OAuth 和钥匙串读取。Anthropic 认证必须通过 ANTHROPIC_API_KEY 或 --settings JSON 中的 apiKeyHelper 提供。Amazon Bedrock、Google Cloud Agent Platform 和 Microsoft Foundry 使用各自的 provider 凭证。
提示:
--bare是脚本和 SDK 调用的推荐模式,未来版本中将成为-p的默认行为。
退出时的后台任务处理¶
如果 Claude 在 claude -p 运行期间启动了后台 Bash 任务(例如开发服务器或 watch 构建),该 shell 会在 Claude 返回最终结果且 stdin 关闭后约五秒钟被终止。 这个宽限期允许刚好在结果之后完成的任务仍然能输出内容。在 v2.1.163 之前,一个永不退出的后台进程会无限期挂起 claude -p 调用。
后台子 Agent 和工作流不受五秒宽限期限制,因为它们的结果属于最终输出的一部分,所以 claude -p 会等待它们完成。从 v2.1.182 起,等待时间默认上限为十分钟,以防止卡住的后台 Agent 无限期占用进程。可以通过 CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS 调整上限,设为 0 则无限等待。
如果通过 SIGTERM 停止 claude -p 运行(例如通过 kill、进程管理器或 SDK 宿主关闭会话),Claude Code 会中止正在进行的回合、终止所有运行中 Bash 命令的进程树、运行 SessionEnd 钩子,然后以退出码 143 退出。
使用示例¶
以下示例展示了常见的 CLI 模式。 在 CI 和其他脚本调用中,建议添加 --bare 以避免加载本地配置。
通过管道传输数据¶
非交互模式会读取 stdin,你可以像使用其他命令行工具一样通过管道输入数据并重定向输出。
下面这个例子将构建错误日志管道传入 Claude,并将解释写入文件:
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt
使用 --output-format json 时,响应负载中包含 total_cost_usd 和按模型拆分的费用,脚本调用方可以按次追踪开支而无需查看用量面板。
注意: 从 Claude Code v2.1.128 起,管道输入的 stdin 上限为 10MB。超出上限时,Claude Code 会输出明确的错误信息并以非零状态退出。如需处理更大的输入,请将内容写入文件并在 Prompt 中引用文件路径。
如果 Claude Code 无法读取 stdin(例如启动它的进程断开了连接),Claude Code 会向 stderr 打印一条警告并继续使用命令行中的 Prompt。在 v2.1.211 之前,Windows 上无法读取的 stdin 会导致会话崩溃或静默退出且无输出。
在构建脚本中使用 Claude¶
你可以在脚本中封装非交互调用,将 Claude 用作项目级的 linter 或 reviewer。
下面这个 package.json 脚本将与 main 分支的 diff 管道传入 Claude,要求报告拼写错误。由于 diff 通过管道传入,Claude 不需要 Bash 权限来读取它;转义的双引号保证了在 Windows 上的兼容性:
{
"scripts": {
"lint:claude": "git diff main | claude -p \"you are a typo linter. for each typo in this diff, report filename:line on one line and the issue on the next. return nothing else.\""
}
}
获取结构化输出¶
使用 --output-format 控制响应的返回格式:
text(默认):纯文本输出json:包含结果、会话 ID 和元数据的结构化 JSONstream-json:以换行符分隔的 JSON,用于实时流式传输
下面这个例子以 JSON 格式返回项目摘要及会话元数据,文本结果在 result 字段中:
claude -p "Summarize this project" --output-format json
如果需要符合特定 schema 的输出, 使用 --output-format json 搭配 --json-schema 和一个 JSON Schema 定义。响应中包含请求的元数据(会话 ID、用量等),结构化输出位于 structured_output 字段。
下面这个例子提取函数名并以字符串数组形式返回:
claude -p "Extract the main function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'
如果传入的值不是有效的 JSON Schema,claude 会以 Error: --json-schema is not a valid JSON Schema 加上验证器的诊断信息退出。Claude Code 接受使用 format 关键字的 schema(如 "format": "email"),但将 format 视为注解而不强制执行。在 v2.1.205 之前,Claude Code 会静默忽略无效的 schema 并返回非结构化文本,且将任何包含 format 的 schema 视为无效。
技巧: 使用 jq 解析响应并提取特定字段:
```bash
提取文本结果¶
claude -p "Summarize this project" --output-format json | jq -r '.result'
提取结构化输出¶
claude -p "Extract function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
| jq '.structured_output'
```
流式响应¶
使用 --output-format stream-json 搭配 --verbose 和 --include-partial-messages 可以逐 token 接收生成内容。 每一行是一个代表事件的 JSON 对象:
claude -p "Explain recursion" --output-format stream-json --verbose --include-partial-messages
流的最后一行是 result 消息,包含最终响应文本、费用和会话元数据。
如果你的消费端读取流的速度较慢,Claude Code 会等待队列中的输出排空后再退出,等待时间随队列中剩余数据量按比例增加,上限为 30 秒。在 v2.1.214 之前,退出等待上限约为两秒,可能会截断大响应的末尾。
下面这个例子使用 jq 过滤文本增量并只显示流式文本。-r 标志输出原始字符串(无引号),-j 无换行拼接以实现连续流式输出:
claude -p "Write a poem" --output-format stream-json --verbose --include-partial-messages | \
jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'
如需通过回调和消息对象进行编程式流处理,请参阅 Agent SDK 文档中的实时流式响应。
跟踪子 Agent 消息¶
子 Agent 的消息在流中以 assistant 和 user 消息的形式出现, 其 parent_tool_use_id 字段为产生该子 Agent 的工具调用 ID。主对话的消息该字段为 null。
默认情况下,Claude Code 只发送子 Agent 的 tool_use 和 tool_result 块。传入 --forward-subagent-text 或设置 CLAUDE_CODE_FORWARD_SUBAGENT_TEXT 可以额外发送子 Agent 的 text 和 thinking 块,便于你重建每个子 Agent 的完整对话记录。此功能需要 Claude Code v2.1.211 或更高版本。
启用上述选项后,Claude Code 会转发所有嵌套层级的子 Agent 消息:当一个子 Agent 再派生自己的子 Agent 时,嵌套子 Agent 的消息在 parent_tool_use_id 中携带产生它的 Agent 工具调用 ID,你可以通过这些 ID 重建完整的嵌套树。在 v2.1.219 之前,嵌套子 Agent 的消息不会出现在流中。
处理 API 重试¶
当 API 请求因可重试错误失败时,Claude Code 会在重试前发出 system/api_retry 事件。 你可以用它来展示重试进度或实现自定义退避逻辑。
| 字段 | 类型 | 说明 |
|---|---|---|
type |
"system" |
消息类型 |
subtype |
"api_retry" |
标识这是一个重试事件 |
attempt |
integer | 当前尝试次数,从 1 开始 |
max_retries |
integer | 允许的最大重试次数 |
retry_delay_ms |
integer | 距离下次尝试的毫秒数 |
error_status |
integer 或 null | HTTP 状态码;连接错误无 HTTP 响应时为 null |
error |
string | 错误分类:authentication_failed、oauth_org_not_allowed、billing_error、rate_limit、overloaded、invalid_request、model_not_found、server_error、max_output_tokens 或 unknown |
uuid |
string | 唯一事件标识符 |
session_id |
string | 事件所属的会话 |
读取会话元数据¶
system/init 事件报告会话元数据, 包括模型、工具、MCP 服务器和已加载的插件。它是流中的第一个事件,除非以下启动事件在它之前:
- 设置了
CLAUDE_CODE_SYNC_PLUGIN_INSTALL时的plugin_install事件。 - 配置了
SessionStart或Setup钩子运行时的hook_started、hook_progress和hook_response事件。这些事件在钩子产生时即时发送。Claude Code v2.1.169 到 v2.1.203 会在钩子完成后批量发送(仍在system/init之前);v2.1.204 恢复了实时发送。
该事件还携带一个可选的 capabilities 字符串数组,列出当前 Claude Code 版本实现的协议行为,如 interrupt_receipt_v1 或 interrupt_cancel_queued_v1。用它来做功能检测而非比较版本号,忽略你不认识的值即可。该字段需要 Claude Code v2.1.205 或更高版本,早期版本中不存在。详见 SDKSystemMessage 获取完整的 capability 列表。
在 CI 中检测插件或 MCP 服务器加载失败¶
使用 system/init 事件中的 plugin 字段检测未成功加载的插件:
| 字段 | 类型 | 说明 |
|---|---|---|
plugins |
array | 成功加载的插件,每个包含 name 和 path |
plugin_errors |
array | 插件加载时的错误,每个包含 plugin、type 和 message。包括未满足的依赖版本和 --plugin-dir 加载失败(如路径不存在或归档无效)。受影响的插件被降级且不在 plugins 中。无错误时省略该字段 |
同样可以使用 MCP 服务器字段来检测加载失败。 Claude Code 在启动时验证每个 --mcp-config 条目,跳过验证失败的条目(例如有 url 但缺少 type 的条目);运行会继续并正常退出,因此需要检查这些字段以捕获未加载的服务器:
| 字段 | 类型 | 说明 |
|---|---|---|
mcp_servers |
array | 会话中的 MCP 服务器,每个包含 name 和 status |
mcp_server_errors |
array | 被配置验证跳过的 --mcp-config 条目,每个包含 name、type 和 message。type 是跳过类别,如 unknown_type、url_missing_type、invalid_config 或 reserved_name;对于不认识的值视为通用跳过。受影响的服务器不在 mcp_servers 中。无错误时省略该字段,因此 CI 门控可以在数组非空时失败。需要 Claude Code v2.1.219 或更高版本 |
在终端中手动运行命令时,Claude Code 还会向 stderr 打印启动警告,如 Warning: 1 MCP server skipped due to invalid config:,后跟每个被跳过条目的原因。当你重定向 stderr,或当程序(如 CI runner 或 SDK 宿主)捕获它时,Claude Code 不打印警告,仅在 mcp_server_errors 字段中报告被跳过的条目。该警告需要 Claude Code v2.1.219 或更高版本。
跟踪插件安装¶
设置 CLAUDE_CODE_SYNC_PLUGIN_INSTALL 后, Claude Code 会在首轮之前安装 marketplace 插件时发出 system/plugin_install 事件。用这些事件在你的 UI 中展示安装进度。
| 字段 | 类型 | 说明 |
|---|---|---|
type |
"system" |
消息类型 |
subtype |
"plugin_install" |
标识这是一个插件安装事件 |
status |
"started"、"installed"、"failed" 或 "completed" |
started 和 completed 包裹整个安装过程;installed 和 failed 报告各个 marketplace 的结果 |
name |
string(可选) | marketplace 名称,出现在 installed 和 failed 状态中 |
error |
string(可选) | 失败信息,出现在 failed 状态中 |
uuid |
string | 唯一事件标识符 |
session_id |
string | 事件所属的会话 |
自动授权工具¶
使用 --allowedTools 让 Claude 无需确认即可使用特定工具。 下面这个例子运行测试套件并修复失败用例,允许 Claude 执行 Bash 命令、读取和编辑文件而无需请求权限:
claude -p "Run the test suite and fix any failures" \
--allowedTools "Bash,Read,Edit"
如果想为整个会话设置基线权限而不是逐个列出工具, 可以传入权限模式。dontAsk 会拒绝不在 permissions.allow 规则或只读命令集中的所有操作,适合锁定的 CI 环境。AskUserQuestion、组织设置为 ask 的 connector 工具、以及标记了 requiresUserInteraction 的 MCP 工具,即使有匹配的 allow 规则也会被拒绝。
acceptEdits 允许 Claude 无需确认即可写入文件,同时自动批准常见的文件系统命令如 mkdir、touch、mv 和 cp。其他 shell 命令和网络请求仍需要 --allowedTools 条目或 permissions.allow 规则,否则运行时会中止:
claude -p "Apply the lint fixes" --permission-mode acceptEdits
创建提交¶
下面这个例子审查暂存的变更并创建一个带有合适信息的提交:
claude -p "Look at my staged changes and create an appropriate commit" \
--allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)"
--allowedTools 标志使用权限规则语法。末尾的 * 启用前缀匹配,所以 Bash(git diff *) 允许任何以 git diff 开头的命令。* 前面的空格很重要:没有它,Bash(git diff*) 还会匹配 git diff-index。
注意: 用户调用的技能和自定义命令在
-p模式下可用:在 Prompt 字符串中包含/skill-name,Claude Code 会在运行前展开它。只在终端界面中运行的内置命令(如/login)在-p模式下不可用。/model、/effort、/fast、/color和/rename接受参数形式(如/model sonnet),/mcp不带参数时输出服务器状态的文本摘要;这些形式需要 Claude Code v2.1.205 或更高版本,并遵循各命令的可用性说明。要在-p调用中更改设置,向/config传入key=value,例如/config thinking=false。
自定义系统 Prompt¶
使用 --append-system-prompt 在保留 Claude Code 默认行为的同时添加指令。 下面这个例子将 PR diff 管道传入 Claude,并指示它以安全工程师的身份审查漏洞:
gh pr diff "$1" | claude -p \
--append-system-prompt "You are a security engineer. Review for vulnerabilities." \
--output-format json
更多选项请参阅系统 Prompt 标志,包括 --system-prompt 完全替换默认 Prompt。
继续对话¶
使用 --continue 继续最近的对话,或使用 --resume 加会话 ID 继续特定对话。 下面这个例子先运行一次审查,然后发送后续 Prompt:
# 第一次请求
claude -p "Review this codebase for performance issues"
# 继续最近的对话
claude -p "Now focus on the database queries" --continue
claude -p "Generate a summary of all issues found" --continue
如果你在并行运行多个对话,捕获会话 ID 以恢复特定对话:
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"
两个命令需要在同一目录下运行:会话 ID 查找的作用域限定在当前项目目录及其 git worktree 中。完整的作用域规则请参阅恢复会话。
后续阅读¶
- Agent SDK 快速入门:用 Python 或 TypeScript 构建你的第一个 Agent
- CLI 参考:所有 CLI 标志和选项
- GitHub Actions:在 GitHub 工作流中使用 Agent SDK
- GitLab CI/CD:在 GitLab 管道中使用 Agent SDK