使用監督 Agent 建立研究協調器
在本指南中,你會使用監督 Agent 建立研究協調器,以協調多個專門 Agent。協調器會將研究工作委派給研究 Agent,並將寫作工作委派給寫作 Agent,然後把結果整合成詳細報告。
你會設定角色清晰的子 Agent,並設定監督 Agent 來協調它們。你亦會使用委派 hook 控制執行,並使用評分器驗證工作是否完成。
先決條件先決條件 的直接連結
- 已安裝 Node.js
v22.13.0或更新版本 - 受支援 Model Provider 的 API 金鑰
- 現有的 Mastra 項目(按照安裝指南設定新項目)
建立研究 Agent建立研究 Agent 的直接連結
研究 Agent 專門收集任何主題的事實資料。它會以精簡項目符號摘要傳回重要事實及來源。
建立新檔案 src/mastra/agents/research-agent.ts:
import { Agent } from '@mastra/core/agent'
export const researchAgent = new Agent({
id: 'research-agent',
name: 'Research Specialist',
description:
'Specializes in gathering factual information and data on any topic. ' +
'Returns concise bullet-point summaries with key facts and sources. ' +
'Does not write full articles or narrative content.',
instructions:
'You are a research specialist. When given a topic, gather key facts, ' +
'statistics, and information. Present findings as clear bullet points. ' +
'Include sources when possible. Focus on accuracy and completeness.',
model: 'openai/gpt-5-mini',
})
description 欄位非常重要,它有助監督 Agent 判斷何時應委派給此 Agent。清晰的描述可提高委派準確度。
建立寫作 Agent建立寫作 Agent 的直接連結
寫作 Agent 會將研究資料轉化為結構良好、段落完整且行文流暢的文章。
建立新檔案 src/mastra/agents/writing-agent.ts:
import { Agent } from '@mastra/core/agent'
export const writingAgent = new Agent({
id: 'writing-agent',
name: 'Writing Specialist',
description:
'Transforms research material into well-structured written content. ' +
'Produces full paragraphs and complete articles with proper flow. ' +
'Best used after research has been gathered.',
instructions:
'You are a writing specialist. Transform research and information into ' +
'well-written articles. Use complete paragraphs, clear structure, and ' +
'engaging language. Maintain a professional yet accessible tone. ' +
'Ensure the content flows naturally from introduction to conclusion.',
model: 'openai/gpt-5-mini',
})
建立監督 Agent建立監督 Agent 的直接連結
監督 Agent 會協調研究及寫作工作。其指示會定義委派策略,包括何時使用各個子 Agent,以及如何整合結果。Memory 直接在 Agent 上設定。
建立新檔案 src/mastra/agents/supervisor-agent.ts:
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
import { LibSQLStore } from '@mastra/libsql'
import { researchAgent } from './research-agent'
import { writingAgent } from './writing-agent'
export const supervisorAgent = new Agent({
id: 'supervisor-agent',
name: 'Research Coordinator',
instructions: `You coordinate research and writing tasks using specialized agents.
Available resources:
- research-agent: Gathers factual data and sources (returns bullet points)
- writing-agent: Transforms research into well-structured articles (returns full paragraphs)
Delegation strategy:
1. For research requests: Delegate to research-agent first to gather facts
2. For writing requests: Delegate to writing-agent with any available research context
3. For comprehensive reports: Delegate to research-agent first, then writing-agent
4. Always ensure you have gathered sufficient information before producing final output
Success criteria:
- All aspects of the user's request are addressed
- Information is accurate and well-sourced
- Final output is well-formatted and complete
- If anything is missing or uncertain, continue gathering information`,
model: 'openai/gpt-5.6-sol',
agents: {
researchAgent,
writingAgent,
},
memory: new Memory({
storage: new LibSQLStore({
id: 'mastra-storage',
url: 'file:mastra.db',
}),
}),
defaultOptions: {
maxSteps: 10,
// Monitor progress after each iteration
onIterationComplete: async context => {
console.log(`\n✓ Iteration ${context.iteration} complete`)
console.log(` Finish reason: ${context.finishReason}`)
console.log(` Response length: ${context.text.length} chars\n`)
// Continue until task is complete
return { continue: true }
},
// Control delegations
delegation: {
onDelegationStart: async context => {
console.log(`→ Delegating to: ${context.primitiveId}`)
// Add context for specific agents
if (context.primitiveId === 'research-agent') {
return {
proceed: true,
modifiedPrompt: `${context.prompt}\n\nFocus on recent developments (2024-2025) and include statistics.`,
}
}
return { proceed: true }
},
onDelegationComplete: async context => {
console.log(`✓ Completed: ${context.primitiveId}\n`)
// Handle errors: bail to stop execution and provide feedback
if (context.error) {
console.error('Delegation failed:', context.error)
context.bail() // Stop further delegations
return {
feedback: `Delegation to ${context.primitiveId} failed: ${context.error}. Try a different approach.`,
}
}
},
// Only pass last 10 messages to subagents
messageFilter: ({ messages }) => {
return messages.slice(-10)
},
},
},
})
在 src/mastra/index.ts 中向 Mastra 註冊監督 Agent:
import { Mastra } from '@mastra/core'
import { supervisorAgent } from './agents/supervisor-agent'
export const mastra = new Mastra({
agents: { supervisorAgent },
})
監督 Agent 上的 defaultOptions 會設定委派 hook 及反覆運算監察:
onDelegationStart修改研究 Agent 的提示,以要求近期資料onDelegationComplete記錄完成狀態,在發生錯誤時停止,然後提供回饋messageFilter將上下文限制為最後 10 則訊息,以提高效率onIterationComplete在每次反覆運算後監察進度
測試基本監督 Agent測試基本監督 Agent 的直接連結
在 src/index.ts 建立檔案,以便與監督 Agent 互動:
import { supervisorAgent } from './mastra/agents/supervisor-agent'
async function main() {
const topic = 'artificial intelligence in education'
console.log(`\nTopic: ${topic}\n`)
const stream = await supervisorAgent.stream(
`Research ${topic} and write a comprehensive article about it`,
)
// Stream the response
console.log('📝 Final Report:\n')
for await (const chunk of stream.textStream) {
process.stdout.write(chunk)
}
console.log('\n')
}
main()
監督 Agent 會使用 defaultOptions 中設定的委派 hook 及反覆運算監察。
加入工作完成評分加入工作完成評分 的直接連結
工作完成評分器會自動驗證工作是否完成,避免監督 Agent 過早結束。
在 src/mastra/scorers/task-complete-scorer.ts 中建立評分器:
import { createScorer } from '@mastra/core/evals'
export const taskCompleteScorer = createScorer({
id: 'task-complete',
name: 'Task Completeness',
description: 'Checks if the research and writing task has been fully completed',
}).generateScore(async context => {
const text = (context.run.output || '').toString()
// Check if response contains required elements
const hasSubstantialContent = text.length > 500
const hasStructure = text.includes('\n\n') // Multiple paragraphs
const hasContext = /\d{4}/.test(text) // Contains years/dates
// Return 1 if complete, 0 if not
if (hasSubstantialContent && hasStructure && hasContext) {
return 1
}
return 0
})
安裝 Evals 依賴套件:
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/evals
pnpm add @mastra/evals
yarn add @mastra/evals
bun add @mastra/evals
更新 src/mastra/agents/supervisor-agent.ts 中的監督 Agent,在 defaultOptions 內加入工作完成評分:
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
import { LibSQLStore } from '@mastra/libsql'
import { researchAgent } from './research-agent'
import { writingAgent } from './writing-agent'
import { taskCompleteScorer } from '../scorers/task-complete-scorer'
export const supervisorAgent = new Agent({
id: 'supervisor-agent',
name: 'Research Coordinator',
instructions: `You coordinate research and writing tasks using specialized agents.
Available resources:
- research-agent: Gathers factual data and sources (returns bullet points)
- writing-agent: Transforms research into well-structured articles (returns full paragraphs)
Delegation strategy:
1. For research requests: Delegate to research-agent first to gather facts
2. For writing requests: Delegate to writing-agent with any available research context
3. For comprehensive reports: Delegate to research-agent first, then writing-agent
4. Always ensure you have gathered sufficient information before producing final output
Success criteria:
- All aspects of the user's request are addressed
- Information is accurate and well-sourced
- Final output is well-formatted and complete
- If anything is missing or uncertain, continue gathering information`,
model: 'openai/gpt-5.6-sol',
agents: {
researchAgent,
writingAgent,
},
memory: new Memory({
storage: new LibSQLStore({
id: 'mastra-storage',
url: 'file:mastra.db',
}),
}),
defaultOptions: {
maxSteps: 10,
onIterationComplete: async context => {
console.log(`\n✓ Iteration ${context.iteration} complete`)
console.log(` Finish reason: ${context.finishReason}`)
console.log(` Response length: ${context.text.length} chars\n`)
return { continue: true }
},
delegation: {
onDelegationStart: async context => {
console.log(`→ Delegating to: ${context.primitiveId}`)
if (context.primitiveId === 'research-agent') {
return {
proceed: true,
modifiedPrompt: `${context.prompt}\n\nFocus on recent developments (2024-2025) and include statistics.`,
}
}
return { proceed: true }
},
onDelegationComplete: async context => {
console.log(`✓ Completed: ${context.primitiveId}\n`)
if (context.error) {
console.error('Delegation failed:', context.error)
context.bail() // Stop further delegations
return {
feedback: `Delegation to ${context.primitiveId} failed: ${context.error}. Try a different approach.`,
}
}
},
messageFilter: ({ messages }) => {
return messages.slice(-10)
},
},
// Validate task completion
isTaskComplete: {
scorers: [taskCompleteScorer],
strategy: 'all',
onComplete: async result => {
console.log('\n🎯 Completion Check:')
console.log(` Complete: ${result.complete}`)
console.log(` Score: ${result.scorers[0]?.score}\n`)
},
},
},
})
評分器會檢查內容是否充實、結構是否恰當,以及是否包含上下文資料。如果工作尚未完成,監督 Agent 會繼續反覆運算。現在,所有 hook 及工作完成評分都已在 Agent 的 defaultOptions 中設定,因此會自動套用至每次呼叫。
測試研究協調器測試研究協調器 的直接連結
執行協調器以查看實際運作:
npx tsx src/index.ts
你會看到監督 Agent 先委派給研究 Agent,再委派給寫作 Agent,而記錄會顯示委派流程:
Topic: artificial intelligence in education
→ Delegating to: research-agent
✓ Iteration 1 complete
Finish reason: tool-calls
Response length: 0 chars
✓ Completed: research-agent
→ Delegating to: writing-agent
✓ Iteration 2 complete
Finish reason: tool-calls
Response length: 0 chars
✓ Completed: writing-agent
🎯 Completion Check:
Complete: true
Score: 1
✓ Iteration 3 complete
Finish reason: stop
Response length: 1247 chars
📝 Final Report:
Artificial Intelligence in Education: Transforming Learning in 2024-2025
[The coordinator will produce a comprehensive article combining research findings with well-structured writing...]
由於 Agent 回應並非確定,你的輸出可能有所不同,但委派模式會保持一致。
後續步驟後續步驟 的直接連結
你可以擴充此研究協調器,以:
- 加入更多專門 Agent(事實查核員、編輯、引用格式化工具)
- 為品質指標(可讀性、來源品質)實作自訂評分器
- 加入用於網絡搜尋或資料庫存取的 Tool
- 為複雜的多步驟研究程序建立 Workflow
- 使用結構化輸出產生特定格式的報告
了解更多: