Skip to main content
Agents are the foundation for creating AI systems in Mastra. An agent is an autonomous system that can make decisions, use tools, maintain conversation memory, and interact with external systems.

Core Concept

Agents in Mastra combine:
  • LLM reasoning: Decision-making powered by language models
  • Tools: Ability to perform actions and access external systems
  • Memory: Thread-based conversation persistence and semantic recall
  • Processors: Input/output transformation pipeline
  • Workspace: File operations and code execution

Basic Agent

Create a minimal agent with instructions and a model:
import { Agent } from '@mastra/core/agent';

const agent = new Agent({
  id: 'assistant',
  name: 'Assistant',
  instructions: 'You are a helpful assistant',
  model: 'openai/gpt-5'
});

// Generate a response
const result = await agent.generate('What is the weather?');
console.log(result.text);

Agent Configuration

The AgentConfig interface defines all available options:
interface AgentConfig<TAgentId, TTools, TOutput, TRequestContext> {
  // Required
  id: TAgentId;                          // Unique identifier
  name: string;                          // Display name
  instructions: AgentInstructions;       // System prompt or messages
  model: MastraModelConfig | ModelFallbacks; // LLM configuration
  
  // Tools & Actions
  tools?: TTools;                        // Available tools
  agents?: Record<string, Agent>;        // Sub-agents for delegation
  
  // Memory & State
  memory?: MastraMemory;                 // Conversation persistence
  workspace?: AnyWorkspace;              // File ops & code execution
  
  // Processing Pipeline
  inputProcessors?: InputProcessorOrWorkflow[];
  outputProcessors?: OutputProcessorOrWorkflow[];
  
  // Advanced
  scorers?: MastraScorers;               // Quality evaluation
  voice?: MastraVoice;                   // Speech capabilities
  maxRetries?: number;                   // Retry failed operations
  requestContextSchema?: ZodSchema;      // Validate request context
}

Instructions

Instructions define the agent’s behavior and can be static or dynamic:

Static Instructions

const agent = new Agent({
  id: 'assistant',
  instructions: 'You are a helpful assistant that provides concise answers.'
});

Dynamic Instructions

Instructions can be computed based on request context:
const agent = new Agent({
  id: 'support',
  instructions: ({ requestContext }) => {
    const tier = requestContext.get('userTier');
    return tier === 'premium'
      ? 'You are a premium support agent. Provide detailed, personalized help.'
      : 'You are a support agent. Provide helpful answers.';
  }
});

Message-based Instructions

Instructions can be structured messages:
const agent = new Agent({
  id: 'coder',
  instructions: [
    { role: 'system', content: 'You are an expert programmer.' },
    { role: 'system', content: 'Always explain your code clearly.' }
  ]
});

Tools

Tools extend agent capabilities with access to external systems:
import { createTool } from '@mastra/core/tools';
import { z } from 'zod';

const weatherTool = createTool({
  id: 'get-weather',
  description: 'Get current weather for a location',
  inputSchema: z.object({
    location: z.string(),
    units: z.enum(['celsius', 'fahrenheit']).optional()
  }),
  execute: async ({ location, units }) => {
    const weather = await fetchWeather(location, units);
    return { temperature: weather.temp, condition: weather.condition };
  }
});

const agent = new Agent({
  id: 'weather-agent',
  instructions: 'You help users with weather information',
  model: 'openai/gpt-5',
  tools: { weather: weatherTool }
});

// Agent automatically uses tool when needed
const result = await agent.generate('What\'s the weather in Paris?');
See Tools for advanced tool patterns.

Memory

Memory enables conversation persistence and semantic recall:
import { Memory } from '@mastra/memory';

const agent = new Agent({
  id: 'assistant',
  instructions: 'You are a helpful assistant',
  model: 'openai/gpt-5',
  memory: new Memory({
    name: 'conversation',
    options: {
      lastMessages: 20,           // Include last 20 messages
      semanticRecall: true,       // Enable semantic search
      workingMemory: { enabled: true } // Structured facts
    }
  })
});

// Conversation persists across calls
const result1 = await agent.generate(
  'My name is Alice',
  { threadId: 'user-123' }
);

const result2 = await agent.generate(
  'What is my name?',
  { threadId: 'user-123' }
);
console.log(result2.text); // "Your name is Alice"
See Memory for advanced memory patterns.

Processors

Processors transform agent inputs and outputs:
import { createStep } from '@mastra/core/workflows';

const translationProcessor = createStep({
  id: 'translate-input',
  inputSchema: z.object({ messages: z.array(z.any()) }),
  outputSchema: z.object({ messages: z.array(z.any()) }),
  execute: async ({ messages }) => {
    // Translate user messages to English
    return {
      messages: await Promise.all(
        messages.map(async (msg) => ({
          ...msg,
          content: await translate(msg.content, 'en')
        }))
      )
    };
  }
});

const agent = new Agent({
  id: 'multilingual',
  instructions: 'You are a helpful assistant',
  model: 'openai/gpt-5',
  inputProcessors: [translationProcessor]
});

Model Configuration

Single Model

const agent = new Agent({
  id: 'assistant',
  model: 'openai/gpt-5',
  maxRetries: 2 // Retry failed requests
});

Model Fallbacks

Configure multiple models with automatic fallback:
const agent = new Agent({
  id: 'resilient',
  model: [
    {
      model: 'openai/gpt-5',
      maxRetries: 2,
      enabled: true
    },
    {
      model: 'anthropic/claude-4',
      maxRetries: 1,
      enabled: true
    }
  ]
});

Dynamic Model Selection

const agent = new Agent({
  id: 'adaptive',
  model: ({ requestContext }) => {
    const complexity = requestContext.get('complexity');
    return complexity === 'high'
      ? 'openai/gpt-5'
      : 'openai/gpt-4o-mini';
  }
});

Generating Responses

Text Generation

const result = await agent.generate('Hello!');
console.log(result.text);

Streaming Responses

const stream = await agent.stream('Tell me a story');

for await (const chunk of stream) {
  if (chunk.type === 'text') {
    process.stdout.write(chunk.text);
  }
}

Structured Output

import { z } from 'zod';

const schema = z.object({
  name: z.string(),
  age: z.number(),
  email: z.string().email()
});

const result = await agent.generate('Extract user info', {
  structuredOutput: { schema }
});

console.log(result.object); // { name: 'Alice', age: 30, email: '...' }

Multi-Agent Collaboration

Agents can delegate to sub-agents:
const codeAgent = new Agent({
  id: 'coder',
  instructions: 'You write code',
  model: 'openai/gpt-5'
});

const reviewAgent = new Agent({
  id: 'reviewer',
  instructions: 'You review code for bugs',
  model: 'anthropic/claude-4'
});

const orchestrator = new Agent({
  id: 'orchestrator',
  instructions: 'Coordinate code writing and review',
  model: 'openai/gpt-5',
  agents: {
    coder: codeAgent,
    reviewer: reviewAgent
  }
});

const result = await orchestrator.generate(
  'Write a function to parse JSON and have it reviewed'
);

Workspace

Workspace provides file operations and code execution:
import { Workspace } from '@mastra/workspace';

const agent = new Agent({
  id: 'file-agent',
  instructions: 'You help with file operations',
  model: 'openai/gpt-5',
  workspace: new Workspace({
    id: 'workspace',
    filesystem: new LocalFilesystem({ rootPath: './workspace' }),
    sandbox: new E2BSandbox({ apiKey: process.env.E2B_API_KEY })
  })
});

// Agent can read/write files and execute code
const result = await agent.generate(
  'Create a file called data.json with user data'
);

Request Context

Pass per-request data to agents:
import { RequestContext } from '@mastra/core';
import { z } from 'zod';

const agent = new Agent({
  id: 'api-agent',
  requestContextSchema: z.object({
    apiKey: z.string(),
    userId: z.string()
  }),
  tools: ({ requestContext }) => {
    const apiKey = requestContext.get('apiKey');
    return {
      fetchData: createTool({
        execute: async () => {
          return await fetch('/api/data', {
            headers: { 'Authorization': `Bearer ${apiKey}` }
          });
        }
      })
    };
  }
});

const ctx = new RequestContext();
ctx.set('apiKey', process.env.API_KEY);
ctx.set('userId', 'user-123');

const result = await agent.generate('Fetch my data', {
  requestContext: ctx
});

Agent Networks

Create sophisticated multi-agent systems:
const result = await orchestrator.network('Build and deploy a web app', {
  maxSteps: 20,
  completion: {
    scorers: [
      createScorer({
        id: 'deployment-check',
        run: async ({ output }) => {
          return output.includes('deployed') ? 1 : 0;
        }
      })
    ],
    threshold: 1.0
  }
});

Execution Options

Control agent behavior per request:
const result = await agent.generate('Hello', {
  maxSteps: 5,              // Max tool use iterations
  temperature: 0.7,         // Creativity (0-2)
  maxTokens: 1000,          // Response length limit
  threadId: 'user-123',     // Conversation thread
  resourceId: 'user-123',   // Resource identifier
  abortSignal: signal,      // Cancellation
  onStepFinish: ({ step }) => {
    console.log('Step:', step);
  }
});

Best Practices

Provide specific, actionable instructions:
// Good: Specific and actionable
instructions: 'You are a customer support agent. Answer questions about our product. Be concise and friendly.'

// Avoid: Vague
instructions: 'Help users'
Enable memory when building conversational agents:
const agent = new Agent({
  memory: new Memory({
    options: { lastMessages: 20 }
  })
});
Use Zod schemas for reliable data extraction:
const result = await agent.generate('Extract info', {
  structuredOutput: {
    schema: z.object({
      name: z.string(),
      email: z.string().email()
    })
  }
});
Use try-catch and configure retries:
const agent = new Agent({
  maxRetries: 2,
  model: [
    { model: 'openai/gpt-5' },
    { model: 'anthropic/claude-4' }
  ]
});

try {
  const result = await agent.generate(prompt);
} catch (error) {
  console.error('Agent failed:', error);
}

Build docs developers (and LLMs) love