首页 / Claude Code 入门教程 / Headless 与脚本化

Claude Code 入门教程

Headless 与脚本化

本教程共 34 篇 · 第 29 篇 · 更新于 2026-07-26 · 约 8 分钟阅读

Claude CodeClaude Code 入门教程HeadlessAgent SDK脚本化CLI

29. Headless 与脚本化

本节目标:学会用 -p 打印模式把 Claude Code 当命令行工具用,掌握管道组合、结构化输出、无人值守配置,并了解 Agent SDK 怎么把 Claude Code 嵌进你自己的程序。

什么是 Headless 模式

前面那么多章,Claude Code 都是交互式跑的:你敲一句、它回一句。但很多时候你想把它塞进脚本里自动跑,比如 CI 里审查代码、定时任务里汇总日志、构建失败时自动分析原因。

这就需要 Headless(无头)模式。说白了,就是不让 Claude 开那个交互界面,直接给它一个提示,让它干完活把结果吐出来,然后退出。

Agent SDK 给了你和 Claude Code 一样的工具、agent 循环和上下文管理。它既能当 CLI 用(就是 claude -p),也能当 Python、TypeScript 包用,做完整的编程控制。

这章主要讲 CLI 这条路(claude -p),SDK 包的部分最后简单提一下。

-p 打印模式基本用法

claude 加个 -p(或 --print)标志,就是非交互模式。所有 CLI 选项都能配合 -p 用:

claude -p "What does the auth module do?"

它跑完直接打印结果,然后退出,不会停下来等你。

跟交互模式一样,-p 默认会加载工作目录或 ~/.claude 里配的 hooks、skills、plugins、MCP 服务器和 CLAUDE.md。这在本地用没问题,但在 CI 里可能就不想要这些「个人配置」干扰。

—bare 裸模式

--bare 跳过所有自动发现,启动更快,结果更可控:

claude --bare -p "Summarize this file" --allowedTools "Read"

裸模式下,队友 ~/.claude 里的 hook、项目 .mcp.json 里的 MCP 服务器都不会跑,只有你显式传的标志才生效。这在 CI 里特别重要,能保证每台机器上结果一致。

裸模式下 Claude 还是能用 Bash、文件读写和文件编辑工具。需要啥上下文,用标志传进去:

要加载的东西用的标志
系统提示补充--append-system-prompt--append-system-prompt-file
设置--settings <file-or-json>
MCP 服务器--mcp-config <file-or-json>
自定义 agents--agents <json>
插件--plugin-dir <path>--plugin-url <url>
Note

--bare 是脚本和 SDK 调用的推荐模式,未来版本会成为 -p 的默认行为。裸模式会跳过 OAuth 和钥匙链读取,认证必须来自 ANTHROPIC_API_KEY 环境变量或 --settings 里的 apiKeyHelper

管道组合

非交互模式会读 stdin,所以你能像用任何 Unix 工具一样,把数据管道喂给它,再把结果重定向出去。

这个例子把构建错误日志喂给 Claude,让它分析根因,结果写进文件:

cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt

也可以塞进 package.json 的脚本里,把 Claude 当项目专用的 linter。下面这个脚本把针对 main 的 diff 喂给 Claude,让它挑拼写错误:

{
  "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.\""
  }
}

管道传 diff 的好处是:Claude 不需要 Bash 权限去读文件,权限更干净。

Warning

从 v2.1.128 起,管道 stdin 上限 10MB。超了会报错退出。内容太大就写进文件,在提示里引用文件路径,别硬管道。

结构化输出

三种输出格式

--output-format 控制返回方式:

  • text(默认):纯文本
  • json:结构化 JSON,包含结果、会话 ID 和元数据
  • stream-json:换行符分隔的 JSON,用于实时流式传输

要 JSON 格式很简单:

claude -p "Summarize this project" --output-format json

JSON 里除了文本结果(result 字段),还带 total_cost_usd 和按模型的成本分解,方便脚本跟踪每次调用的花费。

JSON Schema 约束输出

想让输出严格符合某个结构?用 --output-format json 配合 --json-schema 和 JSON Schema 定义。结构化结果在 structured_output 字段里。

这个例子从 auth.py 提取函数名,返回字符串数组:

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"]}'

配合 jq 工具解析特别顺手:

# 提取纯文本结果
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'
Tip

如果 --json-schema 的值不是合法 JSON Schema,Claude 会报错退出。注意它接受 format 关键字(比如 "format": "email"),但只当注释看,不强制校验。

流式输出

想实时看到 Claude 一个字一个字吐出来,用 stream-json 配合 --verbose--include-partial-messages

claude -p "Explain recursion" --output-format stream-json --verbose --include-partial-messages

每一行是一个 JSON 事件对象。流的最后一行是 result 消息,包含最终文本、成本和会话元数据。

只想要流式文本,用 jq 过滤一下:

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'

流里还有 system/init(会话启动,报告模型、工具、插件)、system/api_retry(API 重试)等事件,方便你做进度展示或退避逻辑。

无人值守的关键配置

让 Claude 自己跑,最怕两件事:一是它停下来问你要权限,二是它无限循环烧钱。下面这几个配置专门解决这些。

自动批准工具

--allowedTools 让 Claude 用某些工具时不弹权限提示:

claude -p "Run the test suite and fix any failures" \
  --allowedTools "Bash,Read,Edit"

这个例子让它跑测试、修失败,Bash 命令和读写文件都不用问。

工具名还能带参数规则。比如只想让它跑 git 相关命令:

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 *)"

Bash(git diff *) 里的 * 是前缀匹配,注意 * 前面要有空格,不然 git diff* 会连 git diff-index 也匹配上。

权限模式

不想一个个列工具,用 --permission-mode 设个基线:

  • acceptEdits:自动批准写文件,还有 mkdirtouchmvcp 这些常见文件命令,但网络请求和其他 shell 命令还得单独批准
  • dontAsk:拒绝所有不在 permissions.allow 规则或只读命令集里的东西,适合锁死的 CI
claude -p "Apply the lint fixes" --permission-mode acceptEdits

继续会话

非交互模式也能延续之前的对话。--continue 接最近的,--resume 接指定会话 ID:

# 第一次请求
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"
Note

会话 ID 的查找范围限定在当前项目目录及其 git worktrees。两个命令要从同一目录跑才能找到对应会话。

自定义系统提示

--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

想完全替换默认提示,用 --system-prompt,但一般不推荐,因为会丢掉 Claude Code 内置的那些工具使用规则。

Agent SDK 概览

上面讲的都是 CLI(claude -p)这条线。如果你想要更深的编程控制,比如结构化输出回调、工具批准回调、原生消息对象,就该上 Agent SDK 的 Python 或 TypeScript 包了。

它是什么

Agent SDK 把驱动 Claude Code 的工具、agent 循环和上下文管理,开放成了可编程的库。简单说,就是把 Claude Code 当一个库来用,嵌进你自己的应用、CI 流水线或自动化脚本里。

内置能力包括:

  • 文件读写、终端命令、代码编辑、Web 搜索等内置工具
  • 钩子(Hook):在工具调用前后执行自定义逻辑
  • 子代理(Subagent):把大任务拆开并行交给独立 agent
  • MCP 服务器:连数据库、浏览器、外部 API
  • 权限控制:精细控制 agent 能干啥、啥时候要审批
  • 会话管理:保持上下文的多轮对话

安装

TypeScript:

npm install @anthropic-ai/claude-agent-sdk

TypeScript SDK 会把当前平台的 Claude Code 二进制文件当可选依赖一起打包,不用单独装 Claude Code。

Python:

# 用 pip
pip install claude-agent-sdk

# 或用 uv(推荐)
uv add claude-agent-sdk

Python 包也会自动带上 Claude Code CLI,默认用打包的 CLI。想用系统装的或指定版本,传 ClaudeAgentOptions(cli_path="/path/to/claude")

配置 API Key

从 Claude Console 拿到 API Key,设成环境变量:

export ANTHROPIC_API_KEY=your-api-key-here

SDK 也支持第三方云:Amazon Bedrock(CLAUDE_CODE_USE_BEDROCK=1)、Google Cloud 的 Agent Platform(CLAUDE_CODE_USE_VERTEX=1)、Microsoft Foundry(CLAUDE_CODE_USE_FOUNDRY=1)。

Warning

除非事先获得 Anthropic 批准,第三方开发者不许在基于 Agent SDK 构建的产品里提供 claude.ai 登录或速率限制。老老实实用 API Key 认证。

一个简单例子

Python 版,让 agent 列出当前目录的文件:

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions

async def main():
    async for message in query(
        prompt="What files are in this directory?",
        options=ClaudeAgentOptions(),
    ):
        print(message)

asyncio.run(main())

TypeScript 版类似,调 query 函数,传 prompt 和 options,异步遍历消息流。

什么时候用哪个

简单总结一下选型:

  • 临时跑一下、写脚本:直接 claude -p,够用
  • CI 里要可控、要可复现claude --bare -p,加 --allowedTools 和权限模式
  • 要嵌进自己的程序、做复杂编排:上 Agent SDK 的 Python 或 TypeScript 包

不管哪条路,核心都是把 Claude Code 的能力从「你盯着它干」变成「它自己干完汇报」。这是从「AI 助手」走向「AI 自动化」的关键一步。