Skip to Content
ドキュメントフレームワークVercel AI SDKを使用

Vercel AI SDKと一緒に使用する

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

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

Mastra + AI SDK

Mastraは、チームが概念実証を迅速かつ容易に製品化するのを支援するために、AI SDKの上に層として機能します。

スパン、LLM呼び出し、ツール実行を示すエージェントインタラクショントレース

モデルルーティング

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とデータストリーム用に連携します。 つまり、構造化された出力は定義されていません。
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を使用する場合は、重要な実装の詳細についてエージェントメモリセクションを確認してください。

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> ); }

ツール呼び出し

AI SDK ツールフォーマット

Mastraは、AI SDKフォーマットで作成されたツールをサポートしているため、Mastraエージェントと直接使用することができます。詳細については、Vercel AI SDKツールフォーマットに関するツールドキュメントをご覧ください。

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

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

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

クライアントサイドのツール呼び出しを活用する一つの方法は、クライアントサイドのツール実行のために@ai-sdk/reactuseChatフックの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オブジェクトを作成します

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 }