Custom Tools Deep Dive
Extend your agent's capabilities by connecting it to any API, database, or function.
The Anatomy of a Tool#
A Tool is the bridge between the LLM and the real world. It consists of a definition (Name, Description, Schema) and an execution function.
tool-interface.ts
interface Tool<T = any> {
name: string // Unique identifier (e.g., "search_users")
description: string // Instructions for the LLM on WHEN to use this
schema: ZodSchema<T> // Validation for the arguments
execute: (args: T) => Promise<string> // The implementation
}Building a Robust Tool#
Let's build a tool that searches a product database. We'll use Zod to ensure the agent provides valid search parameters.
Description Matters
The `description` is part of the prompt. Be specific about input formats (e.g., "Dates must be ISO-8601").
product-search.ts
import { Tool } from '@akios/sdk'
import { z } from 'zod'
const searchProducts = new Tool({
name: 'search_products',
description: 'Search for products by name, category, or price range. Use this when the user is looking for item recommendations.',
// Zod Schema defines the "Contract"
schema: z.object({
query: z.string().optional().describe('The search term (e.g. "wireless headphones")'),
category: z.enum(['electronics', 'clothing', 'home']).optional(),
maxPrice: z.number().positive().optional(),
limit: z.number().min(1).max(20).default(5)
}),
execute: async ({ query, category, maxPrice, limit }) => {
try {
// 1. Call your internal API / Database
const results = await db.products.findMany({
where: {
name: { contains: query },
category: category,
price: { lte: maxPrice }
},
take: limit
})
// 2. Format the output for the LLM
// JSON.stringify is usually best for structured data
if (results.length === 0) {
return "No products found matching those criteria."
}
return JSON.stringify(results)
} catch (error) {
// 3. Handle Errors gracefully
// Return the error message so the Agent knows what went wrong
return `Error searching products: ${error.message}`
}
}
})Best Practices#
1. Keep Outputs Concise
LLMs have context limits. Don't return a 10MB JSON dump. Filter fields to only what's necessary (e.g., ID, Name, Price).
2. Error Recovery
If an API call fails, don't throw an exception. Return a string like "Error: API timeout". The agent might try again or apologize to the user.