Vercel AI SDKと一緒に使用する
Mastraは、AI SDKのモデルルーティング(OpenAI、Anthropicなどの上に統一されたインターフェース)、構造化された出力、およびツール呼び出しを活用しています。
これについては、このブログ記事 でより詳しく説明しています
Mastra + AI SDK
Mastraは、チームが概念実証を迅速かつ容易に製品化するのを支援するために、AI SDKの上に層として機能します。

モデルルーティング
Mastraでエージェントを作成する際、AI SDKがサポートするどのモデルでも指定できます:
import { openai } from "@ai-sdk/openai";
import { Agent } from "@mastra/core/agent";
const agent = new Agent({
name: "WeatherAgent",
instructions: "Instructions for the agent...",
model: openai("gpt-4-turbo"), // Model comes directly from AI SDK
});
const result = await agent.generate("What is the weather like?");
AI SDKフック
Mastraは、フロントエンドとのシームレスな統合のためにAI SDKのフックと互換性があります:
useChat
useChat
フックを使用すると、フロントエンドアプリケーションでリアルタイムのチャット対話が可能になります
- エージェントデータストリーム(
.toDataStreamResponse()
)と連携します - useChatの
api
はデフォルトで/api/chat
に設定されています - Mastra REST APIのエージェントストリームエンドポイント
{MASTRA_BASE_URL}/agents/:agentId/stream
とデータストリーム用に連携します。 つまり、構造化された出力は定義されていません。
import { mastra } from "@/src/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();
}
import { useChat } from '@ai-sdk/react';
export function ChatComponent() {
const { messages, input, handleInputChange, handleSubmit } = useChat({
api: '/path-to-your-agent-stream-api-endpoint'
});
return (
<div>
{messages.map(m => (
<div key={m.id}>
{m.role}: {m.content}
</div>
))}
<form onSubmit={handleSubmit}>
<input
value={input}
onChange={handleInputChange}
placeholder="Say something..."
/>
</form>
</div>
);
}
注意点: エージェントのメモリ機能と
useChat
を使用する場合は、重要な実装の詳細についてエージェントメモリセクションを確認してください。
useCompletion
単一ターンの補完には、useCompletion
フックを使用します:
- エージェントデータストリーム(
.toDataStreamResponse()
)と連携します - useCompletionの
api
はデフォルトで/api/completion
に設定されています - Mastra REST APIのエージェントストリームエンドポイント
{MASTRA_BASE_URL}/agents/:agentId/stream
とデータストリーム用に連携します。 つまり、構造化された出力は定義されていません。
import { mastra } from "@/src/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();
}
import { useCompletion } from "@ai-sdk/react";
export function CompletionComponent() {
const {
completion,
input,
handleInputChange,
handleSubmit,
} = useCompletion({
api: '/path-to-your-agent-stream-api-endpoint'
});
return (
<div>
<form onSubmit={handleSubmit}>
<input
value={input}
onChange={handleInputChange}
placeholder="Enter a prompt..."
/>
</form>
<p>Completion result: {completion}</p>
</div>
);
}
useObject
スキーマに基づいてJSONオブジェクトを表すテキストストリームを消費し、完全なオブジェクトに解析するために使用します。
- エージェントテキストストリーム(
.toTextStreamResponse()
)と連携します - Mastra REST APIのエージェントストリームエンドポイント
{MASTRA_BASE_URL}/agents/:agentId/stream
とテキストストリーム用に連携します。 つまり、構造化された出力が定義されています。
import { mastra } from "@/src/mastra";
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();
}
import { experimental_useObject as useObject } from '@ai-sdk/react';
export default function Page() {
const { object, submit } = useObject({
api: '/api/use-object',
schema: z.object({
weather: z.string(),
}),
});
return (
<div>
<button onClick={() => submit('example input')}>Generate</button>
{object?.weather && <p>{object.weather}</p>}
</div>
);
}
ツール呼び出し
AI SDK ツールフォーマット
Mastraは、AI SDKフォーマットで作成されたツールをサポートしているため、Mastraエージェントと直接使用することができます。詳細については、Vercel AI SDKツールフォーマットに関するツールドキュメントをご覧ください。
クライアントサイドのツール呼び出し
MastraはAI SDKのツール呼び出し機能を活用しているため、AI SDKに適用されることはここでも同様に適用されます。 Mastraのエージェントツールは、AI SDKツールと100%互換性があります。
Mastraツールはオプションのexecute
非同期関数も公開しています。これがオプションである理由は、ツール呼び出しをクライアントやキューに転送する場合があり、同じプロセスで実行したくない場合があるためです。
クライアントサイドのツール呼び出しを活用する一つの方法は、クライアントサイドのツール実行のために@ai-sdk/react
のuseChat
フックのonToolCall
プロパティを使用することです。
カスタムDataStream
特定のシナリオでは、エージェントのdataStreamにカスタムデータやメッセージ注釈を書き込む必要があります。 これは以下のような場合に役立ちます:
- クライアントに追加データをストリーミングする
- 進行状況の情報をリアルタイムでクライアントに返す
MastraはAI SDKとうまく統合して、これを可能にします
CreateDataStream
createDataStream
関数を使用すると、クライアントに追加データをストリーミングできます
import { createDataStream } from "ai"
import { Agent } from '@mastra/core/agent';
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: openai('gpt-4o'),
tools: { weatherTool },
});
const stream = createDataStream({
async execute(dataStream) {
// Write data
dataStream.writeData({ value: 'Hello' });
// Write annotation
dataStream.writeMessageAnnotation({ type: 'status', value: 'processing' });
//mastra agent stream
const agentStream = await weatherAgent.stream('What is the weather')
// Merge agent stream
agentStream.mergeIntoDataStream(dataStream);
},
onError: error => `Custom error: ${error.message}`,
});
CreateDataStreamResponse
createDataStreamResponse
関数は、クライアントにデータをストリーミングするResponseオブジェクトを作成します
import { mastra } from "@/src/mastra";
export async function POST(req: Request) {
const { messages } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
//mastra agent stream
const agentStream = await myAgent.stream(messages);
const response = createDataStreamResponse({
status: 200,
statusText: 'OK',
headers: {
'Custom-Header': 'value',
},
async execute(dataStream) {
// Write data
dataStream.writeData({ value: 'Hello' });
// Write annotation
dataStream.writeMessageAnnotation({ type: 'status', value: 'processing' });
// Merge agent stream
agentStream.mergeIntoDataStream(dataStream);
},
onError: error => `Custom error: ${error.message}`,
});
return response
}