> Discover all available pages from the documentation index: https://mastra.zisheng.pro/zh-HK/llms.txt # Subagent **新增於:** `@mastra/core@1.8.0` Subagent 是專門處理特定工作的 Agent,另一個 Agent 可將任務委派給它們。將它們加入父 Agent 的 `agents` 屬性,然後呼叫 [`Agent.stream()`](https://mastra.zisheng.pro/zh-HK/reference/streaming/agents/stream) 或 [`Agent.generate()`](https://mastra.zisheng.pro/zh-HK/reference/agents/generate)。父 Agent 會根據其 instructions 及每個 Subagent 的 `description`,決定何時及如何委派任務。 ## 何時使用 Subagent 當任務需要具備不同專長的 Agent 協作時,可使用 Subagent。父 Agent 會決定何時委派,並將上下文傳遞給每個 Subagent,然後整合它們的結果。 常見使用情境包括: - 由一個 Agent 收集資料、另一個 Agent 製作內容的研究及寫作 Workflow - 每個階段需要不同專業知識的多步驟任務 - 需要精細控制委派行為的任務 > **備註:** 協調 Subagent 的父 Agent 通常稱為 supervisor。Supervisor 模式是在 Mastra 建立多 Agent 系統的其中一種方式。如要了解其他模式,請閱讀[概念概覽](https://mastra.zisheng.pro/zh-HK/guides/concepts/multi-agent-systems)。 ## 快速開始 為 Subagent 定義清晰的描述,然後將它們加入父 Agent: ```typescript 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 讓你在委派發生時攔截、修改或拒絕委派。可在 Agent 的 `defaultOptions` 或每次呼叫的 `delegation` 選項下設定。 ### `onDelegationStart` 在父 Agent 將任務委派給 Subagent 前呼叫。傳回物件以控制委派: - `proceed: true`:允許委派(預設行為) - `proceed: false`:以 `rejectionReason` 拒絕委派 - `modifiedPrompt`:重寫傳送給 Subagent 的提示 - `modifiedMaxSteps`:限制 Subagent 的迭代次數 ```typescript 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` | 目前的迭代次數 | | `requestContext` | Subagent 執行時將會收到的請求上下文 | ### 委派邊界的請求上下文 每次委派都會收到一個請求上下文,其項目是從父 Agent 執行的上下文淺層複製而來,但不包括執行範圍內的身份識別 key。在 Subagent 執行期間設定或刪除項目,不會影響父 Agent 的上下文。可在 `onDelegationStart` 中於 `context.requestContext` 設定項目,將值傳遞給獲委派的執行: ```typescript const stream = await parentAgent.stream('Research AI trends', { maxSteps: 10, delegation: { onDelegationStart: async context => { context.requestContext.set('audience', 'technical') }, }, }) ``` Subagent 會在其 Tool 及動態設定中讀取這些項目,例如 `instructions: ({ requestContext }) => ...`。詳情請參閱[請求上下文](https://mastra.zisheng.pro/zh-HK/docs/server/request-context)。如要配合 durable Agent 使用,值必須可序列化為 JSON。 ### `onDelegationComplete` 在委派完成後呼叫。可用它檢查結果、提供回饋,或停止執行: - `context.bail()`:立即停止父 Agent 的循環 - 傳回 `{ feedback: '...' }`:加入回饋;回饋會儲存至父 Agent 的記憶,並可供之後的迭代查看 ```typescript 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 收到完整的對話上下文。使用 `messageFilter` 控制分享哪些訊息,例如移除敏感資料或限制上下文大小。 ```typescript 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 完成後,父 Agent 的模型會在之後的迭代中收到 Subagent 的文字回應。巢狀 Tool 呼叫及 Subagent metadata(例如 thread 和 resource ID)不會加入父 Agent 的模型上下文。 應用程式程式碼及 UI 整合仍可檢查 Tool 結果 payload 中的 `subAgentToolResults`,以及原始委派結果的其餘部分。 這樣既可保留除錯及顯示資料,又不會將巢狀 Tool 的引數或輸出傳回父 Agent 的下一次模型呼叫。 設定 `includeSubAgentToolResultsInModelContext`,即可在父 Agent 的模型上下文中加入完整的 Subagent 結果,包括巢狀 Tool 結果及 Subagent metadata。 ```typescript await parentAgent.generate('Research AI trends', { delegation: { includeSubAgentToolResultsInModelContext: true, }, }) ``` ## 迭代監察 父 Agent 每次循環迭代後都會呼叫 `onIterationComplete`。可用它監察執行或引導下一次迭代,亦可提早停止執行。 ```typescript 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`,將指引注入對話。當 `feedback` 與 `continue: false` 一併使用時,模型可能會獲得最後一次 turn,以產生包含該回饋的文字回應;但只有目前的迭代仍在進行時(例如 Tool 呼叫後)才會如此,否則不會提供額外 turn。 ## 記憶隔離 Mastra 會在委派期間隔離 Subagent 的記憶。Subagent 會收到完整的對話上下文,以便作出更佳決策,但只有其特定的委派提示及回應會儲存至其記憶。 運作方式: 1. **轉發完整上下文**:父 Agent 委派時,Subagent 會收到父 Agent 對話中的所有訊息 2. **限定範圍的記憶儲存**:只有委派提示及 Subagent 的回應會儲存至 Subagent 的記憶 3. **每次呼叫使用全新 thread**:每次委派都使用獨有的 thread ID,確保互相清楚分隔 因此,Subagent 可取得所需的上下文,而不會將父 Agent 的整段對話塞滿其記憶。詳情請參閱[多 Agent 系統中的記憶](https://mastra.zisheng.pro/zh-HK/docs/memory/overview)。 ## Tool 核准傳遞 Tool 核准會沿委派鏈傳遞。當 Subagent 使用設有 `requireApproval: true` 的 Tool 或呼叫 `suspend()` 時,核准請求會顯示於父 Agent 的 stream 中。 ```typescript 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()`](https://mastra.zisheng.pro/zh-HK/reference/streaming/agents/stream) 或 [`generate()`](https://mastra.zisheng.pro/zh-HK/reference/agents/generate) 呼叫時,Mastra 會將同一個 signal 轉發給獲委派任務的 Subagent。呼叫 `AbortController.abort()` 會在進行中的 Subagent 執行到下一步時取消它們,而非讓它們執行至完成。 ```typescript 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 得知遺漏了甚麼。 ```typescript 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 讓你以 checklist 定義「正確」的標準,並讓 Agent 自行評估及迭代,直至符合所有準則或達到 `maxSteps`。 它以 **LLM-as-judge** scorer 的方式運作。每次迭代後,另一個 grader 模型會按照 rubric 審查 Agent 的輸出。當所有必要準則都通過時,循環便會結束。未通過的準則會將回饋加入對話,讓 Agent 再次嘗試。 這最適合具有清晰、可驗證成功準則的任務。用法如下: ```typescript 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 參考資料](https://mastra.zisheng.pro/zh-HK/reference/evals/rubric)。 ## 撰寫有效的 instructions 清晰的 instructions 是有效委派的關鍵。 父 Agent 的 `instructions` 應指明可用資源及何時使用各項資源,亦應定義協調行為及成功準則。 每個 Subagent 都應有清晰的 `description`,說明其用途及傳回格式,包括父 Agent 應在何時使用它。 父 Agent 會使用這些描述作出委派決定。 ```typescript 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 呼叫會以 Tool 呼叫形式分派,因此可作為[背景任務](https://mastra.zisheng.pro/zh-HK/docs/long-running-agents/background-tasks)執行。當一項或多項委派需長時間執行,而你不希望它們阻塞父 Agent 的回應時,這會很有用。 在 Mastra instance 啟用 [backgroundTasks manager](https://mastra.zisheng.pro/zh-HK/reference/configuration),然後在父 Agent 選擇啟用 Subagent: ```typescript 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()`](https://mastra.zisheng.pro/zh-HK/reference/streaming/agents/streamUntilIdle) 而非 `stream()`,令 stream 維持開啟,直至 Subagent 完成,而父 Agent 亦有機會回應其結果。 如果某個 Subagent 未列於父 Agent 的 `backgroundTasks.tools` 下,但擁有本身符合背景執行資格的 Tool,父 Agent 仍會將該 Subagent 分派為背景任務,並繼承其設定。詳情請參閱[從 Subagent 繼承](https://mastra.zisheng.pro/zh-HK/docs/long-running-agents/background-tasks)。 ## Subagent 版本控制 使用 [editor](https://mastra.zisheng.pro/zh-HK/docs/editor/overview) 時,你可控制父 Agent 在執行期間使用每個 Subagent 的哪一個已儲存版本。在 Mastra instance 或每次呼叫時設定版本覆寫: ```typescript const result = await parentAgent.generate('Research and write about AI safety', { versions: { agents: { 'research-agent': { status: 'published' }, 'writing-agent': { versionId: 'draft-456' }, }, }, }) ``` 版本覆寫會自動透過委派傳遞。關於解析次序及伺服器 API 使用方式的詳情,請參閱 [Subagent 版本控制](https://mastra.zisheng.pro/zh-HK/reference/editor/versioning)。 ## 相關內容 - [背景任務](https://mastra.zisheng.pro/zh-HK/docs/long-running-agents/background-tasks) - [Subagent 版本控制](https://mastra.zisheng.pro/zh-HK/reference/editor/versioning) - [指南:研究協調員](https://mastra.zisheng.pro/zh-HK/guides/guide/research-coordinator) - [Agent.stream() 參考資料](https://mastra.zisheng.pro/zh-HK/reference/streaming/agents/stream) - [Agent.streamUntilIdle() 參考資料](https://mastra.zisheng.pro/zh-HK/reference/streaming/agents/streamUntilIdle) - [Agent.generate() 參考資料](https://mastra.zisheng.pro/zh-HK/reference/agents/generate) - [Agent 核准](https://mastra.zisheng.pro/zh-HK/docs/agents/agent-approval) - [多 Agent 系統中的記憶](https://mastra.zisheng.pro/zh-HK/docs/memory/overview) - [概念:多 Agent 系統](https://mastra.zisheng.pro/zh-HK/guides/concepts/multi-agent-systems) - 📹 [Mastra supervisor Agent 工作坊](https://www.youtube.com/watch?v=FNb2fL9WhQg\&t=1872s)