引言
如果你使用过 Claude Code,你一定见识过 AI 代理的强大能力:读取文件、执行命令、编辑代码、自主规划任务步骤。它不仅仅是帮你写代码,而是像一位有思考能力的工程师一样,主动接手问题并系统性地解决它们。
现在,支撑 Claude Code 的核心引擎——Claude Agent SDK——已经开放给所有开发者。你可以用它来构建自己的 AI 代理,解决各种实际问题。
本指南将带你从零开始,学习如何使用 Claude Agent SDK 构建一个完整的代码审查代理。更重要的是,你将深入理解 SDK 的工作原理,从而能够构建任何你需要的代理应用。
什么是 Claude Agent SDK?
Claude Agent SDK 是 Claude Code 背后的基础设施,以库的形式对外开放。它为你提供了:
🔄 代理循环(Agent Loop):自动管理与 AI 的多轮交互
🛠️ 内置工具:文件操作、命令执行、代码搜索等开箱即用
💾 上下文管理:自动处理对话历史和工作状态
📦 完整的代理框架:你本来需要从头实现的所有功能
简单来说,你不需要重新发明轮子,SDK 已经把构建代理所需的所有基础设施都准备好了。
为什么使用 Agent SDK?
如果你曾经用原始 API 构建过代理,你一定知道那个繁琐的流程:调用模型 → 检查是否需要工具 → 执行工具 → 将结果反馈给模型 → 重复直到完成。对于复杂任务来说,这很快就会变得难以维护。
SDK 为你管理这个循环:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 不使用 SDK:你需要手动管理循环
let response = await client.messages.create({...});
while (response.stop_reason === "tool_use") {
const result = yourToolExecutor(response.tool_use);
response = await client.messages.create({
tool_result: result,
...
});
}
// 使用 SDK:Claude 自动管理
for await (const message of query({
prompt: "Fix the bug in auth.py"
})) {
console.log(message); // Claude 会自动读取文件、定位 bug、编辑代码
}
内置工具,开箱即用:
📖 Read:读取工作目录中的任何文件
✍️ Write:创建新文件
✏️ Edit:对现有文件进行精确编辑
💻 Bash:运行终端命令
🔍 Glob:按模式查找文件
🔎 Grep:用正则表达式搜索文件内容
🌐 WebSearch:网络搜索
📄 WebFetch:获取和解析网页
所有这些工具都不需要你自己实现。
准备工作
环境要求
Node.js 18 或更高版本
Anthropic API 密钥(在这里获取)
安装步骤
步骤 1:安装 Claude Code CLI
Agent SDK 使用 Claude Code 作为运行时环境:
1
npm install -g @anthropic-ai/claude-code
安装完成后,在终端运行 claude 并按提示进行身份验证。
步骤 2:创建项目
1
2
3
4
mkdir code-review-agent && cd code-review-agent
npm init -y
npm install @anthropic-ai/claude-agent-sdk
npm install -D typescript @types/node tsx
步骤 3:设置 API 密钥
1
export ANTHROPIC_API_KEY=your-api-key
快速开始
让我们从一个简单的示例开始。创建 agent.ts 文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { query } from "@anthropic-ai/claude-agent-sdk";
async function main() {
for await (const message of query({
prompt: "What files are in this directory?",
options: {
model: "opus",
allowedTools: ["Glob", "Read"],
maxTurns: 250
}
})) {
if (message.type === "assistant") {
for (const block of message.message.content) {
if ("text" in block) {
console.log(block.text);
}
}
}
if (message.type === "result") {
console.log("
Done:", message.subtype);
}
}
}
main();
运行它:
1
npx tsx agent.ts
Claude 会使用 Glob 工具列出文件并告诉你发现了什么。就这么简单!
核心概念:理解消息流
query() 函数返回一个异步生成器,在 Claude 工作时流式传输消息。以下是关键的消息类型:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
for await (const message of query({ prompt: "..." })) {
switch (message.type) {
case "system":
// 会话初始化信息
if (message.subtype === "init") {
console.log("Session ID:", message.session_id);
console.log("Available tools:", message.tools);
}
break;
case "assistant":
// Claude 的响应和工具调用
for (const block of message.message.content) {
if ("text" in block) {
console.log("Claude:", block.text);
} else if ("name" in block) {
console.log("Tool call:", block.name);
}
}
break;
case "result":
// 最终结果
console.log("Status:", message.subtype); // "success" 或错误类型
console.log("Cost:", message.total_cost_usd);
break;
}
}
这个消息流机制让你能够:
实时监控代理的工作进度
记录工具调用日志
处理错误和异常
追踪 API 成本
实战项目:构建代码审查代理
现在让我们构建一个真正有用的应用。创建 review-agent.ts:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { query } from "@anthropic-ai/claude-agent-sdk";
async function reviewCode(directory: string) {
console.log(`
🔍 Starting code review for: ${directory}
`);
for await (const message of query({
prompt: `Review the code in ${directory} for:
1. Bugs and potential crashes
2. Security vulnerabilities
3. Performance issues
4. Code quality improvements
Be specific about file names and line numbers.`,
options: {
model: "opus",
allowedTools: ["Read", "Glob", "Grep"],
permissionMode: "bypassPermissions", // 自动批准读取操作
maxTurns: 250
}
})) {
// 实时显示 Claude 的分析过程
if (message.type === "assistant") {
for (const block of message.message.content) {
if ("text" in block) {
console.log(block.text);
} else if ("name" in block) {
console.log(`
📁 Using ${block.name}...`);
}
}
}
// 显示完成状态
if (message.type === "result") {
if (message.subtype === "success") {
console.log(`
✅ Review complete! Cost: $${message.total_cost_usd.toFixed(4)}`);
} else {
console.log(`
❌ Review failed: ${message.subtype}`);
}
}
}
}
// 审查当前目录
reviewCode(".");
测试代理
创建一个包含一些故意错误的测试文件 example.ts:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function processUsers(users: any) {
for (let i = 0; i <= users.length; i++) { // 边界错误
console.log(users[i].name.toUpperCase()); // 没有空值检查
}
}
function connectToDb(password: string) {
const connectionString = `postgres://admin:${password}@localhost/db`;
console.log("Connecting with:", connectionString); // 记录敏感数据
}
async function fetchData(url) { // 缺少类型注解
const response = await fetch(url);
return response.json(); // 没有错误处理
}
运行审查:
1
npx tsx review-agent.ts
Claude 会识别出这些 bug、安全问题,并提出修复建议。
结构化输出:获取可编程数据
对于需要程序化处理的场景,SDK 支持 JSON Schema 输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { query } from "@anthropic-ai/claude-agent-sdk";
const reviewSchema = {
type: "object",
properties: {
issues: {
type: "array",
items: {
type: "object",
properties: {
severity: {
type: "string",
enum: ["low", "medium", "high", "critical"]
},
category: {
type: "string",
enum: ["bug", "security", "performance", "style"]
},
file: { type: "string" },
line: { type: "number" },
description: { type: "string" },
suggestion: { type: "string" }
},
required: ["severity", "category", "file", "description"]
}
},
summary: { type: "string" },
overallScore: { type: "number" }
},
required: ["issues", "summary", "overallScore"]
};
async function reviewCodeStructured(directory: string) {
for await (const message of query({
prompt: `Review the code in ${directory}. Identify all issues.`,
options: {
model: "opus",
allowedTools: ["Read", "Glob", "Grep"],
permissionMode: "bypassPermissions",
maxTurns: 250,
outputFormat: {
type: "json_schema",
schema: reviewSchema
}
}
})) {
if (message.type === "result" && message.subtype === "success") {
const review = message.structured_output as {
issues: Array<{
severity: string;
category: string;
file: string;
line?: number;
description: string;
suggestion?: string;
}>;
summary: string;
overallScore: number;
};
console.log(`
📊 Code Review Results
`);
console.log(`Score: ${review.overallScore}/100`);
console.log(`Summary: ${review.summary}
`);
for (const issue of review.issues) {
const icon = issue.severity === "critical" ? "🔴" :
issue.severity === "high" ? "🟠" :
issue.severity === "medium" ? "🟡" : "🟢";
console.log(`${icon} [${issue.category.toUpperCase()}] ${issue.file}${issue.line ? `:${issue.line}` : ""}`);
console.log(` ${issue.description}`);
if (issue.suggestion) {
console.log(` 💡 ${issue.suggestion}`);
}
console.log();
}
}
}
}
reviewCodeStructured(".");
有了结构化输出,你可以:
将结果存入数据库
生成报告和图表
与其他系统集成
实现自动化工作流
权限管理
默认情况下,SDK 在执行工具前会请求批准。你可以自定义这个行为:
权限模式
1
2
3
4
5
6
7
8
9
10
options: {
// 标准模式 - 提示批准
permissionMode: "default",
// 自动批准文件编辑
permissionMode: "acceptEdits",
// 无提示(谨慎使用)
permissionMode: "bypassPermissions"
}
自定义权限处理器
对于细粒度控制,使用 canUseTool:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
options: {
canUseTool: async (toolName, input) => {
// 允许所有读取操作
if (["Read", "Glob", "Grep"].includes(toolName)) {
return { behavior: "allow", updatedInput: input };
}
// 阻止写入特定文件
if (toolName === "Write" && input.file_path?.includes(".env")) {
return {
behavior: "deny",
message: "Cannot modify .env files"
};
}
// 允许其他一切
return { behavior: "allow", updatedInput: input };
}
}
高级功能
子代理:专业分工
对于复杂任务,你可以创建专门的子代理:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import { query, AgentDefinition } from "@anthropic-ai/claude-agent-sdk";
async function comprehensiveReview(directory: string) {
for await (const message of query({
prompt: `Perform a comprehensive code review of ${directory}.
Use the security-reviewer for security issues and test-analyzer for test coverage.`,
options: {
model: "opus",
allowedTools: ["Read", "Glob", "Grep", "Task"],
permissionMode: "bypassPermissions",
maxTurns: 250,
agents: {
"security-reviewer": {
description: "Security specialist for vulnerability detection",
prompt: `You are a security expert. Focus on:
- SQL injection, XSS, CSRF vulnerabilities
- Exposed credentials and secrets
- Insecure data handling
- Authentication/authorization issues`,
tools: ["Read", "Grep", "Glob"],
model: "sonnet"
} as AgentDefinition,
"test-analyzer": {
description: "Test coverage and quality analyzer",
prompt: `You are a testing expert. Analyze:
- Test coverage gaps
- Missing edge cases
- Test quality and reliability
- Suggestions for additional tests`,
tools: ["Read", "Grep", "Glob"],
model: "haiku" // 对简单分析使用更快的模型
} as AgentDefinition
}
}
})) {
if (message.type === "assistant") {
for (const block of message.message.content) {
if ("text" in block) {
console.log(block.text);
} else if ("name" in block && block.name === "Task") {
console.log(`
🤖 Delegating to: ${(block.input as any).subagent_type}`);
}
}
}
}
}
会话管理:多轮对话
捕获并恢复会话以实现连续对话:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
async function interactiveReview() {
let sessionId: string | undefined;
// 初始审查
for await (const message of query({
prompt: "Review this codebase and identify the top 3 issues",
options: {
model: "opus",
allowedTools: ["Read", "Glob", "Grep"],
permissionMode: "bypassPermissions",
maxTurns: 250
}
})) {
if (message.type === "system" && message.subtype === "init") {
sessionId = message.session_id;
}
// ... 处理消息
}
// 使用相同会话进行后续问题
if (sessionId) {
for await (const message of query({
prompt: "Now show me how to fix the most critical issue",
options: {
resume: sessionId, // 继续对话
allowedTools: ["Read", "Glob", "Grep"],
maxTurns: 250
}
})) {
// Claude 会记住之前的上下文
}
}
}
Hooks:拦截和自定义行为
Hooks 让你能够拦截和自定义代理行为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { query, HookCallback, PreToolUseHookInput } from "@anthropic-ai/claude-agent-sdk";
// 审计日志记录器
const auditLogger: HookCallback = async (input, toolUseId, { signal }) => {
if (input.hook_event_name === "PreToolUse") {
const preInput = input as PreToolUseHookInput;
console.log(`[AUDIT] ${new Date().toISOString()} - ${preInput.tool_name}`);
}
return {};
};
// 阻止危险命令
const blockDangerousCommands: HookCallback = async (input, toolUseId, { signal }) => {
if (input.hook_event_name === "PreToolUse") {
const preInput = input as PreToolUseHookInput;
if (preInput.tool_name === "Bash") {
const command = (preInput.tool_input as any).command || "";
if (command.includes("rm -rf") || command.includes("sudo")) {
return {
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Dangerous command blocked"
}
};
}
}
}
return {};
};
for await (const message of query({
prompt: "Clean up temporary files",
options: {
model: "opus",
allowedTools: ["Bash", "Glob"],
maxTurns: 250,
hooks: {
PreToolUse: [
{ hooks: [auditLogger] },
{ matcher: "Bash", hooks: [blockDangerousCommands] }
]
}
}
})) {
// ...
}
MCP 扩展:自定义工具
使用 Model Context Protocol 扩展 Claude 的能力:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
// 创建自定义工具
const customServer = createSdkMcpServer({
name: "code-metrics",
version: "1.0.0",
tools: [
tool(
"analyze_complexity",
"Calculate cyclomatic complexity for a file",
{
filePath: z.string().describe("Path to the file to analyze")
},
async (args) => {
// 你的复杂度分析逻辑
const complexity = Math.floor(Math.random() * 20) + 1;
return {
content: [{
type: "text",
text: `Cyclomatic complexity for ${args.filePath}: ${complexity}`
}]
};
}
)
]
});
// 在代理中使用
for await (const message of query({
prompt: "Analyze the complexity of main.ts",
options: {
model: "opus",
mcpServers: {
"code-metrics": customServer
},
allowedTools: ["Read", "mcp__code-metrics__analyze_complexity"],
maxTurns: 250
}
})) {
// ...
}
生产环境建议
成本追踪
1
2
3
4
5
6
7
8
9
10
11
for await (const message of query({ prompt: "..." })) {
if (message.type === "result" && message.subtype === "success") {
console.log("Total cost:", message.total_cost_usd);
console.log("Token usage:", message.usage);
// 每个模型的详细分析(在使用子代理时很有用)
for (const [model, usage] of Object.entries(message.modelUsage)) {
console.log(`${model}: $${usage.costUSD.toFixed(4)}`);
}
}
}
错误处理
1
2
3
4
5
6
7
8
9
10
try {
for await (const message of query({ ... })) {
if (message.type === "result" && message.subtype !== "success") {
console.error("Agent failed:", message.subtype);
// 处理特定错误类型
}
}
} catch (error) {
console.error("Unexpected error:", error);
}
超时控制
1
2
3
4
options: {
maxTurns: 250, // 限制最大迭代次数
// 设置合理的超时时间
}
总结
Claude Agent SDK 让构建 AI 代理变得简单而强大。关键要点:
✅ 开箱即用的工具:不需要重新实现文件操作、命令执行等基础功能
✅ 自动化的代理循环:SDK 处理与模型的复杂交互,你只需关注业务逻辑
✅ 灵活的架构:从简单脚本到复杂的多代理系统都能轻松实现
✅ 生产就绪:内置权限管理、成本追踪、错误处理等企业级特性
现在你已经掌握了基础知识,可以开始构建自己的 AI 代理了。无论是代码审查、文档生成、数据分析还是自动化测试,Claude Agent SDK 都能帮你实现。
参考资源
本文基于 Nader Dabit 的原创教程整理而成,感谢他的精彩分享。
