Skip to content

Chapter 5 · Tools Definition ​

Chapter goals: Master the complete pattern for defining tools with createTool — Zod parameter validation, the execute body, and how to bind tools to Agents.

5.1 What Is a Tool ​

An LLM can only generate text. A Tool is the mechanism that gives the model "action capability": you register a function's name, parameter description, and execution logic with the Agent; the model autonomously decides when to call it and what parameters to pass; the framework executes the function and feeds the result back to the model for further reasoning.

text
User question → model decides data lookup is needed → issues tool-call → framework executes your function
        ← result fed back to model ← function return value ← 
model composes final answer based on result

5.2 Defining Your First Tool with createTool ​

typescript
// src/mastra/tools/weather-tool.ts
import { createTool } from '@mastra/core/tools';
import { z } from 'zod';

export const weatherTool = createTool({
  // Unique tool ID: the model references the tool by this id
  id: 'get-weather',
  // Description is for the model: clearly state "when to use me"
  description: 'Get current weather information for a specified city',
  // Input schema: declare parameters with Zod and auto-validate at runtime
  inputSchema: z.object({
    city: z.string().describe('City name, e.g. "Beijing"'),
    unit: z.enum(['celsius', 'fahrenheit']).default('celsius'),
  }),
  // Output schema: declare return structure for type inference
  outputSchema: z.object({
    temperature: z.number(),
    condition: z.string(),
  }),
  // Execution body: real business logic (framework guarantees params are validated)
  execute: async ({ context }) => {
    const { city, unit } = context;
    // In a real project, call an actual weather API here
    const mockData: Record<string, { temperature: number; condition: string }> = {
      Beijing: { temperature: 18, condition: 'Sunny' },
      Shanghai: { temperature: 22, condition: 'Cloudy' },
    };
    const data = mockData[city] ?? { temperature: 20, condition: 'Unknown' };
    return data;
  },
});

Four fields, each with a clear responsibility: id identifies the tool, description teaches the model when to use it, inputSchema constrains and validates parameters, execute carries the real logic.

5.3 The Role of Zod Schema ​

Zod does more than type declaration — it provides three layers of runtime guarantees:

typescript
inputSchema: z.object({
  // .describe() text enters the model's function description, directly affecting param quality
  query: z.string().min(1).describe('Search keyword'),
  // .optional() lets the model omit; .default() auto-fills a default value
  limit: z.number().int().max(50).default(10),
})
  1. Prompt enhancement: .describe() text is injected into the model's tool definition;
  2. Auto-validation: hallucinated invalid parameters are caught and retried;
  3. Type inference: TypeScript automatically gains context.query: string typing.

5.4 Binding Tools to an Agent ​

typescript
// src/mastra/agents/weather-agent.ts
import { Agent } from '@mastra/core/agent';
import { weatherTool } from '../tools/weather-tool';

export const weatherAgent = new Agent({
  id: 'weather-agent',
  name: 'Weather Agent',
  instructions: `
    You are a weather assistant.
    Use the get-weather tool to fetch current conditions.`,
  model: 'openai/gpt-5-mini',
  // tools is an object: the key becomes the tool reference name visible to the model
  tools: { weatherTool },
});
typescript
// Real-world example: tool calls an external HTTP API with timeout protection
execute: async ({ context }) => {
  const res = await fetch(`https://wttr.in/${encodeURIComponent(context.city)}?format=j1`, {
    signal: AbortSignal.timeout(5000), // 5s timeout prevents hanging
  });
  const data = await res.json();
  return {
    temperature: data.current_condition[0].temp_C,
    condition: data.current_condition[0].weatherDesc[0].value,
  };
}

Mention tools in instructions

Explicitly mentioning tool usage in instructions (e.g., "Use the get-weather tool...") significantly improves the model's tool-calling accuracy.

5.5 Chapter Summary ​

  • A Tool gives LLMs "action capability": the model decides to call, the framework executes;
  • createTool({ id, description, inputSchema, outputSchema, execute }) — all five fields are essential;
  • Zod .describe() writes to the model, schema validates at runtime, TS types auto-derive;
  • Mount to Agent via tools: { myTool } object form.

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. What is the purpose of the description field in createTool?

2. What happens when model-generated tool parameters fail inputSchema validation?

3. What does z.string().describe("City name") primarily affect in inputSchema?

4. What is the correct way to mount a tool onto an Agent?

🛠️ Hands-On Exercises ​

  1. Write a searchRecipe tool for the Chapter 4 chef-agent: takes an array of ingredients, returns a list of dishes you can make from a local dictionary.
  2. Add .max(5) array length limit to searchRecipe's inputSchema; intentionally pass 8 ingredients and observe the validation failure behavior.
  3. Call the tool-enabled Agent in Studio; find where tool call parameters are displayed and take a screenshot for your notes.

Next: Chapter 6 · Agent and Tool Integration in Practice