跳至主要內容

Subagents

新增於: @mastra/core@1.8.0

Subagent 是可由另一個 Agent 委派任務的專門 Agent。將它們加入父 Agent 的 agents 屬性,然後呼叫 Agent.stream()Agent.generate()。父 Agent 會根據自身的 instructions 與各 Subagent 的 description,決定何時及如何委派任務。

何時使用 Subagent
「何時使用 Subagent」的直接連結

當任務需要不同專長的 Agent 協同作業時,請使用 Subagent。父 Agent 會決定何時委派,並將 context 傳給各 Subagent,之後再整合它們的結果。

常見使用案例:

  • 由一個 Agent 蒐集資料、另一個 Agent 產出內容的研究與寫作 Workflow
  • 每個階段需要不同專業知識的多步驟任務
  • 需要精細控制委派行為的任務
備註

協調 Subagent 的父 Agent 通常稱為 supervisor。Supervisor pattern 是在 Mastra 中建置多 Agent 系統的一種方法。若要瞭解其他 pattern,請閱讀概念概觀

快速入門
「快速入門」的直接連結

為 Subagent 定義清楚的 description,然後將它們加入父 Agent:

src/mastra/agents/parent-agent.ts
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
import { LibSQLStore } from '@mastra/libsql'

const researchAgent = new Agent({
id: 'research-agent',
description: 'Gathers factual information and returns bullet-point summaries.',
model: 'openai/gpt-5-mini',
})

const writingAgent = new Agent({
id: 'writing-agent',
description: 'Transforms research into well-structured articles.',
model: 'openai/gpt-5-mini',
})

const parentAgent = new Agent({
id: 'parent-agent',
instructions: `You coordinate research and writing using specialized agents.
Delegate to research-agent for facts, then writing-agent for content.`,
model: 'openai/gpt-5.6-sol',
agents: { researchAgent, writingAgent },
memory: new Memory({
storage: new LibSQLStore({ id: 'storage', url: 'file:mastra.db' }),
}),
})

const stream = await parentAgent.stream('Research AI in education and write an article', {
maxSteps: 10,
})

for await (const chunk of stream.textStream) {
process.stdout.write(chunk)
}

委派 hook
「委派 hook」的直接連結

委派 hook 可讓你在委派發生時攔截、修改或拒絕委派。請在 delegation 選項下設定,可放在 Agent 的 defaultOptions 中,也可針對個別呼叫設定。

onDelegationStart
「ondelegationstart」的直接連結

在父 Agent 委派給 Subagent 前呼叫。傳回物件即可控制委派:

  • proceed: true:允許委派(預設行為)
  • proceed: false:透過 rejectionReason 拒絕委派
  • modifiedPrompt:重寫傳送給 Subagent 的 prompt
  • modifiedMaxSteps:限制 Subagent 的 iteration 次數
src/mastra/agents/parent-agent.ts
const stream = await parentAgent.stream('Research AI trends', {
maxSteps: 10,
delegation: {
onDelegationStart: async context => {
console.log(`Delegating to: ${context.primitiveId}`)

// Modify the prompt for a specific agent
if (context.primitiveId === 'research-agent') {
return {
proceed: true,
modifiedPrompt: `${context.prompt}\n\nFocus on 2024-2025 data.`,
modifiedMaxSteps: 5,
}
}

// Reject delegation after too many iterations
if (context.iteration > 8) {
return {
proceed: false,
rejectionReason: 'Max iterations reached. Synthesize current findings.',
}
}

return { proceed: true }
},
},
})

context 物件包含:

屬性說明
primitiveId接受委派的 Subagent ID
prompt父 Agent 傳送的 prompt
iteration目前的 iteration 編號
requestContextSubagent 執行時會收到的 request context

委派邊界的 request context
「委派邊界的 request context」的直接連結

每次委派都會收到 request context,其中的項目是從父層執行作業淺層複製而來,但不包含執行作業範圍的身分識別 key。在 Subagent 執行期間設定或刪除項目,不會影響父 Agent 的 context。若要將值傳給被委派的執行作業,請在 onDelegationStart 中對 context.requestContext 設定項目:

src/mastra/agents/parent-agent.ts
const stream = await parentAgent.stream('Research AI trends', {
maxSteps: 10,
delegation: {
onDelegationStart: async context => {
context.requestContext.set('audience', 'technical')
},
},
})

Subagent 會在其 Tool 與動態設定(例如 instructions: ({ requestContext }) => ...)中讀取這些項目。詳情請參閱 Request Context。若要搭配 durable Agent 使用,值必須可序列化為 JSON。

onDelegationComplete
「ondelegationcomplete」的直接連結

委派完成後呼叫。可用於檢查結果、提供 feedback,或停止執行:

  • context.bail():立即停止父 Agent 的迴圈
  • 傳回 { feedback: '...' }:加入 feedback;它會儲存至父 Agent 的 memory,且後續 iteration 均可看見
src/mastra/agents/parent-agent.ts
const stream = await parentAgent.stream('Research AI trends', {
maxSteps: 10,
delegation: {
onDelegationComplete: async context => {
console.log(`Completed: ${context.primitiveId}`)

// Bail on errors
if (context.error) {
context.bail()
return {
feedback: `Delegation to ${context.primitiveId} failed: ${context.error}. Try a different approach.`,
}
}
},
},
})

context 物件包含:

屬性說明
primitiveId已執行的 Subagent ID
resultSubagent 的回覆
error委派失敗時的錯誤
bail()停止父 Agent 迴圈的函式

訊息篩選
「訊息篩選」的直接連結

預設情況下,Subagent 會從父 Agent 接收完整的對話 context。使用 messageFilter 可控制要分享哪些訊息,例如移除敏感資料或限制 context 大小。

src/mastra/agents/parent-agent.ts
const stream = await parentAgent.stream('Research AI trends', {
maxSteps: 10,
delegation: {
messageFilter: ({ messages, primitiveId, prompt }) => {
// Remove messages containing sensitive data
return messages
.filter(msg => {
const content =
typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)
return !content.includes('confidential')
})
.slice(-10) // Only pass the last 10 messages
},
},
})

Callback 會收到 messages(完整對話記錄)、primitiveId(Subagent ID)與 prompt(委派 prompt)。請傳回篩選後的訊息陣列。

Subagent 結果 context
「Subagent 結果 context」的直接連結

Subagent 完成後,父 Agent 的 model 會在後續 iteration 中收到 Subagent 的文字回覆。巢狀 Tool 呼叫與 Subagent metadata(例如 thread ID 與 resource ID)不會加入父 Agent 的 model context。

應用程式程式碼與 UI 整合仍可在 Tool 結果 payload 中檢查 subAgentToolResults,以及原始委派結果的其餘內容。

如此可保留除錯與顯示資料,又不會將巢狀 Tool argument 或 output 傳回父 Agent 的下一次 model 呼叫。

includeSubAgentToolResultsInModelContext 設為啟用,即可在父 Agent 的 model context 中包含完整的 Subagent 結果,包括巢狀 Tool 結果與 Subagent metadata。

src/mastra/agents/parent-agent.ts
await parentAgent.generate('Research AI trends', {
delegation: {
includeSubAgentToolResultsInModelContext: true,
},
})

Iteration 監控
「Iteration 監控」的直接連結

父 Agent 每完成一次迴圈 iteration,就會呼叫 onIterationComplete。可用它監控執行作業或引導下一次 iteration,也可以提早停止執行。

src/mastra/agents/parent-agent.ts
const stream = await parentAgent.stream('Research AI trends', {
maxSteps: 10,
onIterationComplete: async context => {
console.log(`Iteration ${context.iteration}/${context.maxIterations}`)
console.log(`Finish reason: ${context.finishReason}`)

// Inject feedback to guide the agent
if (!context.text.includes('recommendations')) {
return {
continue: true,
feedback: 'Please include specific recommendations in your analysis.',
}
}

// Stop early when the response is sufficient
if (context.text.length > 1000 && context.finishReason === 'stop') {
return { continue: false }
}

return { continue: true }
},
})

傳回 { continue: true } 可繼續 iteration;傳回 { continue: false } 則會停止。也可加入選用的 feedback,將引導內容注入對話。當 feedbackcontinue: false 搭配使用時,model 可能會獲得最後一次回合,以產生整合 feedback 的文字回覆,但前提是目前的 iteration 仍在進行中(例如 Tool 呼叫後);否則不會提供額外回合。

Memory 隔離
「Memory 隔離」的直接連結

Mastra 會在委派期間隔離 Subagent memory。Subagent 會收到完整的對話 context,以便做出更好的決策,但只有其特定的委派 prompt 與回覆會儲存至 memory。

運作方式:

  1. 轉送完整 context:父 Agent 委派時,Subagent 會收到父 Agent 對話中的所有訊息
  2. 限定範圍的 memory 儲存:只有委派 prompt 與 Subagent 回覆會儲存至 Subagent memory
  3. 每次叫用使用全新 thread:每次委派都使用不重複的 thread ID,確保彼此完全分離

因此,Subagent 能取得所需的 context,又不會讓父 Agent 的完整對話塞滿自身 memory。詳情請參閱多 Agent 系統中的 memory

Tool 核准傳遞
「Tool 核准傳遞」的直接連結

Tool 核准會沿著委派鏈傳遞。當 Subagent 使用設有 requireApproval: true 的 Tool 或呼叫 suspend() 時,核准請求會出現在父 Agent 的 stream 中。

const sensitiveDataTool = createTool({
id: 'get-user-data',
requireApproval: true,
execute: async input => {
return await database.getUserData(input.userId)
},
})

const dataAgent = new Agent({
id: 'data-agent',
tools: { sensitiveDataTool },
})

const parentAgent = new Agent({
id: 'parent-agent',
agents: { dataAgent },
memory: new Memory(),
})

const stream = await parentAgent.stream('Get data for user 123')

for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-approval') {
console.log('Tool requires approval:', chunk.payload.toolName)
}
}

取消
「取消」的直接連結

abortSignal 傳給父 Agent 的 stream()generate() 呼叫時,Mastra 會將同一個 signal 轉送給被委派的 Subagent。呼叫 AbortController.abort() 會在進行中的 Subagent 執行作業抵達下一個步驟時取消作業,而不會讓它們執行至完成。

const controller = new AbortController()

const stream = await parentAgent.stream('Research AI trends', {
abortSignal: controller.signal,
})

// Cancel the parent agent and any in-flight subagents
controller.abort()

任務完成度評分
「任務完成度評分」的直接連結

Agent 不一定能在第一次嘗試時產生完整、正確的 output。任務完成度 scorer 可在每次 iteration 後驗證任務是否完成。若驗證失敗,父 Agent 會繼續 iteration。失敗 scorer 的 feedback 會包含在對話 context 中,讓 Subagent 知道缺少哪些內容。

import { createScorer } from '@mastra/core/evals'

const taskCompleteScorer = createScorer({
id: 'task-complete',
name: 'Task Completeness',
}).generateScore(async context => {
const text = (context.run.output || '').toString()
const hasAnalysis = text.includes('analysis')
const hasRecommendations = text.includes('recommendation')
return hasAnalysis && hasRecommendations ? 1 : 0
})

const stream = await parentAgent.stream('Research AI in education', {
maxSteps: 10,
isTaskComplete: {
scorers: [taskCompleteScorer],
strategy: 'all',
onComplete: async result => {
console.log('Task complete:', result.complete)
},
},
})

Rubric scorer
「Rubric scorer」的直接連結

內建的 rubric scorer 可讓你以 checklist 定義何謂「正確」,並讓 Agent 自我評估、持續 iteration,直到符合每項 criterion 或達到 maxSteps 為止。

它以 LLM-as-judge scorer 的形式運作。每次 iteration 後,都會由另一個 grader model 對照 rubric 檢查 Agent output。當所有必要 criterion 都通過時,迴圈便會結束。失敗的 criterion 會將 feedback 加入對話,讓 Agent 再次嘗試。

這最適合成功 criterion 明確且可驗證的任務。使用方式如下:

src/mastra/agents/rubric-scorer.ts
import { Agent } from '@mastra/core/agent'
import { createRubricScorer } from '@mastra/evals/scorers/prebuilt'

const parentAgent = new Agent({
id: 'parent-agent',
instructions: 'You coordinate research and writing using specialized agents.',
model: 'openai/gpt-5.6-sol',
agents: { researchAgent, writingAgent },
})

const rubricScorer = createRubricScorer({
model: 'openai/gpt-5-mini',
criteria: [
{ description: 'The response includes an analysis section' },
{ description: 'The response includes concrete recommendations' },
],
})

const stream = await parentAgent.stream('Research AI in education', {
maxSteps: 10,
isTaskComplete: {
scorers: [rubricScorer],
strategy: 'all',
},
})

完整 API 詳情請參閱 rubric scorer 參考資料

撰寫有效的 instructions
「撰寫有效的 instructions」的直接連結

清楚的 instructions 是有效委派的必要條件。

父 Agent 的 instructions 應指定可用的 resource,以及何時使用各項 resource。也應定義協調行為與成功 criterion。

每個 Subagent 都應有清楚的 description,說明其用途與回傳格式,包括父 Agent 應於何時使用它。

父 Agent 會根據這些 description 做出委派決策。

const parentAgent = new Agent({
id: 'parent-agent',
instructions: `You coordinate research and writing tasks.

Available resources:
- researchAgent: Gathers factual data and sources (returns bullet points)
- writingAgent: Transforms research into narrative content (returns full paragraphs)

Delegation strategy:
1. For research requests: Delegate to researchAgent first
2. For writing requests: Delegate to writingAgent
3. For complex requests: Delegate to researchAgent first, then writingAgent

Success criteria:
- All user questions are fully answered
- Response is well-formatted and complete`,
agents: { researchAgent, writingAgent },
})

在背景執行 Subagent
「在背景執行 Subagent」的直接連結

Subagent 呼叫會以 Tool 呼叫的形式分派,因此可作為背景任務執行。當一或多個委派需要長時間執行,而且不希望它們阻擋父 Agent 的回覆時,這項功能相當實用。

在 Mastra instance 上啟用 backgroundTasks manager,然後在父 Agent 上選擇啟用 Subagent:

src/mastra/agents/parent-agent.ts
const parentAgent = new Agent({
id: 'parent-agent',
instructions: 'Coordinate research and writing using the available agents.',
model: 'openai/gpt-5.6-sol',
agents: { researchAgent, writingAgent },
backgroundTasks: {
tools: {
researchAgent: { enabled: true, timeoutMs: 900_000 },
writingAgent: { enabled: true, timeoutMs: 900_000 },
},
},
})

const stream = await parentAgent.streamUntilIdle('Research AI in education and write an article', {
memory: { thread: 't1', resource: 'u1' },
})

請使用 streamUntilIdle() 而非 stream(),讓 stream 維持開啟,直到 Subagent 完成,且父 Agent 有機會回覆其結果為止。

如果某個 Subagent 未列在父 Agent 的 backgroundTasks.tools 下,但擁有自己符合背景執行資格的 Tool,父 Agent 仍會將該 Subagent 當成背景任務分派,並繼承其設定。詳情請參閱繼承自 Subagent

Subagent 版本控制
「Subagent 版本控制」的直接連結

使用 editor 時,可控制父 Agent 在 runtime 使用各 Subagent 的哪個已儲存版本。請在 Mastra instance 上或每次呼叫時設定版本 override:

const result = await parentAgent.generate('Research and write about AI safety', {
versions: {
agents: {
'research-agent': { status: 'published' },
'writing-agent': { versionId: 'draft-456' },
},
},
})

版本 override 會自動沿著委派傳遞。若要瞭解解析順序與 server API 使用方式,請參閱 Subagent 版本控制