大语言模型(Large Language Model,LLM)要真正解决实际问题,往往需要利用工具与外部环境进行交互。当LLM开始被集成到业务系统中时,一个绕不开的问题就出现了:该如何组织它与工具之间的协作?
在实际落地中,绝大多数系统其实落在两个明确的架构模式之间:工作流(Workflow)与智能体(Agent)。工作流用预定义的方式编排LLM与工具的协作关系,执行路径固定、步骤可控,适合确定性高、步骤明确的任务;智能体让LLM在运行时动态决定“下一步做什么、调用什么工具”,把执行路径的决定权交给LLM,适合开放性、需要动态规划的任务。
理解工作流和智能体的区别与适用场景,对于LLM的落地非常重要。在这篇文章里,我将聚焦工作流,介绍常见的5种工作方式。关于智能体的核心工作方式及其与工作流的对比,我会放在下一篇文章中展开。
工作流有常见的5种工作方式,分别为提示链(Prompt Chaining)、路由(Routing)、并行化(Parallelization)、编排器-工作器(Orchestrator-Workers)以及生成器-评估器(Generator-Evaluator)。
一、提示链
1.1 工作原理
图1:提示链工作流
提示链工作流的工作原理是:将一个任务分解为一系列顺序执行的步骤,LLM和工具的调用前后串联,如图1所示。这里需要说明的是:LLM和工具的调用次数不限于图1所示;调用工具的位置也不限于图1所示,它可以发生在输入和第一次调用LLM之间,也可以发生在第二次调用LLM和输出之间;LLM的输出可以设置检查点,根据检查结果的不同,工作流可以经过不同的处理分支。检查LLM的输出可以是某类工具的功能。 在工作流中关于LLM和工具的调用次数和位置的说明也适用于下文要介绍的另外4种工作流,下文将不再赘述。
1.2 适用场景
提示链工作流适用于任务可以被清晰、固定地拆分为顺序执行的步骤的场景。
1.3 应用示例
图2:提示链工作流应用示例
应用提示链工作流的一个简单例子是:利用LLM按照需求描述生成产品代码。产品代码生成后会被静态检查和编译,如果成功通过检查和编译则直接输出产品代码,如果不能通过检查和编译,则利用LLM进行失败原因的分析,之后将分析结果和有问题的产品代码一起输出给用户。
二、路由(Routing)
2.1 工作原理
图3:路由工作流
路由工作流的工作原理是:路由器(LLM或者专门的分类模型或者分类算法)先对输入进行分类,再根据类别将任务分发给专门的下游处理流程。这样可以针对不同类型的问题采用不同的模型、提示词和工具,实现因地制宜。在没有路由的情况下,同一套模型、提示词和工具需要同时应对所有类型的任务,如果任务类型差异很大,任务执行结果的性能差异也会很大。
路由工作流如图3所示,在图中,路由器根据输入内容将任务分发给上侧处理流程进行处理。
2.2 适用场景
路由工作流适合以下场景:
-
任务存在明确的、可区分的类别;
-
不同类别的任务被分开处理效果更好。
2.3 示例说明
图4:路由工作流应用示例
用路由工作流对提示链工作流中的示例进行改进,如图4所示。路由器根据需求描述进行分类,如果是简单需求则会使用高性价比LLM生成产品代码,如果是复杂需求则会使用高性能LLM生成产品代码。生成的产品代码之后经过静态检查和编译。如此分类的一个好处是可以同时兼顾输出效果和成本。
三、并行化(Parallelization)
3.1 工作原理
图5:并行化工作流
并行化工作流的工作原理是:同时执行多个子任务,然后将各个子任务的执行结果通过聚合器进行聚合。与前文的两种工作流不同,并行化工作流强调的是"同时进行"。在子任务的安排上有两种典型的做法:
-
分割(Sectioning):将任务拆解为独立的子任务,各个子任务独立执行;
-
投票(Voting):对同一个任务多次执行获得多个不同的输出,然后通过投票得到最终结果。
该工作流如图5所示,在图中,2个并行的子任务同时进行,每个子任务都会调用 LLM和工具。最后,2个子任务的执行结果通过聚合器进行聚合作为该工作流的输出结果。
3.2 适用场景
并行化工作流适用于如下场景:
-
可以预先定义的,独立、并行的子任务;
-
需要从多个角度/多次尝试来获得更高置信度的结果。
3.3 应用示例
图6:并行化工作流应用示例
在图6的应用示例中,并行化工作流的一个子任务调用LLM生成产品代码,然后进行静态检查和编译,另一个并行中的子任务调用LLM生成测试代码,然后进行静态检查和编译。通过静态检查和编译的产品代码和测试代码在聚合器中进行测试,此工作流的最终输出是产品代码和测试代码。
四、编排器-工作器(Orchestrator-Workers)
4.1 工作原理
图7:编排器-工作器工作流
编排器-工作器工作流的工作原理是:一个中心化的编排器(LLM)动态地分解任务。各个子任务通过调用工作器(LLM)和工具独立完成。聚合器将各个子任务的执行结果聚合成工作流的最终结果。
编排器-工作器工作流和并行化工作流很相似,唯一的区别在于:编排器-工作器中的子任务不是预先定义的,而是由编排器根据具体输入动态决定的;并行化工作流中的子任务是静态的、预先定义的。
该工作流如图7所示,编排器根据输入动态地决定了2个子任务。每个子任务都将调用一个工作器和一个工具来独立完成。最后,聚合器将2个子任务的执行结果进行聚合。
4.2 适用场景
编排器-工作器工作流适合那些无法预先定义子任务的复杂任务,即子任务的种类、数量、性质都取决于具体输入内容。
4.3 应用示例
图8:编排器-工作器工作流应用示例
用编排器-工作器工作流对生成测试代码的任务进行细化,如图8所示。针对特定的产品代码,是否需要同时进行功能测试和性能测试是不能预先定义的,尤其性能测试是按需安排的。在该例子中,编排器根据需求描述决定同时进行功能测试和性能测试,因此拆分了2个子任务,即生成功能测试代码和性能测试代码。功能测试代码和性能测试代码分别由各自的工作器生成且进行静态检查和编译。通过静态检查和编译的功能测试代码和性能测试代码合并成最终的测试代码。
五、生成器-评估器(Generator-Evaluator)
5.1 工作原理
图9:生成器-评估器工作流
生成器-评估器工作流的工作原理是:一个生成器(LLM)生成回答,另一个评估器(LLM 或者工具)提供评估和反馈,两者形成循环,经过多轮迭代优化输出结果。
该工作流如图9所示,评估器评估解决方案(生成器的回答),如果方案被接受,则作为工作流的最终输出;如果方案被拒绝,评估器向生成器提供反馈意见,供其优化解决方案。
5.2 适用场景
生成器-评估器工作流适用的场景需满足如下两个条件:
-
评估器可提供清晰、可衡量的评估标准;
-
生成器生成的回答可通过反馈而得到明显改进。
5.3 应用示例
图10:生成器-评估器工作流应用示例
用生成器-评估器工作流对提示链工作流中的示例进行改进,如图10所示。此处评估器的评估标准非常明确,即通过静态检查和编译。LLM生成的产品代码如果能够通过静态检查和编译,则直接作为工作流的输出;如果不能通过,LLM须根据静态检查和编译的错误信息进行代码修复和优化。经过如此多轮迭代后得到工作流的最终输出。
六、5 种工作流的对比
| 提示链 | 路由 | 并行化 | 编排器-工作器 | 生成器-评估器 | |
|---|---|---|---|---|---|
| 执行方式 | 线性顺序执行 | 选择分支执行 | 多分支并行执行à聚合各分支执行结果(分支是预先确定、且固定的) | 动态确定分支à多分支并行执行à聚合各分支执行结果 | 循环迭代执行(生成回答à评估回答à反馈评估à再生成回答) |
| 特殊节点 | / | 路由器 | 聚合器 | 编排器、聚合器 | 评估器 |
| 适用场景 | 任务可以被清晰、固定地分解为顺序执行的步骤 | 任务存在明确的、可区分的类别 | 任务可以预先被定义成独立、并行的子任务 | 无法预先定义子任务的复杂任务 | 可提供清晰、可衡量的评估标准,且输出结果可通过反馈而得到明显改进 |
七、参考文献
- Building effective agents. anthropic.com/engineering…, 2024
本文首发于微信公众号:灵栖八荒
作者:徐宏勤
版权声明:本文为原创内容,版权归”灵栖八荒“所有。如需转载,请务必在文章开头标注作者和来源,并保持文章完整,否则视为侵权。 联系:微信 Honking_HZ