1. Clear Documentation
Provide clear documentation for each tool, including:
- Purpose: What the tool does
- Parameters: What parameters the tool accepts
- Return Value: What the tool returns
- Examples: Examples of how to use the tool
Validate all tool inputs to prevent errors and security issues:
function validateToolInput(toolName, args) {
switch (toolName) {
case 'get_weather':
if (!args.location) {
throw new Error('Location is required for get_weather tool');
}
if (args.unit && !['celsius', 'fahrenheit'].includes(args.unit)) {
throw new Error('Unit must be either "celsius" or "fahrenheit"');
}
break;
case 'search_database':
if (!args.query) {
throw new Error('Query is required for search_database tool');
}
if (args.limit && (!Number.isInteger(args.limit) || args.limit <= 0)) {
throw new Error('Limit must be a positive integer');
}
break;
default:
throw new Error(`Unknown tool: ${toolName}`);
}
}
3. Error Handling
Return meaningful error messages when tools fail:
async function executeToolCall(toolName, args) {
try {
// Validate the tool input
validateToolInput(toolName, args);
// Execute the tool
if (toolFunctions[toolName]) {
return await toolFunctions[toolName](args);
} else {
throw new Error(`Tool not implemented: ${toolName}`);
}
} catch (error) {
// Return a structured error response
return JSON.stringify({
error: {
message: error.message,
type: 'tool_execution_error',
code: error.code || 'unknown_error'
}
});
}
}
4. Timeouts
Implement timeouts for tool execution to prevent blocking:
async function executeToolWithTimeout(toolName, args, timeout = 5000) {
return Promise.race([
executeToolCall(toolName, args),
new Promise((_, reject) => {
setTimeout(() => reject(new Error(`Tool execution timed out: ${toolName}`)), timeout);
})
]);
}
5. Statelessness
Design tools to be stateless when possible:
// Avoid this (stateful)
let cachedData = null;
async function getDataTool(args) {
if (cachedData) {
return cachedData;
}
cachedData = await fetchData(args);
return cachedData;
}
// Prefer this (stateless)
async function getDataTool(args) {
// Use a cache service that's external to the tool
const cacheKey = generateCacheKey(args);
const cachedData = await cacheService.get(cacheKey);
if (cachedData) {
return cachedData;
}
const data = await fetchData(args);
await cacheService.set(cacheKey, data);
return data;
}
6. Security
Implement appropriate security measures for tool access:
function authorizeToolAccess(user, toolName) {
// Check if the user has permission to use this tool
const userPermissions = getUserPermissions(user);
if (!userPermissions.tools.includes(toolName)) {
throw new Error(`User does not have permission to use tool: ${toolName}`);
}
}