跳至主要內容

Subagent

新增於: @mastra/core@1.8.0

Subagent 是專門處理特定工作的 Agent,另一個 Agent 可將任務委派給它們。將它們加入父 Agent 的 agents 屬性,然後呼叫 Agent.stream()Agent.generate()。父 Agent 會根據其 instructions 及每個 Subagent 的 description,決定何時及如何委派任務。

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

當任務需要具備不同專長的 Agent 協作時,可使用 Subagent。父 Agent 會決定何時委派,並將上下文傳遞給每個 Subagent,然後整合它們的結果。

常見使用情境包括:

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

協調 Subagent 的父 Agent 通常稱為 supervisor。Supervisor 模式是在 Mastra 建立多 Agent 系統的其中一種方式。如要了解其他模式,請閱讀概念概覽

快速開始
快速開始 的直接連結

為 Subagent 定義清晰的描述,然後將它們加入父 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 讓你在委派發生時攔截、修改或拒絕委派。可在 Agent 的 defaultOptions 或每次呼叫的 delegation 選項下設定。

onDelegationStart
ondelegationstart 的直接連結

在父 Agent 將任務委派給 Subagent 前呼叫。傳回物件以控制委派:

  • proceed: true:允許委派(預設行為)
  • proceed: false:以 rejectionReason 拒絕委派
  • modifiedPrompt:重寫傳送給 Subagent 的提示
  • modifiedMaxSteps:限制 Subagent 的迭代次數
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 正在傳送的提示
iteration目前的迭代次數
requestContextSubagent 執行時將會收到的請求上下文

委派邊界的請求上下文
委派邊界的請求上下文 的直接連結

每次委派都會收到一個請求上下文,其項目是從父 Agent 執行的上下文淺層複製而來,但不包括執行範圍內的身份識別 key。在 Subagent 執行期間設定或刪除項目,不會影響父 Agent 的上下文。可在 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 }) => ...。詳情請參閱請求上下文。如要配合 durable Agent 使用,值必須可序列化為 JSON。

onDelegationComplete
ondelegationcomplete 的直接連結

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

  • context.bail():立即停止父 Agent 的循環
  • 傳回 { feedback: '...' }:加入回饋;回饋會儲存至父 Agent 的記憶,並可供之後的迭代查看
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 收到完整的對話上下文。使用 messageFilter 控制分享哪些訊息,例如移除敏感資料或限制上下文大小。

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
},
},
})

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

Subagent 結果上下文
Subagent 結果上下文 的直接連結

Subagent 完成後,父 Agent 的模型會在之後的迭代中收到 Subagent 的文字回應。巢狀 Tool 呼叫及 Subagent metadata(例如 thread 和 resource ID)不會加入父 Agent 的模型上下文。

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

這樣既可保留除錯及顯示資料,又不會將巢狀 Tool 的引數或輸出傳回父 Agent 的下一次模型呼叫。

設定 includeSubAgentToolResultsInModelContext,即可在父 Agent 的模型上下文中加入完整的 Subagent 結果,包括巢狀 Tool 結果及 Subagent metadata。

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

迭代監察
迭代監察 的直接連結

父 Agent 每次循環迭代後都會呼叫 onIterationComplete。可用它監察執行或引導下一次迭代,亦可提早停止執行。

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 } 以繼續迭代,或傳回 { continue: false } 以停止。可加入選填的 feedback,將指引注入對話。當 feedbackcontinue: false 一併使用時,模型可能會獲得最後一次 turn,以產生包含該回饋的文字回應;但只有目前的迭代仍在進行時(例如 Tool 呼叫後)才會如此,否則不會提供額外 turn。

記憶隔離
記憶隔離 的直接連結

Mastra 會在委派期間隔離 Subagent 的記憶。Subagent 會收到完整的對話上下文,以便作出更佳決策,但只有其特定的委派提示及回應會儲存至其記憶。

運作方式:

  1. 轉發完整上下文:父 Agent 委派時,Subagent 會收到父 Agent 對話中的所有訊息
  2. 限定範圍的記憶儲存:只有委派提示及 Subagent 的回應會儲存至 Subagent 的記憶
  3. 每次呼叫使用全新 thread:每次委派都使用獨有的 thread ID,確保互相清楚分隔

因此,Subagent 可取得所需的上下文,而不會將父 Agent 的整段對話塞滿其記憶。詳情請參閱多 Agent 系統中的記憶

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 不一定能在第一次嘗試時產生完整而正確的輸出。任務完成 scorer 可在每次迭代後驗證任務是否完成。如果驗證失敗,父 Agent 會繼續迭代。失敗 scorer 的回饋會加入對話上下文,讓 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 自行評估及迭代,直至符合所有準則或達到 maxSteps

它以 LLM-as-judge scorer 的方式運作。每次迭代後,另一個 grader 模型會按照 rubric 審查 Agent 的輸出。當所有必要準則都通過時,循環便會結束。未通過的準則會將回饋加入對話,讓 Agent 再次嘗試。

這最適合具有清晰、可驗證成功準則的任務。用法如下:

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 應指明可用資源及何時使用各項資源,亦應定義協調行為及成功準則。

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

父 Agent 會使用這些描述作出委派決定。

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 在執行期間使用每個 Subagent 的哪一個已儲存版本。在 Mastra instance 或每次呼叫時設定版本覆寫:

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

版本覆寫會自動透過委派傳遞。關於解析次序及伺服器 API 使用方式的詳情,請參閱 Subagent 版本控制