실험 진행 중
추가된 항목: @mastra/core@1.4.0
실험은 대상(Agent, Workflow 또는 채점자)을 통해 데이터세트의 모든 항목을 실행한 다음 선택적으로 출력에 점수를 매깁니다. LLM 심사위원 자체를 평가하려면 채점자를 대상으로 사용하세요. 기본적으로 결과는 스토리지에 유지되므로 다양한 Prompt, Model 또는 코드 변경 사항에 걸쳐 실행을 비교할 수 있습니다.
기초실험기초실험에 대한 직접 링크
부르다startExperiment() with a target and scorers:
import { mastra } from '../index'
const dataset = await mastra.datasets.get({ id: 'translation-dataset-id' })
const summary = await dataset.startExperiment({
name: 'gpt-5.1-baseline',
targetType: 'agent',
targetId: 'translation-agent',
scorers: ['accuracy', 'fluency'],
})
console.log(summary.status) // 'completed' | 'failed'
console.log(summary.succeededCount) // number of items that ran successfully
console.log(summary.failedCount) // number of items that failed
startExperiment()모든 항목이 완료될 때까지 차단됩니다. 실행 후 잊어버리기(Fire-and-forget) 실행에 대해서는 다음을 참조하세요.async experiments.
사진관사진관에 대한 직접 링크
다음에서 실험을 실행할 수도 있습니다.Studio입니다. 데이터 세트 항목을 추가한 후 해당 항목을 열고 Run Experiment and configure the target, scorers, and options.
실험을 실행한 후,Experiments 탭에는 해당 데이터 세트의 모든 실행이 상태, 개수 및 타임스탬프와 함께 표시됩니다. 실험을 선택하면 항목별 결과, 점수 및 실행 Trace를 확인할 수 있습니다.
에서Experiments tab, select Compare 를 선택하고 둘 이상의 실험을 골라 점수와 결과를 나란히 비교합니다.
실험대상실험대상에 대한 직접 링크
등록된 Agent, Workflow 또는 채점자를 대상으로 실험을 지정할 수 있습니다.
등록된 대리점등록된 대리점에 대한 직접 링크
Mastra 인스턴스에 등록된 Agent를 가리킵니다.
const summary = await dataset.startExperiment({
name: 'agent-v2-eval',
targetType: 'agent',
targetId: 'translation-agent',
scorers: ['accuracy'],
})
각 항목의input is passed directly to agent.generate(), so it must be a string, string[], or CoreMessage[].
Memory 지원 AgentMemory 지원 Agent에 대한 직접 링크
대상 Agent에 자체 Memory가 있고 요청 컨텍스트에 리소스 ID(MASTRA_RESOURCE_ID_KEY인 경우, 인증 미들웨어에서 설정한 실험 또는 항목 requestContext, or the Studio Run Experiment 형식인 경우, 실험 실행기는 각 항목에 새로운 Memory 스레드를 주입합니다. 요청 컨텍스트의 리소스 ID는 "이 리소스로 실행"을 의미합니다. 각 항목의 대화는 해당 리소스 아래에 스레드로 유지되며, 재시도된 항목은 시도할 때마다 새 스레드를 사용하므로 이전에 실패한 시도의 내용이 재시도 컨텍스트에 유입되지 않습니다.
주입된 스레드에는 태그가 지정되어 실행에 다시 매핑할 수 있습니다. 스레드 메타데이터는experimentId and the dataset item's id as experimentItemId. No thread title is generated for them.
스레드는 호출자의 리소스에 속하므로 리소스 범위 Memory는 실행 중에 해당 리소스의 상태를 읽고 쓰는 기능을 모두 수행합니다.
- 리소스 범위 작업 Memory 업데이트는 리소스에 유지되며 실행의 이후 항목은 이전 항목의 업데이트를 참조합니다.
- 리소스 범위 의미론적 회상은 리소스의 이전 대화를 실험에 표면화할 수 있으며, 실험 기록은 해당 리소스의 이후 대화에서 회상 가능해집니다.
이는 실제 사용자의 누적된 컨텍스트에 대해 Agent를 평가하려는 경우에 유용합니다. 실제 사용자 상태를 다루는 실험 실행을 원하지 않으면 대신 전용 평가 리소스 ID를 사용하여 실험을 실행하세요.
다음과 같은 경우 스레드 주입을 건너뜁니다.
- 요청 컨텍스트도 설정되는 경우
MASTRA_THREAD_ID_KEY인 경우, 실행기는 해당 스레드를 그대로 사용하므로 모든 항목과 재시도가 동일한 대화를 공유합니다. - Agent에 Memory가 없거나 요청 컨텍스트에 리소스 ID가 없는 경우 실행은 Memory가 없으며 아무것도 지속되지 않습니다.
등록된 Workflow등록된 Workflow에 대한 직접 링크
Mastra 인스턴스에 등록된 Workflow를 가리킵니다.
const summary = await dataset.startExperiment({
name: 'workflow-eval',
targetType: 'workflow',
targetId: 'translation-workflow',
scorers: ['accuracy'],
})
Workflow는 각 항목의input as its trigger data.
등록된 득점자등록된 득점자에 대한 직접 링크
LLM 심사위원을 실제 사실과 비교하여 평가하려면 채점자를 지정하세요.
const summary = await dataset.startExperiment({
name: 'judge-accuracy-eval',
targetType: 'scorer',
targetId: 'accuracy',
})
득점원은 각 항목의input and groundTruth입니다. LLM 기반 평가자는 기반 Model이 변경됨에 따라 시간이 지나면서 편향될 수 있으므로, 검증된 레이블에 맞춰 주기적으로 재조정하는 것이 중요합니다. 데이터 세트는 이러한 편향을 감지할 수 있는 안정적인 벤치마크를 제공합니다.
채점 결과채점 결과에 대한 직접 링크
채점자는 각 항목의 목표 실행 후에 자동으로 실행됩니다. 합격 득점자 인스턴스 또는 등록된 득점자 ID:
- Scorer IDs
- Scorer instances
// Reference scorers registered on the Mastra instance
const summary = await dataset.startExperiment({
name: 'with-registered-scorers',
targetType: 'agent',
targetId: 'translation-agent',
scorers: ['accuracy', 'fluency'],
})
import { createAnswerRelevancyScorer } from '@mastra/evals/scorers/prebuilt'
const relevancy = createAnswerRelevancyScorer({ model: 'openai/gpt-5-mini' })
const summary = await dataset.startExperiment({
name: 'with-scorer-instances',
targetType: 'agent',
targetId: 'translation-agent',
scorers: [relevancy],
})
각 항목의 결과에는 득점자별 점수가 포함됩니다.
for (const item of summary.results) {
console.log(item.itemId, item.output)
for (const score of item.scores) {
console.log(` ${score.scorerName}: ${score.score} — ${score.reason}`)
}
}
방문Scorers overview for details on available and custom scorers.
실행당 제어 지속성실행당 제어 지속성에 대한 직접 링크
사용persistence 를 사용하여 특정 실행의 스토리지 쓰기를 건너뜁니다. 실험 레코드와 점수 레코드는 서로 독립적으로 비활성화할 수 있습니다:
const summary = await dataset.startExperiment({
targetType: 'agent',
targetId: 'translation-agent',
scorers: ['accuracy'],
persistence: {
experiments: 'none',
scores: 'none',
},
})
표적과 득점원은 여전히 달리고 있으며,startExperiment() 는 여전히 항목 결과와 점수를 summary에 반환합니다. 설정은 서로 독립적입니다. 예를 들어 scores: 'none' 만 설정하면 점수 레코드를 생성하지 않고 실험과 해당 항목 결과를 영구 저장할 수 있습니다.
생략된 설정의 기본값은 다음과 같습니다.'default'이며, 표준 스토리지 동작을 유지합니다. 이 정책은 실행에서 생성되는 실험 및 점수 레코드만 제어합니다. Agent Memory, 벡터, Observability 또는 사용자 정의 Tool 스토리지 등 대상이 사용하는 스토리지는 비활성화하지 않습니다.
언제startExperimentAsync() runs with experiments: 'none'인 경우, 실험 레코드, 진행 상황 업데이트 또는 항목 결과를 영구 저장하지 않습니다. 점수 영구 저장은 여전히 persistence.scores에서 별도로 제어합니다. 실험 이벤트 observer가 없으면 실행은 실행 후 관여하지 않는 방식으로 처리되며, 실험 API는 실행의 완료 또는 실패 여부를 보고할 수 없습니다.
동기 사용startExperiment() 는 호출자에게 반환된 요약이 필요할 때 사용합니다. 실험 이벤트 observer는 수명 주기 이벤트와 최종 요약을 수신할 수 있습니다.
실험 이벤트 관찰실험 이벤트 관찰에 대한 직접 링크
사용onEvent 를 사용하여 실험 실행 중 버전이 지정되고 JSON에 안전한 수명 주기 이벤트를 수신합니다. 이는 startExperiment(), startExperimentAsync(), and runExperiment().
import type { ExperimentEvent } from '@mastra/core/datasets'
const events: ExperimentEvent[] = []
await dataset.startExperimentAsync({
task: async ({ input }) => processItem(input),
persistence: { experiments: 'none' },
onEvent: async event => {
events.push(event)
await publishEvent(event)
},
})
관찰자는 다음과 같은 이벤트 유형을 수신합니다.
experiment.run.started: 실행, 대상, 해결된 데이터 세트 버전 및 항목 수를 식별합니다.experiment.item.completed: 점수, 오류, 재시도 횟수, Tool 모의 세부 정보 및 안정적인 항목 ID를 포함하여 채점 후 커밋된 항목 결과를 보고합니다.experiment.run.finished: 최종 결과 및 요약 카운터를 보고합니다.
Mastra는 다음 이벤트를 전달하기 전에 각 관찰자 호출을 기다립니다. 이 직렬화된 전달은 배압을 적용하고 이벤트를 보장합니다.sequence 값이 전달 순서와 일치하도록 하면서도 항목 실행은 동시에 처리할 수 있습니다.
관찰자가 던지거나 거부하면 Mastra는 남은 실행을 중단하고 거부합니다.runExperiment() with a MastraError whose id is EXPERIMENT_EVENT_OBSERVER_FAILED입니다. 실패한 observer를 통해 최종 이벤트를 전송하지 않습니다. startExperimentAsync()의 경우 분리된 observer가 실패할 때는 메서드가 이미 반환된 상태이므로, 호출자에게 직접 오류를 보고해야 한다면 observer 내부에서 전달 실패를 처리하세요.
그만큼experiment.run.finished 이벤트는 Mastra가 최종 실험 상태를 영구 저장하기 전에 완료될 때까지 대기합니다. 실험 영구 저장이 비활성화된 경우 이 이벤트를 신뢰할 수 있는 최종 신호로 취급하되, 스토리지의 쓰기 직후 읽기 신호로 사용하지 마세요.
내보낸 이벤트 유형은 다음과 같습니다.ExperimentEvent, ExperimentRunStartedEvent, ExperimentItemCompletedEvent, and ExperimentRunFinishedEvent. Use the discriminated type 필드를 사용하여 이벤트별 속성을 읽기 전에 이벤트 범위를 좁히세요.
Tool 모의Tool 모의에 대한 직접 링크
실험에서 부작용 Tool을 호출하는 Agent를 실행할 때 정적 Tool 모의를 개별 데이터 세트 항목에 연결하여 실행을 결정적으로 만듭니다. 실험 중에 모의 Tool은 실행되는 대신 선언된 출력을 반환합니다. 항목에 대한 모의가 없는 Tool은 기본적으로 실시간으로 실행됩니다.
모의 항목은 데이터 세트 항목에 있으므로 행 버전을 지정하고 테스트 사례와 함께 이동합니다. 각 모의는 Tool 이름, 예상되는 인수 및 반환할 출력을 선언합니다.
await dataset.addItem({
input: 'What is the weather in Seattle?',
toolMocks: [
{
toolName: 'getWeather',
args: { city: 'Seattle' },
output: { temperature: 60, conditions: 'rainy' },
},
],
})
Tool 모의가 지원됩니다.agent targets only.
선언되지 않은 Tool 차단선언되지 않은 Tool 차단에 대한 직접 링크
세트unmockedToolPolicy: 'deny' 를 실험에 설정하여 모의 응답이 없는 모든 Tool 호출을 차단합니다. 실제 호출이 부작용을 일으킬 수 있을 때 유용합니다:
const summary = await dataset.startExperiment({
targetType: 'agent',
targetId: 'weather-agent',
unmockedToolPolicy: 'deny',
})
기본 정책은 다음과 같습니다.'allow'입니다. 저장된 항목이나 인라인 항목별로 실험 정책을 재정의할 수 있습니다:
await dataset.addItem({
input: 'What is the weather in Seattle?',
unmockedToolPolicy: 'allow',
})
항목 값이 실험 값보다 우선합니다. 다음과 같은 거부된 통화가 실패합니다.TOOL_MOCK_NOT_DECLARED 는 Tool이 실행되기 전에 발생합니다. 실패는 재시도되거나 liveCalls.
매칭과 소비매칭과 소비에 대한 직접 링크
인수는 엄격하게 일치합니다. 객체 키 순서는 무시되고 배열 순서는 상당하며 유형 강제도 없습니다. 모의는 Agent가 모의와 완전히 동일한 인수를 사용하여 Tool을 호출하는 경우에만 제공됩니다.args.
항목이 동일한 Tool 및 인수에 대해 여러 모의 항목을 선언하면 순서대로 사용되며 첫 번째 호출은 첫 번째 모의 항목을 가져오고 다음 호출은 두 번째 모의 항목을 가져오는 식으로 진행됩니다. 주문은 다음과 같이 추적됩니다.(toolName, args) group and is independent across different arguments.
매칭 모드매칭 모드에 대한 직접 링크
기본적으로 각 모의 모형은 해당 항목과 엄격하게 일치합니다.args. Set matchArgs: 'ignore' to match on the tool name only, the mock's args 에 추가되지 않습니다. 인수는 비교하지 않으며, Agent가 Tool을 어떻게 호출했는지와 관계없이 해당 Tool에서 아직 사용되지 않은 다음 모의 응답이 제공됩니다:
const subAgentMock = {
toolName: 'agent-balanceAgent',
args: { prompt: 'look up the balance for YJ' },
output: { text: "YJ's balance is $100." },
matchArgs: 'ignore',
}
이는 Tool의 인수에 잡음이 많거나 Model에 의해 생성된 경우 유용합니다. 가장 일반적인 경우는 조롱입니다.sub-agent's response: 위임된 sub-agent는 상위 Agent에 agent-<name> tool, and its arguments include an LLM-authored prompt plus runtime-injected fields. Mocking agent-<name> 로 노출됩니다. sub-agent와 내부 Tool을 실행하는 대신 미리 준비된 응답을 반환합니다. Trace에서 모의 응답을 생성하면 sub-agent 위임 호출은 matchArgs: 'ignore' automatically. You can change it to 'strict' to pin the exact arguments.
실패실패에 대한 직접 링크
모의 구성을 위반하면 Tool 호출이 항목에 실패합니다.
TOOL_MOCK_MISMATCH: 모의 일치 항목이 없는 인수를 사용하여 Tool이 호출되었습니다.TOOL_MOCK_EXHAUSTED: 일치하는 모든 모의가 이미 소비되었습니다.TOOL_MOCK_NOT_DECLARED: Tool에는 모의가 없으며 효과적입니다.unmockedToolPolicyis'deny'.
이러한 오류가 발생하면 Agent 실행이 즉시 중단되므로 Model은 모의되지 않은 부작용 Tool을 포함하여 라이브로 실행될 추가 Tool을 계속해서 호출할 수 없습니다. 이러한 실패는 결정적이므로 재시도되지 않습니다. 선언되었으나 한 번도 사용되지 않은 모의품은 아이템 실패가 아니며, 소비되지 않은 것으로 보고됩니다.
모의 차단이 활성화된 동안 Agent의 Tool은 순차적으로 실행되므로 반복됩니다.(toolName, args) 를 사용하여 파생됩니다. 모의 응답은 Provider의 호출 순서대로 사용됩니다. 항목이 모의 응답을 선언하거나 유효한 unmockedToolPolicy is 'deny'.
진단진단에 대한 직접 링크
각 항목 결과에는toolMockReport 항목의 mocks를 사용해 실행에서 수행한 작업을 설명합니다:
for (const item of summary.results) {
const report = item.toolMockReport
if (!report) continue
console.log(report.served) // mocks matched and returned
console.log(report.unconsumed) // mocks declared but never used
console.log(report.liveCalls) // undeclared tools allowed to run live
console.log(report.failure) // the first deterministic mock failure, if any
}
~ 안에Studio, dataset 항목을 편집하여 Tool mocks를 JSON 배열로 작성하고 experiment 결과를 열어 동일한 보고서를 확인하세요.
제한사항제한사항에 대한 직접 링크
- 모의 통화를 위한 Tool 범위가 없습니다.모의 호출은 Tool이 실행되기 전에 출력을 반환하므로 Tool 범위를 생성하지 않습니다. 따라서 저장된 추적으로 뒷받침되는 궤적 채점자는 모의 Tool 호출을 볼 수 없습니다. Agent의 메시지 출력으로 대체되는 궤적 추출은 계속해서 이를 확인하므로 Observability 구성에 따라 궤적 점수가 달라질 수 있습니다.
- 스토리지 지원.도구 모의 및 Tool 모의 보고서는 LibSQL, PostgreSQL, MongoDB, Spanner 어댑터에 의해 유지됩니다. MySQL 어댑터는 이를 지원하지 않으며 Tool 모의 또는 Tool 모의 보고서를 전달하는 쓰기를 거부합니다. 모든 데이터 세트 스토리지 어댑터는 지속됩니다.
unmockedToolPolicy.
비동기 실험비동기 실험에 대한 직접 링크
startExperiment()모든 항목이 완료될 때까지 차단됩니다. 장기 실행 데이터세트의 경우 다음을 사용하세요.startExperimentAsync() to start the experiment in the background:
const { experimentId, status } = await dataset.startExperimentAsync({
name: 'large-dataset-run',
targetType: 'agent',
targetId: 'translation-agent',
scorers: ['accuracy'],
})
console.log(experimentId) // UUID
console.log(status) // 'pending'
다음을 사용하여 완료 여부를 폴링합니다.getExperiment():
let experiment = await dataset.getExperiment({ experimentId })
while (experiment.status === 'pending' || experiment.status === 'running') {
await new Promise(resolve => setTimeout(resolve, 5000))
experiment = await dataset.getExperiment({ experimentId })
}
console.log(experiment.status) // 'completed' | 'failed'
구성 옵션구성 옵션에 대한 직접 링크
동시성동시성에 대한 직접 링크
병렬로 실행되는 항목 수를 제어합니다(기본값: 5).
const summary = await dataset.startExperiment({
targetType: 'agent',
targetId: 'translation-agent',
maxConcurrency: 10,
})
시간 초과 및 재시도시간 초과 및 재시도에 대한 직접 링크
항목별 제한 시간(밀리초) 및 재시도 횟수를 설정합니다.
const summary = await dataset.startExperiment({
targetType: 'agent',
targetId: 'translation-agent',
itemTimeout: 30_000, // 30 seconds per item
maxRetries: 2, // retry failed items up to 2 times
})
재시도에는 지수 백오프가 사용됩니다. 중단 오류는 다시 시도되지 않습니다.
실험 중단실험 중단에 대한 직접 링크
통과AbortSignal to cancel a running experiment:
const controller = new AbortController()
// Cancel after 60 seconds
setTimeout(() => controller.abort(), 60_000)
const summary = await dataset.startExperiment({
targetType: 'agent',
targetId: 'translation-agent',
signal: controller.signal,
})
나머지 항목은 요약에서 건너뛴 것으로 표시됩니다.
데이터 세트 버전 고정데이터 세트 버전 고정에 대한 직접 링크
데이터세트의 특정 스냅샷에 대해 실행합니다.
const summary = await dataset.startExperiment({
targetType: 'agent',
targetId: 'translation-agent',
version: 3, // use items from dataset version 3
})
결과 보기결과 보기에 대한 직접 링크
실험 나열실험 나열에 대한 직접 링크
const { experiments, pagination } = await dataset.listExperiments({
page: 0,
perPage: 10,
})
for (const exp of experiments) {
console.log(`${exp.name} — ${exp.status} (${exp.succeededCount}/${exp.totalItems})`)
}
실험 세부정보실험 세부정보에 대한 직접 링크
const experiment = await dataset.getExperiment({
experimentId: 'exp-abc-123',
})
console.log(experiment.status)
console.log(experiment.startedAt)
console.log(experiment.completedAt)
:::tip[📹 보기]
보다Mastra datasets and experiments workflow datasets와 experiments가 안정성 향상에 어떻게 도움이 되는지 확인하세요.
:::
품목 수준 결과품목 수준 결과에 대한 직접 링크
const { results, pagination } = await dataset.listExperimentResults({
experimentId: 'exp-abc-123',
page: 0,
perPage: 50,
})
for (const result of results) {
console.log(result.itemId, result.output, result.error)
}
요약 이해요약 이해에 대한 직접 링크
startExperiment()반환합니다ExperimentSummary with counts and per-item results:
completedWithErrors~이다trueexperiment가 완료되었지만 일부 항목이 실패한 경우입니다.- 다음을 통해 취소된 상품
signalappear inskippedCount.
방문startExperiment reference 전체 매개변수 및 반환 타입 문서를 참조하세요.