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:
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 的 promptmodifiedMaxSteps:限制 Subagent 的 iteration 次數
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 編號 |
requestContext | Subagent 執行時會收到的 request context |
委派邊界的 request context「委派邊界的 request context」的直接連結
每次委派都會收到 request context,其中的項目是從父層執行作業淺層複製而來,但不包含執行作業範圍的身分識別 key。在 Subagent 執行期間設定或刪除項目,不會影響父 Agent 的 context。若要將值傳給被委派的執行作業,請在 onDelegationStart 中對 context.requestContext 設定項目:
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 均可看見
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 |
result | Subagent 的回覆 |
error | 委派失敗時的錯誤 |
bail() | 停止父 Agent 迴圈的函式 |
訊息篩選「訊息篩選」的直接連結
預設情況下,Subagent 會從父 Agent 接收完整的對話 context。使用 messageFilter 可控制要分享哪些訊息,例如移除敏感資料或限制 context 大小。
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。
await parentAgent.generate('Research AI trends', {
delegation: {
includeSubAgentToolResultsInModelContext: true,
},
})
Iteration 監控「Iteration 監控」的直接連結
父 Agent 每完成一次迴圈 iteration,就會呼叫 onIterationComplete。可用它監控執行作業或引導下一次 iteration,也可以提早停止執行。
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,將引導內容注入對話。當 feedback 與 continue: false 搭配使用時,model 可能會獲得最後一次回合,以產生整合 feedback 的文字回覆,但前提是目前的 iteration 仍在進行中(例如 Tool 呼叫後);否則不會提供額外回合。
Memory 隔離「Memory 隔離」的直接連結
Mastra 會在委派期間隔離 Subagent memory。Subagent 會收到完整的對話 context,以便做出更好的決策,但只有其特定的委派 prompt 與回覆會儲存至 memory。
運作方式:
- 轉送完整 context:父 Agent 委派時,Subagent 會收到父 Agent 對話中的所有訊息
- 限定範圍的 memory 儲存:只有委派 prompt 與 Subagent 回覆會儲存至 Subagent memory
- 每次叫用使用全新 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 明確且可驗證的任務。使用方式如下:
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:
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 版本控制。