简单函数
基础函数工具
从简单函数创建工具:复制
import { tool } from '@ag-kit/tools';
import { z } from 'zod';
const addNumbersTool = tool(
async ({ a, b }) => {
return ToolResult({
success: true,
data: { result: a + b }
});
},
{
name: 'add_numbers',
description: 'Add two numbers together',
schema: z.object({
a: z.number().describe('First number'),
b: z.number().describe('Second number')
})
}
);
文本处理工具
创建文本处理工具:复制
const textProcessTool = tool(
async ({ text, operation, options = {} }) => {
let processedText = text;
if (options.trim) {
processedText = processedText.trim();
}
if (options.removeSpaces) {
processedText = processedText.replace(/\s+/g, '');
}
let result;
switch (operation) {
case 'uppercase':
result = processedText.toUpperCase();
break;
case 'lowercase':
result = processedText.toLowerCase();
break;
case 'reverse':
result = processedText.split('').reverse().join('');
break;
case 'word_count':
result = processedText.split(/\s+/).length;
break;
}
return ToolResult({
success: true,
data: {
original: text,
processed: result,
operation
}
});
},
{
name: 'process_text',
description: 'Process text with various operations',
schema: z.object({
text: z.string().describe('Input text'),
operation: z.enum(['uppercase', 'lowercase', 'reverse', 'word_count']),
options: z.object({
trim: z.boolean().default(true),
removeSpaces: z.boolean().default(false)
}).optional()
})
}
);
异步操作
HTTP请求工具
创建发起HTTP请求的工具:复制
const httpRequestTool = tool({
name: 'http_request',
description: 'Make HTTP requests to external APIs',
schema: z.object({
url: z.string().url(),
method: z.enum(['GET', 'POST', 'PUT', 'DELETE']).default('GET'),
headers: z.record(z.string()).optional(),
body: z.any().optional(),
timeout: z.number().default(30000)
}),
invoke: async ({ url, method, headers, body, timeout }) => {
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
const response = await fetch(url, {
method,
headers: {
'Content-Type': 'application/json',
...headers
},
body: body ? JSON.stringify(body) : undefined,
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
return ToolResult({
success: false,
error: `HTTP ${response.status}: ${response.statusText}`,
error_type: 'network'
});
}
const data = await response.json();
return ToolResult({
success: true,
data: {
status: response.status,
headers: Object.fromEntries(response.headers.entries()),
body: data
}
});
} catch (error) {
if (error.name === 'AbortError') {
return ToolResult({
success: false,
error: 'Request timeout',
error_type: 'network'
});
}
return ToolResult({
success: false,
error: error.message,
error_type: 'execution'
});
}
}
});
复杂参数
验证与转换
创建具有复杂验证的工具:复制
const userManagementTool = tool({
name: 'manage_user',
description: '通过验证管理用户账户',
schema: z.object({
action: z.enum(['create', 'update', 'delete', 'get']),
userId: z.string().uuid().optional(),
userData: z.object({
email: z.string().email(),
name: z.string().min(2).max(50),
age: z.number().min(13).max(120),
roles: z.array(z.enum(['admin', 'user', 'moderator'])).default(['user']),
preferences: z.object({
theme: z.enum(['light', 'dark']).default('light'),
notifications: z.boolean().default(true),
language: z.string().length(2).default('en')
}).optional()
}).optional()
}).refine(
(data) => {
if (data.action === 'create' && !data.userData) {
return false;
}
if (['update', 'delete', 'get'].includes(data.action) && !data.userId) {
return false;
}
return true;
},
{
message: '创建操作需要userData,更新/删除/获取操作需要userId'
}
),
invoke: async ({ action, userId, userData }) => {
try {
switch (action) {
case 'create':
const newUser = {
id: crypto.randomUUID(),
...userData,
createdAt: new Date().toISOString()
};
// 模拟数据库保存
await saveUser(newUser);
return ToolResult({
success: true,
data: { user: newUser, message: '用户创建成功' }
});
case 'update':
const existingUser = await getUser(userId);
if (!existingUser) {
return ToolResult({
success: false,
error: '用户未找到',
error_type: 'execution'
});
}
const updatedUser = {
...existingUser,
...userData,
updatedAt: new Date().toISOString()
};
await saveUser(updatedUser);
return ToolResult({
success: true,
data: { user: updatedUser, message: '用户更新成功' }
});
case 'delete':
await deleteUser(userId);
return ToolResult({
success: true,
data: { message: '用户删除成功' }
});
case 'get':
const user = await getUser(userId);
if (!user) {
return ToolResult({
success: false,
error: '用户未找到',
error_type: 'execution'
});
}
return ToolResult({
success: true,
data: { user }
});
default:
return ToolResult({
success: false,
error: '无效操作',
error_type: 'validation'
});
}
} catch (error) {
return ToolResult({
success: false,
error: error.message,
error_type: 'execution'
});
}
}
});
// 模拟数据库函数
async function saveUser(user: any) {
// 实现代码
}
async function getUser(userId: string) {
// 实现代码
}
async function deleteUser(userId: string) {
// 实现代码
}
错误处理
全面的错误处理
实现健壮的错误处理模式:复制
const robustApiTool = tool({
name: 'robust_api_call',
description: '通过全面的错误处理进行API调用',
schema: z.object({
endpoint: z.string().url(),
retries: z.number().min(0).max(5).default(3),
backoffMs: z.number().min(100).max(10000).default(1000)
}),
invoke: async ({ endpoint, retries, backoffMs }) => {
let lastError: Error | null = null;
for (let attempt = 0; attempt <= retries; attempt++) {
try {
const response = await fetch(endpoint, {
timeout: 10000,
headers: {
'User-Agent': 'AG-Kit Tool/1.0'
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
return ToolResult({
success: true,
data: {
result: data,
attempts: attempt + 1,
endpoint
}
});
} catch (error) {
lastError = error;
// 特定错误不重试
if (error.message.includes('404') || error.message.includes('401')) {
break;
}
// 重试前等待(指数退避)
if (attempt < retries) {
const delay = backoffMs * Math.pow(2, attempt);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
return new ToolResult({
success: false,
error: `经过${retries + 1}次尝试后失败: ${lastError?.message}`,
error_type: 'network',
executionTime: Date.now()
});
}
});
输入净化
对输入进行净化和验证:复制
const sanitizedInputTool = tool({
name: 'process_user_input',
description: '对用户输入进行净化处理',
schema: z.object({
userInput: z.string(),
allowHtml: z.boolean().default(false),
maxLength: z.number().default(1000)
}),
invoke: async ({ userInput, allowHtml, maxLength }) => {
try {
// 长度验证
if (userInput.length > maxLength) {
return ToolResult({
success: false,
error: `输入过长(最多${maxLength}个字符)`,
error_type: 'validation'
});
}
// 净化输入
let sanitized = userInput.trim();
if (!allowHtml) {
// 移除HTML标签
sanitized = sanitized.replace(/<[^>]*>/g, '');
// 转义特殊字符
sanitized = sanitized
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
// 检查可疑模式
const suspiciousPatterns = [
/javascript:/i,
/data:text\/html/i,
/vbscript:/i,
/<script/i
];
const hasSuspiciousContent = suspiciousPatterns.some(
pattern => pattern.test(sanitized)
);
if (hasSuspiciousContent) {
return ToolResult({
success: false,
error: '输入包含可疑内容',
error_type: 'validation'
});
}
return ToolResult({
success: true,
data: {
original: userInput,
sanitized,
length: sanitized.length,
wasModified: userInput !== sanitized
}
});
} catch (error) {
return ToolResult({
success: false,
error: error.message,
error_type: 'execution'
});
}
}
});
集成模式
工具组合
组合多个功能工具:复制
// 创建独立工具
const validateEmailTool = tool({
name: 'validate_email',
description: '验证电子邮件地址格式',
schema: z.object({
email: z.string()
}),
invoke: async ({ email }) => {
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
return ToolResult({
success: true,
data: { email, isValid }
});
}
});
const sendEmailTool = tool({
name: 'send_email',
description: '发送电子邮件',
schema: z.object({
to: z.string().email(),
subject: z.string(),
body: z.string()
}),
invoke: async ({ to, subject, body }) => {
// 邮件发送逻辑
return ToolResult({
success: true,
data: { messageId: 'msg_123', sentAt: new Date().toISOString() }
});
}
});
// 组合工具
const emailWorkflowTool = tool({
name: 'email_workflow',
description: '一次性完成电子邮件验证和发送',
schema: z.object({
to: z.string(),
subject: z.string(),
body: z.string()
}),
invoke: async ({ to, subject, body }) => {
// 先验证电子邮件
const validationResult = await validateEmailTool.invoke({ email: to });
if (!validationResult.success || !validationResult.data.isValid) {
return ToolResult({
success: false,
error: '无效的电子邮件地址',
error_type: 'validation'
});
}
// 发送邮件
const sendResult = await sendEmailTool.invoke({ to, subject, body });
return ToolResult({
success: sendResult.success,
data: {
validation: validationResult.data,
email: sendResult.data
},
error: sendResult.error,
error_type: sendResult.error_type
});
}
});
与Agent配合使用
将功能工具与AG-Kit agent结合使用:复制
import { Agent, OpenAIProvider } from '@ag-kit/agents';
const agent = new Agent({
name: 'multi-tool-agent',
model: new OpenAIProvider({
apiKey: process.env.OPENAI_API_KEY!,
defaultModel: 'gpt-4'
}),
tools: [
addNumbersTool,
textProcessTool,
httpRequestTool,
userManagementTool
],
instructions: `您是一个拥有多种工具的有用助手:
- 数学运算
- 文本处理
- HTTP请求
- 用户管理
使用这些工具帮助用户完成任务。`
});
const response = await agent.run({
input: '计算15加27,然后将结果转换为大写文本'
});
缓存实现
为耗时操作实现缓存:复制
const cache = new Map();
const cachedApiTool = tool({
name: 'cached_api_call',
description: 'API call with caching',
schema: z.object({
url: z.string().url(),
cacheTtl: z.number().default(300000) // 5分钟
}),
invoke: async ({ url, cacheTtl }) => {
const cached = cache.get(url);
if (cached && Date.now() - cached.timestamp < cacheTtl) {
return ToolResult({
success: true,
data: { ...cached.data, fromCache: true }
});
}
try {
const response = await fetch(url);
const data = await response.json();
cache.set(url, {
data,
timestamp: Date.now()
});
return ToolResult({
success: true,
data: { ...data, fromCache: false }
});
} catch (error) {
return ToolResult({
success: false,
error: error.message,
error_type: 'network'
});
}
}
});