Real agents need multiple tools. The key challenge: how does the agent decide which tool to use?
const tools = [
{
name: "search_web",
description: "Search the web for current information. Use for recent events or facts. Do NOT use for general knowledge.",
input_schema: { type: "object", properties: { query: { type: "string" } }, required: ["query"] }
},
{
name: "read_file",
description: "Read a local file. Use when user references a file by name.",
input_schema: { type: "object", properties: { path: { type: "string" } }, required: ["path"] }
},
{
name: "run_code",
description: "Execute JavaScript. Use for calculations. NEVER for file modifications.",
input_schema: { type: "object", properties: { code: { type: "string" } }, required: ["code"] }
}
];
async function executeTool(name: string, args: any) {
switch (name) {
case "search_web": return await searchWeb(args.query);
case "read_file": return await readFile(args.path);
case "run_code": return await runCode(args.code);
default: return { error: `Unknown tool: ${name}` };
}
}
| Rule | Why |
|---|---|
| Keep tools under 10 | More tools = more confusion. 5-7 is the sweet spot. |
| Include "when NOT to use" | Prevents over-eager tool calling |
| Handle unknown tools gracefully | Return error, don't crash |
| Log every tool call | Essential for debugging |
| Sandbox dangerous tools | run_code must be sandboxed |