目标:讲清三个层次------(1)
claude -pheadless 模式:Claude Code 自身的非交互入口,完整 Agent 循环,dontAsk 权限,stdin/stdout 管道;(2)Anthropic API + Agent SDK:用 Messages API 调 Claude 模型,用 Tool Runner 自动管理 tool_use/tool_result 循环,造自己的 agent 应用;(3)Managed Agents:Anthropic 托管的远程沙箱 agent,纯 HTTP API,SSE 流式。核心认知:Claude Code CLI 不开 API,不能当服务调用。但它用的原料(Anthropic API + Tool Runner)你也可以用。 受众:专业程序员。本机版本2.1.220。
17.1 基本事实:Claude Code CLI 没有 API
你不能这样调用 Claude Code:
bash
❌ curl http://localhost:3000/claude-code -d '{"prompt": "fix bug"}'
❌ client.claudeCode.run({ prompt: "fix bug" })
Claude Code 是一个终端应用。进程启动了,读 stdin、调 Anthropic API、执行工具、写 stdout。进程结束就结束。没有 HTTP 端口在监听,没有 SDK 可以 import。
但你确实可以这样:
bash
✅ claude -p "分析 src/auth.ts 的认证逻辑并给出改进建议"
这是 Claude Code 的 headless 模式------仍然是同一个二进制,同一个 Agent 循环,但交互方式变成了单次输入、单次输出。
17.2 Headless 模式(claude -p)
它是什么
-p(--print)让 Claude Code 以非交互方式运行。Ch02 提过,这里展开内部机制。
从二进制确认的关键行为:
vbnet
isNonInteractiveSession: true ← 非交互标志
permission mode: "dontAsk" ← 不会弹窗问"可以吗?"
完整流程
c
claude -p "分析 error.log 找出根因"
│
├─→ 启动(加载 CLAUDE.md、memory、skills、rules------和交互模式完全一样)
│
├─→ 进入 Agent 循环
│ │
│ ├─→ LLM 回复 → 可能包含 tool_use(Read、Grep、Bash...)
│ ├─→ 工具执行(权限全放行,dontAsk)
│ ├─→ tool_result 发回 LLM
│ └─→ 循环直到 stop_reason == "end_turn"
│
└─→ 打印最终结果到 stdout → 退出
关键认知:它不是"把 prompt 发给 Claude 拿个回复就完了"。它是完整的 Agent 循环------LLM 可以调 Read 读文件、Grep 搜代码、Bash 跑命令------和你交互式会话完全一样的能力。只是没人坐在终端前按"批准"。
与交互模式的区别
| 维度 | 交互模式 | Headless(-p) |
|---|---|---|
| 交互 | 持续对话 | 单次执行,打印即退出 |
| Agent 循环 | 完整 | 完整(相同) |
| 权限 | 危险操作弹窗确认 | dontAsk 全放行 |
| CLAUDE.md / memory / skills | 加载 | 加载(相同) |
| 输出 | 流式打印到终端 | 打印最终结果到 stdout |
| 退出码 | N/A(不退出) | 0=成功,1=失败 |
工程化用法
bash
# CI: 检查 CHANGELOG 是否更新
claude -p "检查本次 git diff 是否包含对 CHANGELOG.md 的更新。如未更新,返回非零退出码。"
# Git pre-commit hook
#!/bin/bash
claude -p "审查暂存区代码变更,检查:1) 硬编码凭据 2) SQL 注入 3) 路径遍历。列出问题。"
# 自动化 release note
git log --oneline v1.0..HEAD | claude -p "用这些 commit 生成发布说明,按 feature/bugfix/breaking 分类。"
# 管道中作为一个环节
grep -r "TODO" src/ | claude -p "分析这些 TODO 注释,按优先级排序,标注哪些是技术债、哪些是功能缺口。"
--headless 子标志
二进制中还出现了一个更彻底的模式:agent hook 的 isNonInteractiveSession 和 headless profiler 追踪。这个模式关闭所有可能等待用户输入的路径------包括 structured output 的 thinking config 被设为 disabled,确保 agent 永远不会"等待用户确认"。
17.3 Anthropic API:调 Claude 模型的 HTTP 接口
Headless 模式解决的是"在脚本中使用 Claude Code"。如果你想要更大的控制权------自定义工具、自定义循环逻辑、嵌入自己的应用------那需要往下走一层。
Messages API
这是最底层的接口------不是 Claude Code 的东西,是 Anthropic 的云服务:
python
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5-20251001",
max_tokens=1024,
messages=[{"role": "user", "content": "解释这段代码的算法复杂度"}],
)
print(response.content[0].text)
这就是一次 HTTP POST /v1/messages。你给 messages,Claude 给回复。没有工具、没有循环、没有文件系统。
加上工具
python
response = client.messages.create(
model="claude-sonnet-5-20251001",
messages=[{"role": "user", "content": "读 README.md 并告诉我项目名称"}],
tools=[{
"name": "Read",
"description": "Read a file from the local filesystem",
"input_schema": {
"type": "object",
"properties": {
"file_path": {"type": "string", "description": "Path to the file to read"}
},
"required": ["file_path"]
}
}]
)
# response.stop_reason 可能是 "tool_use"
# response.content 包含 tool_use 块 → 你需要自己执行
这一步之后,你自己负责:
- 解析
response.content中的tool_use块 - 执行实际的文件读取
- 构造
tool_result消息 - 把
assistant消息和tool_result消息一起发回messages.create - 检查
stop_reason------"tool_use"就继续循环,"end_turn"就退出
这就是手动 Agent 循环。
17.4 Agent SDK:Tool Runner 帮你跑循环
手动循环写着烦。Agent SDK(@anthropic-ai/claude-agent-sdk for TS,claude-agent-sdk for Python)提供了 Tool Runner------帮你自动化。
它做什么
python
# Tool Runner 管理整个循环
runner = client.beta.messages.tool_runner(
model="claude-sonnet-5-20251001",
messages=[{"role": "user", "content": "检查 src/ 下所有 .ts 文件的类型错误"}],
tools=[bash_tool, read_tool, grep_tool],
)
for event in runner:
if event.stop_reason.type == "end_turn":
break # agent 做完了
if event.stop_reason.type == "requires_action":
continue # 需要你处理 tool_use → 但 runner 已自动处理
Tool Runner 自动做的事:
- 发送 messages → 收到 response
- 解析
tool_use块 → 执行对应工具函数 - 构造
tool_result→ 追加到 messages - 继续循环 → 直到
stop_reason == "end_turn"
你可以通过 hook 介入:
- PreToolUse hook:在每个工具执行前批准/拒绝/修改参数
- PostToolUse hook:在每个工具执行后记录/分析/注入反馈
stop_reason 的几个关键值
从二进制确认:
| stop_reason | 含义 | 怎么做 |
|---|---|---|
"end_turn" |
Agent 完成,不需要更多操作 | 退出循环,返回结果 |
"tool_use" |
Agent 想调工具 | 执行工具,发回 tool_result |
"pause_turn" |
Agent 暂停(等待外部事件) | 等事件发生后继续 |
"requires_action" |
需要客户端动作(如审批) | 处理后继续 |
工具定义------sdk-tools.d.ts 的来源
Claude Code npm 包根目录的 sdk-tools.d.ts 定义了所有工具的 TypeScript 类型。这是 Claude Code 从自身二进制中提取出来给 SDK 开发者参考的:
typescript
// 不是"调 Claude Code 的 API"
// 是"参考 Claude Code 用了什么工具、长什么样"
export interface FileReadInput {
file_path: string;
offset?: number;
limit?: number;
}
export interface BashInput {
command: string;
description: string;
timeout?: number;
// ...
}
它不是 SDK 的"接口定义"------它是 Claude Code 内部工具的类型快照,供你建自己的 agent 时参考。
手写循环的场景
二进制 SDK 文档列出了真正需要跳过 Tool Runner 的情况:
- 自定义 transport(不是标准 HTTP)
- 需要 per-token 级流控(Tool Runner 的粒度是 per-message)
- 请求格式 SDK 不能构建
多数场景不需要手写。Tool Runner 的 PreToolUse/PostToolUse 钩子已经覆盖了审批、日志、拦截、修改。
17.5 Managed Agents:Anthropic 帮你跑
如果你不想自己搭 Agent 循环、不想管沙箱、不想维护服务器------Anthropic 提供托管方案。
从二进制确认:
Managed Agents: server-hosted stateful agents with an Anthropic-managed sandbox --- create an agent once, start sessions that reference it; SSE event stream, Skills + MCP, file mounts
模型
bash
你: POST /v1/agents/{id}/sessions → 启动 agent 会话
Anthropic: 托管沙箱里跑 agent → 通过 SSE 流式返回事件
你: GET /v1/sessions/{id}/events/stream → 收事件,显示进度
关键特性
| 特性 | 说明 |
|---|---|
| 一次创建,多次使用 | agents.create() 是 setup 步骤,存下 agent_id 复用 |
| SSE 事件流 | 实时 streaming:agent.tool_use→agent.tool_result→agent.text |
| Skills + MCP | Agent 可以使用 skills 和 MCP 工具 |
| MCP 认证走 vault | 凭据存在 vault 中,不暴露在 agent 配置里。OAuth token 自动刷新 |
| 文件挂载 | 挂载文件到沙箱,agent 只能访问挂载的内容 |
| 沙箱隔离 | 不碰你的本地文件系统 |
| 版本化 | 每次更新 agent 配置创建新版本,session 可以锁定特定版本 |
| 自托管沙箱 | self_hosted 模式:工具执行在你自己的环境(Anthropic 只管模型推理) |
相关 HTTP Headers
managed-agents-2026-04-01 ← Managed Agents API
files-api-2025-04-14 ← Files API(挂载文件)
skills-2025-10-02 ← Skills API
与本地 Claude Code 的本质区别
yaml
本地 Claude Code CLI:
二进制跑在你机器上 → 直接读你的文件 → 用你的 shell → 调 Anthropic API
Managed Agent:
HTTP POST 过去 → Anthropic 的沙箱里跑 → 只访问你挂载的文件
→ 沙箱内的 shell → SSE 流回结果
17.6 三层全景
objectivec
┌──────────────────────────────────────────────┐
│ │
│ Managed Agents │
│ (Anthropic 托管,纯 HTTP API + SSE) │
│ 你不写循环、不管沙箱、不维护服务器 │
│ │
├──────────────────────────────────────────────┤
│ │
│ Agent SDK (Tool Runner) │
│ (npm/pip 包,帮你管理 tool_use 循环) │
│ 你自己定义工具、写循环逻辑、部署应用 │
│ │
├──────────────────────────────────────────────┤
│ │
│ Claude Code CLI │
│ (终端应用,本书 00~17 章完整拆解) │
│ 交互式 REPL / headless -p │
│ 工具: Read Write Edit Bash Glob Grep ... │
│ 机制: CLAUDE.md memory skills hooks MCP ... │
│ │
└──────────────────────────────────────────────┘
Claude Code CLI 自己没有 API。
下面两层(Agent SDK + Managed Agents)使用的是同一套工具定义和 Agent 循环模型。
理解下面两层就能理解 Claude Code CLI 是怎么被造出来的。
17.7 本章核心带走
-
Claude Code CLI 没有 API。 它是终端应用,不能当服务调、不能 import。
claude -p是它唯一的非交互入口。 -
-p是完整的 Agent 循环。 不是"发个 prompt 拿回复"。LLM 可以调 Read、Grep、Bash,和在交互模式中一样。区别只是没人点"批准"------权限自动放行。 -
Anthropic Messages API 是原材料。
POST /v1/messages,给 messages 拿回复。加上 tools 定义后,模型会返回tool_use块------你负责执行、发回结果、继续循环。 -
Agent SDK (Tool Runner) 帮你跑循环。 自动化
send → receive(tool_use) → execute → send(tool_result) → ... → end_turn。PreToolUse/PostToolUse 钩子可以批准、拒绝、修改。sdk-tools.d.ts是参考文档,不是 Claude Code 的 API。 -
Managed Agents 是 Anthropic 托管方案。 HTTP 调、SSE 收。沙箱隔离、凭据走 vault、文件挂载。可以不碰本地文件系统。
-
三层同一套模型。 Claude Code CLI 内部也在跑 Agent 循环、定义工具。Agent SDK 把同样的能力暴露为编程接口。Managed Agents 把同样的能力暴露为云服务。