学习如何开发自定义工具来扩展 Agent 能力。
Tool 是使 Agent 能够与外部系统交互的构建块。@agent-tars/core 提供了一个全面的工具包,用于创建与 Agent 生态系统无缝集成的自定义工具。
系统中的每个工具都遵循一致的结构:
interface Tool {
name: string;
description: string;
parameters: JSONSchema7;
execute: (params: any) => Promise<ToolResult>;
}import { Tool, ToolResult } from '@agent-tars/core';
export class CalculatorTool implements Tool {
name = 'calculator';
description = '执行基本数学计算';
parameters = {
type: 'object',
properties: {
operation: {
type: 'string',
enum: ['add', 'subtract', 'multiply', 'divide'],
description: '要执行的数学运算'
},
a: {
type: 'number',
description: '第一个数字'
},
b: {
type: 'number',
description: '第二个数字'
}
},
required: ['operation', 'a', 'b']
};
async execute(params: {
operation: string;
a: number;
b: number;
}): Promise<ToolResult> {
const { operation, a, b } = params;
let result: number;
switch (operation) {
case 'add':
result = a + b;
break;
case 'subtract':
result = a - b;
break;
case 'multiply':
result = a * b;
break;
case 'divide':
if (b === 0) {
return {
success: false,
error: '不允许除以零'
};
}
result = a / b;
break;
default:
return {
success: false,
error: `未知运算: ${operation}`
};
}
return {
success: true,
data: {
result,
operation: `${a} ${operation} ${b} = ${result}`
}
};
}
}import { Agent } from '@agent-tars/core';
import { CalculatorTool } from './calculator-tool';
const agent = new Agent({
tools: [
new CalculatorTool()
]
});@agent-tars/core 包含 32 个内置工具,分为 4 个类别:
通过实现分类接口来组织你的自定义工具:
export interface ToolCategory {
name: string;
description: string;
tools: Tool[];
}
export class DatabaseToolCategory implements ToolCategory {
name = 'database';
description = '数据库操作和查询';
tools = [
new QueryTool(),
new InsertTool(),
new UpdateTool()
];
}Tool 可以执行复杂的异步操作:
export class ApiTool implements Tool {
name = 'api_request';
description = '发起 HTTP API 请求';
async execute(params: {
url: string;
method: string;
headers?: Record<string, string>;
body?: any;
}): Promise<ToolResult> {
try {
const response = await fetch(params.url, {
method: params.method,
headers: params.headers,
body: params.body ? JSON.stringify(params.body) : undefined
});
const data = await response.json();
return {
success: true,
data: {
status: response.status,
headers: Object.fromEntries(response.headers.entries()),
body: data
}
};
} catch (error) {
return {
success: false,
error: `API 请求失败: ${error.message}`
};
}
}
}Tool 可以在执行过程中维护状态:
export class SessionTool implements Tool {
private sessions = new Map<string, any>();
name = 'session_manager';
description = '管理会话数据';
async execute(params: {
action: 'get' | 'set' | 'delete';
key: string;
value?: any;
}): Promise<ToolResult> {
const { action, key, value } = params;
switch (action) {
case 'get':
return {
success: true,
data: { value: this.sessions.get(key) }
};
case 'set':
this.sessions.set(key, value);
return {
success: true,
data: { message: '值设置成功' }
};
case 'delete':
this.sessions.delete(key);
return {
success: true,
data: { message: '值删除成功' }
};
}
}
}始终提供有意义的错误消息:
async execute(params: any): Promise<ToolResult> {
try {
// 工具逻辑
return { success: true, data: result };
} catch (error) {
return {
success: false,
error: `工具执行失败: ${error.message}`,
details: {
stack: error.stack,
params
}
};
}
}使用全面的 JSON Schema 验证:
parameters = {
type: 'object',
properties: {
email: {
type: 'string',
format: 'email',
description: '有效的邮箱地址'
},
age: {
type: 'number',
minimum: 0,
maximum: 150,
description: '年龄(岁)'
}
},
required: ['email'],
additionalProperties: false
};正确清理资源:
export class DatabaseTool implements Tool {
private connection: DatabaseConnection;
async execute(params: any): Promise<ToolResult> {
try {
await this.connection.connect();
const result = await this.connection.query(params.sql);
return { success: true, data: result };
} finally {
await this.connection.close();
}
}
}import { CalculatorTool } from './calculator-tool';
describe('CalculatorTool', () => {
let tool: CalculatorTool;
beforeEach(() => {
tool = new CalculatorTool();
});
it('应该正确执行加法', async () => {
const result = await tool.execute({
operation: 'add',
a: 5,
b: 3
});
expect(result.success).toBe(true);
expect(result.data.result).toBe(8);
});
it('应该处理除零错误', async () => {
const result = await tool.execute({
operation: 'divide',
a: 10,
b: 0
});
expect(result.success).toBe(false);
expect(result.error).toContain('除以零');
});
});import { Agent } from '@agent-tars/core';
import { CalculatorTool } from './calculator-tool';
describe('Calculator 集成测试', () => {
it('应该与 agent 协同工作', async () => {
const agent = new Agent({
tools: [new CalculatorTool()]
});
const response = await agent.execute(
'计算 15 加 25'
);
expect(response).toContain('40');
});
});全面记录你的工具:
/**
* 邮箱验证和发送工具
*
* @example
* ```typescript
* const emailTool = new EmailTool({
* smtpHost: 'smtp.gmail.com',
* smtpPort: 587
* });
*
* await emailTool.execute({
* to: 'user@example.com',
* subject: 'Hello',
* body: 'Hello world!'
* });
* ```
*/
export class EmailTool implements Tool {
// 实现...
}