DT 技術解説 Mastra -

Mastra - TypeScript AIエージェントフレームワーク完全ガイド

MastraフレームワークでAIエージェントとワークフローを構築する方法を、実例を交えて詳しく解説します。

約5分で読めます
技術記事
実践的

この記事のポイント

MastraフレームワークでAIエージェントとワークフローを構築する方法を、実例を交えて詳しく解説します。

この記事では、実践的なアプローチで技術的な課題を解決する方法を詳しく解説します。具体的なコード例とともに、ベストプラクティスを学ぶことができます。

Mastraは、TypeScriptで構築されたモダンなAIエージェントフレームワークです。LLMを活用したワークフロー、ツール統合、RAG(Retrieval-Augmented Generation)システムを簡単に構築できます。

� なぜMastraが注目されているのか

2025年現在、AIエージェントの需要は急速に高まっています。しかし、多くの開発者が直面する課題があります:

graph TD
    A[開発者の課題] --> B[複雑なLLM統合]
    A --> C[型安全性の欠如]
    A --> D[ワークフロー管理の困難さ]
    A --> E[ツール統合の煩雑さ]
    
    F[Mastraの解決策] --> G[統一されたAPI]
    F --> H[TypeScript完全対応]
    F --> I[ビジュアルワークフロー]
    F --> J[100+の統合済みツール]
    
    style A fill:#ff6b6b
    style F fill:#4ecdc4

� Mastraが解決する具体的な問題

従来の課題Mastraでの解決方法メリット
LLMプロバイダごとの異なるAPI統一されたインターフェース学習コスト削減
実行時エラーの多発完全な型安全性バグの早期発見
複雑なステート管理宣言的なワークフロー保守性向上
ツール統合の手間プラグアンドプレイ開発速度向上

�️ Mastraのアーキテクチャ

graph TB
    subgraph "Mastra Core"
        A[Agent Manager] --> B[Workflow Engine]
        B --> C[Tool Registry]
        C --> D[Provider Abstraction]
    end
    
    subgraph "Providers"
        E[OpenAI]
        F[Anthropic]
        G[Google AI]
        H[Custom]
    end
    
    subgraph "Tools"
        I[Database]
        J[API]
        K[File System]
        L[Web Scraper]
    end
    
    D --> E
    D --> F
    D --> G
    D --> H
    
    C --> I
    C --> J
    C --> K
    C --> L
    
    style A fill:#e9c46a
    style B fill:#f4a261
    style C fill:#e76f51
    style D fill:#2a9d8f

� 主要コンポーネントの説明

  1. Agent Manager - エージェントのライフサイクルを管理
  2. Workflow Engine - 複雑なワークフローの実行を制御
  3. Tool Registry - ツールの登録と管理
  4. Provider Abstraction - 異なるLLMプロバイダーを統一的に扱う

Mastraの主な特徴

Mastraは以下の特徴を持つAIフレームワークです:

  • TypeScriptファースト - 完全な型安全性とインテリセンス
  • モジュラー設計 - エージェント、ツール、ワークフローを独立して管理
  • 複数LLM対応 - OpenAI、Anthropic、Google AI、その他のプロバイダーをサポート
  • ビルトインツール - 100以上の統合済みツールとカスタムツール作成機能
  • ワークフロー - 複雑なAIワークフローを視覚的に構築・管理

� 基本的なセットアップ

インストール手順

# Mastraコアパッケージのインストール
npm install @mastra/core

# 使用するプロバイダーを追加
npm install @mastra/openai @mastra/anthropic

# オプション: 追加ツール
npm install @mastra/tools-database @mastra/tools-web

� 推奨プロジェクト構造

my-ai-project/
├── src/
│   ├── agents/           # エージェント定義
│   │   ├── assistant.ts
│   │   └── researcher.ts
│   ├── workflows/        # ワークフロー定義
│   │   └── content-generation.ts
│   ├── tools/           # カスタムツール
│   │   └── custom-api.ts
│   └── config/          # 設定ファイル
│       └── mastra.ts
├── .env                 # 環境変数
└── package.json

基本設定

import { Mastra } from '@mastra/core';
import { OpenAIProvider } from '@mastra/openai';

// Mastraインスタンスの初期化
const mastra = new Mastra({
  providers: {
    openai: new OpenAIProvider({
      apiKey: process.env.OPENAI_API_KEY,
    }),
  },
  defaultProvider: 'openai',
});

🤖 エージェントの作成

エージェントのライフサイクル

stateDiagram-v2
    [*] --> 初期化
    初期化 --> 待機中
    待機中 --> メッセージ受信
    メッセージ受信 --> 処理中
    処理中 --> ツール実行: ツールが必要な場合
    ツール実行 --> 処理中
    処理中 --> レスポンス生成
    レスポンス生成 --> 待機中
    レスポンス生成 --> [*]: 終了時

シンプルなエージェント

import { Agent } from '@mastra/core';

// エージェントの定義
const assistantAgent = new Agent({
  id: 'assistant',
  name: 'アシスタントエージェント',
  description: 'ユーザーの質問に答えるエージェント',
  instructions: `
    あなたは親切で知識豊富なアシスタントです。
    ユーザーの質問に対して、正確で分かりやすい回答を提供してください。
    技術的な内容も初心者に理解できるように説明してください。
  `,
  model: 'gpt-4',
  temperature: 0.7,
});

// エージェントの実行
async function runAgent() {
  const response = await assistantAgent.run({
    messages: [
      { role: 'user', content: 'TypeScriptの型システムについて説明してください' }
    ],
  });
  
  console.log(response.content);
}

ツール付きエージェント

� ツールの種類と使用例

ツールタイプ説明使用場面
APIツール外部APIへのアクセス天気情報、株価取得
データベースツールDB操作の実行ユーザー情報取得、データ更新
ファイルシステムツールファイルの読み書きドキュメント処理
計算ツール数値計算・分析統計処理、データ分析
import { Agent, Tool } from '@mastra/core';

// カスタムツールの定義
const weatherTool = new Tool({
  id: 'get-weather',
  name: '天気情報取得',
  description: '指定された都市の天気情報を取得します',
  parameters: {
    type: 'object',
    properties: {
      city: {
        type: 'string',
        description: '都市名',
      },
    },
    required: ['city'],
  },
  execute: async ({ city }) => {
    // 実際のAPI呼び出し
    const response = await fetch(`https://api.weather.com/v1/weather/${city}`);
    const data = await response.json();
    return data;
  },
});

// ツール付きエージェント
const weatherAgent = new Agent({
  id: 'weather-assistant',
  name: '天気予報アシスタント',
  instructions: '天気に関する質問に答えるアシスタントです',
  tools: [weatherTool],
  model: 'gpt-4',
});

// 実行例
const response = await weatherAgent.run({
  messages: [
    { role: 'user', content: '東京の今日の天気を教えて' }
  ],
});

� ワークフローの構築

ワークフローの概念図

graph LR
    A[入力] --> B[トピック分析]
    B --> C{分析結果}
    C -->|OK| D[コンテンツ生成]
    C -->|NG| E[再分析]
    E --> B
    D --> F[品質チェック]
    F --> G{品質 OK?}
    G -->|Yes| H[公開]
    G -->|No| I[修正]
    I --> D
    
    style A fill:#e9c46a
    style H fill:#52b788
    style E fill:#f4a261
    style I fill:#f4a261

基本的なワークフロー

import { Workflow, Step } from '@mastra/core';

// ワークフローの定義
const contentWorkflow = new Workflow({
  id: 'content-generation',
  name: 'コンテンツ生成ワークフロー',
  description: 'ブログ記事を自動生成するワークフロー',
});

// ステップ1: トピック分析
const analyzeTopicStep = new Step({
  id: 'analyze-topic',
  name: 'トピック分析',
  execute: async ({ topic }) => {
    const agent = new Agent({
      instructions: 'トピックを分析して、キーワードと構成を提案してください',
    });
    
    const analysis = await agent.run({
      messages: [
        { role: 'user', content: `次のトピックについて分析してください: ${topic}` }
      ],
    });
    
    return { analysis: analysis.content };
  },
});

// ステップ2: コンテンツ生成
const generateContentStep = new Step({
  id: 'generate-content',
  name: 'コンテンツ生成',
  execute: async ({ analysis }) => {
    const agent = new Agent({
      instructions: 'SEOに最適化されたブログ記事を生成してください',
    });
    
    const content = await agent.run({
      messages: [
        { role: 'user', content: `次の分析に基づいて記事を作成してください: ${analysis}` }
      ],
    });
    
    return { content: content.content };
  },
});

// ワークフローにステップを追加
contentWorkflow
  .addStep(analyzeTopicStep)
  .addStep(generateContentStep)
  .connect('analyze-topic', 'generate-content');

// ワークフローの実行
async function runWorkflow() {
  const result = await contentWorkflow.run({
    input: { topic: 'Next.js 15の新機能' },
  });
  
  console.log(result.content);
}

条件分岐を含むワークフロー

� 感情分析によるルーティング

flowchart TD
    A[ユーザー入力] --> B[感情分析]
    B --> C{Sentiment}
    C -->|Positive| D[ポジティブ応答]
    C -->|Negative| E[ネガティブ応答]
    C -->|Neutral| F[ニュートラル応答]
    
    D --> G[フィードバック収集]
    E --> H[問題解決フロー]
    F --> G
    
    style C fill:#ffd60a
    style D fill:#52b788
    style E fill:#f4a261
const conditionalWorkflow = new Workflow({
  id: 'conditional-processing',
  name: '条件付き処理ワークフロー',
});

// 感情分析ステップ
const sentimentAnalysisStep = new Step({
  id: 'sentiment-analysis',
  name: '感情分析',
  execute: async ({ text }) => {
    const agent = new Agent({
      instructions: 'テキストの感情を分析して、positive/negative/neutralを返してください',
    });
    
    const result = await agent.run({
      messages: [{ role: 'user', content: text }],
    });
    
    return { sentiment: result.content };
  },
});

// ポジティブな応答
const positiveResponseStep = new Step({
  id: 'positive-response',
  name: 'ポジティブ応答',
  execute: async ({ text }) => {
    return { response: 'ありがとうございます!お役に立てて嬉しいです。' };
  },
});

// ネガティブな応答
const negativeResponseStep = new Step({
  id: 'negative-response',
  name: 'ネガティブ応答',
  execute: async ({ text }) => {
    return { response: 'ご不便をおかけして申し訳ございません。改善に努めます。' };
  },
});

// 条件分岐の設定
conditionalWorkflow
  .addStep(sentimentAnalysisStep)
  .addStep(positiveResponseStep)
  .addStep(negativeResponseStep)
  .addCondition('sentiment-analysis', {
    positive: 'positive-response',
    negative: 'negative-response',
    neutral: 'positive-response',
  });

� RAGシステムの実装

RAGアーキテクチャ

graph TB
    subgraph "1. インデックス作成"
        A[ドキュメント] --> B[チャンク分割]
        B --> C[エンベディング]
        C --> D[ベクターDB保存]
    end
    
    subgraph "2. 検索プロセス"
        E[ユーザークエリ] --> F[クエリエンベディング]
        F --> G[類似度検索]
        G --> H[コンテキスト取得]
    end
    
    subgraph "3. 生成プロセス"
        H --> I[プロンプト構築]
        I --> J[LLM]
        J --> K[回答生成]
    end
    
    style A fill:#e9c46a
    style E fill:#e9c46a
    style K fill:#52b788

� ベクターストアの比較

プロバイダー特徴適した用途料金
Pinecone高速、スケーラブル大規模アプリ従量課金
Weaviateオープンソースセルフホスト無料(セルフホスト)
Chroma軽量、簡単プロトタイプ無料
QdrantRust製、高速中規模アプリ無料/有料

ベクターストアの設定

import { VectorStore, Document } from '@mastra/core';
import { PineconeProvider } from '@mastra/pinecone';

// ベクターストアの初期化
const vectorStore = new VectorStore({
  provider: new PineconeProvider({
    apiKey: process.env.PINECONE_API_KEY,
    environment: 'us-east-1',
    indexName: 'knowledge-base',
  }),
  embeddings: {
    provider: 'openai',
    model: 'text-embedding-ada-002',
  },
});

// ドキュメントの追加
async function addDocuments() {
  const documents = [
    new Document({
      content: 'Next.js 15では、Turbopackがデフォルトになりました',
      metadata: { source: 'nextjs-docs', topic: 'build-tools' },
    }),
    new Document({
      content: 'React Server Componentsの改善により、パフォーマンスが向上',
      metadata: { source: 'nextjs-docs', topic: 'performance' },
    }),
  ];
  
  await vectorStore.addDocuments(documents);
}

// RAGエージェントの作成
const ragAgent = new Agent({
  id: 'rag-assistant',
  name: 'RAGアシスタント',
  instructions: `
    提供されたコンテキストに基づいて質問に答えてください。
    コンテキストに情報がない場合は、その旨を伝えてください。
  `,
  retriever: vectorStore.asRetriever({
    k: 5, // 取得するドキュメント数
    scoreThreshold: 0.7,
  }),
});

// RAGエージェントの実行
async function askQuestion() {
  const response = await ragAgent.run({
    messages: [
      { role: 'user', content: 'Next.js 15の新機能について教えて' }
    ],
  });
  
  console.log(response.content);
  console.log('使用されたコンテキスト:', response.context);
}

高度な機能

�️ パフォーマンス比較

graph LR
    subgraph "通常のレスポンス"
        A[ユーザー] -->|Request| B[サーバー]
        B -->|5秒待機| C[完全なレスポンス]
        C --> A
    end
    
    subgraph "ストリーミング"
        D[ユーザー] -->|Request| E[サーバー]
        E -->|0.1秒| F[最初のチャンク]
        F --> D
        E -->|0.2秒| G[次のチャンク]
        G --> D
        E -->|...継続| H[最後のチャンク]
        H --> D
    end
    
    style C fill:#f4a261
    style F fill:#52b788
    style G fill:#52b788
    style H fill:#52b788

ストリーミングレスポンス

const streamingAgent = new Agent({
  id: 'streaming',
  name: 'ストリーミングエージェント',
  streaming: true,
});

async function streamResponse() {
  const stream = await streamingAgent.stream({
    messages: [
      { role: 'user', content: '長い物語を書いてください' }
    ],
  });
  
  for await (const chunk of stream) {
    process.stdout.write(chunk.content);
  }
}

関数呼び出し(Function Calling)

const functionCallingAgent = new Agent({
  id: 'function-caller',
  name: '関数呼び出しエージェント',
  tools: [
    {
      name: 'calculate',
      description: '数式を計算します',
      parameters: {
        type: 'object',
        properties: {
          expression: { type: 'string' },
        },
      },
      execute: async ({ expression }) => {
        // eval は危険なので、実際には数式パーサーを使用
        return { result: eval(expression) };
      },
    },
    {
      name: 'searchDatabase',
      description: 'データベースを検索します',
      parameters: {
        type: 'object',
        properties: {
          query: { type: 'string' },
          table: { type: 'string' },
        },
      },
      execute: async ({ query, table }) => {
        // データベース検索の実装
        const results = await db.query(`SELECT * FROM ${table} WHERE ${query}`);
        return { results };
      },
    },
  ],
});

🤝 マルチエージェントシステム

エージェント間のコラボレーション

sequenceDiagram
    participant U as ユーザー
    participant M as マネージャー
    participant R as 調査エージェント
    participant W as ライターエージェント
    participant E as 編集エージェント
    
    U->>M: 記事作成依頼
    M->>R: トピック調査指示
    R->>R: 情報収集
    R-->>M: 調査結果
    M->>W: 記事作成指示
    W->>W: コンテンツ作成
    W-->>M: 初稿
    M->>E: 編集指示
    E->>E: 推敲・改善
    E-->>M: 完成稿
    M-->>U: 最終記事
// エージェントチームの作成
const researchAgent = new Agent({
  id: 'researcher',
  name: '調査エージェント',
  instructions: '与えられたトピックについて詳細な調査を行います',
});

const writerAgent = new Agent({
  id: 'writer',
  name: 'ライターエージェント',
  instructions: '調査結果を基に魅力的な記事を書きます',
});

const editorAgent = new Agent({
  id: 'editor',
  name: '編集エージェント',
  instructions: '記事を推敲し、改善点を提案します',
});

// マルチエージェントワークフロー
const multiAgentWorkflow = new Workflow({
  id: 'content-production',
  name: 'コンテンツ制作チーム',
});

const researchStep = new Step({
  id: 'research',
  execute: async ({ topic }) => {
    const research = await researchAgent.run({
      messages: [{ role: 'user', content: `${topic}について調査してください` }],
    });
    return { research: research.content };
  },
});

const writeStep = new Step({
  id: 'write',
  execute: async ({ research }) => {
    const article = await writerAgent.run({
      messages: [{ role: 'user', content: `次の調査結果を基に記事を書いてください: ${research}` }],
    });
    return { article: article.content };
  },
});

const editStep = new Step({
  id: 'edit',
  execute: async ({ article }) => {
    const edited = await editorAgent.run({
      messages: [{ role: 'user', content: `次の記事を編集してください: ${article}` }],
    });
    return { finalArticle: edited.content };
  },
});

multiAgentWorkflow
  .addStep(researchStep)
  .addStep(writeStep)
  .addStep(editStep)
  .connect('research', 'write')
  .connect('write', 'edit');

� 統合とデプロイ

� デプロイメント戦略

環境推奨プロバイダー特徴コスト
開発Vercelゼロコンフィグ無料枠あり
ステージングRailway簡単デプロイ従量課金
本番AWS Lambdaスケーラブル従量課金
エンタープライズオンプレミス完全管理固定費

Next.js API Routeでの使用

// app/api/chat/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { mastra } from '@/lib/mastra';

export async function POST(request: NextRequest) {
  const { messages } = await request.json();
  
  const agent = mastra.getAgent('assistant');
  const response = await agent.run({ messages });
  
  return NextResponse.json({ 
    message: response.content,
    usage: response.usage,
  });
}

エラーハンドリング

import { MastraError, RateLimitError, AuthenticationError } from '@mastra/core';

async function safeAgentRun() {
  try {
    const response = await agent.run({ messages });
    return response;
  } catch (error) {
    if (error instanceof RateLimitError) {
      console.error('レート制限に達しました:', error.message);
      // リトライロジック
    } else if (error instanceof AuthenticationError) {
      console.error('認証エラー:', error.message);
      // 認証の更新
    } else if (error instanceof MastraError) {
      console.error('Mastraエラー:', error.message);
    } else {
      console.error('予期しないエラー:', error);
    }
  }
}

� ベストプラクティス

� 効果的なプロンプトの構成

graph TD
    A[プロンプト] --> B[役割定義]
    A --> C[タスク説明]
    A --> D[制約条件]
    A --> E[出力形式]
    
    B --> F[明確な役割]
    C --> G[具体的な指示]
    D --> H[境界条件]
    E --> I[構造化出力]
    
    style A fill:#003566
    style F fill:#52b788
    style G fill:#52b788
    style H fill:#52b788
    style I fill:#52b788

プロンプトエンジニアリング

const optimizedAgent = new Agent({
  id: 'optimized',
  name: '最適化エージェント',
  instructions: `
    # 役割
    あなたはTypeScriptの専門家です。
    
    # タスク
    - コードレビューを提供する
    - ベストプラクティスを提案する
    - パフォーマンスの改善点を指摘する
    
    # 制約
    - TypeScript 5.0以降の機能を使用
    - 型安全性を最優先
    - 読みやすさを重視
    
    # 出力形式
    1. 問題点の指摘
    2. 改善案の提示
    3. コード例
  `,
  model: 'gpt-4',
  temperature: 0.3, // より一貫性のある出力
});

� コスト最適化

LLMコスト比較(2025年6月現在)

モデル入力コスト出力コスト適した用途
GPT-3.5 Turbo$0.0005/1K$0.0015/1K簡単なタスク
GPT-4$0.03/1K$0.06/1K複雑な推論
Claude 3 Haiku$0.00025/1K$0.00125/1K高速処理
Claude 3 Sonnet$0.003/1K$0.015/1Kバランス型
Claude 3 Opus$0.015/1K$0.075/1K最高品質

� コスト削減戦略

pie title "AIアプリケーションのコスト内訳"
    "LLM API" : 45
    "ベクターDB" : 20
    "サーバー" : 15
    "ストレージ" : 10
    "その他" : 10
// キャッシュの実装
const cachedAgent = new Agent({
  id: 'cached',
  cache: {
    enabled: true,
    ttl: 3600, // 1時間
    storage: 'redis',
  },
});

// モデルの使い分け
const costOptimizedWorkflow = new Workflow({
  id: 'cost-optimized',
  steps: [
    {
      id: 'simple-task',
      agent: { model: 'gpt-3.5-turbo' }, // 安価なモデル
    },
    {
      id: 'complex-task',
      agent: { model: 'gpt-4' }, // 高性能モデル
    },
  ],
});

� まとめ

Mastraは、AIエージェントとワークフローを構築するための強力で柔軟なフレームワークです。

� Mastraの導入効果

graph LR
    A[導入前] --> B[複雑な統合コード]
    A --> C[エラーの多発]
    A --> D[開発に数ヶ月]
    
    E[導入後] --> F[統一API]
    E --> G[型安全]
    E --> H[開発が数週間に短縮]
    
    style A fill:#ff6b6b
    style E fill:#52b788

� 成功事例

企業用途成果
スタートアップAカスタマーサポート応答時間 70%削減
大手小売B商品推薦コンバージョン35%向上
メディアCコンテンツ生成作業効率5倍
金融Dリスク分析精度 90%以上

� 今すぐ始める

主な利点:

  • 開発効率: TypeScriptの型安全性とモジュラー設計
  • 🤖 柔軟性: 複数のLLMプロバイダーとツールの統合
  • スケーラビリティ: マルチエージェントとワークフローのサポート
  • RAG対応: ベクターストアとの簡単な統合
  • 本番対応: エラーハンドリングとキャッシング機能

Mastraを使用することで、複雑なAIアプリケーションを短時間で構築し、メンテナンスしやすいコードベースを維持できます。

// 今すぐ始める!
import { Mastra } from '@mastra/core';

const myFirstAIApp = new Mastra({
  // あなたのAIアプリケーションがここから始まる
});