Zenn
👀

MastraをPokeAPIを使って試してみた

2025/03/22に公開
1

概要

最近、TypeScriptエージェントフレームワークの「Mastra」を目にすることが増えてきたため、少しだけ試してみました。

1. Mastraとは?

MastraはAIアプリケーションや機能を構築するためのフレームワークで、エージェント開発、メモリ管理、関数呼び出し、RAG(Retrieval-Augmented Generation)、ワークフロー管理など多くの機能を提供しています。また、Vercel AI SDKを利用してOpenAIやAnthropic、Google GeminiなどのさまざまなLLMプロバイダーと連携できます。
https://mastra.ai/

2. PokeAPIとは?

PokeAPIはポケットモンスターシリーズに登場するポケモンの情報を提供するオープンなREST APIです。
PokeAPIは無料で利用でき、認証不要のため、今回検証のために利用しました。
https://pokeapi.co/

3. 初期サンプルの構築

下記チュートリアルを参考に進め、サンプルの天気情報検索エージェントを構築します。
https://mastra.ai/docs/getting-started/installation

3.1 新しいプロジェクトの作成

npm create mastra@latest

3.2 質問に答える

モデルはGoogleのGeminiを選択しました。

生成されるディレクトリ

project
    ├── node_modules
    ├── src
    │   └── mastra
    │       ├── agents
    │       │   ├── index.ts
    │       ├── tools
    │       │   └── index.ts
    │       └── index.ts
    │
    ├── .env.development
    ├── package.json
    └── tsconfig.json

3.3 APIキーの設定

.env.developmentにGeminiのAPIキーをセットします。

.env.development
GOOGLE_GENERATIVE_AI_API_KEY=your-api-key

3.4 サンプルの天気情報検索エージェントがローカルで使えることを確認

下記にアクセスし、「Weather Agent」が利用できることを確認します。
http://localhost:4111/

4. ポケモンの情報を取得するAIエージェントを追加する

先ほど作成したサンプルに手を加えて、PokeAPI使ったポケモンの情報を取得するAIエージェントを追加していきます。

4.1 index.tsファイルの変更

src/mastra/index.ts

import { Mastra } from '@mastra/core/mastra';
import { createLogger } from '@mastra/core/logger';

- import { weatherAgent } from './agents';
+ import { weatherAgent, pokemonAgent } from './agents';

export const mastra = new Mastra({
-  agents: { weatherAgent },
+  agents: { 
+    weatherAgent,
+    pokemonAgent
+   },
  logger: createLogger({
    name: 'Mastra',
    level: 'info',
  }),
});

4.2 agentsのファイルの変更

src/mastra/agents/index.ts
import { google } from '@ai-sdk/google';
import { Agent } from '@mastra/core/agent';
- import { weatherTool } from '../tools';
+ import { weatherTool } from '../tools/weather';
+ import { pokemonTool } from '../tools/pokemon';

export const weatherAgent = new Agent({
  name: 'Weather Agent',
  instructions: `
      You are a helpful weather assistant that provides accurate weather information.

      Your primary function is to help users get weather details for specific locations. When responding:
      - Always ask for a location if none is provided
      - If the location name isn’t in English, please translate it
      - If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
      - Include relevant details like humidity, wind conditions, and precipitation
      - Keep responses concise but informative

      Use the weatherTool to fetch current weather data.
`,
  model: google('gemini-1.5-pro-latest'),
  tools: { weatherTool },
});

+ export const pokemonAgent = new Agent({
+   name: 'Pokemon Agent',
+   instructions: `
+        あなたはポケモン博士です。応答するときは、
+        - ポケモンの名前が指定されない場合は、名前を要求してください。
+        - ポケモンの名前が指定された場合は、そのポケモンのタイプ、重さ、高さ、および特性を提供してください。
+        - 日本語で応答することができますが、ポケモンの名前は英語に翻訳してpokemonToolを使用してください。
+        - 応答は日本語でわかりやすくしてください。
+  `,
+    model: google('gemini-1.5-pro-latest'),
+    tools: { pokemonTool },
+  });

4.3 toolsのファイルの変更

  • 既存のsrc/mastra/tools/index.tssrc/mastra/tools/weather.tsに変更します。
  • 新しくsrc/mastra/tools/pokemon.tsを追加します。
src/mastra/tools/pokemon.ts
import { createTool } from '@mastra/core/tools';
import { z } from 'zod';

interface PokemonResponse {
  name: string;
  types: { type: { name: string } }[];
  weight: number;
  height: number;
  abilities: { ability: { name: string } }[];
}

export const pokemonTool = createTool({
  id: 'get-pokemon',
  description: '指定されたポケモンの名前からポケモンの情報を取得します。',
  inputSchema: z.object({
    name: z.string().describe('Pokemon name'),
  }),
    outputSchema: z.object({
        name: z.string(),
        type: z.string(),
        weight: z.number(),
        height: z.number(),
        abilities: z.string(),
    }),
  execute: async ({ context }) => {
    return await getPokemon(context.name);
  },
});

const getPokemon = async (name: string) => {
    const pokemonUrl = `https://pokeapi.co/api/v2/pokemon/${name}`;
    const response = await fetch(pokemonUrl);
    const data = (await response.json()) as PokemonResponse;
    console.log('pokemon.ts 34', data);
    
    return {
        name: data.name,
        type: data.types.map((type) => type.type.name).join(', '),
        weight: data.weight,
        height: data.height,
        abilities: data.abilities.map((ability) => ability.ability.name).join(', '),
    };
};

4.4 ポケモン情報取得AIエージェントがローカルで使えることを確認

エージェントに新しくPokemon Agentが追加されています。

質問をしてみます。

最後に

Mastraの機能のうちエージェントとツールの使い方はなんとなくわかりました。
他の機能は全然試せていないので、学習して活用できるようになりたいと思います。

1

Discussion

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