Next.js 프로젝트에 Mastra 통합
이 가이드에서는 Mastra를 사용하여 Tool 호출 AI Agent를 구축한 다음 경로에서 직접 Agent를 가져오고 호출하여 Next.js에 연결합니다.
AI SDK UI와 AI Elements를 사용하여 아름다운 대화형 채팅 환경을 만듭니다.
Mastra + Next.js 프로젝트를 빌드합니다. 이 가이드를 정확하게 따르십시오.https://mastra.ai/guides/getting-started/next-js.md
시작하기 전에 다음 질문을 하나씩 물어보세요. 이미 제공되지 않은 경우 답변을 기다리십시오.
- 프로젝트 이름? (기본값: "my-nextjs-agent")
- 공급자? (기본값: "openai", 옵션: "openai", "anthropic", "groq", "google", "cerebras", "mistral")
- 이미 Next.js 앱이 있나요? (기본값: "아니요")
공급자 규칙:
- 허용된 공급자 -> 사용하세요.
- 다른 값 -> "openai"를 사용하세요.
새로운 앱인 경우: 실행npx create-next-app@latest <project-name> --yes --ts --eslint --tailwind --src-dir --app --turbopack --no-react-compiler --no-import-alias
"마스트라 초기화" 단계에서는 가이드의 대화형 명령을 실행하지 마세요. 대신 다음을 실행하세요.cd <project-name> && npx mastra@latest init --default --llm <provider>
그런 다음 가이드의 모든 단계를 따르세요. 가이드의 코드를 정확하게 복사하세요. 즉흥적으로 하지 마십시오.
시작하기 전에시작하기 전에에 대한 직접 링크
- 지원되는 Model Provider의 API 키가 필요합니다. 선호하는 Provider가 없다면 OpenAI를 사용하세요.
- Node.js
v22.13.0이상 설치
새 Next.js 앱 만들기(선택 사항)새 Next.js 앱 만들기(선택 사항)에 대한 직접 링크
Next.js 앱이 이미 있는 경우 다음 단계로 건너뜁니다.
다음 명령을 실행하여 새 Next.js 앱을 생성합니다.
- npm
- pnpm
- Yarn
- Bun
npx create-next-app@latest my-nextjs-agent --yes --ts --eslint --tailwind --src-dir --app --turbopack --no-react-compiler --no-import-alias
pnpm dlx create-next-app@latest my-nextjs-agent --yes --ts --eslint --tailwind --src-dir --app --turbopack --no-react-compiler --no-import-alias
yarn dlx create-next-app@latest my-nextjs-agent --yes --ts --eslint --tailwind --src-dir --app --turbopack --no-react-compiler --no-import-alias
bun x create-next-app@latest my-nextjs-agent --yes --ts --eslint --tailwind --src-dir --app --turbopack --no-react-compiler --no-import-alias
이 명령은 my-nextjs-agent라는 프로젝트를 생성하지만 원하는 이름으로 바꿀 수 있습니다.
마스트라 초기화마스트라 초기화에 대한 직접 링크
Next.js 프로젝트로 이동합니다.
cd my-nextjs-agent
mastra init을 실행합니다. 메시지가 표시되면 Provider(예: OpenAI)를 선택하고 키를 입력합니다.
- npm
- pnpm
- Yarn
- Bun
npx mastra@latest init
pnpm dlx mastra@latest init
yarn dlx mastra@latest init
bun x mastra@latest init
그러면 예제 날씨 Agent와 다음 파일을 포함하는 src/mastra 폴더가 생성됩니다.
index.ts- Memory를 포함한 마스트라 구성tools/weather-tool.ts- 특정 위치의 날씨를 가져오는 Toolagents/weather-agent.ts- Tool을 사용하는 Prompt가 있는 기상 요원
다음 단계에서는 Next.js 라우트에서 weather-agent.ts를 호출합니다.
:::tip[Next.js와 함께 Studio 사용]
Next.js 앱과 함께 Studio를 실행하고 두 프로세스가 같은 데이터베이스를 공유하게 하려면 src/mastra/index.ts의 스토리지 URL이 절대 경로를 사용하도록 변경하세요.
url: 'file:/absolute/path/to/your/project/mastra.db'
상대 경로는 next dev와 mastra dev 각 프로세스의 작업 디렉터리를 기준으로 해석됩니다.
:::
AI SDK UI 및 AI 요소 설치AI SDK UI 및 AI 요소 설치에 대한 직접 링크
Mastra 어댑터와 함께 AI SDK UI를 설치합니다.
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/ai-sdk@latest @ai-sdk/react ai
pnpm add @mastra/ai-sdk@latest @ai-sdk/react ai
yarn add @mastra/ai-sdk@latest @ai-sdk/react ai
bun add @mastra/ai-sdk@latest @ai-sdk/react ai
다음으로 AI 요소를 초기화합니다. 메시지가 표시되면 기본 옵션을 선택합니다.
- npm
- pnpm
- Yarn
- Bun
npx ai-elements@latest
pnpm dlx ai-elements@latest
yarn dlx ai-elements@latest
bun x ai-elements@latest
그러면 전체 AI Elements UI 구성 요소 라이브러리가@/components/ai-elements folder.
채팅 경로 만들기채팅 경로 만들기에 대한 직접 링크
만들다src/app/api/chat/route.ts:
import { handleChatStream } from '@mastra/ai-sdk'
import { toAISdkV5Messages } from '@mastra/ai-sdk/ui'
import { createUIMessageStreamResponse } from 'ai'
import { mastra } from '@/mastra'
import { NextResponse } from 'next/server'
const THREAD_ID = 'example-user-id'
const RESOURCE_ID = 'weather-chat'
export async function POST(req: Request) {
const params = await req.json()
const stream = await handleChatStream({
mastra,
agentId: 'weather-agent',
params: {
...params,
memory: {
...params.memory,
thread: THREAD_ID,
resource: RESOURCE_ID,
},
},
})
return createUIMessageStreamResponse({ stream })
}
export async function GET() {
const memory = await mastra.getAgentById('weather-agent').getMemory()
let response = null
try {
response = await memory?.recall({
threadId: THREAD_ID,
resourceId: RESOURCE_ID,
})
} catch {
console.log('No previous messages found.')
}
const uiMessages = toAISdkV5Messages(response?.messages || [])
return NextResponse.json(uiMessages)
}
POST 라우트는 Prompt를 받아 Agent의 응답을 AI SDK 형식으로 스트리밍하고, GET 라우트는 Memory에서 메시지 기록을 가져와 클라이언트가 다시 로드될 때 UI를 hydrate할 수 있게 합니다.
채팅 페이지 만들기채팅 페이지 만들기에 대한 직접 링크
만들다src/app/chat/page.tsx:
'use client'
import '@/app/globals.css'
import { useEffect, useState } from 'react'
import { DefaultChatTransport, ToolUIPart } from 'ai'
import { useChat } from '@ai-sdk/react'
import {
PromptInput,
PromptInputBody,
PromptInputTextarea,
} from '@/components/ai-elements/prompt-input'
import {
Conversation,
ConversationContent,
ConversationScrollButton,
} from '@/components/ai-elements/conversation'
import { Message, MessageContent, MessageResponse } from '@/components/ai-elements/message'
import { Tool, ToolHeader, ToolContent, ToolInput, ToolOutput } from '@/components/ai-elements/tool'
function Chat() {
const [input, setInput] = useState<string>('')
const { messages, setMessages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({
api: '/api/chat',
}),
})
useEffect(() => {
const fetchMessages = async () => {
const res = await fetch('/api/chat')
const data = await res.json()
setMessages([...data])
}
fetchMessages()
}, [setMessages])
const handleSubmit = async () => {
if (!input.trim()) return
sendMessage({ text: input })
setInput('')
}
return (
<div className="relative size-full h-screen w-full p-6">
<div className="flex h-full flex-col">
<Conversation className="h-full">
<ConversationContent>
{messages.map(message => (
<div key={message.id}>
{message.parts?.map((part, i) => {
if (part.type === 'text') {
return (
<Message key={`${message.id}-${i}`} from={message.role}>
<MessageContent>
<MessageResponse>{part.text}</MessageResponse>
</MessageContent>
</Message>
)
}
if (part.type?.startsWith('tool-')) {
return (
<Tool key={`${message.id}-${i}`}>
<ToolHeader
type={(part as ToolUIPart).type}
state={(part as ToolUIPart).state || 'output-available'}
className="cursor-pointer"
/>
<ToolContent>
<ToolInput input={(part as ToolUIPart).input || {}} />
<ToolOutput
output={(part as ToolUIPart).output}
errorText={(part as ToolUIPart).errorText}
/>
</ToolContent>
</Tool>
)
}
return null
})}
</div>
))}
<ConversationScrollButton />
</ConversationContent>
</Conversation>
<PromptInput onSubmit={handleSubmit} className="mt-20">
<PromptInputBody>
<PromptInputTextarea
onChange={e => setInput(e.target.value)}
className="md:leading-10"
value={input}
placeholder="Type your message..."
disabled={status !== 'ready'}
/>
</PromptInputBody>
</PromptInput>
</div>
</div>
)
}
export default Chat
이 컴포넌트는 useChat()을 api/chat 엔드포인트에 연결하여 Prompt를 전송하고 응답을 청크 단위로 스트리밍합니다.
<MessageResponse> 컴포넌트로 응답 텍스트를 렌더링하고, <Tool> 컴포넌트로 Tool 호출을 표시합니다.
Agent 테스트Agent 테스트에 대한 직접 링크
- 다음을 사용하여 Next.js 앱을 실행하세요.
npm run dev - 다음에서 채팅을 엽니다.http://localhost:3000/chat
- 날씨에 대해 물어보세요. API 키가 올바르게 설정되면 응답을 받게 됩니다.
다음 단계다음 단계에 대한 직접 링크
Next.js를 사용하여 Mastra Agent를 구축한 것을 축하합니다! 🎉
여기에서 자신만의 Tool와 논리를 사용하여 프로젝트를 확장할 수 있습니다.