LCEL与AgentExecutor的局限性分析

news/2024/11/15 2:58:45/文章来源:https://www.cnblogs.com/muzinan110/p/18539950

在大语言模型(LLM)应用开发领域,LangChain表达式语言(LCEL)和AgentExecutor一直是开发者的得力助手。然而,随着应用场景的复杂化,这些工具的局限性也日益凸显。本文将深入探讨LCEL和AgentExecutor的不足,并引入一个新的解决方案。

LCEL链表达式的局限性

LangChain表达式语言(LCEL)提供了一种便捷的方式来创建链式应用,将知识库、LLM、prompt、工具调用和输出解析器等组件串联成一个有向无环图。尽管LCEL极大地降低了LLM应用的开发难度,但在处理复杂、动态的对话流程时,它仍然存在一些明显的局限性:

  1. 线性流程: LCEL链通常是线性的,只能按照预定义的顺序执行步骤。这种线性结构限制了在对话中进行动态路由和条件分支的能力,使得处理复杂对话场景变得困难。

  2. 状态管理复杂: 在处理多轮对话时,LCEL的状态管理变得非常复杂。每次调用链时,都需要手动传递和更新状态,这不仅增加了代码的复杂性,也提高了出错的可能性。

  3. 工具集成不直观: 虽然LCEL链可以调用外部工具,但在链的内部结构中集成和协调多个工具的使用并不直观,尤其是在需要根据对话上下文动态选择工具时。

举个例子,在构建一个问题分解策略的并行子问题优化链时,LCEL表达式的复杂性就会显现出来:

# 分解问题链
decomposition_chain = ({"question": RunnablePassthrough()}| decomposition_prompt| ChatOpenAI(model="gpt-4o-mini", temperature=0)| StrOutputParser()| (lambda x: x.strip().split("\n"))
)# 子问题答案生成链
sub_question_chain = ({"context": retriever, "question": RunnablePassthrough()}| sub_question_prompt| ChatOpenAI(model="gpt-4o-mini")| StrOutputParser()
)# 组装链
chain = ({"question": RunnablePassthrough(),"context": decomposition_chain | {"questions": RunnablePassthrough(),"answers": sub_question_chain.map()} | RunnableLambda(format_qa_pairs)} | prompt | llm_output_str
)

这个例子展示了当工具嵌套层级稍微多一些时,LCEL链的构建就会变得相当复杂。

AgentExecutor的局限性

AgentExecutor的出现在一定程度上解决了LCEL的部分缺陷,它允许智能体根据输入动态选择工具和操作。然而,AgentExecutor也存在一些值得注意的局限性:

  1. 复杂性: AgentExecutor的配置和使用相对复杂,特别是在处理复杂的对话流程和多轮对话时。需要手动管理智能体的状态和工具调用,这增加了开发的难度。

  2. 动态路由能力有限: 尽管AgentExecutor支持动态选择工具,但在处理复杂的条件分支和动态路由时仍然不够灵活。缺乏一种直观的方式来定义和执行复杂的对话流程。

  3. 状态持久性不足: AgentExecutor在处理长时间运行的对话时,缺乏内置的状态持久性机制。每次对话重启时,都需要从头开始,无法恢复之前的对话状态。

  4. 过度封装: AgentExecutor要求被包装的Agent必须符合特定的要求才能使用,例如输入变量固定、输入prompt固定、解析器固定等。这使得二次开发AgentExecutor变得困难。

  5. 黑盒不可控: 在构建复杂Agent时,无法修改工具的使用顺序,也无法在执行过程中添加人机交互。

引入新概念: 图和状态机

面对LCEL和AgentExecutor的局限性,我们需要一个更灵活、更强大的框架来构建复杂的智能体应用。在介绍这个新框架之前,让我们先通过一个简单的概念来帮助大家认识"图"和"状态机"。

想象一下"带娃状态图"这个场景:

  1. 状态: 婴儿的行为状态,包括饥饿程度、睡眠状态、体感温度等。
  2. 事件: 哄睡、喂奶、换尿布等行为。
  3. 节点: 妈妈(决策者)、奶奶/外婆(检查者)、爸爸(执行者)。

我们可以将这个场景构建成一个状态图:

在这个状态图中:

  • 妈妈负责决定需要执行什么事件
  • 老人负责判断妈妈的决定是否合理
  • 爸爸负责执行具体的事件
  • 执行完特定事件后,更新婴儿状态,然后由妈妈再次检测状态继续做决定

这个"带娃状态图"实际上就是一个简化版的图结构和状态机模型。将这个概念应用到LLM/Agent应用开发中,我们可以得到一个更灵活、更强大的框架。

结语

通过分析LCEL和AgentExecutor的局限性,我们认识到在构建复杂LLM应用时需要一个更灵活的框架。图结构和状态机的概念为我们提供了新的思路。在下一篇文章中,我们将介绍一个基于这些概念的新框架——LangGraph,它如何解决现有技术的问题,以及如何使用它来构建更强大的LLM应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/831833.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SSD201/202D的SPI通讯该怎么操作,触觉智能带来保姆级攻略

本文介绍SigmaStar SSD201/SSD202D中SPI通讯的测试方法,SPI是一种常见的串行通信协议,它被广泛用于微控制器与各种外设之间的数据传输。使用触觉智能Purple Pi R1双网口开发板演示。本文介绍SigmaStarSSD201/SSD202D中SPI通讯的测试方法,SPI全称是Serial Peripheral Interfa…

多线程锁的升级原理是什么

锁的级别:无锁 => 偏向锁 => 轻量级锁 => 重量级锁 无锁:没有对资源进行锁定,所有线程都可以访问,但是只有一个线程能成功修改资源,其他的线程会不断尝试,直至修改成功。 偏向锁:偏向锁是指当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储…

Eplan2022卡顿问题解决

EPLAN2022卡顿崩溃怎么解决第一步:可以检查下用户设置。打开菜单 "选项 → 设置:用户 → 翻译 → 字典": 不勾选"自动完成"和"自动更正"。在选项设置框中输入"自动",快速找到用户设置,取消勾选,如下图。 第二步:可以检查下电脑语…

Linux中文件系统层次结构简述

在Linux操作系统中,并没有像Windows那样的“盘符”概念。相反,Linux使用一个统一的文件系统层次结构,所有的文件和目录都挂载在一个单一的根目录 / 下。这种设计使得文件系统的管理更加灵活和一致。 文件系统层次结构 在Linux中,文件系统通常按照以下层次结构组织:/(根目…

创建线程有哪几种方式

1. 继承 ​​Thread​​ 类 优点:简单直观,适合初学者。 直接继承 ​​Thread​​ 类,可以方便地访问和使用 ​​Thread​​ 类的方法。缺点:Java 不支持多继承,因此如果你的类已经继承了其他类,则不能继承 ​​Thread​​ 类。 仅适用于简单的线程任务。示例:class MyT…

[豪の学习笔记] CI/CD相关 - Docker

Docker常见命令,命名别名,数据卷挂载,本地目录挂载,自定义镜像,容器网络互联一、docker常见命令单独下载镜像文件 docker pull 查看本地镜像文件 docker images 删除本地镜像文件 docker rmi 基于dockerfile构建自定义镜像 docker build 将打包好的镜像保存在本地 docker …

excel中查找亏损第一大第二大第三大的商品的亏损金额;涨出第一大,第二大,第三大的金额;以及查找对应数值的商品的名称,

k2 里的公式 =LARGE(IF(B:B="品类1",E:E),1) lL 里的公式 =LARGE(IF(B:B="品类1",E:E),2) M2里额公式 =LARGE(IF(B:B="品类1",E:E),3) N2里的公式=MIN(IF(B:B="品类1",E:E),1) O2里的公式=SMALL(IF(B:B="品类1",E:E),2) P2里…

线程池都有哪些状态

线程池有五种典型状态: 1.RUNNING(运行状态):在这个状态下,线程池可以接收新的任务提交,并且能够处理已添加到任务队列中的任务。这是线程池的初始状态,也是最活跃的状态。这是最正常的状态 2.SHUTDOWN(关闭状态)当调用了线程池的`shutdown()`方法后,线程池进入此状…

GIT RE-BASIN: MERGING MODELS MODULO PERMUTATION SYMMETRIES (1)

在深度学习模型的训练过程中,经常会遇到这样的现象:每次训练,虽然初始值、随机种子、训练数据的顺序不一样,但是得到的loss曲线都差不多,在验证集上的结果也差不多.这篇论文从land scape的角度解释了这个问题:神经网络的loss landscape并不是我们想象中的很混乱、毫无规律,而…

GIT RE-BASIN: MERGING MODELS MODULO PERMUTATION SYMMETRIES

在深度学习模型的训练过程中,经常会遇到这样的现象:每次训练,虽然初始值、随机种子、训练数据的顺序不一样,但是得到的loss曲线都差不多,在验证集上的结果也差不多.这篇论文从land scape的角度解释了这个问题:神经网络的loss landscape并不是我们想象中的很混乱、毫无规律,而…

hashCode()与equals()之间的关系

在Java中,`hashCode()`和`equals()`方法之间存在紧密的关系,主要体现在它们共同作用于对象的比较和存储上,尤其是在集合(如HashSet、HashMap)和哈希表的实现中。 1.hashCode()和equals()是Object类中定义的两个重要方法,用于对象的比较和哈希处理。 2.hashCode()方法:h…