TypeScriptADK-TS

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:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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:

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:

How is this guide?