Zenn
📝

TypeScript AI AgentフレームワークのMastraについて調べた

2025/03/22に公開

自身の理解のために、mastraのコードリーディングをほぼClaudeが行い、ほぼClaudeが 言語化したのでこちらに残しておく。

アーキテクチャ概要

mastraのアーキテクチャは、複数の相互に連携するコアコンポーネントで構成されています。中心となるのはMastraクラスで、他のすべてのコンポーネントの初期化と管理を担当します。

公式ドキュメントによると、mastraは次のような主要機能を提供しています:

  1. LLMモデルルーティング: Vercel AI SDKを活用して、OpenAI、Anthropic、Google Geminiなど様々なLLMプロバイダーへの統一インターフェースを提供
  2. エージェント: 言語モデルが自律的にアクションのシーケンスを決定し実行するシステム
  3. ツール: エージェントやワークフローで実行できる型付き関数
  4. ワークフロー: 持続性のあるグラフベースのステートマシン
  5. RAG (Retrieval-Augmented Generation): 知識ベース構築のためのETLパイプライン
  6. 統合機能: サードパーティサービスのための自動生成された型安全APIクライアント
  7. 評価 (Evals): LLM出力を評価するための自動テスト

主要コンポーネント

Mastra(中核エンジン)

Mastraクラスは、フレームワーク全体のエントリポイントとして機能し、すべてのコンポーネントを初期化して管理します。

export class Mastra<
  TAgents extends Record<string, Agent<any>> = Record<string, Agent<any>>,
  TWorkflows extends Record<string, Workflow> = Record<string, Workflow>,
  TVectors extends Record<string, MastraVector> = Record<string, MastraVector>,
  TTTS extends Record<string, MastraTTS> = Record<string, MastraTTS>,
  TLogger extends Logger = Logger,
  TNetworks extends Record<string, AgentNetwork> = Record<string, AgentNetwork>,
> {
  // ...
}

主な責務:

  • 各種コンポーネント(エージェント、ワークフロー、ベクターストア等)の初期化と管理
  • ロギング、テレメトリー、ストレージなどの共通サービスの提供
  • コンポーネント間の相互作用の促進

Agent(エージェント)

Agentクラスは、LLM(大規模言語モデル)とのインターフェースを提供し、テキスト生成と複雑なタスクの実行を担当します。公式ドキュメントによると、エージェントはmastraにおいて「言語モデルが自律的にアクションのシーケンスを決定するシステム」として定義されています。

export class Agent<
  TTools extends ToolsInput = ToolsInput,
  TMetrics extends Record<string, Metric> = Record<string, Metric>,
> extends MastraBase {
  // ...
}

主な機能:

  • LLMを使用したテキスト生成
  • ツールの実行と管理
  • 会話履歴の保持とコンテキスト管理
  • ストリーミングレスポンスのサポート
  • 構造化出力の生成

エージェントは、会話型AI機能を構築するための中核コンポーネントで、LLMモデル、命令セット、ツールセットを統合します。公式ドキュメントでは、エージェントは「名前、永続的なメモリ、一貫したモデル設定、命令、そして有効化されたツールのセットを持つ従業員のようなもの」と表現されています。

Workflow(ワークフロー)

Workflowクラスは、耐久性のあるグラフベースのステートマシンを提供し、複雑なタスクフローを定義して実行します。公式ドキュメントによると、ワークフローはループ、分岐、人間の入力待ち、エラーハンドリング、リトライなどの機能を備えた持続性のあるグラフベースのステートマシンです。

export class Workflow<
  TSteps extends Step<string, any, any>[] = Step<string, any, any>[],
  TTriggerSchema extends z.ZodObject<any> = any,
> extends MastraBase {
  // ...
}

主な機能:

  • ステップの定義と接続(stepthenafterメソッド)
  • 条件分岐(ifelse
  • ループ処理(whileuntil
  • イベント待機(afterEvent
  • 一時停止と再開(suspendresume
  • 状態の永続化
  • 並列実行
  • リソースのサスペンド

公式ドキュメントによると、ワークフローは「分岐、並列実行、リソースサスペンションなどの機能を持つ複雑な操作シーケンスをオーケストレーションするのに役立つ」とされています。具体的には、単一のLLM呼び出しよりも複雑なAIアプリケーションの構築に適しており、複数のステップの実行、条件付きでの特定パスのスキップ、ユーザー入力の待機などの機能を提供します。

RAG機能(Retrieval-Augmented Generation)

mastraのRAG機能は、LLM出力を強化するために独自のデータソースからの関連コンテキストを組み込むためのシステムです。公式ドキュメントによると、RAGはドキュメント処理、チャンキング、埋め込み、ベクトル検索を含むETL(抽出・変換・ロード)パイプラインとして実装されています。

MDocumentクラスはRAGのドキュメント処理部分を担当します:

export class MDocument {
  private chunks: Chunk[];
  private type: string; // e.g., 'text', 'html', 'markdown', 'json'
  
  // ...
}

公式ドキュメントから、mastraのRAGシステムは以下の機能を提供していることがわかります:

  • 標準化されたAPI: ドキュメントの処理と埋め込み
  • 複数のベクトルストアのサポート: 異なるベクトルデータベースとの統合
  • 最適な検索のためのチャンキングと埋め込み戦略: 様々な文書形式(テキスト、HTML、Markdown、JSON)のサポート
  • 様々なチャンキング戦略: 文字ベース、トークンベース、再帰的、マークダウン、HTMLなど
  • メタデータ抽出: タイトル、要約、キーワード等
  • 再ランキング機能: セマンティック、ベクター、ポジションスコアの組み合わせによる関連性向上
  • クエリ分析と最適化: 検索効率の向上

RAGシステムは、LLM出力の精度を向上させ、実際の情報に基づいた回答を生成するための重要なコンポーネントです。

Agent Memory(エージェントメモリ)

公式ドキュメントによると、mastraのエージェントは会話履歴とコンテキスト情報を保存する高度なメモリシステムを持っています。この機能はMastraMemoryクラスによって実装されています:

export abstract class MastraMemory extends MastraBase {
  MAX_CONTEXT_TOKENS?: number;
  storage: MastraStorage;
  vector: MastraVector;
  embedder: EmbeddingModel<string>;
  
  // ...
}

エージェントメモリは、従来のメッセージストレージとベクトルベースのセマンティック検索の両方をサポートしており、エージェントがやり取りを通じて状態を維持し、関連する過去のコンテキストを取得することを可能にします。

公式ドキュメントから追加された重要な特徴:

  • スレッドとリソース: 会話はthread_idによって整理され、同じディスカッションに属する過去のメッセージの文脈維持と取得を可能にします
  • リソースID: 会話はより広い関係性の中で整理され、特定のユーザーやプロジェクトに関連するすべての会話の検索が可能になります
  • セマンティック検索: 過去の会話から意味的に関連するコンテキストの取得
  • メモリ設定: 最大メッセージ数、セマンティック検索の有効化などの設定

主な機能:

  • スレッド管理(作成、保存、取得)
  • メッセージの保存と取得
  • ベクトル検索による関連メッセージの検索
  • UIメッセージ形式への変換
  • システムメッセージの生成と注入

エージェントメモリは、エージェントに「記憶」を提供し、長期間にわたる会話コンテキストを維持するための重要なコンポーネントです。

MastraStorage(ストレージ)

ストレージシステムは、データの永続化を担当します。MastraStorageはインターフェースを定義し、様々な実装(SQLite、リモートAPI等)をサポートしています。

主な機能:

  • スレッドとメッセージの永続化
  • ワークフローの状態の保存と読み込み
  • サーバーレス環境での使用をサポート

MastraVector(ベクトルストア)

ベクトルストアは、埋め込みベクトルの保存と検索を担当します。公式ドキュメントによると、mastraはRAGシステムの一部として複数のベクトルストアをサポートしています。

主な機能:

  • 埋め込みベクトルのインデックス作成と保存
  • 類似性検索
  • フィルタリング機能
  • 複数の次元サイズのサポート
  • ベクトルデータベースとの統合(libSQL/SQLite実装を含む)

ベクトルストアはRAGシステムの中核であり、ドキュメントチャンクの埋め込みを格納し、ユーザークエリに対して意味的に関連するコンテンツの効率的な検索を可能にします。

動作フロー

mastraフレームワークの典型的な動作フローは以下の通りです:

  1. 初期化: Mastraインスタンスが作成され、エージェント、ワークフロー、ベクトルストアなどが設定される
  2. ユーザー入力: ユーザーからの入力(テキスト、音声等)がシステムに送信される
  3. コンテキスト取得: メモリシステムから関連する過去の会話が取得される
  4. RAG処理(必要に応じて):
    • ユーザークエリに基づくベクター検索
    • 関連ドキュメントのチャンクの取得
    • 再ランキングによる最も関連性の高い情報の選択
  5. エージェント処理:
    • LLMへの命令、コンテキスト、ツール情報の送信
    • ツールの実行(必要に応じて)
    • 最終応答の生成
  6. 状態保存: 会話の状態がメモリに保存される
  7. ワークフロー更新(ワークフローを使用している場合): 現在のステップが実行され、次のステップが決定される

ディレクトリ構造

mastraリポジトリは、モジュール化された構造で整理されています:

mastra/
├── packages/         # 主要なnpmパッケージ
│   ├── _config/      # 設定関連
│   ├── cli/          # コマンドラインインターフェース
│   ├── core/         # コア機能
│   │   ├── src/
│   │   │   ├── action/       # アクション関連
│   │   │   ├── agent/        # エージェント機能
│   │   │   ├── deployer/     # デプロイ機能
│   │   │   ├── eval/         # 評価機能
│   │   │   ├── integration/  # 外部サービス統合
│   │   │   ├── llm/          # 言語モデル
│   │   │   ├── logger/       # ロギング
│   │   │   ├── mastra/       # コアのmastra関連機能
│   │   │   ├── memory/       # メモリ管理
│   │   │   ├── network/      # ネットワーク
│   │   │   ├── relevance/    # 関連性評価
│   │   │   ├── storage/      # ストレージ
│   │   │   ├── telemetry/    # テレメトリーとトレーシング
│   │   │   ├── tools/        # ツール関連
│   │   │   ├── vector/       # ベクトル関連(RAG用)
│   │   │   ├── workflows/    # ワークフロー機能
│   │   │   └── ...
│   ├── create-mastra/  # プロジェクト作成ツール
│   ├── deployer/       # デプロイツール
│   ├── evals/          # 評価機能
│   ├── loggers/        # ロギング機能
│   ├── memory/         # メモリシステム
│   ├── playground-ui/  # プレイグラウンドUI
│   ├── rag/            # RAG機能
│   └── ...
├── client-sdks/     # クライアントSDK
├── deployers/       # デプロイツール
├── docs/            # ドキュメント
├── e2e-tests/       # エンドツーエンドテスト
├── examples/        # 使用例
├── integrations/    # 外部サービスとの統合
├── speech/          # 音声関連機能
├── stores/          # データストア
└── voice/           # 音声関連機能

拡張性と統合

mastraは高い拡張性を持ち、様々なサービスやツールと統合できるように設計されています:

  1. LLMプロバイダー: OpenAI、Anthropic、Google Gemini、Llamaなど複数のLLMをサポート
  2. ツールとAPIの統合: 外部APIを簡単に統合できるツールシステム
  3. ストレージオプション: カスタムストレージバックエンドのサポート
  4. 音声とTTS: 音声インターフェースの統合
  5. カスタムRAGパイプライン: 独自のドキュメント処理、チャンキング、ランキング戦略の実装

ユースケース

公式ドキュメントと実装を分析すると、mastraフレームワークは以下のようなユースケースに特に適していることがわかります:

  1. 会話型AIアシスタント:

    • カスタムツールとナレッジベースを持つアシスタント
    • 永続的なメモリを活用したコンテキスト維持機能
    • 複数のLLMモデルを切り替え可能な柔軟なアーキテクチャ
  2. ドキュメントQAシステム:

    • RAGパイプラインを活用した大量のドキュメントに対する質問応答
    • 高度なチャンキングと埋め込み戦略による検索精度の向上
    • 再ランキング機能による関連性の高い回答の提供
  3. 複雑な自動化ワークフロー:

    • 条件分岐、ループ、一時停止・再開機能を持つワークフロー
    • 人間のフィードバックを含むハイブリッドプロセス
    • 持続性のあるステートマシンによる長時間実行プロセスの管理
  4. AI強化アプリケーション:

    • 既存のTypeScriptアプリケーションへのAI機能の統合
    • サードパーティAPIとの自動生成された型安全な統合
    • 包括的なテレメトリーとモニタリング
  5. マルチステップAIエージェント:

    • 複数のステップと意思決定を要する複雑なタスクの自動化
    • エージェント間の連携と情報共有
    • ツール実行とLLM呼び出しの組み合わせによる高度な処理
  6. 評価と品質管理:

    • LLM出力の品質を自動的に評価するシステム
    • モデルグレード、ルールベース、統計的手法による正規化されたスコアリング
    • 複数のアプローチの比較と継続的な改善

設計パターン

コードベースを分析すると、mastraはいくつかの優れた設計パターンを採用していることがわかります:

  1. 依存性注入: Mastraクラスが中心となり、各コンポーネント(エージェント、ワークフロー、ストレージなど)に依存関係を注入することで疎結合を実現しています。例えば、次のように__registerPrimitivesメソッドでロガーやテレメトリなどを注入しています:

    agent.__registerPrimitives({
      logger: this.getLogger(),
      telemetry: this.#telemetry,
      storage: this.storage,
      memory: this.memory,
      agents: agents,
      // ...
    });
    
  2. 抽象化と継承: MastraBaseを基底クラスとし、AgentWorkflowなどが継承する形で拡張可能なコンポーネント階層を構築しています。

  3. ファクトリーパターン: ツールやステップなどのコンポーネントを動的に生成するためのファクトリーメソッドを提供しています。例えばmakeCoreToolメソッドなど。

  4. オブザーバーパターン: ワークフローやエージェントの状態変化を監視するwatchメソッドなど、イベント駆動の処理を実現しています。

  5. プロキシパターン: テレメトリーの実装で見られるように、実際のオブジェクトへの呼び出しを透過的に追跡する機能を提供しています:

    this.#telemetry.traceClass(storage, {
      excludeMethods: ['__setTelemetry', '__getTelemetry'],
    });
    
  6. デコレーターパターン: @InstrumentClassデコレーターを使用して、クラスにテレメトリー機能を追加しています。

  7. サービスロケーターパターン: Mastraクラスが様々なサービスの検索と取得を一元化し、getAgentgetVectorなどのメソッドを提供しています。

課題と今後の展望

公式ドキュメントと実装を分析すると、mastraの現在の課題と今後の展望として以下の点が考えられます:

  1. 開発の初期段階: リポジトリが2024年8月に作成されたことから、比較的新しいプロジェクトであり、一部の機能やドキュメントが発展途上である可能性があります。

  2. 大規模データセットの処理: 現在のRAG実装は基本的なチャンキングと埋め込みをサポートしていますが、非常に大規模なデータセットを効率的に処理するための最適化が今後の課題となるでしょう。

  3. マルチモーダル対応の拡張: 現在のフレームワークはテキストとある程度の音声をサポートしていますが、画像、動画などのマルチモーダルコンテンツへの対応拡張が期待されます。

  4. 分散システムのサポート: 現在はローカル実装が中心ですが、分散環境でのエージェントとワークフローの実行に関するさらなるサポートが有用でしょう。

  5. コミュニティの成長: オープンソースプロジェクトとして、コミュニティの成長とコントリビューションの増加が期待されます。

ここまでのまとめ

mastra-aiは、TypeScriptで書かれた包括的なAIエージェントフレームワークであり、エージェント、RAG、ワークフロー、統合機能など、AIアプリケーション開発に必要な主要コンポーネントを提供しています。Y Combinatorからの支援を受けており、Gatsbyの開発者たちによって創設されたプロジェクトとしての信頼性も備えています。

このフレームワークの最大の強みは、複雑なAIアプリケーションの開発を簡素化する豊富な機能セットとTypeScriptの型安全性を組み合わせている点です。特に、OpenAI、Anthropic、Google Geminiなど複数のLLMプロバイダーに対応する柔軟なアーキテクチャは、特定のベンダーにロックインされることなくAIアプリケーションを構築したい開発者にとって魅力的です。

モジュール化された設計により、必要なコンポーネントだけを使用したり、独自のカスタム実装に置き換えたりすることが可能です。オープンソースであるため、コミュニティによる貢献も期待でき、継続的な進化と改善が見込まれます。

mastraは、AIアプリケーション開発の生産性を大幅に向上させる強力なツールであり、LLMを活用したアプリケーションをTypeScriptで構築したい開発者にとって有力な選択肢となるでしょう。


実用例と処理フロー

複数のコンポーネントがどのように連携して動作するのか、mastraの実際の使用例とその処理フローを見てみましょう。以下で、リポジトリのexamplesディレクトリから特徴的な例を取り上げます。

Agent Network - 研究エージェントの連携

agent-networkの例では、複数のエージェントが連携して複雑な研究タスクを実行します。この例では、専門知識を持つ異なるエージェント同士が協力して作業を行うネットワークが実装されています。

// examples/agent-network/src/index.ts
import { mastra } from './mastra';

async function main() {
  const researchNetwork = mastra.getNetwork('Research_Network');

  if (!researchNetwork) {
    throw new Error('Research network not found');
  }

  console.log('🔍 Starting research on Napoleon Bonaparte...\n');

  // エージェントネットワークを使って研究レポートを生成
  const result = await researchNetwork.stream('Give me a report on Napoleon Bonaparte', {
    maxSteps: 20, // LLMルーターが最適なエージェントを決定するための十分なステップ数
  });

  // ストリーミングレスポンスの処理
  for await (const part of result.fullStream) {
    switch (part.type) {
      case 'error':
        console.error(part.error);
        break;
      case 'text-delta':
        process.stdout.write(part.textDelta);
        break;
      case 'tool-call':
        console.log(`calling tool ${part.toolName} with args ${JSON.stringify(part.args, null, 2)}`);
        break;
      case 'tool-result':
        console.log(`tool result ${JSON.stringify(part.result, null, 2)}`);
        break;
    }
  }

  // エージェント間のやり取りの要約を表示
  console.log('\n\n📊 Agent Interaction Summary:');
  console.log(researchNetwork.getAgentInteractionSummary());
}

処理フロー

  1. 初期化: Mastraインスタンスが作成され、複数の専門エージェントを含むネットワークが設定されます。
// examples/agent-network/src/mastra/index.ts
export const mastra = new Mastra({
  agents: {
    webSearchAgent,
  },
  networks: {
    researchNetwork,
  },
  logger: createLogger({ name: 'Chef', level: 'info' }),
});
  1. エージェントネットワークの定義: 異なる専門知識を持つエージェント群と、それらを調整するための指示が設定されます。
// examples/agent-network/src/mastra/network/index.ts
export const researchNetwork = new AgentNetwork({
  name: 'Research Network',
  agents: [primaryResearchAgent, webSearchAgent, academicResearchAgent, factCheckingAgent, dataAnalysisAgent],
  model: openai('gpt-4o'),
  instructions: `
      あなたは研究調整システムで、クエリを適切な専門エージェントに振り分けます。
      
      利用可能なエージェント:
      1. Primary Research Agent: 研究作業の調整、複雑な質問の分解、情報の統合
      2. Web Search Agent: 最新の情報をオンラインで検索し、適切に引用
      3. Academic Research Agent: 学術的視点、理論、学術的文脈の提供
      4. Fact Checking Agent: 主張の検証と潜在的な誤情報の特定
      5. Data Analysis Agent: 数値データ、統計の解釈、パターンの特定
      
      各ユーザークエリに対して:
      1. Primary Research Agentから始めて、クエリを分析・分解
      2. 専門知識に基づいて適切な専門エージェントにサブクエリを振り分け
      3. 必要に応じてFact Checking Agentを使用して重要な主張を検証
      4. Primary Research Agentに戻り、すべての調査結果を包括的な回答に統合
      
      常にエージェント間の証拠の連鎖と適切な帰属を維持してください。
    `,
});
  1. 各エージェントの定義: それぞれの専門エージェントに特化した指示と能力が定義されています。
// examples/agent-network/src/mastra/agents/index.ts
export const webSearchAgent = new Agent({
  name: 'Web Search Agent',
  instructions: `
    あなたはWeb検索の専門家です。あなたの仕事:
    1. 与えられたクエリに対して最も関連性が高く最新の情報をオンラインで見つける
    2. ソースの信頼性を評価し、信頼できる情報を優先する
    3. Webコンテンツから重要な事実とデータポイントを抽出する
    4. 適切な場合は直接引用と引用を提供する
    5. 明確で簡潔な方法で検索結果をまとめる
    
    情報を報告する際は、必ずソースURLを含めてください。
  `,
  model: openai.responses('gpt-4o-mini'),
  tools: {
    web_search_preview: openai.tools.webSearchPreview(),
  },
});
  1. 実行: ユーザークエリがエージェントネットワークに送られ、ネットワークは内部で適切なエージェントにタスクを分配します。
  2. 調整と統合: プライマリリサーチエージェントが全体のプロセスを調整し、他のエージェントから得られた結果を統合して最終的な回答を生成します。
  3. 結果のストリーミング: 生成されたレスポンスはストリーミング形式で返され、ユーザーはリアルタイムで進捗を確認できます。

Workflow - AIリクルーターの例

workflow-ai-recruiterの例では、ワークフローを使用して求人プロセスの自動化を実装しています。この例は、条件分岐を持つ複数ステップのワークフローを示しています。

// examples/workflow-ai-recruiter/src/mastra/index.ts
import { openai } from '@ai-sdk/openai';
import { Mastra } from '@mastra/core';
import { Agent } from '@mastra/core/agent';
import { Step, Workflow } from '@mastra/core/workflows';
import { z } from 'zod';

// リクルーターエージェントの定義
const recruiter = new Agent({
  name: 'Recruiter Agent',
  instructions: `You are a recruiter.`,
  model: openai('gpt-4o-mini'),
});

// 候補者情報収集ステップ
const gatherCandidateInfo = new Step({
  id: 'gatherCandidateInfo',
  inputSchema: z.object({
    resumeText: z.string(),
  }),
  outputSchema: z.object({
    candidateName: z.string(),
    isTechnical: z.boolean(),
    specialty: z.string(),
    resumeText: z.string(),
  }),
  execute: async ({ context, mastra }) => {
    const resumeText = context?.getStepResult<{ resumeText: string }>('trigger')?.resumeText;

    const prompt = `
          You are given this resume text:
          "${resumeText}"
        `;
    const res = await recruiter.generate(prompt, {
      output: z.object({
        candidateName: z.string(),
        isTechnical: z.boolean(),
        specialty: z.string(),
        resumeText: z.string(),
      }),
    });

    return res.object;
  },
});

// 専門分野について質問するステップ
const askAboutSpecialty = new Step({
  id: 'askAboutSpecialty',
  outputSchema: z.object({
    question: z.string(),
  }),
  execute: async ({ context, mastra }) => {
    const candidateInfo = context?.getStepResult<CandidateInfo>('gatherCandidateInfo');

    const prompt = `
          You are a recruiter. Given the resume below, craft a short question
          for ${candidateInfo?.candidateName} about how they got into "${candidateInfo?.specialty}".
          Resume: ${candidateInfo?.resumeText}
        `;
    const res = await recruiter.generate(prompt);
    return { question: res?.text?.trim() || '' };
  },
});

// ロールについて質問するステップ
const askAboutRole = new Step({
  id: 'askAboutRole',
  outputSchema: z.object({
    question: z.string(),
  }),
  execute: async ({ context, mastra }) => {
    const candidateInfo = context?.getStepResult<CandidateInfo>('gatherCandidateInfo');

    const prompt = `
          You are a recruiter. Given the resume below, craft a short question
          for ${candidateInfo?.candidateName} asking what interests them most about this role.
          Resume: ${candidateInfo?.resumeText}
        `;
    const res = await recruiter.generate(prompt);
    return { question: res?.text?.trim() || '' };
  },
});

// ワークフローの定義と実行
const candidateWorkflow = new Workflow({
  name: 'candidate-workflow',
  triggerSchema: z.object({
    resumeText: z.string(),
  }),
});

// ワークフローのステップ定義と条件分岐
candidateWorkflow
  .step(gatherCandidateInfo)
  .then(askAboutSpecialty, {
    when: { 'gatherCandidateInfo.isTechnical': true },  // 技術職の場合のみ実行
  })
  .after(gatherCandidateInfo)
  .step(askAboutRole, {
    when: { 'gatherCandidateInfo.isTechnical': false },  // 非技術職の場合のみ実行
  });

candidateWorkflow.commit();

// Mastraインスタンスの作成とワークフローの実行
const mastra = new Mastra({
  workflows: {
    candidateWorkflow,
  },
});

(async () => {
  const { runId, start } = mastra.getWorkflow('candidateWorkflow').createRun();
  const runResult = await start({
    triggerData: { resumeText: 'Simulated resume content...' },
  });
  console.log('Final output:', runResult.results);
})();

処理フロー

  1. ワークフローとステップの定義: 履歴書のテキストから候補者情報を抽出し、条件に基づいて異なる質問を生成するワークフローが定義されます。
  2. 条件分岐の設定: 候補者が技術職か非技術職かに基づいて異なるステップを実行する分岐が設定されています。
  3. ワークフローの実行: トリガーデータ(履歴書)を指定してワークフローが開始され、各ステップが順番に実行されます。
  4. コンテキストの共有: 各ステップは前のステップの結果にアクセスでき、それに基づいて処理を行います。
  5. 結果の取得: 最終的な結果がrunResultオブジェクトとして返されます。

Travel App - 複数コンポーネントの連携

travel-appの例は、エージェント、ツール、ワークフロー、統合機能を組み合わせた複合的なアプリケーションです。この例では、旅行プランニングのための様々な機能が実装されています。

Mastraインスタンスの初期化

// examples/travel-app/src/mastra/index.ts
import { Mastra } from "@mastra/core";
import { createLogger } from "@mastra/core/logger";

import { travelAgent, travelAnalyzer } from "./agents";
import { syncCsvDataWorkflow } from "./workflows/attractions";
import { storage } from "./agents/storage";

export const mastra = new Mastra({
  workflows: { syncCsvDataWorkflow },
  storage,
  agents: { travelAgent, travelAnalyzer },
  logger: createLogger({
    name: "CONSOLE",
    level: "info",
  }),
});

エージェントの定義

// examples/travel-app/src/mastra/agents/index.ts
export const travelAgent = new Agent({
  name: "travelAgent",
  instructions: `You are an expert travel agent responsible for finding a flight, hotel, and three attractions for a user. You will be given a set of user preferences along with some tools and you will need to find the best options for them. Be as concise as possible with your response.`,
  model: anthropic("claude-3-5-sonnet-20240620"),
  memory,
  tools: {
    searchFlights,
    searchHotels,
    searchAttractions,
    searchAirbnbLocation,
    searchAirbnb,
  },
});

ツールの実装

// examples/travel-app/src/mastra/tools/index.ts
export const searchFlights = createTool({
  id: "Get Flight Info",
  inputSchema: z.object({
    startDate: z.string(),
    endDate: z.string(),
    origin: z.string(),
    destination: z.string(),
  }),
  description: `Fetches flight information for a given date range, origin and destination. Origin and Destination are Airport codes like DFW.AIRPORT or SEA.AIRPORT`,
  execute: async ({ context: { startDate, endDate, origin, destination } }) => {
    console.log(
      "Using tool to fetch flight information: ",
      startDate,
      endDate,
      origin,
      destination,
    );
    const flights = await booking.getFlights({
      startDate,
      endDate,
      origin,
      destination,
    });
    return {
      flights: flights as Flight[],
    };
  },
});

ワークフローの実装

// examples/travel-app/src/mastra/workflows/attractions.ts
export const syncCsvDataWorkflow = new Workflow({
  name: "Sync CSV Data",
});

const syncCsvDataStep = new Step({
  id: "sync-csv-data-step",
  description: "Sync data from City CSV",
  execute: async () => {
    const csvFilePath =
      process.env.CSV_FILE_PATH ||
      path.join(process.cwd(), "src/data/city-data.csv");
    console.log("Resolved CSV file path:", csvFilePath);
    const records: { data: CityData; externalId: string }[] = [];

    await new Promise((resolve, reject) => {
      fs.createReadStream(csvFilePath)
        .pipe(csvParser())
        .on("data", (row: CityData) => {
          records.push({
            data: row,
            externalId: row.cityId,
          });
        })
        .on("end", resolve)
        .on("error", reject);
    });

    return {
      records,
    };
  },
});

syncCsvDataWorkflow.step(syncCsvDataStep);

処理フロー

  1. 初期化: Mastraインスタンスが作成され、エージェント、ワークフロー、ストレージが設定されます。
  2. データ同期: syncCsvDataWorkflowワークフローがCSVファイルから都市データを読み込み、システムに同期します。
  3. エージェントの準備: 旅行エージェントが様々な検索ツール(フライト、ホテル、アトラクション、Airbnb)でセットアップされます。
  4. ユーザーリクエスト処理: ユーザーからの旅行プランのリクエストを受け取ると、エージェントは適切なツールを使用して情報を検索します。
  5. 統合API呼び出し: 各ツールは、Bookingクラスを通じて外部APIを呼び出し、必要な情報を取得します。
  6. 結果の統合: エージェントは取得した情報を統合し、ユーザーに最適な旅行プランを提案します。

このアプリケーションは、mastraの複数のコンポーネント(エージェント、ツール、ワークフロー、メモリ、統合機能)を組み合わせた実際的な例です。外部APIとの統合、データ処理、エージェントによる意思決定を組み合わせて、エンドユーザー向けの役立つアプリケーションを作成しています。# mastra-aiのアーキテクチャ分析:TypeScriptによるAIエージェントフレームワーク

mastra-aiは、TypeScriptで書かれたオープンソースのAIエージェントフレームワークです。このフレームワークは、LLMを活用したアプリケーションを迅速に構築するための基本要素(エージェント、RAG、ワークフロー、統合機能など)を提供し、複雑なAIアプリケーションとAI機能を容易に構築できるようにします。

Discussion

ログインするとコメントできます