Skip to Content
DocsAgentsOverview

Using Agents

Agents let you build intelligent assistants powered by language models that can make decisions and perform actions. Each agent has required instructions and an LLM, with optional tools and memory.

An agent coordinates conversations, calls tools when needed, maintains context through memory, and produces responses tailored to the interaction. Agents can operate on their own or work as part of larger workflows.

Agents overview

To create an agent:

  • Define instructions with the Agent class and set the LLM it will use.
  • Optionally configure tools and memory to extend functionality.
  • Run the agent to generate responses, with support for streaming, structured output, and dynamic configuration.

This approach provides type safety and runtime validation, ensuring reliable behavior across all agent interactions.

Getting started

To use agents, install the required dependencies:

npm install @mastra/core @ai-sdk/openai

Mastra works with all AI SDK provider. See Model Providers for more information.

Import the necessary class from the agents module, and an LLM provider:

src/mastra/agents/test-agent.ts
import { openai } from "@ai-sdk/openai"; import { Agent } from "@mastra/core/agent";

LLM providers

Each LLM provider needs its own API key, named using the provider’s identifier:

.env
OPENAI_API_KEY=<your-api-key>

See the AI SDK Providers  in the Vercel AI SDK docs.

Creating an agent

To create an agent in Mastra, use the Agent class. Every agent must include instructions to define its behavior, and a model parameter to specify the LLM provider and model:

src/mastra/agents/test-agent.ts
import { openai } from "@ai-sdk/openai"; import { Agent } from "@mastra/core/agent"; export const testAgent = new Agent({ name: "test-agent", instructions: "You are a helpful assistant.", model: openai("gpt-4o-mini") });

See Agent for more information.

Registering an agent

Register your agent in the Mastra instance:

src/mastra/index.ts
import { Mastra } from "@mastra/core/mastra"; import { testAgent } from './agents/test-agent'; export const mastra = new Mastra({ // ... agents: { testAgent }, });

Referencing an agent

You can call agents from workflow steps, tools, the Mastra Client, or the command line. Get a reference by calling .getAgent() on your mastra or mastraClient instance, depending on your setup:

const testAgent = mastra.getAgent("testAgent");

See Calling agents for more information.

Generating responses

Use .generate() to get a response from an agent. Pass a single string for simple prompts, an array of strings when providing multiple pieces of context, or an array of message objects with role and content for precise control over roles and conversational flows.

See .generate() for more information.

Generating text

Call .generate() with an array of message objects that include role and content:

const response = await testAgent.generate([ { role: "user", content: "Help me organize my day" }, { role: "user", content: "My day starts at 9am and finishes at 5.30pm" }, { role: "user", content: "I take lunch between 12:30 and 13:30" }, { role: "user", content: "I have meetings Monday to Friday between 10:30 and 11:30" } ]); console.log(response.text);

Streaming responses

Use .stream() for real-time responses. Pass a single string for simple prompts, an array of strings when providing multiple pieces of context, or an array of message objects with role and content for precise control over roles and conversational flows.

See .stream() for more information.

Streaming text

Call .stream() with an array of message objects that include role and content:

const stream = await testAgent.stream([ { role: "user", content: "Help me organize my day" }, { role: "user", content: "My day starts at 9am and finishes at 5.30pm" }, { role: "user", content: "I take lunch between 12:30 and 13:30" }, { role: "user", content: "I have meetings Monday to Friday between 10:30 and 11:30" } ]); for await (const chunk of stream.textStream) { process.stdout.write(chunk); }

Completion using onFinish()

When streaming responses, the onFinish() callback runs after the LLM finishes generating its response and all tool executions are complete. It provides the final text, execution steps, finishReason, token usage statistics, and other metadata useful for monitoring or logging.

const stream = await testAgent.stream("Help me organize my day", { onFinish: ({ steps, text, finishReason, usage }) => { console.log({ steps, text, finishReason, usage }); } }); for await (const chunk of stream.textStream) { process.stdout.write(chunk); }

Structured output

Agents can return structured, type-safe data by defining the expected output with either Zod  or JSON Schema . In both cases, the parsed result is available on response.object, allowing you to work directly with validated and typed data.

Using Zod

Define the output shape using Zod :

import { z } from "zod"; const response = await testAgent.generate("Monkey, Ice Cream, Boat", { experimental_output: z.object({ summary: z.string(), keywords: z.array(z.string()) }) }); console.log(response.object);

Using Tools

If you need to generate structured output alongside tool calls, you’ll need to use the experimental_output or structuredOutput property instead of output. Here’s how:

const response = await testAgent.generate("Monkey, Ice Cream, Boat", { experimental_output: z.object({ summary: z.string(), keywords: z.array(z.string()) }) }); const responseWithExperimentalOutput = await testAgent.generate( [ { role: "user", content: "Please analyze this repository and provide a summary and keywords...", }, ], { // Use experimental_output to enable both structured output and tool calls experimental_output: schema, }, ); console.log("Structured Output:", responseWithExperimentalOutput.object); const responseWithStructuredOutput = await testAgent.generate( [ { role: "user", content: "Please analyze this repository and provide a summary and keywords...", }, ], { structuredOutput: { schema: z.object({ summary: z.string(), keywords: z.array(z.string()) }), model: openai("gpt-4o-mini"), } }, ); console.log("Structured Output:", responseWithStructuredOutput.object);

Describing images

Agents can analyze and describe images by processing both the visual content and any text within them. To enable image analysis, pass an object with type: 'image' and the image URL in the content array. You can combine image content with text prompts to guide the agent’s analysis.

const response = await testAgent.generate([ { role: "user", content: [ { type: "image", image: "https://placebear.com/cache/395-205.jpg", mimeType: "image/jpeg" }, { type: "text", text: "Describe the image in detail, and extract all the text in the image." } ] } ]); console.log(response.text);

Multi-step tool use

Agents can be enhanced with tools, functions that extend their capabilities beyond text generation. Tools allow agents to perform calculations, access external systems, and process data. Agents not only decide whether to call tools they’re given, they determine the parameters that should be given to that tool.

For a detailed guide to creating and configuring tools, see the Tools Overview page.

Using maxSteps

The maxSteps parameter controls the maximum number of sequential LLM calls an agent can make, particularly important when using tool calls. By default, it is set to 1 to prevent infinite loops in case of misconfigured tools:

const response = await testAgent.generate("Help me organize my day", { maxSteps: 5 }); console.log(response.text);

Using onStepFinish

You can monitor the progress of multi-step operations using the onStepFinish callback. This is useful for debugging or providing progress updates to users.

onStepFinish is only available when streaming or generating text without structured output.

const response = await testAgent.generate("Help me organize my day", { onStepFinish: ({ text, toolCalls, toolResults, finishReason, usage }) => { console.log({ text, toolCalls, toolResults, finishReason, usage }); } });

Testing agents locally

Use the mastra dev CLI command to run your agents behind a local API. By default, it loads exported agents from the src/mastra/agents directory and creates endpoints for testing (for example, http://localhost:4111/api/agents/myAgent/generate). It also launches a visual playground where you can chat with your agent and view execution traces.

For more information, see the Local Dev Playground documentation.

Next Steps