본문으로 건너뛰기

내구성 Agent

DurableAgent기존을 래핑Agent내구성 있는 실행과 재개 가능한 스트림을 제공합니다. 클라이언트가 이벤트 누락 없이 연결을 끊었다가 다시 연결할 수 있도록 Agent 루프를 실행하고 해당 이벤트를 스트리밍합니다.PubSub. 실행이 단일 요청보다 오래 지속되거나 연결이 끊어진 후에도 유지되어야 하는 경우에 사용하십시오.

다음을 사용하여 하나를 만듭니다.createDurableAgent factory, or use createEventedAgent 를 사용하면 기본 제공 Workflow 엔진에서 실행 후 결과를 기다리지 않는 방식으로 실행할 수 있습니다. Inngest 기반 실행에는 다음을 사용하세요: createInngestAgent from @mastra/inngest.

사용예
사용예에 대한 직접 링크

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { Agent } from '@mastra/core/agent'
import { createDurableAgent } from '@mastra/core/agent/durable'

const agent = new Agent({
id: 'my-agent',
name: 'My Agent',
instructions: 'You are a helpful assistant',
model: 'openai/gpt-5.6-sol',
})

const durableAgent = createDurableAgent({ agent })

export const mastra = new Mastra({
agents: { myAgent: durableAgent },
})

응답을 스트리밍하고 결과를 읽습니다. 그만큼cleanup 함수는 실행이 끝났을 때 PubSub 구독을 해제합니다:

const { output, runId, cleanup } = await durableAgent.stream('Hello!')

const text = await output.text

cleanup()

사용하여durable config flag
using-the-durable-config-flag에 대한 직접 링크

세트durable: true on AgentConfig and the agent is automatically wrapped with createDurableAgent when it's attached to a Mastra 인스턴스입니다. 다음과 같은 고급 옵션을 전달하려면 객체를 사용하세요: cache, pubsub, maxSteps, 또는cleanupTimeoutMs.

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { Agent } from '@mastra/core/agent'

const myAgent = new Agent({
id: 'my-agent',
name: 'My Agent',
instructions: 'You are a helpful assistant',
model: 'openai/gpt-5.6-sol',
durable: true, // or: { maxSteps: 10, cleanupTimeoutMs: 60_000 }
})

export const mastra = new Mastra({
agents: { myAgent },
})

mastra.getAgent('myAgent')포장된 것을 돌려준다DurableAgent. 독립형 Agent(생성되었지만 Mastra 인스턴스에 등록되지 않은 Agent)는 지속형으로 전환되지 않습니다. 래핑은 등록 시 적용됩니다.

createDurableAgent(options)
createdurableagentoptions에 대한 직접 링크

래핑Agent 를 사용하면 지속형 실행과 재개 가능한 스트림을 이용할 수 있습니다. 다음을 생성할 때 권장되는 방법입니다: DurableAgent.

import { createDurableAgent } from '@mastra/core/agent/durable'

const durableAgent = createDurableAgent({ agent })

보고:DurableAgent

매개변수
매개변수에 대한 직접 링크

agent:

Agent
The Agent to wrap with durable execution capabilities. Agent methods delegate to this agent.

id?:

string
= agent.id
ID override.

name?:

string
= agent.name
Name override.

cache?:

MastraServerCache | false
Cache for stored stream events, which enables resumable streams. If omitted, the agent inherits the cache from the Mastra instance, or uses an InMemoryServerCache. Set to false to disable caching, which makes streams non-resumable.

pubsub?:

PubSub
= EventEmitterPubSub
PubSub instance for streaming events.

maxSteps?:

number
Maximum number of steps for the agentic loop.

createEventedAgent(options)
createeventedagentoptions에 대한 직접 링크

래핑Agent 를 사용하면 기본 제공 Workflow 엔진에서 실행 후 결과를 기다리지 않는 지속형 실행을 이용할 수 있습니다. createDurableAgent와 마찬가지로 스트리밍할 수 있는 결과를 반환하지만, 기본 Workflow는 스트림 연결 전에 완료될 때까지 실행되는 대신 비차단 방식으로 실행됩니다(다음을 통해: startAsync). 호출자와 독립적으로 실행이 진행되도록 하려면 사용하세요. 다음은 허용하지 않습니다: id or name overrides.

import { createEventedAgent } from '@mastra/core/agent/durable'

const eventedAgent = createEventedAgent({ agent })

보고:EventedAgent (a subclass of DurableAgent)

매개변수
매개변수에 대한 직접 링크

agent:

Agent
The Agent to wrap with evented durable execution capabilities.

cache?:

MastraServerCache | false
Cache for stored stream events, which enables resumable streams. If omitted, the agent inherits the cache from the Mastra instance, or uses an InMemoryServerCache. Set to false to disable caching.

pubsub?:

PubSub
= EventEmitterPubSub
PubSub instance for streaming events.

maxSteps?:

number
Maximum number of steps for the agentic loop.

생성자 매개변수
생성자 매개변수에 대한 직접 링크

그만큼DurableAgent class accepts the same options as createDurableAgent, plus cleanupTimeoutMs. 서브클래싱이 필요한 경우가 아니라면 팩토리를 사용하는 것이 좋습니다.

agent:

Agent
The Agent to wrap with durable execution capabilities.

id?:

string
= agent.id
ID override.

name?:

string
= agent.name
Name override.

cache?:

MastraServerCache | false
Cache for stored stream events. If omitted, inherits from the Mastra instance or uses an InMemoryServerCache. Set to false to disable caching.

pubsub?:

PubSub
= EventEmitterPubSub
PubSub instance for streaming events.

maxSteps?:

number
Maximum number of steps for the agentic loop.

cleanupTimeoutMs?:

number
= 30000
Grace period in milliseconds before registry entries are cleaned up automatically after a stream finishes or errors. Set to 0 to disable auto-cleanup and require a manual cleanup() call. Auto-cleanup does not fire on suspended events.

행동 양식
행동 양식에 대한 직접 링크

실행
실행에 대한 직접 링크

stream(messages, options?)
streammessages-options에 대한 직접 링크

지속 가능한 실행을 사용하여 응답을 스트리밍합니다. 다음과 같은 결과를 즉시 반환합니다.output produces events as the run progresses.

const { output, runId, cleanup } = await durableAgent.stream('Hello!', {
onChunk: chunk => console.log(chunk),
onFinish: result => console.log('done', result),
})

const text = await output.text
cleanup()

보고:Promise<DurableAgentStreamResult>

resume(runId, resumeData, options?)
resumerunid-resumedata-options에 대한 직접 링크

예를 들어 Tool 승인 후 일시 중지된 실행을 재개합니다. 통과runId 를 원본 스트림 및 실행이 대기하던 데이터와 함께 사용합니다. 해당 실행의 레지스트리 항목이 없으면 오류가 발생합니다.

const { output, cleanup } = await durableAgent.resume(runId, {
approved: true,
})

await output.text
cleanup()

보고:Promise<DurableAgentStreamResult>

observe(runId, options?)
observerunid-options에 대한 직접 링크

기존 실행에 다시 연결하여 라이브 이벤트를 전달하기 전에 캐시된 이벤트를 재생합니다. 네트워크 연결이 끊어진 후 사용하세요. 통과하다offset to start replay from a known position.

const { output, cleanup } = await durableAgent.observe(runId, {
offset: 0,
onChunk: chunk => console.log(chunk),
})

await output.text

기본적으로observe() 는 이벤트를 무기한 기다립니다. 실행을 수행하는 프로세스가 예기치 않게 중지되면 실행은 이벤트 생성을 중지하지만 완료 이벤트를 내보내지 않으므로, 관찰 중인 스트림은 영원히 기다리게 됩니다. 다음을 전달하여 idleTimeoutMs 대기 시간을 제한하세요. 지정한 밀리초 동안 아무 이벤트도 없으면 스트림이 종료됩니다. 선택적 isAlive check is consulted first. Return true 는 실행이 계속 처리 중일 때(예: 장시간 실행되는 Tool 호출 또는 사람의 입력을 기다리며 일시 중지된 실행) 대기를 계속하도록 합니다. 다음을 반환하면 false, or omitting isAlive, 오류와 함께 스트림이 종료됩니다. 다음에서 일시적인 예외가 발생하면 isAlive "아직 실행 중"으로 처리되므로 일시적인 확인 실패로 인해 라이브 스트림이 종료되지 않습니다.

const { output } = await durableAgent.observe(runId, {
idleTimeoutMs: 30_000,
isAlive: () => runHeartbeat.isFresh(runId),
})

유휴 시간 초과 시 실행을 종료하면 오류가 발생한 실행과 동일한 정리가 실행되므로(아래 경고 참조) 캐시된 상태가 유지되지 않고 해제됩니다. 두 옵션 모두 선택 가능합니다. 이전의 무기한 대기 동작에 대해서는 이를 생략합니다.

보고:Promise<DurableAgentStreamResult>

경고

그만큼cleanup() returned by observe() 는 실행의 레지스트리 항목과 캐시된 이벤트를 삭제합니다. 해당 실행을 더 이상 사용하지 않을 때만 호출하세요. 실행이 일시 중지되어 있고 나중에 재개하려는 경우에는 cleanup()를 호출하지 마세요. 실행이 완료되거나 오류가 발생한 후 자동 정리 타이머가 처리하도록 두세요. 일시 중지 이벤트에서는 자동 정리가 실행되지 않습니다.

prepare(messages, options?)
preparemessages-options에 대한 직접 링크

시작하지 않고 지속 가능한 실행을 위해 실행을 준비합니다. 내부 레지스트리에 실행을 등록하고 직렬화된 Workflow 입력을 반환합니다. Workflow가 트리거되는 시기와 방법을 제어해야 할 때 이 기능을 사용하세요.

const { runId, messageId, workflowInput, threadId, resourceId } = await durableAgent.prepare(
'Summarize the document',
{
memory: { threadId: 'thread-1', resourceId: 'user-1' },
},
)

보고:

interface PrepareResult {
runId: string
messageId: string
workflowInput: any
registryEntry: object
threadId?: string
resourceId?: string
}

회복
회복에 대한 직접 링크

recoverActiveRuns(options?)
recoveractiverunsoptions에 대한 직접 링크

Discovers 실행이 중단됨running 상태인 이 Agent의 실행을 찾아 마지막으로 유지된 스냅샷부터 다시 구동합니다. 최대 options.limit 개의 실행을 복구합니다(기본값: 100). 복구된 항목의 요약을 반환합니다.

const result = await durableAgent.recoverActiveRuns()
// { recovered: [{ runId, status }], succeeded: 2, failed: 0 }

통과runId to recover a single known run:

await durableAgent.recoverActiveRuns({ runId: 'run-abc-123' })

보고:

interface DurableAgentRecoverActiveRunsResult {
recovered: Array<{ runId: string; status: 'success' | 'failed'; error?: Error }>
succeeded: number
failed: number
}

options.runId?:

string
Recover a specific run by ID. When set, discovery filters are ignored.

options.limit?:

number
Maximum number of active runs to discover. Defaults to 100.

options.createdBefore?:

Date
Only recover runs created before this date.

recover(runId, options?)
recoverrunid-options에 대한 직접 링크

ID별로 단일 실행을 복구합니다. 다음과 같은 모양으로 스트리밍 가능한 결과를 반환합니다.stream(). 복구 스트림을 실시간으로 관찰해야 할 때 사용하세요.

const { output, cleanup } = await durableAgent.recover('run-abc-123', {
onChunk: chunk => console.log(chunk),
onError: ({ error }) => console.error(error),
})

await output.text
cleanup()

보고:Promise<DurableAgentStreamResult>

스트림 옵션
스트림 옵션에 대한 직접 링크

stream()받아들인다DurableAgentStreamOptions 객체입니다. 아래의 Agent 실행 옵션과 수명 주기 콜백을 지원합니다.

runId?:

string
Unique identifier for this run. Use it later with resume() or observe().

instructions?:

AgentExecutionOptions['instructions']
Overrides the agent's default instructions for this run. Accepts a static string or the same dynamic instructions value the agent supports.

context?:

ModelMessage[]
Additional context messages to provide to the agent.

memory?:

object
Memory configuration for conversation persistence and retrieval.

requestContext?:

RequestContext
Request context carrying dynamic configuration and state for this run.

maxSteps?:

number
Maximum number of steps to run for this stream.

toolsets?:

object
Additional tool sets available for this run.

clientTools?:

object
Client-side tools available during execution.

toolChoice?:

'auto' | 'none' | 'required' | { type: 'tool'; toolName: string }
Tool selection strategy.

activeTools?:

string[]
Restricts execution to the named subset of the agent's tools.

modelSettings?:

object
Model-specific settings such as temperature. Credential-bearing headers (Authorization, X-Api-Key, and similar) are stripped from the serialized snapshot before it crosses process boundaries.

stopWhen?:

AgentExecutionOptions['stopWhen']
Predicate or composition that ends the agentic loop early. The closure rides on the in-process run registry; cross-process resumes degrade to maxSteps only.

system?:

string | string[]
Additional system message appended after the agent instructions and before user messages.

requireToolApproval?:

boolean | ((args: { toolName: string; args: unknown; requestContext: RequestContext; workspace?: string }) => boolean | Promise<boolean>)
Require approval for tool calls. Pass true or false to gate all or none, or a function for per-call policy. Function-form policies live on the in-process run registry; cross-process resumes fall back to a true shadow.

autoResumeSuspendedTools?:

boolean
Automatically resume tools that suspended, instead of waiting for an external resume() call.

toolCallConcurrency?:

number
Maximum number of tool calls to execute concurrently.

includeRawChunks?:

boolean
Include raw provider chunks in the stream output.

maxProcessorRetries?:

number
Maximum number of processor retries per generation.

structuredOutput?:

object
Structured output configuration.

untilIdle?:

boolean | { maxIdleMs?: number }
When set, keeps the stream open across background-task continuations until the agent is idle. Pass true for the default 5-minute idle timeout, or { maxIdleMs } to customise. Equivalent to the deprecated streamUntilIdle() method. Also supported on resume().

disableBackgroundTasks?:

boolean
Disable background-task dispatch for this run. Background-eligible tools execute inline instead.

tracingOptions?:

AgentExecutionOptions['tracingOptions']
Tracing metadata, tags, trace ID, parent span ID, and requestContextKeys forwarded to the agent and model spans. Fully JSON-serializable.

actor?:

AgentExecutionOptions['actor']
Per-call actor signal forwarded to FGA checks and tool execution.

transform?:

AgentExecutionOptions['transform']
Per-invocation tool payload transform policy. The transformToolPayload closure lives on the in-process run registry; only the JSON-safe targets shadow is serialized.

prepareStep?:

AgentExecutionOptions['prepareStep']
Per-step preparation hook invoked as a PrepareStepProcessor at the start of every iteration. Closure-only — stored on the in-process run registry. Cross-process resumes lose the hook.

isTaskComplete?:

AgentExecutionOptions['isTaskComplete']
Per-call completion policy. Scorer instances and onComplete live on the in-process run registry; the JSON-safe primitives (strategy, timeout, parallel, suppressFeedback, scorerNames) are serialized for cross-process observability.

delegation?:

AgentExecutionOptions['delegation']
Sub-agent delegation hooks (onDelegationStart, onDelegationComplete, messageFilter). Callbacks are baked into the sub-agent tool wrappers at prepare time. Cross-process resumes lose the callbacks.

versions?:

object
Version overrides for sub-agent delegation.

abortSignal?:

AbortSignal
External abort signal. Forwarded to the durable run's internal AbortController, so either source can cancel the run. Cross-process resumes cannot recover the signal — pass a fresh one to resume() if you need post-resume abortability.

onChunk?:

(chunk: ChunkType) => void | Promise<void>
Called for each streamed chunk.

onStepFinish?:

(result: AgentStepFinishEventData) => void | Promise<void>
Called when a step in the agentic loop finishes.

onFinish?:

(result: AgentFinishEventData) => void | Promise<void>
Called when the run finishes.

onError?:

(error: Error) => void | Promise<void>
Called when the run errors.

onSuspended?:

(data: AgentSuspendedEventData) => void | Promise<void>
Called when the run suspends, for example for tool approval.

onAbort?:

AgentExecutionOptions['onAbort']
Called when the run is aborted via abortSignal or result.abort().

onIterationComplete?:

AgentExecutionOptions['onIterationComplete']
Called after every agentic-loop iteration with the latest messageList, finishReason, and isFinal flag. Observation-only on durable agents: returning continue: false or feedback does not influence the loop.

resume()그리고observe() accept the same lifecycle callbacks (onChunk, onStepFinish, onFinish, onError, onSuspended). observe() also accepts an offset to control where replay starts.

내구성 있는 Agent스트림 결과
내구성 있는 Agent스트림 결과에 대한 직접 링크

반환된 객체stream(), resume(), observe(), and recover().

interface DurableAgentStreamResult<OUTPUT = undefined> {
output: MastraModelOutput<OUTPUT>
readonly fullStream: ReadableStream<any>
runId: string
threadId?: string
resourceId?: string
cleanup: () => void
abort: () => void
}

output:

MastraModelOutput
The streaming output. Await output.text for the full text, or consume output.fullStream.

fullStream:

ReadableStream
The full event stream, delegating to output.fullStream.

runId:

string
The unique run ID. Pass it to resume() or observe() to reconnect.

threadId?:

string
Thread ID when using memory.

resourceId?:

string
Resource ID when using memory.

cleanup:

() => void
Unsubscribes from PubSub and clears registry entries for the run. Call it when done with the run.

abort:

() => void
Aborts the run by flipping the internal AbortController. Surfaces as an AbortError inside the durable LLM-execution step and fires the onAbort callback. Safe to call after the run has finished — a no-op in that case.