Agentic AITypeScriptverifiedVerified

Tool Use Agent Pattern in TypeScript

Augment an LLM with callable external tools — APIs, code interpreters, databases — so it can take actions and retrieve real-time information beyond its training data.

How to Implement the Tool Use Agent Pattern in TypeScript

1Step 1: Define the tool and message interfaces

interface ToolDefinition {
  name: string;
  description: string;
  parameters: Record<string, { type: string; description: string }>;
}

interface ToolResult {
  toolName: string;
  output: string;
  isError: boolean;
}

interface AgentMessage {
  role: "user" | "assistant" | "tool";
  content: string;
  toolName?: string;
}

type ToolHandler = (params: Record<string, unknown>) => Promise<string>;

2Step 2: Create the ToolRegistry for registration and execution

class ToolRegistry {
  private tools = new Map<string, { definition: ToolDefinition; handler: ToolHandler }>();

  register(definition: ToolDefinition, handler: ToolHandler): void {
    this.tools.set(definition.name, { definition, handler });
  }

  getDefinitions(): ToolDefinition[] {
    return [...this.tools.values()].map(t => t.definition);
  }

  async execute(name: string, params: Record<string, unknown>): Promise<ToolResult> {
    const tool = this.tools.get(name);
    if (!tool) return { toolName: name, output: `Unknown tool: ${name}`, isError: true };

    try {
      const output = await tool.handler(params);
      return { toolName: name, output, isError: false };
    } catch (e) {
      return { toolName: name, output: String(e), isError: true };
    }
  }
}

3Step 3: Implement the tool-use loop

async function toolUseLoop(
  userMessage: string,
  registry: ToolRegistry,
  llm: (messages: AgentMessage[], tools: ToolDefinition[]) => Promise<{ content: string; toolCall?: { name: string; params: Record<string, unknown> } }>
): Promise<string> {
  const messages: AgentMessage[] = [{ role: "user", content: userMessage }];

  for (let i = 0; i < 10; i++) {
    const response = await llm(messages, registry.getDefinitions());
    messages.push({ role: "assistant", content: response.content });

    if (!response.toolCall) return response.content;

    const result = await registry.execute(response.toolCall.name, response.toolCall.params);
    messages.push({ role: "tool", content: result.output, toolName: result.toolName });
  }

  return "Max iterations reached";
}

Tool Use Agent Pattern Architecture

hourglass_empty

Rendering diagram...

lightbulb

Tool Use Agent Pattern in the Real World

A lawyer (the LLM) in a courtroom knows the law but needs a paralegal team (the tools) to pull case files, run searches, and retrieve exhibits. The lawyer directs which file to fetch, the paralegal returns it, and the lawyer integrates that information into their argument — the lawyer's intelligence is amplified by the support staff's ability to reach into the real world.