
欢迎来到AI代理构建的世界!如果你曾对能够自主分析代码、运行命令、甚至修复错误的AI感到好奇,那么本教程就是为你量身打造的。我们的目标清晰而具体:从零开始,一步步构建一个可以分析代码库、发现潜在问题并提供专业反馈的AI代码审查代理(Code Review Agent)。
本教程专为初学者设计,你不需要任何AI代理开发经验。只要跟着我们的步骤,你就能亲手创造出第一个属于自己的实用AI工具。
简单来说,Claude Agent SDK 是著名AI助手 Claude Code 背后的核心引擎。它是一个强大的工具库,让你能够轻松地构建、测试和部署自己的AI代理。
为了让你更直观地理解SDK的优势,让我们对比一下使用原生API和使用Agent SDK构建代理的区别:
特性 使用原生API 使用Agent SDK 循环管理 开发者需要手动编写循环逻辑,不断调用模型、检查工具使用、返回结果,过程繁琐。 SDK自动处理整个代理循环,你只需关注业务逻辑。 工具执行 需要自己实现所有工具(如文件读取、网络搜索)的调用和结果处理。 内置了一系列即开即用的强大工具(文件操作、Shell命令、网络搜索等)。 代码简洁性 代码冗长,需要管理大量的状态和API调用细节。 代码极其简洁,几行代码就能启动一个强大的代理会话。
下面的代码片段生动地展示了这种简洁性带来的巨大差异:
// 使用原生API:你需要手动管理整个循环
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, ... });
}
// 使用Agent SDK:Claude 会为你处理好一切
for await (const message of query({ prompt: "修复 auth.py 中的错误" })) {
console.log(message); // Claude 会自动读取文件、发现错误并修改代码
}它为何如此强大?内置的工具集是关键。 Agent SDK 的一个核心优势在于它为你处理了所有繁琐的底层逻辑,让你能够将精力完全集中在定义代理的目标和功能上。它自带一套强大的预置工具,极大地加快了开发速度,让你不必从零开始实现常见的文件和命令行操作。
核心理念:消息流 (The Core Idea: The Message Stream)
在深入编写代码之前,理解SDK的核心工作方式至关重要:异步消息流。你可以把代理的整个工作过程想象成一个持续不断的事件流。从代理启动、思考、调用工具,到最终给出答案,每一步都会通过这个流发送一条消息。
我们之后会用 for await...of 循环来监听这个流。理解不同类型的消息是掌握SDK的关键:
提前理解这个概念,会让你在看到第一个代码示例时豁然开朗。
在本教程中,我们将构建一个代码审查代理,它具备以下三个核心功能:
我们将使用以下现代且强大的技术栈来完成本次构建:
理论知识已经足够,现在让我们卷起袖子,开始搭建我们的开发环境吧!
在开始之前,请确保你的电脑上已经准备好以下两样东西:
我们将通过三个简单的步骤来完成所有设置。
太棒了!你的开发环境已经准备就绪。现在,让我们来编写并运行第一个简单的AI代理,感受一下SDK的魔力。
在你的项目目录 code-review-agent 中,创建一个名为 agent.ts 的新文件,并将以下代码粘贴进去:
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("\nDone:", message.subtype);
}
}
}
main();这段代码虽然简短,但包含了与代理交互的核心要素。让我们来逐一解析:
3.3 运行并观察结果
在你的终端中,运行以下命令:
npx tsx agent.ts你会看到,Claude接收到指令后,会决定使用 Glob 工具来列出当前目录下的文件,最后以一段文本的形式告诉你它找到了哪些文件。
现在你已经成功运行了一个简单的代理,它能够使用工具并与你交流。接下来,让我们在这个基础上构建一个更强大、更具实际用途的代码审查代理。
让我们创建一个新文件 review-agent.ts,并填入以下更专业的代码:
import { query } from "@anthropic-ai/claude-agent-sdk";
async function reviewCode(directory: string) {
console.log(`\n🔍 Starting code review for: ${directory}\n`);
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(`\n📁 Using ${block.name}...`);
}
}
}
// 显示任务完成状态
if (message.type === "result") {
if (message.subtype === "success") {
console.log(`\n✅ Review complete! Cost: $${message.total_cost_usd.toFixed(4)}`);
} else {
console.log(`\n❌ Review failed: ${message.subtype}`);
}
}
}
}
// 开始审查当前目录
reviewCode(".");与上一个简单的代理相比,这段代码有了显著的升级:
为了验证我们的代理是否有效,我们需要给它一些“有问题”的代码来审查。在项目根目录下创建一个名为 example.ts 的新文件,并粘贴以下代码:
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(); // 缺少错误处理
}这段代码中故意留下了几个常见问题:
一切准备就绪!现在,让我们启动代码审查代理:
npx tsx review-agent.ts观察你的终端输出。你会看到Claude开始分析,并实时打印出它对 example.ts 文件中每一个问题的发现,包括具体的文件名、行号以及详细的修复建议。
做得好!你的代理现在已经可以像一个初级工程师一样找出代码中的问题了。但为了让审查结果更易于被其他程序使用,我们需要让它输出结构化的数据,比如JSON格式。
人类可以轻松理解自由格式的文本,但对于计算机程序来说,处理这些文本非常困难。如果审查结果是结构化的(如JSON格式),我们就可以轻松地将其集成到CI/CD流程、生成报告或在仪表盘上展示。
为了告诉Claude我们想要的输出格式,我们需要定义一个“模板”,这个模板就是 JSON Schema。它精确地描述了JSON对象应该包含哪些字段、每个字段的类型是什么,就像一份合同一样,确保代理返回的数据是我们期望的样子。
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"]
};这个Schema告诉Claude,最终的输出必须是一个包含 issues 数组、summary 字符串和 overallScore 数字的对象。同时,它还详细定义了issues数组中每个问题对象的结构。
现在,我们可以修改 review-agent.ts 文件(或创建一个新文件)来使用这个Schema。以下是完整代码:
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(`\n📊 Code Review Results`);
console.log(`✅ Review complete! Cost: $${message.total_cost_usd.toFixed(4)}\n`);
console.log(`Score: ${review.overallScore}/100`);
console.log(`Summary: ${review.summary}\n`);
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(".");这里的关键改动有两处:
你现在得到的不仅仅是文本,而是一个可以被其他系统集成的、机器可读的专业审查报告。这就是将AI代理融入自动化工作流程的关键一步。
再次运行 npx tsx review-agent.ts,你将看到一个格式精美、结构清晰的专业代码审查报告!
恭喜你!你已经成功构建了一个功能强大且能输出专业审查报告的AI代码审查代理。你掌握了SDK的核心用法,是时候看看未来还有哪些更酷的功能等待你去探索了。
通过本教程,你已经从零开始,掌握了构建一个AI代理所需的核心技能:
你刚刚构建的代理仅仅是一个开始。Claude Agent SDK 提供了更多强大的功能,可以帮助你构建更复杂的应用。以下是一些值得你深入探索的方向:
值得注意的是,本指南涵盖的是SDK的V1版本。V2版本目前正在积极开发中。请保持关注,因为工具链在不断进化。
你已经迈出了最重要的一步。现在,世界充满了等待被解决的问题,而你拥有了创造解决方案的强大工具。继续探索,不断创造,看看你能用AI代理构建出怎样令人惊叹的应用吧!