基于多 Agent 的 Planning-Executor 架构设计

一、核心设计原则

1.1 统一的 Planning 能力

每个 Agent 都具备独立的 Planning 能力,这是多 Agent 系统的基础设计原则。无论 Agent 的角色如何(Leader 或 Executor),都需要能够:

  • 理解任务需求
  • 分解复杂任务为可执行的步骤
  • 生成执行计划

设计理由:

  • 支持将复杂任务递归分解为可执行的步骤:Agent 在执行任务时可能需要进一步分解子任务
  • 提高系统的灵活性和可扩展性
  • 避免单点故障,每个 Agent 都能独立工作

1.2 Agent 技能差异化

虽然所有 Agent 都具备 Planning 能力,但每个 Agent 的技能集(工具函数)是不同的。这是基于以下考虑:

  • 资源限制:不可能让每个 Agent 都拥有所有技能
  • 专业化:不同 Agent 专注于不同领域,提高执行效率
  • 模块化设计:便于维护和扩展
  • LLM 上下文窗口限制
    • 当前主流 LLM 的上下文窗口有限(如 GPT-4 的 128K tokens),如果将所有工具描述都放入上下文,会占用大量 token
    • 工具数量过多时,工具描述本身就会消耗大量上下文空间,留给实际对话和推理的空间会大幅减少
    • 通过技能差异化,每个 Agent 只需要了解自己领域的工具,大幅减少上下文消耗
  • 工具选择准确性问题
    • 当工具数量过多时,LLM 容易出现"工具选择困难症",在相似功能的工具之间犹豫不决
    • 工具描述过多会导致 LLM 理解偏差,可能选择错误的工具或传递错误的参数
    • 通过专业化分工,每个 Agent 的工具集更小更精准,降低工具误用概率
  • 推理能力限制
    • 复杂任务需要多步骤推理,如果一次性提供所有工具和完整任务,LLM 的推理链容易断裂
    • 通过任务分解和专业化 Agent,每个 Agent 只需处理相对简单的子任务,降低推理复杂度

二、Planning 机制设计

2.1 Plan Stack 数据结构

每个 Agent 维护一个 Plan Stack(计划栈),采用 LIFO(后进先出)的数据结构。

Stack 结构:

yaml 复制代码
Plan Stack:
  Layer 0: [Task1, Task2, Task3, ...]  <- 当前执行层
  Layer 1: [TaskA, TaskB, TaskC, ...]  <- 上一层计划
  Layer 2: [TaskX, TaskY, TaskZ, ...]  <- 更上层计划
  ...

为什么需要 Stack:

当 Agent 创建完一个计划任务列表后,其中某个任务可能需要 Agent 自己执行。在执行这个任务时,Agent 又会创建新的计划列表。如果不使用 Stack,新计划会"替换"当前计划,导致上层计划丢失。

典型场景:

  1. Leader Agent 创建主计划:[搜索信息, 分析结果, 生成报告]
  2. 执行"搜索信息"任务时,需要创建子计划:[搜索关键词A, 搜索关键词B, 整合结果]
  3. 执行"搜索关键词A"时,可能需要更细粒度的计划:[调用搜索工具, 过滤结果, 提取关键信息]
  4. 当子任务完成后,需要回到上一层计划继续执行

Stack 操作:

  • Push:创建新计划时,将当前计划压入 Stack,新计划成为当前层
  • Pop:当前层计划完成后,弹出 Stack,恢复上一层计划
  • Peek:查看当前层计划,不修改 Stack

2.2 Plan 的数据结构

每个 Plan 层包含:

  • Plan ID:唯一标识符
  • Task Groups :任务组列表(按顺序执行 ),每个任务组包含:
    • Group ID:任务组的唯一标识符
    • Group Name:任务组名称(描述性名称,如"信息收集阶段"、"内容创作阶段")
    • Parallel:是否并行执行
      • false:任务组内的任务按顺序执行(串行),后面的任务可能依赖前面的结果
      • true:任务组内的任务可以同时执行(并行),提高效率
    • Jobs:任务列表,每个任务包含:
      • Job ID:任务的唯一标识符
      • Job Name:任务名称(简短描述)
      • Job Description:任务描述(清晰描述要完成的具体工作)
      • Team Role(执行者角色):
        • 指定目标 Agent 的 Team Role(如 searcher, writer, researcher, content_creator 等)
        • Team Role 是一个描述性的角色名称,能够清晰表达任务所需的专业能力
        • 系统会根据 Team Role 找到对应的团队成员来执行任务
        • 如果 Team Role 为空或与当前 Agent 的角色相同,则由当前 Agent 自己执行(使用自己的工具,工具调用通过 LLM 自动完成)
      • With File:是否需要文件输入
        • true:任务需要文件输入
        • false:任务不需要文件输入
      • Intent Condition:意图条件(用于条件执行,通常为空数组)
      • Type:任务的分类标识(如 search, outline, article, analysis 等)
      • Task Result:任务执行结果(任务执行完成后存储的结果)
      • Status(任务状态):
        • pending:等待执行
        • executing:正在执行中
        • completed:执行完成
        • failed:执行失败
  • Context:执行上下文信息
  • Metadata:创建时间、更新时间等元数据

任务执行顺序说明:

Plan 采用任务组(Task Group)的结构,支持任务组级别的并行控制:

  1. 任务组顺序执行:任务组按照列表顺序依次执行
  2. 任务组内执行方式 :由 parallel 字段控制
    • parallel: false :任务组内的任务按顺序执行(串行)
    • parallel: true :任务组内的任务可以同时执行(并行)
  3. 上下文传递:后续任务可以访问前面已完成任务的结果(通过 Task Result)
  4. 失败处理:如果某个任务失败,可以根据策略决定是否继续执行后续任务

执行流程示例:

示例1:串行任务组

markdown 复制代码
Plan:
  TaskGroup 1: "信息收集阶段" (parallel: false)
    - Job 1: 搜索相关资料
    - Job 2: 整理资料
  TaskGroup 2: "内容创作阶段" (parallel: false)
    - Job 3: 撰写大纲
    - Job 4: 撰写文章

执行流程:
1. 执行 TaskGroup 1(串行):
   - 执行 Job 1 → 完成
   - 执行 Job 2 → 完成(可以使用 Job 1 的结果)
2. 执行 TaskGroup 2(串行):
   - 执行 Job 3 → 完成(可以使用 TaskGroup 1 的结果)
   - 执行 Job 4 → 完成(可以使用 Job 3 的结果)
3. Plan 完成

示例2:并行任务组

markdown 复制代码
Plan:
  TaskGroup 1: "多源信息收集" (parallel: true)
    - Job 1: 搜索主题A
    - Job 2: 搜索主题B
    - Job 3: 搜索主题C
  TaskGroup 2: "信息整合" (parallel: false)
    - Job 4: 整合所有搜索结果
    - Job 5: 生成报告

执行流程:
1. 执行 TaskGroup 1(并行):
   - 并发执行 Job 1, Job 2, Job 3
   - 等待所有任务完成后继续
2. 执行 TaskGroup 2(串行):
   - 执行 Job 4 → 完成(可以使用 Job 1,2,3 的结果)
   - 执行 Job 5 → 完成(可以使用 Job 4 的结果)
3. Plan 完成

任务组设计优势:

  • 清晰的并行控制 :通过 parallel 字段明确控制任务组内的执行方式
  • 灵活的组织方式:可以将相关任务组织成任务组,提高计划的可读性
  • 高效的执行:支持任务组级别的并行,提高执行效率
  • 简单的依赖管理:任务组之间的依赖通过顺序自然体现,无需显式依赖关系
  • 易于理解:任务组名称和并行标志使计划结构一目了然

Team Role 选择原则:

  • Team Role 应该是一个描述性的角色名称,能够清晰表达任务所需的专业能力
  • 根据任务的核心能力需求选择 Team Role,例如:
    • 搜索信息、收集资料:searcher, researcher
    • 创作内容、撰写文章:writer, content_creator
    • 图像设计、美术创作:artist, designer
    • 3D建模、技术实现:modeler, developer
  • 系统会根据 Team Role 自动找到对应的团队成员来执行任务

三、Agent 团队架构

3.1 角色划分

Leader Agent(领导者)

职责:

  • 分析用户输入的领域问题
  • 理解用户意图和需求
  • 创建初始执行计划
  • 协调团队成员执行任务
  • 汇总和整合执行结果

特点:

  • 具备全局视野和问题分解能力
  • 不专注于具体技能执行,而是任务规划
  • 可以调用自己(递归规划),例如:
    • 总结任务执行结果
    • 重新理解用户需求
    • 调整执行计划

Executor Agent(执行者)

职责:

  • 执行具体的技能任务
  • 专注于特定领域的工具使用
  • 返回任务执行结果

特点:

  • 具备特定技能集(如搜索、写作、数据分析等)
  • 更倾向于执行而非分析
  • 可以相互调用,形成协作链,例如:
    • 搜索 Agent 调用写作 Agent 完成搜索结果的总结
    • 数据分析 Agent 调用可视化 Agent 生成图表

3.2 调用关系规则

Leader 调用规则

  1. Leader 不能被 Executor 调用

    • 原因:Leader 负责理解和分解最初的用户问题,不是具体执行者
    • 例外情况:当用户问题发生变化或需要重新理解时,Executor 可以请求 Leader 重新分析
    • 实现方式:通过特殊的"重新规划"请求机制
  2. Leader 可以调用自己

    • 场景

      • 总结多个任务的执行结果
      • 根据执行结果调整计划
      • 重新评估用户需求

Executor 调用规则

  1. Executor 可以相互调用

    • 场景

      • 搜索 Agent → 写作 Agent:搜索完成后需要总结
      • 数据分析 Agent → 可视化 Agent:分析完成后需要可视化
      • 多个 Executor 协作完成复杂任务
  2. Executor 可以调用 Leader(特殊情况)

    • 场景

      • 用户需求发生变化
      • 执行过程中发现需要重新理解问题
    • 实现方式:通过"重新规划请求"机制,而非直接调用

3.3 团队协作流程

graph TD A[用户输入] --> B[Leader Agent] B --> C[创建初始计划] C --> D[分配任务给 Executor] D --> E1[Executor 1] D --> E2[Executor 2] D --> E3[Executor 3] E1 --> F1[执行任务] E2 --> F2[执行任务] E3 --> F3[执行任务] F1 --> G[结果汇总] F2 --> G F3 --> G G --> H{需要重新规划?} H -->|是| B H -->|否| I[返回最终结果] E1 -.协作调用.-> E2 E2 -.协作调用.-> E3

四、Agent 实例管理

4.1 Agent ID vs Agent Instance ID

Agent ID(模板标识):

  • 表示 Agent 的类型/模板
  • 例如:searcher, writer, analyzer
  • 一个 Agent ID 可以对应多个运行实例

Agent Instance ID(实例标识):

  • 表示 Agent 的运行实例
  • 唯一标识符,例如:searcher_001, searcher_002
  • 用于区分同一类型 Agent 的不同实例

为什么需要 Instance ID:

在运行时,可能会同时启动多个相同 Agent ID 的实例,例如:

  • 多个 searcher 并发搜索不同主题
  • 多个 writer 并行处理不同的写作任务
  • 多个 analyzer 同时分析不同的数据集

实例管理:

  • 每个 Agent Instance 维护独立的对话上下文
  • 每个 Agent Instance 维护独立的 Plan Stack
  • 通过 Instance ID 进行任务路由和结果关联

4.2 消息隔离机制

LLM 交互的消息隔离

在跟 LLM 进行交互时,必须区分不同 Agent Instance 的消息,确保每个 Agent Instance 的对话消息是分开独立的。

原因:

  • LLM 对消息顺序有严格要求
  • Tool Call 的消息后面必须紧跟 Tool 的返回消息
  • 如果多个 Agent 的消息混合在一起,会导致:
    • LLM 无法正确理解上下文
    • Tool Call 和 Tool Response 不匹配
    • 对话状态混乱

实现方式:

  • 每个 Agent Instance 维护独立的 Message History
  • 消息存储时关联 Agent Instance ID
  • LLM 调用时只传入当前 Agent Instance 的消息

五、Agent 协作与信息共享

5.1 任务执行上下文共享

虽然每个 Agent Instance 的消息是隔离的,但 Agent 之间需要协作,因此需要共享任务执行上下文。

共享的信息:

  • 任务输入:谁收到了什么任务(消息)
  • 任务输出:输出了什么任务结果(消息)
  • 任务状态:任务的执行状态(pending, executing, completed, failed)
  • 任务顺序:任务在 Plan 中的执行顺序(通过列表顺序自然体现)

共享方式:

  1. 内部 Agent(同一系统内)

    • 内存共享:适用于单机部署,速度快
    • Redis 共享:适用于分布式部署,支持跨进程
    • 数据库共享:适用于需要持久化的场景
  2. 外部 Agent(通过 A2A 接入)

    • 封装层:不能直接继承调用
    • 安全隔离:避免涉密信息泄露
    • 接口标准化:通过标准化的 API 接口交互
    • 信息过滤:只共享必要的任务上下文,过滤敏感信息

5.2 上下文共享的数据结构

python 复制代码
class TaskExecutionContext:
    task_id: str
    agent_instance_id: str  # 执行任务的 Agent
    task_description: str
    task_input: dict  # 任务输入
    task_output: dict  # 任务输出
    status: str  # pending, executing, completed, failed
    task_index: int  # 任务在 Plan 中的顺序索引
    created_at: datetime
    updated_at: datetime
    metadata: dict  # 额外的元数据

5.3 外部 Agent 的安全封装

封装层设计:

  • 代理模式:外部 Agent 通过代理层接入
  • 权限控制:限制外部 Agent 的访问范围
  • 数据脱敏:共享前进行数据脱敏处理
  • 审计日志:记录所有外部 Agent 的交互

实现示例:

python 复制代码
class ExternalAgentWrapper:
    def __init__(self, agent_id: str, endpoint: str, credentials: dict):
        self.agent_id = agent_id
        self.endpoint = endpoint
        self.credentials = credentials
        self.sanitizer = DataSanitizer()
    
    def execute_task(self, task: TaskExecutionContext) -> TaskExecutionContext:
        # 数据脱敏
        sanitized_task = self.sanitizer.sanitize(task)
        # 调用外部 Agent
        result = self._call_external_agent(sanitized_task)
        # 记录审计日志
        self._log_interaction(task, result)
        return result

六、实现要点总结

6.1 核心数据结构

  1. Plan Stack:每个 Agent Instance 一个
  2. Message History:每个 Agent Instance 一个,隔离存储
  3. Task Execution Context:共享存储,所有 Agent 可访问

6.2 关键设计决策

设计点 决策 理由
统一的 Planning 能力 所有 Agent 都具备 支持递归任务分解
Plan Stack LIFO 栈结构 支持嵌套计划管理
Leader/Executor 角色 明确分工 提高系统效率和可维护性
Agent Instance ID 区分实例 支持并发执行
消息隔离 每个 Instance 独立 保证 LLM 交互正确性
上下文共享 任务级别的共享 支持 Agent 协作

6.3 待完善的设计点

  1. Plan 的版本管理:当计划需要调整时,如何管理版本
  2. 失败重试机制:任务执行失败时的重试策略
  3. 任务执行策略:任务失败时是否继续执行后续任务,还是停止整个 Plan
  4. 资源限制:如何限制 Agent 的资源使用(如并发数、内存等)
  5. 监控和调试:如何监控和调试多 Agent 系统的运行状态
相关推荐
明明如月学长1 分钟前
深度揭秘:为什么顶尖开发者都开始在终端用 Claude Code 写代码?
人工智能
Debroon3 分钟前
openCHA: 个性化LLM驱动的对话健康代理框架
人工智能
心动啊1213 分钟前
了解语音识别模型Whisper
人工智能·whisper·语音识别
汤姆yu11 分钟前
基于深度学习的车牌识别系统
人工智能·深度学习
数智大号18 分钟前
艾利特×迈幸机器人:引领智能操作新范式,开启具身智能新纪元
人工智能·数据挖掘
wechat_Neal18 分钟前
智能座舱_车载语音交互相关技术术语简介
人工智能·语音识别
lpfasd12319 分钟前
《21世纪金融资本论:投机资本的新理论》精读导引笔记
人工智能·笔记·金融
虫小宝20 分钟前
电商AI导购系统设计:基于深度学习的商品推荐算法与架构实践
人工智能·深度学习·推荐算法
skywalk816321 分钟前
Auto-Coder常用秘籍 autocoder.chat启动之后的处理
开发语言·人工智能
課代表24 分钟前
大语言模型能够理解的11种文件格式
人工智能·语言模型·自然语言处理·llm·markdown·token·模型