面对多样的 LLM 应用需求,无论是主流如 LangChain 这样的基础开发框架,还是以云服务提供的低代码开发平台,都试图在提供基础组件抽象的基础上,提供更便捷的组装与编排这些组件的方式,以帮助构建更高级的 AI 工作流应用。比如年初发布的 LangChain 新版本中就引入了 LangGraph,以帮助构建 Graph 表示的 AI 工作流。
最近,另一家主流 LLM 框架 LlamaIndex 推出了一项新 beta 特性:Workflows。提供了一种与 LangGraph 不同、事件驱动的框架,以编排复杂的 RAG 或 Agent 应用工作流,支持灵活的分支、并行与循环等处理。
我们将分成两篇来给大家深入解析与介绍 LlamaIndex Workflows:
- Workflows 的思想、概念与简单演示
- 基于 Workflows 构建多分支与循环的复杂 LLM 应用
回顾:为什么需要 Workflows
以两种主流 LLM 应用开发框架 LangChain 与 LlamaIndex 来看,它们都提供了大量的基础组件封装,将常见的 RAG 或 Agent 应用开发中常用到的流程环节进行了抽象,简化了开发并避免锁定到特定的底层设施(如大模型、向量库)。利用它们提供的 API 可以在极短的时间内开发出大模型应用,比如在 LlamaIndex 中,几行代码可以快速完成一个 RAG 原型:
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
documents = SimpleDirectoryReader("../data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query('你的问题')
print(response)
但这里的问题是:当面对复杂的业务与优化需求时,不断出现更多的 RAG 工作模块与算法(重写、路由、排序、图索引等),如何用最佳的方法来组合与协调这些组件,实现更复杂的工作流程?
在框架的早期,可以总结成两种主要方式:
1. 提供更高层的组件与 API 的封装
比如简单的向量检索器是 VectorIndexRetriever,但现在需要增加路由功能,就封装一个带有路由的 RouterRetriever;简单的查询引擎是 QueryEngine,但现在需要增加重排功能,就增加一个可以传入 Reranker 模块的参数。
2. 提供链式或 DAG(单向无环图)结构的可编排方法
最具代表性的是 LangChain 框架中的 Chain(链)与 LCEL(LangChain 表达语言)特性;以及 LlamaIndex 在年初推出的 Query Pipeline(查询管道)声明式 API 特性。它们都在一定程度上提供了编排能力。
尽管这种受限的工作流编排仍然面临较大的局限性:
- **高层的组件或 API 封装缺乏足够的灵活性。**体现在随着需求的复杂化,需要封装更多的高层组件,框架变得更臃肿。高层组件的内部过于'黑盒'。比如很难对 LangChain 或 LlamaIndex 的 ReActAgent 组件构建的智能体的执行过程做更精细化的控制。
- **链式或 DAG 结构的流程无法支持循环,限制了使用场景。**但在如今的很多 AI 工作流中,比如智能体的反思(Reflection)以及一些新的 RAG 范式(如 C-RAG 等)都需要循环的支持。
- 不够简洁与直观,也难以调试。
基于这样一些原因,提供一种更强大的工作流定义与编排的支持,也成为了开发框架的发力重点,典型的就是之前介绍过的 LangGraph 以及本篇将一窥究竟的 LlamaIndex Workflows。
LlamaIndex Workflows 初探
LlamaIndex Workflows 是 LlamaIndex 近期推出(仍然是测试版)的用来替代之前 Query Pipeline(查询管道)的新特性。与 LangGraph 不同的是,其没有采用类似 LangGraph 基于图结构的流程编排模式,而是采用了一种事件驱动的工作流编排方式:


