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

Vercel AI SDKとの使用

MastraはAI SDKのモデルルーティング(OpenAI、Anthropicなどの上に構築された統一インターフェース)、構造化出力、およびツール呼び出しを活用しています。

これについてはこのブログ記事でより詳しく説明しています。

Mastra + AI SDK

MastraはAI SDKの上位レイヤーとして機能し、チームが概念実証を迅速かつ簡単に本格運用できるよう支援します。

Agent interaction trace showing spans, LLM calls, and tool executions

モデルルーティング

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 Hooks

MastraはAI SDKのhooksと互換性があり、シームレスなフロントエンド統合を実現します:

useChat

useChatフックは、フロントエンドアプリケーションでリアルタイムチャットインタラクションを可能にします

  • エージェントデータストリーム(.toDataStreamResponse())と連携します
  • useChat apiのデフォルトは/api/chatです
  • Mastra REST APIエージェントストリームエンドポイント{MASTRA_BASE_URL}/agents/:agentId/streamでデータストリームと連携します。 つまり、構造化出力が定義されていない場合です。
app/api/chat/route.ts
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を使用する場合は、重要な実装詳細についてAgent Memoryセクションを必ず確認してください。

useCompletion

単発の補完には、useCompletionフックを使用します:

  • エージェントデータストリーム(.toDataStreamResponse())と連携します
  • useCompletion apiのデフォルトは/api/completionです
  • Mastra REST APIエージェントストリームエンドポイント{MASTRA_BASE_URL}/agents/:agentId/streamでデータストリームと連携します。 つまり、構造化出力が定義されていない場合です。
app/api/completion/route.ts
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でテキストストリームと連携します。 つまり、構造化出力が定義されている場合です。
app/api/use-object/route.ts
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> ); }

Tool Calling

AI SDK Tool Format

MastraはAI SDK形式で作成されたツールをサポートしているため、Mastraエージェントで直接使用できます。詳細については、Vercel AI SDK Tool Format のツールドキュメントをご覧ください。

クライアントサイドでのツール呼び出し

MastraはAI SDKのツール呼び出し機能を活用しているため、AI SDKで適用されることはここでも同様に適用されます。 MastraのAgent Toolsは、AI SDKツールと100%互換性があります。

Mastraツールは、オプションのexecute非同期関数も公開しています。これは、同じプロセス内でツールを実行する代わりに、ツール呼び出しをクライアントやキューに転送したい場合があるため、オプションとなっています。

クライアントサイドでのツール呼び出しを活用する一つの方法は、@ai-sdk/reactuseChatフックのonToolCallプロパティを使用してクライアントサイドでツールを実行することです。

Custom 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オブジェクトを作成します

app/api/chat/route.ts
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; }