简介
本实战基于 Claude Agent SDK,开发自定义工具(Tool),让 Claude Agent 主动调用你编写的函数,实现读取本地文件、查询数据库、调用第三方接口等能力。
说明:Claude Agent SDK 的自定义工具机制,和 Claude Code 的 MCP 目标一致。MCP 是独立协议服务;SDK Tools 是代码内直接定义工具,适合后端程序内快速集成。
实战目标
开发一个文件信息查询工具:Agent 收到请求后,自动调用工具获取文件大小、修改时间,再把结果整理成自然语言回答。
前置准备
- Python 3.10+ / Node.js 18+
- 安装 SDK:
pip install anthropic或者npm install @anthropic-ai/sdk - Anthropic API Key(环境变量配置,禁止硬编码)
- 基础了解:工具定义 JSON Schema、Agent 工具调用回调机制
核心原理
- 在代码中定义工具描述(名称、说明、入参 JSON Schema)
- 将工具数组传入 SDK
messages.create() - Agent 判断是否需要调用工具,返回
tool_use块 - 你的程序接收工具参数,执行自定义函数
- 将工具执行结果包装为
tool_result,再次发给 Agent - Agent 基于工具返回内容继续生成回答
实战1:Python 完整示例(文件查询工具)
import os
import time
from anthropic import Anthropic
# 初始化客户端,从环境变量读取 API Key
client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
# ========== 1. 定义工具描述给 Agent ==========
tools = [
{
"name": "get_file_info",
"description": "获取指定路径文件的大小、最后修改时间,仅用于本地文件查询",
"input_schema": {
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "文件的本地路径"
}
},
"required": ["file_path"]
}
}
]
# ========== 2. 实现工具业务函数 ==========
def get_file_info(file_path: str):
try:
stat = os.stat(file_path)
return {
"size_bytes": stat.st_size,
"modify_time": time.ctime(stat.st_mtime),
"exists": True
}
except FileNotFoundError:
return {"exists": False, "msg": "文件不存在"}
# ========== 3. 主会话逻辑 ==========
messages = [
{"role": "user", "content": "查看当前目录 README.md 文件信息"}
]
response = client.messages.create(
model="claude-3-5-sonnet-latest",
max_tokens=1024,
tools=tools,
messages=messages
)
# 处理 Agent 返回内容
for block in response.content:
if block.type == "tool_use":
tool_name = block.name
tool_input = block.input
tool_use_id = block.id
# 执行对应工具
if tool_name == "get_file_info":
result = get_file_info(**tool_input)
# 将工具调用结果追加进消息历史
messages.append(response.content[0].to_dict())
messages.append({
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use_id,
"content": str(result)
}
]
})
# 二次请求,让Agent整合工具结果输出回答
final_resp = client.messages.create(
model="claude-3-5-sonnet-latest",
max_tokens=1024,
messages=messages,
tools=tools
)
print(final_resp.content[0].text)
实战2:TypeScript / Node.js 版本示例
import Anthropic from "@anthropic-ai/sdk";
import fs from "fs/promises";
import path from "path";
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
// 工具定义
const tools = [
{
name: "get_file_info",
description: "获取本地文件大小与修改时间",
input_schema: {
type: "object",
properties: {
file_path: { type: "string", description: "文件路径" },
},
required: ["file_path"],
},
},
];
// 工具函数
async function getFileInfo(filePath: string) {
try {
const stat = await fs.stat(filePath);
return {
size_bytes: stat.size,
modify_time: stat.mtime.toString(),
exists: true,
};
} catch (e) {
return { exists: false, msg: "文件不存在" };
}
}
async function main() {
const messages = [
{ role: "user", content: "查看 README.md 文件信息" },
];
const resp = await anthropic.messages.create({
model: "claude-3-5-sonnet-latest",
max_tokens: 1024,
tools,
messages,
});
const block = resp.content[0];
if (block.type === "tool_use") {
const result = await getFileInfo(block.input.file_path);
messages.push(resp.content[0]);
messages.push({
role: "user",
content: [
{
type: "tool_result",
tool_use_id: block.id,
content: JSON.stringify(result),
},
],
});
const finalResp = await anthropic.messages.create({
model: "claude-3-5-sonnet-latest",
max_tokens: 1024,
tools,
messages,
});
console.log(finalResp.content[0].text);
}
}
main();
工具开发规范
1. 工具描述规范
description写清楚工具能力、边界,告诉 Agent 什么时候调用input_schema严格 JSON Schema,类型不能乱写- 参数命名清晰,避免歧义;必填参数放在
required
2. 工具返回规范
- 返回结构化 JSON,方便 Agent 解析
- 一定要返回错误信息(文件不存在、接口超时等)
- 不要返回超长原始文本,精简结果,降低 token
3. 多工具注册
你可以一次性传入多个工具到 tools 数组,Agent 会自动判断选择合适工具。
例如同时注册:文件查询、数据库查询、HTTP 请求工具。
流式工具调用(Stream)
生产环境推荐使用流式模式,实时接收 Agent 输出,工具调用逻辑不变:
流式只是边返回内容边接收,当检测到
tool_use块完整后,执行工具回调。
安全要点(重点)
- 输入校验:工具收到参数必须校验,防止路径穿越(
../)、命令注入 - 权限限制:文件工具限定工作目录,禁止读取系统敏感文件
- 超时控制:网络类工具设置超时时间,防止长时间阻塞
- 参数白名单:不允许直接执行 shell 命令,高危操作禁止开放
- 日志记录:记录工具名称、入参、返回结果,方便审计排查
调试技巧
- 先单独运行工具函数,确保函数本身可以正常返回结果
- 打印 Agent 返回的
tool_use块,检查参数是否符合预期 - 减少 system prompt 干扰,最小 demo 先跑通,再加业务规则
- 如果 Agent 不调用工具:优化
description,明确触发条件
SDK Tools vs MCP 对比
| 项目 | SDK 自定义工具 | MCP |
|---|---|---|
| 部署方式 | 代码内直接定义函数 | 独立进程服务 |
| 适用场景 | 后端程序内轻量工具 | 跨进程、IDE/Claude Code 复用工具 |
| 开发成本 | 低,直接写代码 | 高,需要实现 MCP 协议 |
| 复用性 | 仅当前程序可用 | 多个客户端共用同一个工具服务 |
常见问题
Q:Agent 不调用我定义的工具?
A:①工具描述写得不清楚;②用户提问没有触发工具场景;③模型版本不支持工具调用,使用 claude-3-5-sonnet-latest。
Q:工具调用循环触发,无限来回?
A:增加终止条件,或者在 system prompt 限制最大工具调用轮次。
Q:工具返回内容太长,token 消耗很高?
A:工具返回结果做摘要,只返回必要字段,不要返回完整原始数据。
小结
Claude Agent SDK 自定义工具开发流程:定义工具 Schema → 编写工具业务函数 → 处理 Agent 的 tool_use 请求 → 回传 tool_result。
轻量工具直接使用 SDK Tools;如果需要给 Claude Code、多个项目复用工具,优先选择 MCP。
0 条笔记