내구성 있는 Agent
추가된 항목: @mastra/core@1.45.0
지속형 Agent는 현재 beta입니다. API는 향후 릴리스에서 변경될 수 있습니다.
지속형 Agent는 일반 Agent를 래핑하여 Agent 루프가 Workflow 내부에서 실행되도록 합니다. 이벤트는 PubSub를 통해 전달되므로 클라이언트가 청크를 놓치지 않고 연결을 끊었다가 다시 연결할 수 있습니다. 실행 상태가 영속화되므로 프로세스가 다시 시작되어도 유지됩니다.
내구성 Agent를 사용해야 하는 경우내구성 Agent를 사용해야 하는 경우에 대한 직접 링크
다음 중 하나에 해당하는 경우 내구성 있는 Agent를 사용하십시오.
- 클라이언트가 스트리밍 도중 연결을 끊었다가 다시 연결할 수 있어야 합니다(모바일, 불안정한 네트워크, 장시간 실행되는 호출).
- Agent 루프가 단일 HTTP 요청보다 오래 지속되어야 합니다(백그라운드 조사, 다단계 Tool 사용).
- 두 번째 클라이언트가 첫 번째 클라이언트가 시작한 스트림을 이어받을 수 있는 관찰/재연결 API가 필요합니다.
- 단계 메모이제이션, 재시도 및 모니터링을 제공하는 Inngest 기반 실행이 필요합니다.
클라이언트가 연결을 유지하는 단기 요청 범위 호출에는
stream()또는generate()를 사용하는 일반Agent가 더 간단합니다.
빠른 시작빠른 시작에 대한 직접 링크
@mastra/core/agent/durable의 createDurableAgent()를 사용하여 기존 Agent를 래핑하세요.
import { Agent } from '@mastra/core/agent'
import { createDurableAgent } from '@mastra/core/agent/durable'
const agent = new Agent({
id: 'researcher',
name: 'Researcher',
instructions: 'You research topics thoroughly.',
model: 'openai/gpt-5.6-sol',
})
export const durableResearcher = createDurableAgent({ agent })
Mastra에 지속형 Agent를 등록하고 호출합니다.stream():
import { Mastra } from '@mastra/core'
import { durableResearcher } from './agents/researcher'
const mastra = new Mastra({
agents: { durableResearcher },
})
const { output, runId, cleanup } = await durableResearcher.stream(
'Research quantum computing advances in 2025',
)
for await (const chunk of output.fullStream) {
// Process each chunk as it arrives
}
// Release PubSub subscriptions and clear the run from the registry.
// If you skip this, an automatic cleanup timer fires after the stream ends.
cleanup()
반환된 runId는 실행을 식별합니다. 다른 클라이언트에서 다시 연결하려면 이를 observe()에 전달하세요. 전체 구성 및 메서드 API는 DurableAgent 레퍼런스를 참조하세요.
작동 원리작동 원리에 대한 직접 링크
지속성 Agent는 일반 Agent 위에 세 개의 레이어를 추가합니다.
- Workflow 실행:
stream()은 메시지와 옵션을 Workflow 입력으로 직렬화한 다음, 지속형 Workflow 내부에서 Agent 루프를 시작합니다. Workflow는Agent.stream()과 동일한 루프를 실행하지만 각 단계는 메모이제이션하고 재생할 수 있습니다. - PubSub 스트리밍: 루프가 실행되면 실행 ID를 키로 사용하는 PubSub 주제에 청크가 게시됩니다. 호출자는 이 주제를 구독하고 청크를
ReadableStream으로 수신합니다. 호출자가 연결을 끊었다가 다시 연결하면 누락된 청크가 캐시에서 재생됩니다. - 캐시 레이어: 선택적 캐시(기본적으로 인Memory, Redis 또는 프로덕션의 다른 백엔드)는 늦게 구독자가 따라잡을 수 있도록 게시된 이벤트를 저장합니다.
실행 변형실행 변형에 대한 직접 링크
Mastra는 내구성 있는 Agent를 생산하는 세 가지 공장 기능을 제공합니다. Workflow가 실행되는 방식이 다릅니다.
| 팩토리 | 패키지 | |
|---|---|---|
createDurableAgent() | @mastra/core | 로컬 개발 및 단일 프로세스 서버에 적합합니다. 직접 await할 수 있는 스트림을 제공합니다. |
createEventedAgent() | @mastra/core | 백그라운드 실행에 적합합니다. Workflow는 호출을 차단하지 않고 시작되며 PubSub를 통해 청크를 소비합니다. |
createInngestAgent() | @mastra/inngest | 프로덕션 배포에 적합합니다. Inngest가 단계 메모이제이션, 재시도 및 모니터링 대시보드를 추가합니다. |
세 가지 모두 일반 Agent와 동일한 방식으로 Mastra에 등록하는 객체를 반환합니다. createDurableAgent()와 createEventedAgent()는 Agent를 확장하는 클래스 인스턴스를 반환합니다. createInngestAgent()는 Agent 메서드를 내부 Agent로 전달하는 Proxy 기반 객체를 반환합니다. |
처리 중createDurableAgent()in-process-with-createdurableagent에 대한 직접 링크
Agent를 래핑하고 stream()을 호출하세요. 동일한 프로세스에서 DurableAgentStreamResult를 반환받습니다. 외부 인프라가 필요하지 않으므로 가장 빠르게 시작할 수 있는 방법입니다.
import { Agent } from '@mastra/core/agent'
import { createDurableAgent } from '@mastra/core/agent/durable'
const agent = new Agent({
id: 'helper',
instructions: 'You are a helpful assistant.',
model: 'openai/gpt-5.6-sol',
})
export const durableHelper = createDurableAgent({ agent })
실행 후 잊어버리세요createEventedAgent()fire-and-forget-with-createeventedagent에 대한 직접 링크
Workflow는 호출자를 차단하지 않고 백그라운드에서 시작됩니다. 청크는 여전히 PubSub를 통해 수신되므로 stream()은 소비할 수 있는 결과를 반환합니다. 실행을 시작한 HTTP 핸들러는 Workflow가 완료될 때까지 기다릴 필요가 없습니다.
import { Agent } from '@mastra/core/agent'
import { createEventedAgent } from '@mastra/core/agent/durable'
const agent = new Agent({
id: 'writer',
instructions: 'You write articles.',
model: 'openai/gpt-5.6-sol',
})
export const eventedWriter = createEventedAgent({ agent })
Ingest 기반createInngestAgent()inngest-powered-with-createinngestagent에 대한 직접 링크
Inngest 플랫폼에서 Workflow를 실행합니다. 각 Tool 호출은 Inngest가 독립적으로 재시도할 수 있는 메모이제이션된 단계가 되며, 실행을 모니터링하는 대시보드도 제공됩니다.
import { Agent } from '@mastra/core/agent'
import { createInngestAgent } from '@mastra/inngest'
import { Inngest } from 'inngest'
const inngest = new Inngest({ id: 'my-app' })
const agent = new Agent({
id: 'analyst',
instructions: 'You analyze data.',
model: 'openai/gpt-5.6-sol',
})
export const inngestAnalyst = createInngestAgent({ agent, inngest })
PubSub 및 캐시 구성과 같은 Inngest 전용 옵션을 포함한 전체 API는 createInngestAgent() 레퍼런스를 참조하세요.
재개 가능한 스트림재개 가능한 스트림에 대한 직접 링크
지속형 Agent는 PubSub 및 이벤트 캐시를 통해 재개 가능한 스트림을 지원합니다. 클라이언트가 스트리밍 도중 연결을 끊어도 캐시는 이벤트를 계속 저장합니다. 동일한 클라이언트는 runId와 함께 observe()를 호출하여 다시 연결할 수 있습니다.
const { output, cleanup } = await durableResearcher.observe(runId)
for await (const chunk of output.fullStream) {
// Chunks from the run, including any missed while disconnected
}
cleanup()
createDurableAgent()와 createEventedAgent()는 기본적으로 인메모리 캐시를 사용하므로 단일 프로세스 내에서 재개 가능한 스트림이 작동합니다. 프로덕션 환경에서는 캐시된 이벤트가 프로세스 재시작 후에도 유지되도록 영속 캐시 백엔드(예: Redis)를 제공하세요.
import { createDurableAgent } from '@mastra/core/agent/durable'
import { RedisServerCache } from '@mastra/redis'
import Redis from 'ioredis'
const cache = new RedisServerCache({ client: new Redis('redis://localhost:6379') })
export const durableAgent = createDurableAgent({
agent,
cache,
})
createInngestAgent()는 기본적으로 캐싱을 활성화하지 않습니다. 재개 가능한 스트림을 활성화하려면 cache 옵션을 전달하거나 serverCache가 구성된 Mastra 인스턴스에 Agent를 등록하세요.
백그라운드 작업으로 스트리밍백그라운드 작업으로 스트리밍에 대한 직접 링크
지속형 Agent는 일반 Agent와 동일한 untilIdle 옵션을 지원합니다. untilIdle을 설정하면 stream()은 Agent가 유휴 상태가 될 때까지 백그라운드 작업의 후속 실행 전반에 걸쳐 연결을 열어 둡니다.
const { output, cleanup } = await durableAgent.stream('Research and summarize the topic', {
untilIdle: true,
memory: { thread: 'thread-1', resource: 'user-1' },
})
for await (const chunk of output.fullStream) {
// Chunks from the initial turn AND any follow-up turns triggered by
// background task completions
}
cleanup()
유휴 시간 제한을 맞춤 설정하려면 { maxIdleMs }를 전달하세요(기본값은 5분).
await durableAgent.stream('Research topic', {
untilIdle: { maxIdleMs: 30_000 },
memory: { thread: 'thread-1', resource: 'user-1' },
})
구성, 하위 Agent, 일시 중지/재개를 포함한 전체 백그라운드 작업 가이드는 백그라운드 작업을 참조하세요.
대청소대청소에 대한 직접 링크
모든 stream() 및 observe() 호출은 cleanup 함수를 반환합니다. 이 함수를 호출하면 PubSub 구독이 해제되고 내부 레지스트리에서 실행이 제거됩니다. 호출하지 않으면 스트림이 종료된 후 자동 타이머가 작동하지만, cleanup()을 직접 호출하면 리소스가 즉시 해제됩니다.
Tool 승인Tool 승인에 대한 직접 링크
지속형 Agent는 Tool 승인(휴먼 인 더 루프)을 지원합니다. Tool 호출에 승인이 필요하면 Workflow가 일시 중지되고 onSuspended 콜백이 호출되며, 호출자가 resume()으로 재개할 때까지 기다립니다.
const { output, runId, cleanup } = await durableAgent.stream('Delete the old records', {
requireToolApproval: true,
onSuspended: ({ toolCallId, toolName, args }) => {
// Notify the user and ask for approval
},
})
승인 후 일시 중단된 실행을 재개합니다.
await durableAgent.resume(runId, { approved: true })
충돌 복구충돌 복구에 대한 직접 링크
지속형 Agent 실행 중 서버 프로세스가 충돌하면 해당 실행은 자동 재시도 없이 스토리지에 running 상태로 남습니다. 다음 서버 시작 시 이러한 고아 실행을 다시 구동하여 중단된 지점부터 계속할 수 있습니다.
자동 복구자동 복구에 대한 직접 링크
Mastra 구성에서 recovery.durableAgents를 'auto'로 설정하세요. 배포자는 활성 Workflow 실행을 다시 시작한 직후 부팅 과정에서 recoverAllDurableAgents()를 호출합니다.
export const mastra = new Mastra({
agents: { myAgent: durableAgent },
storage: new PostgresStore({ connectionString: process.env.DATABASE_URL! }),
recovery: { durableAgents: 'auto' },
})
시작 시 running 상태로 중단된 등록된 모든 지속형 Agent 실행을 검색하고 마지막으로 영속화된 스냅샷부터 다시 구동합니다.
복구는 마지막 스냅샷에서 Agent 루프를 다시 실행하여 LLM 호출(실제 비용)을 재발행하고 Tool 호출을 다시 실행합니다. 자동 복구를 활성화하기 전에 Tool이 멱등성인지 확인하세요.
수동 복구수동 복구에 대한 직접 링크
리더 선택 뒤에 복구를 제어하거나 일정에 따라 복구를 실행하는 등 더 세부적인 제어가 필요한 경우 메서드를 직접 호출하세요.
// Recover all durable agents
const result = await mastra.recoverAllDurableAgents()
console.log(`Recovered ${result.recovered} runs (${result.succeeded} ok, ${result.failed} failed)`)
// Recover a specific agent
const agentResult = await durableAgent.recoverActiveRuns()
// Recover a single known run
await durableAgent.recoverActiveRuns({ runId: 'run-abc-123' })
다중 인스턴스 배포다중 인스턴스 배포에 대한 직접 링크
Mastra는 아직 분산 리스 또는 잠금을 제공하지 않습니다. 다중 복제본 배포에서는 recovery.durableAgents: 'auto'로 시작하는 모든 복제본이 동일한 실행을 복구하기 위해 경합합니다. 현재는 자체 리더 선출 뒤에서 복구를 제어하거나 단일 복제본에서만 실행하세요.