LlamaIndex - workflow

在这里插入图片描述

本文翻译整理自: Introducing workflows beta: a new way to create complex AI applications with LlamaIndex (2024年 8月1日
https://www.llamaindex.ai/blog/introducing-workflows-beta-a-new-way-to-create-complex-ai-applications-with-llamaindex



一、关于 workflow

我们很高兴推出LlamaIndex的全新测试功能:工作流,这是一种在我们看到用户构建的日渐复杂的 AI 应用程序中 编排操作的机制。

随着LLM的出现开始成为一种趋势,现在已经成为事实上的标准:人工智能应用程序由不同组件实现的多个任务组成。
市场上的开源框架通过为数据加载器、LLM、矢量数据库和重新排名器等基础组件提供易于使用的抽象,一直到外部服务,努力让人工智能工程师的生活更轻松。
与此同时,所有这些框架也在寻找协调这些组件的最佳抽象,研究什么对人工智能开发人员来说最直观和最有效,以便实现将复合人工智能系统结合在一起的逻辑。

其中两个潜在的编排模式是链和管道,它们都是相同有向无环图(DAG)抽象的实现。
我们尝试了一下今年年初发布的 查询管道 ——它是一个声明性API,可让您针对不同的用例(如QA、结构化提取和代理自动化)在数据上编排从简单到高级的查询工作流。
但是当我们试图在此基础上构建并尝试添加循环以更好地支持更复杂的工作流时,我们注意到了几个问题,这让我们思考为什么DAG可能不适合代理环境,以及我们可以在框架中引入哪些替代方案。


二、基于图的用户体验的局限性

DAG的一个基本方面是DAG中的“A”:它们是非循环的,这意味着没有循环。
但是在一个越来越代理的世界里,无法在人工智能应用程序的逻辑中执行循环是完全不可接受的。
例如,如果一个组件提供了糟糕的结果,人工智能开发人员应该有办法告诉系统自我纠正并重试。

即使没有向DAG添加循环和循环,查询管道也会遇到一些明显的问题:

  • 出错时很难调试
  • 它们掩盖了组件和模块的执行方式
  • 我们的管道编排器变得越来越复杂,必须处理大量不同的边缘情况
  • 对于复杂的管道,它们很难阅读

一旦我们为查询管道添加了周期,这些围绕图表的开发人员用户体验问题就被放大了。
我们在以下领域经历了第一手开发人员的痛苦:

  • 许多核心编排逻辑,如if-else语句和while循环都被烘焙到图的边缘。
    定义这些边变得既麻烦又冗长。

  • 围绕可选值和默认值处理边缘情况变得很困难。
    作为一个框架,我们很难弄清楚参数是否会从上游节点传递。

  • 对于构建代理的开发人员来说,用周期定义图并不总是那么自然。
    代理封装了一个通用的LLM驱动的实体,可以接收观察并生成响应。
    在这里,图用户体验强制“代理”节点明确定义传入边和传出边,迫使用户定义与其他节点的详细通信模式。

我们问:图真的是我们可以用来编排复合AI系统中的组件的唯一抽象吗?


三、从图表到EDA:去事件驱动

复合人工智能系统可以用LlamaIndex工作流来实现。
工作流通过一组称为步骤的Python函数来回调度事件。
每个步骤都可以被视为系统的一个组件:一个用于处理查询,一个用于与LLM对话,一个用于从矢量数据库加载数据,等等。
每个步骤都接收一个或多个要处理的事件,并且可以选择发送回事件,如果需要,这些事件将被中继到其他组件。

转向事件驱动的体系结构会导致设计的根本性转变。
在许多图实现中,图遍历算法负责确定下一步应该运行什么组件以及应该传递什么数据。
在事件驱动的体系结构中,组件订阅特定类型的事件,并最终负责根据它接收到的数据决定做什么。

在事件驱动的系统中,输入的可选性和默认值等概念在组件级别进行排序,从而显着简化了编排代码。


四、工作流入门

为了帮助澄清这个想法,让我们看一个例子。

1、基本使用

最小的LlamaIndex工作流程如下所示:

from llama_index.core.workflow import (
    StartEvent,
    StopEvent,
    Workflow,
    step,
)

from llama_index.llms.openai import OpenAI

class OpenAIGenerator(Workflow):
    @step()
    async def generate(self, ev: StartEvent) -> StopEvent:
        query = ev.get("query")
        llm = OpenAI()
        response = await llm.acomplete(query)
        return StopEvent(result=str(response))

w = OpenAIGenerator(timeout=10, verbose=False)
result = await w.run(query="What's LlamaIndex?")
print(result)

使用@step装饰器将generate函数标记为工作流步骤,并使用带有正确类型注释的方法签名声明它想要接收哪些事件以及将发回哪些事件。
为了运行工作流,我们创建一个OpenAIGenerator类的实例,传递一些配置参数,如所需的超时,然后我们调用run方法。
传递给run的任何关键字参数都将被打包到一个StartEvent类型的特殊事件中,该事件将被中继到请求它的步骤(在本例中,仅为generate步骤)。
generate步骤返回一个StopEvent类型的特殊事件,该事件将指示工作流优雅地停止其执行。
StopEvent携带我们希望作为工作流结果返回给调用者的任何数据,在本例中为LLM响应。


2、工作流可以循环

在事件驱动的架构中,循环与通信有关,而不是拓扑。
任何步骤都可以通过制作和发送适当的事件来决定多次调用另一个步骤。
例如,让我们看一个自我纠正循环(查看笔记本以获取完整代码):

class ExtractionDone(Event):
    output: str
    passage: str


class ValidationErrorEvent(Event):
    error: str
    wrong_output: str
    passage: str
    
    
class ReflectionWorkflow(Workflow):
    @step()
    async def extract(
        self, ev: StartEvent | ValidationErrorEvent
    ) -> StopEvent | ExtractionDone:
        if isinstance(ev, StartEvent):
            passage = ev.get("passage")
            if not passage:
                return StopEvent(result="Please provide some text in input")
            reflection_prompt = ""
        elif isinstance(ev, ValidationErrorEvent):
            passage = ev.passage
            reflection_prompt = REFLECTION_PROMPT.format(
                wrong_answer=ev.wrong_output, error=ev.error
            )

        llm = Ollama(model="llama3", request_timeout=30)
        prompt = EXTRACTION_PROMPT.format(
            passage=passage, schema=CarCollection.schema_json()
        )
        if reflection_prompt:
            prompt += reflection_prompt

        output = await llm.acomplete(prompt)

        return ExtractionDone(output=str(output), passage=passage)

    @step()
    async def validate(
        self, ev: ExtractionDone
    ) -> StopEvent | ValidationErrorEvent:
        try:
            json.loads(ev.output)
        except Exception as e:
            print("Validation failed, retrying...")
            return ValidationErrorEvent(
                error=str(e), wrong_output=ev.output, passage=ev.passage
            )

        return StopEvent(result=ev.output)

w = ReflectionWorkflow(timeout=60, verbose=True)
result = await w.run(
    passage="There are two cars available: a Fiat Panda with 45Hp and a Honda Civic with 330Hp."
)
print(result)

在本例中,validate步骤将尝试模式提取的结果作为事件接收,它可以通过返回最终将传递给extract步骤的ValidationErrorEvent来决定重试,该步骤将执行另一次尝试。
请注意,在本例中,如果提取/验证循环持续提供较差的结果时间过长,工作流可能会超时,但另一种策略可能会在尝试了精确的次数后放弃,仅举一个例子。


3、工作流保持状态

工作流在执行过程中保持全局状态,该状态可以根据请求共享并传播到其步骤。
这种共享状态被实现为Context对象,可以由步骤用于在迭代之间存储数据,也可以作为不同步骤之间的替代通信形式。
让我们看一个更复杂的RAG示例的摘录,作为一个示例,展示如何使用全局上下文(查看笔记本以获取完整代码):

class RAGWorkflow(Workflow):
    @step(pass_context=True)
    async def ingest(self, ctx: Context, ev: StartEvent) -> Optional[StopEvent]:
        dataset_name = ev.get("dataset")
        _, documents = download_llama_dataset(dsname, "./data")
        ctx.data["INDEX"] = VectorStoreIndex.from_documents(documents=documents)
        return StopEvent(result=f"Indexed {len(documents)} documents.")
        
    ...

在这种情况下,ingest步骤创建了一个索引,它希望将其提供给稍后在工作流执行期间可能需要它的任何其他步骤。
在LlamaIndex工作流中执行此操作的惯用方法是声明该步骤需要全局上下文的实例(@step(pass_context=True)并使用其他步骤稍后可能访问的预定义键将索引存储在上下文本身中。


4、工作流程可以定制

除了工作流,我们还将发布一组预定义的工作流,以便最常见的用例可以用一行代码来实现。
使用这些预定义的流,用户可能仍然希望稍微更改预定义的工作流以引入一些自定义行为,而无需从头开始重写整个工作流。
假设您想自定义RAG工作流并使用自定义重新排名步骤,您需要做的就是子类化一个假设的内置RAGWorkflow类并覆盖rerank步骤,如下所示:

class MyWorkflow(RAGWorkflow):
    @step(pass_context=True)
    def rerank(
        self, ctx: Context, ev: Union[RetrieverEvent, StartEvent]
    ) -> Optional[QueryResult]:
        # my custom reranking logic here
        
 
w = MyWorkflow(timeout=60, verbose=True)
result = await w.run(query="Who is Paul Graham?")

5、可以调试工作流

工作流的复杂性会随着应用程序逻辑的复杂性而增加,有时仅通过查看Python代码很难理解事件在执行过程中是如何流动的。
为了简化对复杂工作流的理解并支持工作流执行的调试,LlamaIndex提供了两个功能:

  • draw_all_possible_flows生成一个图片,显示工作流中的所有步骤以及事件可能如何流动
  • draw_most_recent_execution生成类似的图片,仅显示上次工作流执行期间实际发送的事件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最重要的是,可以通过多次调用run_step()手动执行工作流,直到所有步骤完成。
每次run_step调用后,可以检查工作流,检查任何中间结果或调试日志。


五、为什么今天应该使用工作流

尽管LlamaIndex工作流处于开发的早期阶段,但与查询管道相比,它已经向前迈进了一步,扩展了它们的功能并增加了更多的灵活性。
最重要的是,工作流附带了一组您通常期望从更成熟的软件中获得的功能:

  • 完全异步,支持流式传输
  • 默认检测,通过支持的集成提供一键式可观察性
  • 分步执行,更易于调试
  • 事件驱动依赖项的验证和可视化
  • 事件被实现为pydantic模型,以简化定制和新功能的进一步开发

六、资源

查看我们的工作流程留档示例,包括:


2024-08-06(二)

  • 36
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
Vue Workflow 是指在 Vue.js 开发过程中,开发者所遵循的一系列工作流程和规范。它包括项目的初始化、代码的组织与管理、模块化开发、构建与打包等方面。 在 Vue Workflow 中,通常会使用脚手架工具(如 Vue CLI)来初始化项目,它可以帮助我们快速搭建一个基本的 Vue.js 项目结构,并集成了一些常用的开发工具和配置。接下来,我们可以按照项目的需求,进行组件的划分和编写,使用 Vue Router 实现页面路由,使用 Vuex 进行状态管理等。 在代码的组织与管理方面,我们可以采用模块化的方式组织代码,将不同功能的代码分散到不同的模块中,提高可维护性和复用性。常见的方式有使用单文件组件(.vue 文件)来编写组件,使用 ES6 的模块系统来导入导出模块。 在开发过程中,我们可以使用一些开发工具来提高效率,如代码编辑器(如 VS Code)的插件支持、调试工具等。同时,我们也可以使用一些辅助工具来进行代码质量检查(如 ESLint)、单元测试(如 Jest)和集成测试等,以确保代码的质量和稳定性。 最后,在构建与打包方面,我们可以使用工具(如 webpack)来将项目代码进行打包,优化资源加载和性能。我们可以配置不同的环境变量来区分开发环境和生产环境,以便在不同环境下进行不同的配置和优化。 总结来说,Vue Workflow 是一种在 Vue.js 开发中遵循的工作流程和规范,它可以帮助开发者更高效地开发和维护 Vue.js 项目。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值