任务型Agent:执行计划详细设计
一、执行计划定义
在 Agent 的上下文中,执行计划(Execute Plan)是指:Agent 在接收到用户需求后,通过推理生成的一系列有序、可执行的步骤序列,用以系统性地达成最终目标,通常执行计划被建模为有向无环图(DAG)。我们实现的任务型 Agent 框架是一个多智能体系统,核心采用“中枢”转发的模式(还有另一种P2P模式),由“中枢 Agent”将用户需求拆解为多个适合子 Agent 独立负责的任务,并由“中枢 Agent”统一协调,同时子 Agent 执行时会生成内部执行计划。如下图所示:
图中以基于 Reflection 的自主规划模式为例说明 AEP 和 EP 两个概念:
Agent 级别的任务执行计划:简称 AEP,用于将用户需求拆解为多个子 Agent 能独立解决的任务,这些子任务组成 Agent 级别的任务执行计划。
Agent 内部的执行计划:简称 EP,子 Agent 将负责的任务进一步拆解成更细粒度、可执行的执行计划。EP 中节点的类型可以工具、工具组等。
二、GraphViz 可视化工具在执行计划中的应用
Graphviz(全称:Graph Visualization Software)是一个开源的图形可视化软件包,它主要用于将结构化信息(特别是图和网络)以清晰、美观的图形方式展现出来。Graphviz 使用 DOT 语言作为输入语言,图中的节点属性可自定义,示例如下:
执行计划要找到一种表达方式,不仅让大模型能方便理解,也能让产品、运营和技术人员能快速理解和修改执行计划结构。执行计划被建模为有向无环图,天然适合于使用 Graphviz 协议来表达。目前 Agent 支持的所有模型涉及的执行计划均采用这种方式实现,比如基于 Reflection 的自主规划模式的动态 EP 和 workflow 模式下的 EP 模板,前者会动态修改 EP 结构,后者采用人工预设模板不通动态修改。另外 EP 中的节点可以分工具、多工具等类型,同时节点也包含了丰富的属性(参考领域模型设计),示例如下:
digraph G {1 [label = "节点A" shape=record type="function" status="待初始化" toolCode="functionA" toolInput="xx" toolOutput="xx" question=""];2 [label = "节点B" shape=ellipse type="confirm" status="待初始化" question="xx" answer="xx"];3 [label = "节点C" shape=record type="function" toolCode="functionC" status="待初始化" toolInput="xx" toolOutput="xx" question="xx"];4 [label = "节点D" shape=ellipse type="confirm" status="待初始化" component="xx" payload="xx" question="请查收xx" answer="xx"];1 -> 2; 2 -> 3; 3 -> 4;
}
三、执行计划领域模型
1. 领域模型
a. 执行计划模板:ExecutePlanTemplate
执行计划模板应用于 workflow 模式,template 属性存放人工预设的模板内容(使用 graphviz 协议表示的工作流)。
b. 执行计划:ExecutePlan
workflow 模式下,ExecutePlan 是 ExecutePlanTemplate 的实例。基于 Reflection 的自主规划模式或者 ReAct 模式下,ExecutePlan 是一个可动态变化的实例。
c. 执行计划节点:ExecutePlanNode
执行计划节点是一个抽象的概念,不同 Agent 模式下节点对应不同的业务概念。核心的属性如下(每种节点类型的属性不一样,这里只做部分属性说明):
graphId:节点图 id, graphviz 协议 dot 语言中节点的 id
label:节点展示名称
shape:节点图形类型,graphviz 协议 dot 语言支持的类型
type:节点类型,枚举如下:
function :表示函数类型,此时节点是一个函数工具节点,适用于 workflow 模式和基于 Reflection 的自主规划模式。
multiFunction:表示多函数类型,此时节点可以包含多个函数,适用于 ReAct模式,在 ReAct 模式下一轮推理结束后,大模型可能会推理出多个函数工具。
confirm:表示待用户输入节点,该节点通常用于依赖更多输入(用户输入和上游节点执行结点等)来综合评估做出下一步待执行的决策(比如反问用户)。
agent:AEP 下的节点类型,此时代表一个 agent 执行任务节点,适用于多智能体。
status:EP 节点的状态,详细见状态机描述。
2. EP 及 EP 节点状态机
基于 Reflection 的自主规划模式下的 EP 节点是 function 类型,即一个节点对应一个工具。该模式下每次对话或者工具执行结束后会动态刷新 EP 结构(包括节点的状态),在设计之初未严格区分节点状态的驱动职责,导致节点状态未按照预设的流程流转,为了解决这个问题,把节点的状态的驱动职责一拆为二:大模型驱动和异步框架驱动(如图示),既减轻大模型理解成本,又能明确职责界限和简化系统。另外,为了防止更多的状态出现复杂系统,特意简化了 EP 状态机。
3. EP 调度执行
EP 调度执行由三方异步框架来完成,结合产品交互设计了两个调度任务:
EP 调用执行任务:每 30 s 轮询一次,轮询过程中找出“待运行”状态节点来执行。
待用户输入任务:考虑到任务型 agent 长周期特点,当节点进入到“待用户输入中”状态时,该任务会把大模型反问的问题通知到用户,除在对话框通知外,该任务会小时级别通过钉钉形式异步提醒用户。
四、prompt 示例
下面是对动态刷新 EP 的输出规范示例摘要:
▌ 最终输出规范
最终需要输出两部分指定格式的内容
** 第一部分是EP的更新说明,格式要求如下:
使用\"@epupdatelog@\"作为起始符和结束符包裹更新信息,采用markdown格式,严格遵守以下格式:
@epupdatelog@
{更新内容说明}
@epupdatelog@** 第二部分是最终更新后的EP内容,其中EP结构说明、EP节点属性说明、更新说明格式要求参考下面的描述,
,使用\"@EP@\"作为特殊符号包裹更新信息,严格遵守以下格式:
@EP@
*id=1
*graph=digraph G {1 [label = "标题1" shape=record type="function" toolCode="" status="待用户输入中" toolInput="" toolOutput="", question=""];2 [label = "标题2" shape=ellipse type="confirm" status="待初始化"];3 [label = "标题3" shape=record type="function" toolCode="samplePreAnalysis" status="待初始化" toolInput="" toolOutput="" profile="" question=""];1 -> 2; 2 -> 3;
}
@EP@** EP结构说明 **
其中@EP@是起始标识符,@EP@是结束表示符
其中*id是当前EP的ID,更新EP时需要输出,新增EP不需要输出
其中*graph=digraph G {} 表示Graphviz格式的编排EP图,里面包含节点和节点之间的边关系,EP图中每个节点都代表一个EPNode** EP节点属性说明 **
//......