Mastraを使ってAIエージェントを作ろう! - 基礎編(2) -
はじめに
本ハンズオンでは、AIエージェントフレームワークのMastraを使って、シンプルなAIエージェントの実装を解説します。
基礎編2つ目の記事では、チャットUI付きのAIエージェントをVercelにデプロイするまで進めていきます。curlコマンドでしか動作確認ができなかった前回と比べ、非エンジニアにも利用してもらいやすいアプリが作れることを目指します💪
【前回】Mastraを使ってAIエージェントを作ろう! - 基礎編(1) -
ハンズオンのステップ
- MastraのサンプルAIエージェントをVercelにデプロイし、curlコマンドで実行する
- 【本記事で解説】サンプルAIエージェントにチャットUIを実装し、Vercelにデプロイする
- サンプルAIエージェントを改造し、複数のToolを自律的に実行するAIエージェントを実装する
事前に準備が必要なもの
- Node.js(v20.0以上)
- サポート対象のモデルプロバイダー[1]のAPIキー
- 本記事では、OpenAIのAPIキーを利用します
 
1. チャットUI付きのAIエージェントをローカルで立ち上げる
基本方針
assistant-uiを利用します。
ChatGPTのようなチャットUIを簡単に組み込むことができる、TypeScript/Reactライブラリです。
 1-1. assistant-ui createコマンドを実行する
npx assistant-ui@latest create
対話形式でプロジェクトの設定が進むため、順番に答えて行きます。
実行ログ
~ % npx assistant-ui@latest create
Need to install the following packages:
assistant-ui@0.0.62
Ok to proceed? (y) y
Need to install the following packages:
create-next-app@15.5.6
Ok to proceed? (y) y
✔ What is your project named? … mastra-with-ui-sample
Creating a new Next.js app in /Users/subroh_0508/mastra-with-ui-sample.
Downloading files from repo https://github.com/assistant-ui/assistant-ui-starter. This might take a moment.
Installing packages. This might take a couple of minutes.
added 592 packages, and audited 593 packages in 1m
259 packages are looking for funding
  run `npm fund` for details
found 0 vulnerabilities
Initialized a git repository.
Success! Created mastra-with-ui-sample at /Users/subroh_0508/mastra-with-ui-sample
Inside that directory, you can run several commands:
  npm run dev
    Starts the development server.
  npm run build
    Builds the app for production.
  npm start
    Runs the built app in production mode.
We suggest that you begin by typing:
  cd mastra-with-ui-sample
  npm run dev
作成されたmastra-with-ui-sample以下のディレクトリ構成は、以下のようになります。
├── .env.example
├── .git
├── .gitignore
├── app
│   ├── api
│   │   └── chat
│   │       └── route.ts
│   ├── assistant.tsx
│   ├── favicon.ico
│   ├── globals.css
│   ├── layout.tsx
│   └── page.tsx
├── components
│   ├── assistant-ui
│   │   ├── attachment.tsx
│   │   ├── markdown-text.tsx
│   │   ├── thread-list.tsx
│   │   ├── thread.tsx
│   │   ├── threadlist-sidebar.tsx
│   │   ├── tool-fallback.tsx
│   │   └── tooltip-icon-button.tsx
│   └── ui
│       ├── avatar.tsx
│       ├── breadcrumb.tsx
│       ├── button.tsx
│       ├── dialog.tsx
│       ├── input.tsx
│       ├── separator.tsx
│       ├── sheet.tsx
│       ├── sidebar.tsx
│       ├── skeleton.tsx
│       └── tooltip.tsx
├── components.json
├── eslint.config.mjs
├── hooks
│   └── use-mobile.ts
├── lib
│   └── utils.ts
├── next-env.d.ts
├── next.config.ts
├── node_modules
├── package-lock.json
├── package.json
├── pnpm-lock.yaml
├── postcss.config.mjs
├── README.md
└── tsconfig.json
npm run devを実行し、http://localhost:3000/にアクセスしてみましょう。以下のようなチャットUIが開きます。


OpenAIのAPIキーを.envに設定すると、AIからの応答も返る
1-2. 作成したプロジェクトにMastraをインストール
Mastraに関する依存関係をインストールします。
npm install @mastra/core@latest @mastra/memory@latest @mastra/libsql@latest @ai-sdk/openai
Mastraのコードが正しくバンドルされるよう、next.config.tsを修正します。
@@ -1,7 +1,7 @@
 import type { NextConfig } from "next";
 const nextConfig: NextConfig = {
-  /* config options here */
+  serverExternalPackages: ["@mastra/*"],
 };
1-3. Mastraのサンプルプロジェクト作成コマンドを実行
プロジェクトルートでMastraのサンプルプロジェクト作成コマンドを実行します。
npx mastra@latest init
対話形式でプロジェクトの設定が進むため、順番に答えて行きます。
- zodのインストール → Yes
- ディレクトリ → .※カレントディレクトリ
実行ログ
mastra-with-ui-sample % npx mastra@latest init
│
◇  You do not have the zod package installed. Would you like to install it?
│  Yes
✔ zod installed successfully
┌   Mastra Init
│
◇  Where should we create the Mastra files? (default: src/)
│  .
│
◇  Select a default provider:
│  OpenAI
│
◇  Enter your OpenAI API key?
│  Skip for now
│
◇  Make your IDE into a Mastra expert? (Installs Mastra's MCP server)
│  Skip for now
│
◇
│
◇   ─────────────────────────────────────────────────────────╮
│                                                            │
│                                                            │
│        Mastra initialized successfully!                    │
│                                                            │
│        Add your OPENAI_API_KEY as an environment variable  │
│        in your .env file                                   │
│                                                            │
│                                                            │
├────────────────────────────────────────────────────────────╯
mastraディレクトリが新たに作成されており、以下のような構成でファイル・ディレクトリが作成されます。
└── mastra
     ├── agents
     │   └── weather-agent.ts
     ├── index.ts
     ├── tools
     │   └── weather-tool.ts
     └── workflows
          └── weather-workflow.ts
mastra initコマンドでは、.gitignoreの編集がされないため、.mastraディレクトリがGit管理の対象外になるよう、忘れず追記しておきましょう。
@@ -39,3 +39,6 @@
 # typescript
 *.tsbuildinfo
 next-env.d.ts
+
+# Mastra
+.mastra
1-4. MastraのPlayground起動コマンドを追加
Mastra CLIをインストールし、npm run mastra:devでPlaygroundが起動するように設定しておきます。
npm install -D mastra@latest
@@ -8,7 +8,8 @@
     "start": "next start",
     "lint": "next lint",
     "prettier": "prettier --check .",
-    "prettier:fix": "prettier --write ."
+    "prettier:fix": "prettier --write .",
+    "mastra:dev": "mastra dev --dir ./mastra"
   },
   "prettier": {
     "plugins": [
npm run mastra:devを実行し、http://localhost:4111/からPlaygroundを開くことができるか、確かめておきましょう。
1-5. APIのルート設定を変更する
事前に@mastra/ai-sdkをインストールしておきます。
npm install @mastra/ai-sdk@latest
チャットUIからのリクエストに対して、Mastraのコードが実行されるように修正します。主な変更点は、以下の通りです。
- 1️⃣ mastra/index.tsから、Mastraインスタンスを取得
- 2️⃣ weatherAgentを取得
- 3️⃣ AIへのリクエスト結果をストリーム形式で取得
- 4️⃣ ストリームをassistant-uiのチャットUIと互換性のある形式に変換し、レスポンスとして返す
@@ -1,12 +1,22 @@
-import { openai } from "@ai-sdk/openai";
-import { streamText, UIMessage, convertToModelMessages } from "ai";
+import { mastra } from "@/mastra"; // 1️⃣
+import { toAISdkFormat } from "@mastra/ai-sdk";
+import { createUIMessageStreamResponse, UIMessage } from "ai";
+
+// Allow streaming responses up to 30 seconds
+export const maxDuration = 30;
 export async function POST(req: Request) {
   const { messages }: { messages: UIMessage[] } = await req.json();
-  const result = streamText({
-    model: openai("gpt-5-nano"),
-    messages: convertToModelMessages(messages),
-  });
+
+  const agent = mastra.getAgent("weatherAgent"); // 2️⃣
+  const result = await agent.stream(messages); // 3️⃣
-  return result.toUIMessageStreamResponse();
+  // Return the result as a data stream response
+  // Workaround: https://discord.com/channels/1309558646228779139/1413241662091694100/1425928259513749554
+  return createUIMessageStreamResponse({
+    stream: toAISdkFormat(
+      result,
+      { from: "agent" },
+    ),
+  }); // 4️⃣
 }
チャットUI上で、どこかの天気を尋ねるリクエストを投げてみてください。AIから応答が返ってくれば成功です👍️

2. Vercelにデプロイする
前回の記事を参考に、Vercelへのデプロイを進めます。異なる点は、以下の2点です。
- VercelDeployerの設定が不要であること
- Vercelの設定画面での「Build Command」の設定が不要であること
LibSQL関連のコードの削除、それから環境変数の設定は引き続き必要なので、忘れないようにしましょう。
デプロイ後、チャットUIから天気情報が取得できれば完成です!🎉
まとめ
assistant-uiで構成されたチャットUIを持つAIエージェントをVercelにデプロイすることができました!前回と比べ、本番利用をイメージしやすい形となったのではないでしょうか。
基礎編最後の記事では、天気情報エージェントの動作を少し改良してみます。これまでは1つのツールをAIが実行する単純なエージェントでしたが、ツールの数を増やし、「地点名を市区町村レベルまで絞り込んでから、天気情報を返す」ようにしてみます。引き続き、よろしくお願いします🙇
【次回】Mastraを使ってAIエージェントを作ろう! - 基礎編(3) -
参考リンク
レポジトリはこちら
- 
Mastraが対応しているモデルプロバイダーは、以下の3つに大別されます。 
 ・ AI SDKチームがメンテナンスする公式プロバイダー
 ・ OpenAI互換プロバイダー
 ・ コミュニティプロバイダー ↩︎





Discussion