In the previous chapter, Data Schema & Validation, we defined the "language" (Input and Output schemas) that our tool uses to communicate.
Now that we have the forms for the data, we need to officially hire the employee who will handle them. In this chapter, we will focus on Tool Definition & Configuration.
Imagine you have written a brilliant piece of code that can list every task in your database. It's fast, it's accurate, and it uses the schemas we built in Chapter 1.
However, the AI Agent acts like a busy project manager. It doesn't know your code exists. It doesn't know:
Without a formal definition, your code is just a ghostβinvisible to the system.
buildTool)
To solve this, we use a utility called buildTool. Think of this as filling out a detailed Employee Registration Form or creating an ID Badge.
When we fill out this configuration, we tell the system:
Let's break down the registration form into small, manageable pieces. All of this happens inside the TaskListTool.ts file.
First, we need to give the tool a name and tell the AI how to find it.
import { buildTool } from '../../Tool.js'
import { TASK_LIST_TOOL_NAME } from './constants.js'
export const TaskListTool = buildTool({
name: TASK_LIST_TOOL_NAME, // Unique internal ID
userFacingName: () => 'TaskList', // What the user sees in the UI
// The 'Hint' helps the AI find this tool via semantic search
searchHint: 'list all tasks',
// ... configuration continues
})
Explanation:
name: A unique string ID (e.g., 'TaskList').searchHint: This is crucial. When the user types "Show me everything on my plate," the system compares that phrase to 'list all tasks'. If they are similar, the AI picks this tool.Remember the "Order Tickets" we made in Data Schema & Validation? We need to attach them here.
// ... inside buildTool
get inputSchema() {
return inputSchema() // Defined in Chapter 1
},
get outputSchema() {
return outputSchema() // Defined in Chapter 1
},
// ... configuration continues
Explanation:
get) to attach the schemas.The AI needs to know if this tool is dangerous or heavy.
// ... inside buildTool
isConcurrencySafe() {
return true
},
isReadOnly() {
return true
},
shouldDefer: true,
Explanation:
isConcurrencySafe: Returns true. This means if the user asks for 5 different things at once, this tool can run in parallel without breaking anything.isReadOnly: Returns true. This tool only looks at data; it doesn't change it. This makes the AI more confident in using it freely.shouldDefer: If true, the tool runs in the background for a smoother user experience.Sometimes, we want to hide a tool without deleting the code (e.g., if a feature isn't ready for the public yet).
import { isTodoV2Enabled } from '../../utils/tasks.js'
// ... inside buildTool
isEnabled() {
return isTodoV2Enabled()
},
Explanation:
isTodoV2Enabled() returns false, the AI will pretend this tool doesn't exist.How does the system actually use this configuration object? Let's look at the "hiring" process.
isEnabled().searchHint. It adds this hint to a "semantic search" index.
Here is how it looks when we put these pieces together in the code. We wrap it all in buildTool and ensure it satisfies our ToolDef type for safety.
export const TaskListTool = buildTool({
name: TASK_LIST_TOOL_NAME,
searchHint: 'list all tasks',
// Linking our Schemas
get inputSchema(): InputSchema { return inputSchema() },
get outputSchema(): OutputSchema { return outputSchema() },
// Safety & Config
isEnabled() { return isTodoV2Enabled() },
isConcurrencySafe() { return true },
isReadOnly() { return true },
// ... (Logic and Prompts come later)
} satisfies ToolDef<InputSchema, Output>)
Explanation:
satisfies ToolDef<...>: This is a TypeScript trick. It ensures we didn't forget any required fields in our ID Badge. If we forget name, TypeScript will yell at us.
We have successfully created the ID Card for our TaskListTool.
However, simply having an ID badge isn't enough. The AI might know what the tool is, but it doesn't intuitively understand the nuances of how to use it to get the best results. For that, we need to teach the AI with dynamic instructions.
Next Chapter: Dynamic Prompt Engineering
Generated by Code IQ