Skip to Content
ドキュメントフレームワークエージェンティックUIVercel AI SDKを使用

Vercel AI SDK の使用

Mastra は、モデルのルーティング、React Hooks、データストリーミングに対応するために、Vercel の AI SDK  と統合されています。

AI SDK v5

Mastra は AI SDK v5 にも対応しています。v5 固有のメソッドについては、次のセクションをご覧ください: Vercel AI SDK v5

このページのコード例は、プロジェクトのルートで Next.js の App Router を使用していることを前提としています。 例: src/app ではなく app を使用します。

モデルのルーティング

Mastra でエージェントを作成する際は、AI SDK がサポートする任意のモデルを指定できます。

agents/weather-agent.ts
import { openai } from "@ai-sdk/openai"; import { Agent } from "@mastra/core/agent"; export const weatherAgent = new Agent({ name: "Weather Agent", instructions: "Instructions for the agent...", model: openai("gpt-4-turbo"), });

詳細は Model ProvidersModel Capabilities をご覧ください。

React Hooks

Mastra は、HTTP ストリームを使ってフロントエンドコンポーネントをエージェントに直接接続するための AI SDK フックをサポートしています。

必要な AI SDK の React パッケージをインストールします:

npm install @ai-sdk/react

useChat() フックの使用

useChat フックはフロントエンドと Mastra エージェント間のリアルタイムなチャットを処理し、プロンプトを送信して HTTP 経由でストリーミング応答を受け取れるようにします。

app/test/chat.tsx
"use client"; import { useChat } from "@ai-sdk/react"; export function Chat() { const { messages, input, handleInputChange, handleSubmit } = useChat({ api: "api/chat" }); return ( <div> <pre>{JSON.stringify(messages, null, 2)}</pre> <form onSubmit={handleSubmit}> <input value={input} onChange={handleInputChange} placeholder="Name of city" /> </form> </div> ); }

useChat フックで送信したリクエストは、標準的なサーバールートで処理されます。次の例は、Next.js の Route Handler を使って POST ルートを定義する方法を示しています。

app/api/chat/route.ts
import { mastra } from "../../mastra"; export async function POST(req: Request) { const { messages } = await req.json(); const myAgent = mastra.getAgent("weatherAgent"); const stream = await myAgent.stream(messages); return stream.toDataStreamResponse(); }

エージェントメモリと併用して useChat を使う場合は、重要な実装の詳細について Agent Memory セクション を参照してください。

useCompletion() フックの使用

useCompletion フックは、フロントエンドと Mastra エージェント間の単発の補完処理を行い、プロンプトを送信して HTTP 経由でストリーミング応答を受け取れるようにします。

app/test/completion.tsx
"use client"; import { useCompletion } from "@ai-sdk/react"; export function Completion() { const { completion, input, handleInputChange, handleSubmit } = useCompletion({ api: "api/completion" }); return ( <div> <form onSubmit={handleSubmit}> <input value={input} onChange={handleInputChange} placeholder="Name of city" /> </form> <p>Completion result: {completion}</p> </div> ); }

useCompletion フックで送信したリクエストは、標準的なサーバールートで処理されます。次の例は、Next.js の Route Handler を使って POST ルートを定義する方法を示しています。

app/api/completion/route.ts
import { mastra } from "../../../mastra"; export async function POST(req: Request) { const { prompt } = await req.json(); const myAgent = mastra.getAgent("weatherAgent"); const stream = await myAgent.stream([{ role: "user", content: prompt }]); return stream.toDataStreamResponse(); }

useObject() フックの使用

useObject フックは、Mastra エージェントからストリーミングされるテキストを受け取り、定義されたスキーマに基づいて構造化された JSON オブジェクトに変換します。

app/test/object.tsx
"use client"; import { experimental_useObject as useObject } from "@ai-sdk/react"; import { z } from "zod"; export function Object() { const { object, submit } = useObject({ api: "api/object", schema: z.object({ weather: z.string() }) }); return ( <div> <button onClick={() => submit("London")}>Generate</button> {object ? <pre>{JSON.stringify(object, null, 2)}</pre> : null} </div> ); }

useObject フックで送信したリクエストは、標準的なサーバールートで処理されます。次の例は、Next.js の Route Handler を使って POST ルートを定義する方法を示しています。

app/api/object/route.ts
import { mastra } from "../../../mastra"; import { z } from "zod"; export async function POST(req: Request) { const body = await req.json(); const myAgent = mastra.getAgent("weatherAgent"); const stream = await myAgent.stream(body, { output: z.object({ weather: z.string() }) }); return stream.toTextStreamResponse(); }

sendExtraMessageFields で追加データを渡す

sendExtraMessageFields オプションを使うと、フロントエンドから Mastra に追加データを渡せます。このデータはサーバー側で RuntimeContext として利用できます。

app/test/chat-extra.tsx
"use client"; import { useChat } from "@ai-sdk/react"; export function ChatExtra() { const { messages, input, handleInputChange, handleSubmit } = useChat({ api: "/api/chat-extra", sendExtraMessageFields: true }); const handleFormSubmit = (e: React.FormEvent) => { e.preventDefault(); handleSubmit(e, { data: { userId: "user123", preferences: { language: "en", temperature: "celsius" } } }); }; return ( <div> <pre>{JSON.stringify(messages, null, 2)}</pre> <form onSubmit={handleFormSubmit}> <input value={input} onChange={handleInputChange} placeholder="Name of city" /> </form> </div> ); }

sendExtraMessageFields を使って送信されたリクエストは、通常のサーバールートで処理されます。次の例では、カスタムデータを取り出して RuntimeContext インスタンスに設定する方法を示します。

app/api/chat-extra/route.ts
import { mastra } from "../../../mastra"; import { RuntimeContext } from "@mastra/core/runtime-context"; export async function POST(req: Request) { const { messages, data } = await req.json(); const myAgent = mastra.getAgent("weatherAgent"); const runtimeContext = new RuntimeContext(); if (data) { for (const [key, value] of Object.entries(data)) { runtimeContext.set(key, value); } } const stream = await myAgent.stream(messages, { runtimeContext }); return stream.toDataStreamResponse(); }

server.middleware による runtimeContext の取り扱い

サーバーのミドルウェアでカスタムデータを読み取り、RuntimeContext に設定することもできます:

mastra/index.ts
import { Mastra } from "@mastra/core/mastra"; export const mastra = new Mastra({ agents: { weatherAgent }, server: { middleware: [ async (c, next) => { const runtimeContext = c.get("runtimeContext"); if (c.req.method === "POST") { try { const clonedReq = c.req.raw.clone(); const body = await clonedReq.json(); if (body?.data) { for (const [key, value] of Object.entries(body.data)) { runtimeContext.set(key, value); } } } catch { } } await next(); }, ], }, });

その後、このデータには runtimeContext パラメータ経由でツールからアクセスできます。詳しくは Runtime Context のドキュメント を参照してください。

ストリーミングデータ

ai パッケージは、カスタムデータストリームを管理するためのユーティリティを提供します。場合によっては、エージェントの dataStream を使って、構造化された更新や注釈(アノテーション)をクライアントへ送信したいことがあります。

必要なパッケージをインストールします:

npm install ai

createDataStream() の使用

createDataStream 関数を使うと、クライアントへ追加のデータをストリーミングできます。

mastra/agents/weather-agent.ts
import { createDataStream } from "ai"; import { Agent } from "@mastra/core/agent"; export const weatherAgent = new Agent({...}); createDataStream({ async execute(dataStream) { dataStream.writeData({ value: "Hello" }); dataStream.writeMessageAnnotation({ type: "status", value: "processing" }); const agentStream = await weatherAgent.stream("What is the weather"); agentStream.mergeIntoDataStream(dataStream); }, onError: (error) => `Custom error: ${error}` });

createDataStreamResponse() の使用

createDataStreamResponse 関数は、クライアントにデータをストリーミングするレスポンスオブジェクトを作成します。

app/api/chat-stream/route.ts
import { mastra } from "../../../mastra"; import { createDataStreamResponse } from "ai"; export async function POST(req: Request) { const { messages } = await req.json(); const myAgent = mastra.getAgent("weatherAgent"); const agentStream = await myAgent.stream(messages); const response = createDataStreamResponse({ status: 200, statusText: "OK", headers: { "Custom-Header": "value" }, async execute(dataStream) { dataStream.writeData({ value: "Hello" }); dataStream.writeMessageAnnotation({ type: "status", value: "processing" }); agentStream.mergeIntoDataStream(dataStream); }, onError: (error) => `Custom error: ${error}` }); return response; }

Vercel AI SDK v5

このガイドでは、AI SDK v4 から v5 への移行時における Mastra 固有の考慮事項を解説します。

フィードバックやバグ報告は、AI SDK v5 の GitHub メガ Issue  にお寄せください。

実験的な streamVNext サポート

Mastra の実験的な streamVNext メソッドは、format パラメータにより AI SDK v5 をネイティブにサポートするようになりました。これにより、互換ラッパーを用意せずとも、AI SDK v5 のストリーミングインターフェースとシームレスに統合できます。

// Use streamVNext with AI SDK v5 format const stream = await agent.streamVNext(messages, { format: 'aisdk' // Enable AI SDK v5 compatibility }); // The stream is now compatible with AI SDK v5 interfaces return stream.toUIMessageStreamResponse();

公式移行ガイド

AI SDK コアの破壊的変更、パッケージ更新、API 変更については、公式のAI SDK v5 移行ガイド に従ってください。

本ガイドは、移行のうち Mastra 固有の側面のみを扱います。

  • データ互換性: v5 形式で保存された新しいデータは、v5 から v4 にダウングレードすると動作しません
  • バックアップ推奨: v5 にアップグレードする前の DB バックアップを保持してください

メモリとストレージ

Mastra は内部の MessageList クラスを使用して AI SDK v4 のデータを自動的に処理します。このクラスが v4→v5 を含む形式変換を管理します。データベース移行は不要で、既存のメッセージはオンザフライで変換され、アップグレード後もそのまま動作します。

メッセージ形式の変換

AI SDK と Mastra の形式間でメッセージを手動で変換する必要がある場合は、convertMessages ユーティリティを使用してください:

import { convertMessages } from '@mastra/core/agent'; // Convert AI SDK v4 messages to v5 const aiv5Messages = convertMessages(aiv4Messages).to('AIV5.UI'); // Convert Mastra messages to AI SDK v5 const aiv5Messages = convertMessages(mastraMessages).to('AIV5.Core'); // Supported output formats: // 'Mastra.V2', 'AIV4.UI', 'AIV5.UI', 'AIV5.Core', 'AIV5.Model'

このユーティリティは、ストレージ DB からメッセージを直接取得し、AI SDK で使用できる形式へ変換したい場合に役立ちます。

ストリーミング互換性の有効化

AI SDK v5 との互換性を有効にするには、実験的な streamVNext メソッドを format パラメータとともに使用します:

app/api/chat/route.ts
import { mastra } from "../../../mastra"; export async function POST(req: Request) { const { messages } = await req.json(); const myAgent = mastra.getAgent("weatherAgent"); // Use streamVNext with AI SDK v5 format (experimental) const stream = await myAgent.streamVNext(messages, { format: 'aisdk' }); return stream.toUIMessageStreamResponse(); }

Note: The streamVNext method with format support is experimental and may change as we refine the feature based on feedback. See the Agent Streaming documentation for more details about streamVNext.