6.4 产品实战:每个 Agent 怎么设计
SubAgent 通用机制
4 个 Agent 共享一套基础机制:
通过 TaskTool 派发
LeadAgent 不直接调用 SubAgent,而是通过 TaskTool 派发任务:
csharp
TaskTool.ExecuteAsync(
description: "规划视频转码工作流",
prompt: "用户需求:把视频转成mp4格式...",
subAgentType: "WorkflowPlanner");类型注册表
每个 SubAgent 类型注册了自己的配置:
| SubAgent 类型 | Prompt | 工具集 | 超时 |
|---|---|---|---|
| WorkflowPlanner | 规划专家提示词 | search_nodes, get_node_definition, list_node_categories | 10min |
| WorkflowCreator | 创建专家提示词 | workflow_create, workflow_add_node, workflow_set_param, workflow_connect, workflow_save | 15min |
| WorkflowChecker | 检查专家提示词 | workflow_get_structure, workflow_validate, get_node_definition | 5min |
| WorkflowExecutor | 执行专家提示词 | workflow_execute, workflow_get_result | 30min |
Skill 按 Agent 类型加载
不同 Agent 加载不同的 Skill 文档:
| Skill 文档 | 加载到哪个 Agent |
|---|---|
| workflow-design-guide.md | Planner + Creator |
| node-usage-patterns.md | Planner |
| category-usage-guide.md | Planner |
| validation-rules.md | Checker |
| execution-guide.md | Executor |
规划 Agent:只读的架构师
职责
规划 Agent 是流水线的"大脑",不执行任何写操作:
- 理解用户需求:将自然语言转化为具体的工作流目标
- 查询节点库:搜索匹配需求的节点类型
- 规划节点拓扑:决定用哪些节点、以什么顺序连接
- 建议参数:为每个节点提供参数配置建议
- 输出 WorkflowPlan
工具集(只读)
Planner Tools (只读)
search_nodes(keyword, category?) → 搜索节点
get_node_definition(nodeType) → 获取节点完整定义
list_node_categories() → 列出所有节点分类
list_nodes_in_category(category) → 获取某分类下所有节点关键设计:规划 Agent 没有任何写接口。从架构上保证"规划不做"。
思维链要求
输出最终方案前,需要展示思考过程:
- 需求理解:用自己的话复述用户需求
- 节点匹配过程:为什么选这个节点而不是另一个
- 拓扑逻辑:为什么这样编排
- 参数建议:哪些参数需要用户提供,哪些可自动推断
约束规则
- 每个工作流必须有 Entry 和 Exit
- 节点必须有明确的输入来源(引用前序节点输出)
- 参数区分"用户必填"和"可自动推断"
- 如果节点不明确,询问用户而不是猜测
边界情况
| 场景 | 处理方式 |
|---|---|
| 用户需求模糊 | 反问具体要做什么 |
| 没有完全匹配的节点 | 推荐最接近的节点并说明差异 |
| 多个节点可完成同一件事 | 列出选项让用户选择 |
| 需求无法用现有节点实现 | 说明能力边界 |
创建 Agent:严格按方案的工程师
职责
接收 WorkflowPlan,通过 API 调用将其实现为真实的工作流实例:
- 创建空白工作流
- 逐个添加节点
- 配置参数
- 建立连接
- 保存并返回 workflowId
工具集(读写)
Creator Tools (读写)
workflow_create(name, description) → 创建空白工作流
workflow_add_node(workflowId, nodeType, ...) → 添加节点
workflow_set_param(workflowId, nodeId, ...) → 设置参数
workflow_connect(workflowId, srcId, tgtId) → 连接节点
workflow_save(workflowId) → 保存核心原则:严格按方案执行
创建 Agent 不擅自修改规划方案。如果发现方案有问题(参数不完整、节点类型不对),应返回错误而不是自行修正。
这个约束很重要——如果 Creator 可以自行修改方案,那规划和创建的分离就失去了意义。
变量引用转换
规划方案中的 <Node2.outputPath> 格式,需要转换为工作流引擎能识别的引用格式。创建 Agent 负责这个转换。
错误处理
| 场景 | 处理方式 |
|---|---|
| 节点类型不存在 | 返回错误,LeadAgent 通知 Planner 修正 |
| 参数路径错误 | 返回详细错误信息 |
| 创建中断(超时) | 返回已创建的部分信息,可继续 |
检查 Agent:独立的 QA
职责
检查 Agent 是"QA 质检员",对创建的工作流进行独立质量检查。不修改任何内容,只发现问题并报告。
检查维度
① 结构完整性检查
├─ 是否有 Entry/Exit 节点?
├─ 所有节点是否可达?(BFS/DFS 遍历)
└─ 是否有孤立节点?
② 参数正确性检查
├─ 所有 required 参数是否已设置?
├─ 参数类型是否匹配?
└─ 变量引用是否有效?
③ 控制流逻辑检查
├─ Selector: 是否有 true/false 两条输出边?
├─ Loop: 内部是否有 Break/Continue?
└─ 循环嵌套深度是否超过 3 层?
④ 兼容性检查
├─ 连接两端的节点输入/输出类型是否匹配?
└─ 引用参数是否形成循环依赖?工具集(只读)
Checker Tools (只读)
workflow_get_structure(workflowId) → 获取工作流结构
get_node_definition(nodeType) → 获取节点定义
workflow_validate(workflowId) → 调用底层规则引擎校验
workflow_validate_structure(workflowId) → 仅结构校验
workflow_validate_params(workflowId) → 仅参数校验LLM 检查 + 规则引擎检查
检查 Agent 用两种方式做检查:
| 检查类型 | 用 LLM | 用规则引擎 |
|---|---|---|
| Entry/Exit 存在性 | 可以,但慢 | 更快更准 |
| 必填参数完整性 | 可以 | 更快更准 |
| 变量引用链有效性 | 可以 | 更快更准 |
| 参数值语义是否合理 | LLM 更擅长 | 做不到 |
| 节点选择是否最优 | LLM 更擅长 | 做不到 |
做法:Agent 先调用 workflow_validate 获取规则检查结果,再基于结果做 LLM 层面的语义检查。两者互补。
校验报告结构
ValidationReport
├── passed: bool # 是否通过
├── summary:
│ ├── errorCount: int
│ ├── warningCount: int
│ └── infoCount: int
├── issues: ValidationIssue[] # 问题列表(按严重程度排序)
│ ├── severity: "error"|"warning"|"info"
│ ├── nodeId: string?
│ ├── message: string
│ └── suggestion: string
└── recommendation: string执行 Agent:运维与验收
职责
执行 Agent 是"运维",运行已验证的工作流、监控执行过程、收集执行结果。
- 执行工作流
- 监控执行状态
- 收集执行结果
- 分析失败原因
- 报告执行情况
工具集(执行相关)
Executor Tools
workflow_execute(workflowId, inputParams?) → 启动执行
workflow_get_execution_status(executionId) → 获取状态
workflow_get_execution_result(executionId) → 获取结果
workflow_get_execution_log(executionId) → 获取日志
workflow_stop_execution(executionId) → 停止执行执行过程的状态报告
执行 Agent 需要实时更新状态,不要最后才一次性报告:
"正在执行工作流"视频处理"
→ HttpDownload(下载视频)... 执行中
→ HttpDownload(下载视频)... 完成 ✅(2.3秒)
→ VideoRemoveAudio(移除音频)... 执行中
→ VideoRemoveAudio(移除音频)... 完成 ✅(5.1秒)
→ VideoFormatConversion(转mp4)... 执行中
→ ...(等待中)
总计:3/4 节点完成,预计剩余 10 秒失败分析
执行失败时,Agent 需要分析原因:
工作流执行失败
↓
① 定位失败节点 → 找到 status=failed 的节点
↓
② 获取错误信息 → errorMessage, exitCode, stderr
↓
③ 分类错误类型
├─ 参数错误:参数值不符合要求
├─ 环境错误:ffmpeg 未安装、网络不可达
├─ 权限错误:无法写入目录、FTP 登录失败
└─ 超时:节点执行超过时间限制
↓
④ 生成分析结论
├─ "节点 HttpDownload 执行失败"
├─ "错误:无法访问 URL,连接超时"
└─ "建议:检查 URL 是否正确"设计要点总结
通过 Tool 权限控制 Agent 边界
这是整个设计最核心的要点:
| Agent | 读接口 | 写接口 | 执行接口 |
|---|---|---|---|
| Planner | ✅ | ❌ | ❌ |
| Creator | ✅ | ✅ | ❌ |
| Checker | ✅ | ❌ | ❌ |
| Executor | ✅ | ❌ | ✅ |
Agent 的边界不是靠 Prompt 约束的,是靠 Tool 权限约束的。 Planner 的 Prompt 里就算写了"请创建工作流",它也没有工具可以调用。
这就是 Harness 工程中"边界"的落地方式——不依赖 LLM 的自觉性,依赖架构的硬性约束。