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 がサポートする任意のモデルを指定できます。
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 Providers と Model Capabilities をご覧ください。
React Hooks
Mastra は、HTTP ストリームを使ってフロントエンドコンポーネントをエージェントに直接接続するための AI SDK フックをサポートしています。
必要な AI SDK の React パッケージをインストールします:
npm
npm install @ai-sdk/react
useChat()
フックの使用
useChat
フックはフロントエンドと Mastra エージェント間のリアルタイムなチャットを処理し、プロンプトを送信して HTTP 経由でストリーミング応答を受け取れるようにします。
"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 ルートを定義する方法を示しています。
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 経由でストリーミング応答を受け取れるようにします。
"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 ルートを定義する方法を示しています。
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 オブジェクトに変換します。
"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 ルートを定義する方法を示しています。
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
として利用できます。
"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
インスタンスに設定する方法を示します。
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
に設定することもできます:
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
npm install ai
createDataStream()
の使用
createDataStream
関数を使うと、クライアントへ追加のデータをストリーミングできます。
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
関数は、クライアントにデータをストリーミングするレスポンスオブジェクトを作成します。
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
パラメータとともに使用します:
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.