人工确认与多 Agent:让系统知道什么时候停下来
问题场景
Agent 能自动调用工具,但不是所有工具都应该自动执行。删除资料、发送邮件、付款、调用昂贵 API、访问敏感数据,这些动作即使参数看起来正确,也需要人工确认。
另一类问题是任务太大:一个 Agent 同时负责检索、写作、审查、执行工具,instructions 会越来越长,工具也越来越多。此时可以拆成多个专门 Agent,再由 Supervisor Agent 负责分派。
Agent Approval
Mastra 的 Agent Approval 用于在工具执行前暂停。官方文档给出两种暂停机制:
| 机制 | 什么时候暂停 | 适合用途 |
|---|---|---|
requireApproval: true | 工具 execute 前 | 删除、发送、付款等高风险动作 |
suspend() | 工具执行过程中 | 运行时才发现需要补充信息或确认 |
const deleteNoteTool = createTool({
id: 'delete-note',
description: 'Delete a study note by id.',
inputSchema: z.object({ id: z.string() }),
outputSchema: z.object({ deleted: z.boolean() }),
requireApproval: true,
execute: async ({ id }) => {
await db.delete(id)
return { deleted: true }
},
})存储要求
官方文档说明 Agent Approval 使用 snapshots 保存请求状态,因此 Mastra 实例需要配置 storage。否则可能出现 snapshot not found 一类错误。
Workflow Human-in-the-loop
Workflow 也可以在某个 step 暂停,等待人工输入后再继续。它更适合「流程中的审批点」:
flowchart LR
A[生成学习计划] --> B[人工确认]
B -- approve --> C[生成练习题]
B -- reject --> D[结束或重做计划]设计判断:
- 风险在工具本身:用 Agent Approval。
- 风险在流程阶段:用 Workflow
suspend()/resume()。 - 拒绝后流程应正常结束:用
bail()表达「用户拒绝,不是系统错误」。
Supervisor Agents
Supervisor Agent 通过 agents 属性挂载子 Agent。官方文档说明,Supervisor 会根据自身 instructions 和子 Agent 的 description 决定何时委派。
const researchAgent = new Agent({
id: 'research-agent',
description: '检索资料并返回事实要点。',
model: 'openai/gpt-5-mini',
})
const exerciseAgent = new Agent({
id: 'exercise-agent',
description: '根据学习目标生成练习题。',
model: 'openai/gpt-5-mini',
})
export const supervisor = new Agent({
id: 'study-supervisor',
instructions: '根据任务选择 researchAgent 或 exerciseAgent,并整合结果。',
model: 'openai/gpt-5.4',
agents: { researchAgent, exerciseAgent },
})Supervisor 适合职责分明的任务,不适合把简单流程复杂化。本教程最终项目暂时使用单 Agent + Workflow,是为了先掌握核心机制。扩展到多 Agent 时,应该先拆职责,再加 Supervisor。
不建议继续学习旧 Agent networks API
Mastra 当前 Agent networks 页面标记为 deprecated,并建议使用 Supervisor Agents。旧 .network() 文档只作为迁移参考,不作为本教程主线。
多 Agent 的记忆边界
官方文档指出,Supervisor 委派给子 Agent 时会做 memory isolation:子 Agent 能看到必要上下文,但保存到自己记忆中的主要是委派 prompt 和子 Agent 响应,而不是完整父对话。
实践中需要明确:
| 数据 | 是否应该共享 |
|---|---|
| 用户长期偏好 | 可以按 resource 共享 |
| 当前任务中间结果 | 通常由 Supervisor 汇总 |
| 敏感工具参数 | 默认不共享,必要时显式过滤 |
| 子 Agent 内部失败日志 | 可观测系统记录,不一定进入模型上下文 |
长任务不要阻塞主对话
官方 Background tasks 文档说明,长耗时工具可以作为后台任务执行:Agent 先返回确认,任务完成后结果写入 memory。它适合大资料分析、外部队列、长时间工作流,不适合普通快速工具调用。
Study Agent 的扩展示例:
| 能力 | 推荐方式 |
|---|---|
| 搜索本地课程资料 | 普通 Tool |
| 生成 3 天计划 | Workflow |
| 导出长篇学习报告 | Background task |
| 写入日历 | requireApproval + Tool |
| 删除学习记录 | requireApproval + 明确拒绝分支 |
Background tasks 需要配置 storage,因为任务状态要在进程重启后仍能恢复。教学项目不默认实现,是为了先保持 Agent Loop、Tool、Workflow 和 Memory 主线清晰。
Vibe coding 提示词
请帮我为这个 Mastra Agent 设计人工确认机制。
需求:
- [列出工具名和风险]
- [说明哪些操作必须人工确认]
- [说明确认 UI 是聊天消息、按钮还是后台队列]
请输出:
1. 哪些工具用 requireApproval。
2. 哪些步骤用 workflow suspend/resume。
3. 拒绝时如何处理。
4. 需要哪些 storage/memory 前提。
5. 最小测试用例。
6. 哪些长任务应该转为 background task。
先不要写完整业务代码。验证方式
| 验证项 | 检查方式 |
|---|---|
| 高风险工具未直接执行 | stream 中出现 tool-call-approval 或 generate 返回 suspended |
| 审批信息清楚 | approval payload 包含工具名和参数摘要 |
| 拒绝能继续对话 | decline 后 Agent 说明未执行,并给替代建议 |
| 自动恢复不串线程 | 使用相同 resource/thread 才能恢复 |
| 子 Agent 审批能上浮 | Supervisor stream 能看到子 Agent 的 approval chunk |
| 长任务不阻塞主回答 | Agent 先返回确认,后台结果写入 memory |
常见错误
| 错误 | 后果 | 修复 |
|---|---|---|
| 所有工具都要求确认 | 用户体验很差 | 只给高风险工具加审批 |
| 审批文案不显示参数 | 用户不知道批准什么 | 展示动作、对象、影响范围 |
| 没有处理拒绝 | Agent 卡住或重试同一动作 | decline 后明确结束或换方案 |
| Supervisor 下面挂太多 Agent | 委派不稳定 | 保持职责少而清晰 |
小练习
为 Study Agent 设计一个 publishStudyPlanTool:它会把学习计划写入外部日历。先不要实现外部 API,只写出为什么它需要 requireApproval、审批 payload 应包含哪些字段、拒绝后 Agent 应该怎么回答。