工作流规划 Planning workflows

规划设计模式与高度自主智能体

就像复杂软件系统需要工厂模式、单例模式、依赖倒置等等设计模式和原则一样,Agent系统想要实现复杂度与效率并重,也需要一些设计模式。
本节我们将介绍规划 (Planning) 设计模式,规划模式的Agent系统高度自主,能够自行决定执行复杂任务所需的工具调用序列,而无需事先硬编码。

真实案例:客服助理Agent

在这里插入图片描述

  • 目标: 构建能够回答广泛、复杂查询的智能体,在运行时灵活地决定采取哪些行动。在本系统中,是一个能够回答客户像“你们有没有库存中售价低于100美元的圆形太阳眼镜?”这类复杂问题的Agent。
  • 方法:
    • 提供工具集: 给 LLM 提供一套功能工具。在本例中,是如下工具:

在这里插入图片描述

  • LLM编写计划:要求LLM根据用户请求返回一个逐步的执行计划,说明应该按什么顺序调用哪些工具。
    • LLM计划调用 get_item_descriptions 来找"round sunglasses"
    • 根据step1 的输出(找到的产品)
    • 再调用check_inventory查看库存
    • 对库存中有货的结果
    • 调用get_item_price检查哪些低于$100
    • 输出最终结果
  • **逐步执行:**按照计划,将每一步的指令和上一步的输出、上下文依次喂给LLM。让它调用相应的工具并执行。
  • 最终输出: 将所有步骤的结果反馈给 LLM,生成最终的用户答案。

可以看出,规划模式的Agent有许多好处,比如Agent拥有非常丰富的能力,进而扩展了能执行的任务范围。开发者也无需事先编排工具调用的确切序列,提高了系统的灵活性和自主性。

规划模式的Agent系统在流程控制与实际场景上也有些风险点。在运行时,开发者无法预知 LLM 会生成什么样的计划,带来了结果不稳定/出错/越权的风险。目前,规划模式在AI Coding应用中非常成功,但在其他领域仍然处在尝试阶段。

这里推荐一个笔者个人十分喜欢的Agent框架:来自Huggingface社区的smolagents框架。它代码简洁,抽象程度少,工具开发难度低(只需要一个@tool装饰器),自由程度高,也具有流程跟踪功能,开发者很容易入门,也很方便理解重写其中的一些逻辑,来实现自己定制化的系统。

创建与执行LLM计划

在规划模式中,如何利用【结构化输出】来保证 LLM 生成的计划能够被下游代码可靠地执行,是非常重要的。

在上一讲中,我们让LLM直接讲出自己的任务规划,但自然语言不够清晰和明确,难以被下游代码稳定地解析和执行。所以在本节中,我们要求 LLM 以结构化格式(如 JSON 或 XML)输出计划。

结构化格式能够清楚地界定计划的步骤、所需工具及其参数,从而允许下游代码更可靠地解析 (parse) 计划的每个步骤,从而系统性地、一步一步地执行。

为了实现结构化输出,开发者应该这样写 LLM 指示词:“你可以访问以下工具,并需要以 JSON 格式创建一个分步计划”,同时详细描述所需的 JSON 结构。


在这里插入图片描述

LLM 会返回一个 JSON 列表,列表中的每个对象代表一个步骤,包含清晰的键值:

  • description (步骤描述)
  • tool (要调用的工具名称)
  • arguments (传递给工具的参数)
    这样一来,我们只要接收LLM的字符串输出,转化为JSON格式,并提取参数,执行对应函数即可。这样的解析器编写起来非常方便。

结合代码执行的规划

使用代码作为行动( Planning with code execution )
在上节中,我们让LLM用JSON描述了自己的动作。但是不妨想想,与其让 LLM 输出 JSON 等结构化数据来表示计划,不如直接让 LLM 直接编写软件代码来的效果更好。LLM可以直接用代码来表达计划的多个步骤和工具调用。

许多论文也表示,同样的工具与参数,让LLM直接编写代码的任务评估分数通常明显大于编写JSON而后解析。Huggingface出品的smolagents框架中的CodeAgent概念正是在这种思想的指导下设计出的。

在处理复杂的数据查询(如“哪个月份热巧克力销量最高?”)时,如果只提供少量基础工具(如 获取最大值过滤行),代理需要极其复杂且冗长的工具调用序列来解决问题

更糟糕的是,对于新的、更复杂的查询(如“上周有多少风险交易?”),还需要不断地创建新的定制工具,这种方法是脆弱且低效的。

而若是允许LLM直接执行代码,就能获得下列优势:

  • 利用大型库: LLM 得以利用像 Pandas 这样的数据处理库中数百甚至数千个内置函数。
  • 高表达能力: LLM 能够编写简洁的代码来表达一个涉及多步骤、复杂逻辑的计划,例如解析日期、按日期排序、过滤、去重、计数。
  • 性能更优: 研究表明,在许多任务中,让 LLM 编写代码来采取行动的性能优于让它编写 JSON 或纯文本计划

在这里插入图片描述

不过,这种CodeAgent的形式也有些需要注意的风险点:

  • 提示词要求: 明确要求LLM编写代码来解决用户的查询,并以 Python 代码返回结果,通常使用 ‘ ‘ ‘ ‘ ‘ ````` ‘‘‘‘‘<code>等标签进行分隔。
  • 安全问题: 直接运行 LLM 生成的代码存在安全风险,需要考虑使用沙箱 (Sandbox) 等安全执行环境。

现在,我们已经充分了解了这种使用代码执行任务的规划模式Agent系统。该模式下 LLM 可以生成一个详细的“构建清单”并逐步执行复杂的软件开发任务。
规划模式的缺点是难以控制,因为开发者无法预先知道 LLM 会生成什么样的行动序列。尽管如此,放弃一些控制权可以显著增加模型的能力范围,大多数时候这是值得的。

无评分 - 客服代理(实验略,没有找到工具函数的代码)

正如 Andrew 在讲座中解释的那样,结合代码执行的规划意味着让 LLM 编写代码并将其作为计划本身。
与纯文本或基于 JSON 的计划相比,这种方法更具表达力和灵活性:代码不仅记录步骤,还能直接执行它们。

在本实验中,你将实践这一设计模式
我们不再让 LLM 输出 JSON 计划并手动执行每一步,而是允许它编写 Python 代码来直接表达一个计划的多步逻辑。通过执行这些代码,我们可以自动完成复杂查询。

为更具体地展示这一点,我们模拟一个太阳镜商店,包含产品库存一组交易(销售、退货、余额更新)。该示例展示了 LLM 如何生成用于查询或更新记录的代码,体现这一模式的灵活性。

实验概览
我们将:

  1. 创建简单的库存与交易数据集。
  2. 构建描述数据的模式块(schema block)。
  3. 通过提示让 LLM 用 Python 代码编写计划(并在代码注释中解释每一步)。
  4. 在沙箱中执行代码以获得答案。

学习目标
完成本实验后,你将能够:

  1. 说明为何让模型编写代码(而非 JSON 或纯文本计划)能实现更丰富、更灵活的规划。
  2. 提示 LLM 生成带有逐步注释的 Python 代码,使其既能文档化也能执行计划。
  3. 安全运行生成的代码于沙箱中,并解释结果。

多智能体工作流

尽管所有Agent可能都基于同一个底层 LLM ,并运行在同一台电脑上,但将复杂任务分解成多个独立的角色或进程是一种更有效的开发方法,就像团队协作或计算机的多线程/多进程一样。
想想看,你现在有一个十分复杂的AI业务系统,LLM需要调用十几种甚至几十种工具,并在一段几千字的提示词的指导下运行。一个典型的业务流程都需要七八步才能实现。
在这种情况下,把【一个Agent拆成很多次级Agent】,并构成一个【多Agent系统】,即MultiAgent系统,就十分有必要了。多个承担不同任务的Agent可以靠互相协作来解决复杂的任务,提高系统的效率和模块化。

下图就是一个拆分市场Agent的例子,拆出了调研、生成报表、创建文件三个子Agent

在这里插入图片描述
在这里插入图片描述
【MultiAgent系统】具有以下优势:

  • 任务分解: 像人类团队一样,将复杂任务自然地分解为拥有不同角色和技能的子任务。
  • 专注性: 允许开发者一次专注于构建一个特定角色,就像只需专注于构建最好的“平面设计师智能体”。通常,单个Agent的任务越简单,任务完成的效果就越好。
  • 模块化与复用: 有机会创建可复用于其他应用的通用智能体,就像一个通用的“平面设计师智能体”可以用于营销手册和社交媒体帖子。

此外,笔者还认为MultiAgent系统有以下两个优势

  • 突破上下文限制。现在绝大多数模型都具有128k的上下文,对于一些需要多轮规划执行的调研类任务或业务分析任务来说是完全不够的。但如果让每个Agent只负责自己的部分,最终只返回自己部分的调研结果,让一个总结Agent总结各个子Agent的调研结果,生成最终报告,就能规避上下文的限制,因为总结Agent不必在上下文中存储其它Agent的调研过程,它只看结果就够了。
  • 节约成本。
    • 在资金成本上,每次请求都附带大量上下文是非常烧钱的,即使命中缓存。MultiAgent体系中每个Agent 上下文都比较短,更节约Tokens费用;
    • 在时间成本上,上下文越短,LLM回复速度越快,延迟越低,同时多个Agent还能并行处理任务,可以将时间成本大大降低。

通常,我们通过提示词+工具的组合来创建不同的Agent。比如对于一个市场分析Agent,就需要告诉LLM它具有高超的市场分析技巧,和他讲一些市场分析的范式与最佳实践,并给它配备网页浏览工具,以便它可以自己去做市场调研

无评分 - 市场调研团队(略)

多智能体的通信模式

当一个团队一起工作时,他们之间的沟通模式可能会非常复杂。类似地,设计多智能体系统的通信模式也同样复杂,而组织结构的好坏会极大影响系统的效率与结果。
本节我们会基于上面一节里的市场调研Agent,介绍四种协作模式:线性、双层、多层和去中心

  1. 线性模式(Linear communication pattern)
    就像一个市场团队的工作流:研究员 → 平面设计师 → 文案撰写者。每个人只和下一个环节沟通。
    线性模式按顺序执行任务,信息单向流动;
  • 优点:结构简单、易于理解;
  • 缺点:不灵活,出错时难以反馈或修正。
  1. 双层模式(Hierarchical communication pattern)
    有一个“管理员(Manager Agent)”负责协调所有下属Agent。 就像项目负责人依次给研究员、设计师、写手分配任务,收集结果,再整合。
    双层模式下,所有通信都经过经理
  • 优点 :清晰、易于控制、任务协调性强;
  • 缺点 :可能成为瓶颈(manager负担重)。
  1. 多层模式(Deep Hierarchy)
    一些高级系统会让子Agent自己也拥有下属Agent。 例如“研究员”下面有“网页研究员”和“事实核查员”,“作家”下面有“风格写手”和“引用校对员”。
  • **优点:**可扩展、模块化、可分层调度;
  • **缺点:**通信复杂、难以调试、出错难追踪。
  1. 去中心模式(All-to-all communication)
    在这种模式下,每个Agent都能随时与其他Agent交流,没有中心,也没有固定顺序。
    每个Agent都知道其他Agent是谁,他们可以互相发消息,谁都可以决定何时回复。直到最后大家都“认为任务完成”时,产出最终结果。
    在这里插入图片描述

**特点:**高度去中心化、非常灵活、创意性强,但也 难以预测结果。
这种模式适用于容忍一定混乱、追求创造性结果的场景。
在这里插入图片描述

实际生产中,线性模式与双层模式会更常用一些,因为至少对于当前LLM的能力而言,信息会在层级之间传递时丢失部分信息,层级越多,信息越匮乏/失真。
其实在这四种模式外,还有一种对话模式,比较类似去中心模式的降级版。对话模式每次都只有两个Agent互相对话交流,一方执行任务,另一方审查任务,最终交出一份双方都满意的结果。
在常见的Agent框架中,langchain是忠实的线性结构,smolagents更青睐于双层/多层结构,而metagpt、camelai则致力于做去中心结构。当然,大部分框架都可以同时实现这些不同的结构,只是代码风格不同,读者可以自行多尝试,找到自己最喜欢的框架,与最适合某项具体任务的框架。


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐