Tools
Extend agent capabilities with tools for external interactions and actions
What is a Tool?
A Tool in ADK-TS is a specialized component that extends an AI agent's capabilities beyond text generation. Tools enable agents to perform concrete actions like retrieving data from APIs, accessing databases, or interacting with external systems.
In technical terms, a tool in ADK-TS is an implementation of the BaseTool class or a function that can be converted into a tool. Each tool has a name, description, and a function that executes when called by an agent. Tools receive structured input arguments and return structured data that the agent can use for further reasoning.
Core Principles
Focused Functionality: Each tool should have a single, well-defined purpose. Rather than creating one complex tool that does everything, build multiple focused tools that each excel at specific tasks—fetching user profiles, sending notifications, processing payments, etc.
Structured Data Exchange: Tools communicate with agents using defined schema. They accept structured inputs validated against TypeScript types or Zod schemas, and return structured data that agents can process predictably.
Deterministic Execution: Tools execute the exact logic you define. When an agent calls a tool, it runs your implementation with the provided arguments, returning consistent results for the same inputs. The agent decides when to call the tool, but the tool itself performs predictably.
Seamless Integration: Tools integrate directly into the agent's reasoning process. The agent can examine tool outputs, make decisions based on results, and chain multiple tools together to accomplish complex workflows.
Division of Responsibilities
Your agent handles the "thinking"—understanding user intent, deciding which tools to use, and interpreting results. Your tools handle the "doing"—executing specific operations and returning structured data for the agent to work with.
How Agents Work with Tools
The interaction between agents and tools follows a natural cycle that mirrors how humans might work with specialized assistants:
-
Understanding: Your agent processes the user's request and determines what actions might be needed to fulfill it. It considers the available tools and their documented capabilities.
-
Decision Making: The agent chooses which tool to use based on the situation. This choice is guided by each tool's name, description, and the current context of the conversation.
-
Execution: The agent calls the selected tool with appropriate parameters, automatically validating inputs against your TypeScript definitions. The tool runs your custom logic and returns results.
-
Processing: The agent receives the tool's response and incorporates it into its understanding. It can then decide to call additional tools, process the data further, or respond to the user.
-
Response: Finally, the agent uses all gathered information to provide a comprehensive answer or take the next appropriate action.
Types of Tools Available
ADK-TS provides several approaches for creating and integrating tools, each suited to different development scenarios:
🔧 Function Tools
Wrap TypeScript functions as tools by extracting metadata from JSDoc comments and function signatures
✨ createTool Utility
Streamlined utility that converts TypeScript functions into tools using Zod schemas
⚡ Built-in Tools
Ready-to-use tools for search, file operations, user interaction, and more
🌐 MCP Tools
Connect to external systems using the Model Context Protocol standard
🔐 Google Cloud Tools
Specialized tools for Google Cloud Platform services with built-in authentication
📊 OpenAPI Tools
Automatically generate tools from OpenAPI/Swagger specifications
🔑 Authentication
Implement secure access to external APIs and services
📦 Third-Party Tools
Integrate existing npm packages and JavaScript libraries as tools
Example: Building a Customer Support Agent
Let's build a simple customer support agent that can look up customer information and create support tickets using two custom tools.
import { createTool, LlmAgent } from "@iqai/adk";
import { z } from "zod";
// Tool 1: Look up customer account information
const lookupCustomerTool = createTool({
name: "lookupCustomerTool",
description: "Looks up a customer profile by ID",
schema: z.object({
customerId: z.string().describe("Customer identifier (usually email)"),
}),
fn: async ({ customerId }: { customerId: string }) => {
// Simulate database lookup
type Customer = {
name: string;
tier: string;
status: string;
lastLogin: string;
};
const customerDb: Record<string, Customer> = {
"john@example.com": {
name: "John Smith",
tier: "premium",
status: "active",
lastLogin: "2024-12-10",
},
"jane@example.com": {
name: "Jane Doe",
tier: "basic",
status: "suspended",
lastLogin: "2024-11-15",
},
};
const customer = customerDb[customerId];
if (customer) {
return {
status: "found",
customer,
canAssist: customer.status === "active",
};
}
return { status: "not_found", message: "Customer not found in system" };
},
});
// Tool 2: Create a support ticket
const createTicketTool = createTool({
name: "createTicketTool",
description: "Creates a new support ticket for tracking issues",
schema: z.object({
customerId: z.string().describe("Customer identifier"),
category: z
.enum(["technical", "billing", "account", "general"])
.describe("Issue category"),
priority: z
.enum(["low", "medium", "high", "urgent"])
.describe("Ticket priority level"),
description: z.string().describe("Detailed issue description"),
}),
fn: async ({ customerId, category, priority, description }) => {
// Generate ticket ID and simulate creation
const ticketId = `TK-${Date.now().toString().slice(-6)}`;
return {
status: "created",
ticketId,
estimatedResponse: priority === "urgent" ? "1 hour" : "24 hours",
category,
assignedTeam:
category === "technical" ? "Engineering" : "General Support",
description,
customerId,
createdAt: new Date().toISOString(),
};
},
});
// Create customer support agent with tools for handling inquiries and ticket creation
export const getCustomerSupportAgent = () => {
const customerSupportAgent = new LlmAgent({
name: "customer_support_agent",
model: "gemini-2.0-flash",
description: "Handles customer support inquiries and ticket creation",
tools: [lookupCustomerTool, createTicketTool],
});
return customerSupportAgent;
};This example demonstrates:
- Creating focused tools with clear responsibilities
- Defining structured input and output using Zod schemas
- Implementing practical workflows for customer support scenarios
Integrating Tools with Agents
There are multiple ways to connect tools to your agents in ADK-TS:
Using LlmAgent
Add tools directly to the agent's configuration by passing an array to the tools property:
import { LlmAgent } from "@iqai/adk";
import { weatherTool, timeTool, calculatorTool } from "./my-tools";
// Using tools with LlmAgent
const agent = new LlmAgent({
name: "assistant_agent",
description: "A helpful assistant",
instruction: "Use the provided tools when needed to answer questions",
tools: [weatherTool, timeTool, calculatorTool],
});Using AgentBuilder
Add tools using the fluent withTools() method:
import { AgentBuilder } from "@iqai/adk";
import { weatherTool, timeTool, calculatorTool } from "./my-tools";
// Using tools with AgentBuilder
const { agent } = await AgentBuilder.create("assistant_agent")
.withModel("gemini-2.5-flash")
.withTools(weatherTool, timeTool, calculatorTool)
.build();Adding Tools Dynamically
Both approaches support conditional tool addition based on configuration or user permissions:
import { AgentBuilder, LlmAgent } from "@iqai/adk";
import { searchTool, systemAdminTool } from "./my-tools";
const tools = [];
const config = { enableSearch: true };
const userRole = "admin";
if (config.enableSearch) {
tools.push(searchTool);
}
if (userRole === "admin") {
tools.push(systemAdminTool);
}
const agent = new LlmAgent({
name: "dynamic_agent",
description: "Agent with dynamic tool configuration",
tools: tools,
});Guiding Tool Usage
Provide clear guidance in your agent instructions on when and how to use each tool:
const agent = new LlmAgent({
name: "research_agent",
description: "An agent that assists with research tasks using various tools.",
instruction: `You are a research assistant. Follow these guidelines:
- Use 'searchDocumentsTool' when the user asks about policies or procedures
- Use 'fetchWebContentTool' to find current information about recent events
- Use 'lookupDatabaseTool' only for specific data the user explicitly requests
- If a tool returns insufficient data, try a different source before giving up`,
tools: [searchDocumentsTool, fetchWebContentTool, lookupDatabaseTool],
});Key points for effective tool guidance:
- Focus on decision logic (when to use each tool) rather than repeating what the tool does
- Specify how to handle different tool outcomes (success, failure, partial results)
- Describe workflows when tools should be used in sequence
- Keep instructions clear and concise
Best Practices
Creating effective tools requires careful design. Here are some key principles:
- Use Clear Names: Tool names should intuitively indicate their purpose
- Structured Input/Output: Use Zod schemas to define and validate inputs; return consistent object structures
- Error Handling: Always handle errors gracefully and return informative messages
- Single Responsibility: Each tool should have a focused, well-defined purpose
- Guide Agent Usage: Provide clear instructions on when and how your agent should use each tool
For detailed best practices, organization strategies, and tool creation approaches, see the dedicated guides in the sidebar.
Next Steps
Ready to explore tools in depth? Here are the recommended next steps:
🔧 Function Tools
Create custom tools from TypeScript functions
✨ createTool Utility
Create custom tools with Zod schema validation
⚡ Built-in Tools
Ready-to-use tools for search, file operations, and user interaction
🔧 ToolContext Parameter
Access session data, memory, artifacts, and flow control within your tools
How is this guide?