国科网

2024-06-26 14:13:29  星期三
立足国科融媒,服务先进科技
揭秘LangGraph的无限潜能

点赞

0
发布时间:2024年02月26日 浏览量:158次 所属栏目:人工智能 发布者:田佳恬

作者 | 崔皓

审校 | 重楼

摘要

本文介绍了一种基于LangChain的新技术LangGraph,通过循环图协调大模型和外部工具,解决复杂任务。首先,介绍了LangChain的DAG模型处理简单任务,以及LangGraph使用循环图处理复杂任务的原理。然后,详细阐述了LangGraph的三个核心组成部分:状态图StateGraph、节点Nodes和边Edges。最后,通过一个实例演示了如何使用LangGraph查询北京2024年春节的旅游情况,包括创建代理、定义图状态、节点和边,以及执行工作流。

开篇

在当今的技术领域,大型语言模型(Large Language Models, LLMs)已经逐渐成为我们日常生活和工作中的得力助手。无论是写作辅助、编程调试,还是简单的问答系统,LLMs都能够提供快速且准确的服务。然而,当面对一些更为复杂的任务时,LLMs可能就显得力不从心。为了解决这些挑战,我们引入了LangGraph,这是一种结合了人工智能代理(AI Agents)的新技术,旨在处理更为复杂的任务和交互。

LangGraph是建立在LangChain之上,与其生态系统完全兼容的新库。它通过引入循环图的方法,协调大模型和外部工具,从而解决应用场景中的复杂问题。

在本篇文章中,我们将通过一个简单的例子——询问北京2024年春节期间的旅游情况——来展示如何创建一个属于自己的LangGraph应用。我们将一步步地引导您了解LangGraph的概念、组成部分,以及如何将其应用于实际场景中。通过这个例子,您将能够直观地看到LangGraph如何提高工作效率,解决复杂问题。

什么需要使用LangGraph

使用过LangChain的朋友都知道,LangChain的核心优势在于其能够轻松构建自定义链,这些链通常是线性的,类似于有向无环图(DAG)。DAG是一种数据结构,其中任务按照一定的顺序执行,每个任务只有一个输出和一个后续任务,形成一个没有循环的线性流程。例如,当我们从向量库中搜索内容时,我们首先输入提示词,然后通过向量比对进行搜索,并返回结果,这个过程就是一个典型的DAG,每个步骤都严格按顺序执行。

有向无环图(DAG)是数据编排和工作流管理系统中的一个基本概念。它代表了一组具有依赖关系和关联关系的任务,指明了执行的顺序。在DAG中,任务被视为节点,节点之间的有向边表示了它们之间的依赖关系,确保了一个任务只有在它的前驱任务成功完成后才会运行。

例如,一个基本的有向无环图可能会定义任务A、B、C和D,并明确指出它们的执行顺序和依赖关系。这种结构不仅指出了哪些任务必须先于其他任务执行,而且还指定了调度参数,比如从明天开始每5分钟运行一次DAG,或者从2024年1月1日开始每天运行一次。

DAG的主要关注点并不是任务内部的运作机制,而是它们应该如何执行,包括执行的顺序、重试逻辑、超时以及其他操作方面的问题。这种抽象使得创建复杂的工作流变得容易管理和监控。

然而,并非所有任务都如此简单。在遇到复杂任务时,比如第一次搜索没有找到想要的内容,我们可能需要进行第二次、第三次搜索,甚至可能需要调用网络搜索来完成。在这种情况下,顺序执行的任务(DAG)显然无法满足需求。此时,请求方和搜索方之间需要经历多次来回沟通,请求方可能会要求搜索方根据反馈调整搜索策略,这种多次的循环沟通才能逐步逼近最终答案。

这种情况下,我们需要的不再是DAG,而是一个循环图,它能够描述多个参与者之间的多轮对话和互动,以确认最终的答案。这种循环图能够处理更模糊、更复杂的用例,因为它允许系统根据反馈进行调整和迭代。那么,在循环图的运行模式就是智能代理,也就是AI Agent。

AI Agent,即人工智能代理,是一种基于强化学习理论设计的系统。如下图所示,强化学习是一种机器学习方法,它使智能体(Agent)能够根据环境的不同状态(State)采取行动(Action),目的是获取最大程度的奖励(Reward)。这种学习过程涉及到智能体与环境的不断互动,通过尝试和错误来学习哪种行动策略能够带来最佳的结果。

例如,在微信的跳一跳游戏中,智能体每次成功跳上平台都会获得奖励,而未能跳上平台则会受到惩罚。通过这种奖励和惩罚机制,智能体能够学习如何调整跳跃的力量和方向,以获得更高的分数。这个过程就是强化学习的一个简单体现,智能体通过不断的互动来优化其行动策略。

在LangGraph中,AI Agent的工作原理类似。LLM(大型语言模型)用于确定要采取的行动和向用户提供的响应,然后执行这些行动,并返回到第一步。这个过程会重复进行,直到生成最终的响应。这就是LangChain中核心AgentExecutor的工作循环原理。

然而,在实际应用过程中,我们发现需要对智能代理进行更多的控制。例如,我们可能希望智能代理始终首先调用特定工具,或者我们可能希望对工具的调用方式有更多的控制,甚至可能希望根据智能代理的状态使用不同的提示。为了解决这些问题,LangGraph提出了“状态机”的概念。通过状态机为图创建对应的状态机,这种方法可以更好地控制智能代理的行动流程,使其更加灵活和有效地处理复杂任务。

LangGraph的组成部分

在介绍LangGraph如何通过应用“状态机”来实现AI Agent功能时,有几个重要的概念我们需要理解,它们也是LangGraph的重要组成部分。

StateGraph(状态图)

首先,需要理解StateGraph这个核心概念。StateGraph是一个类,它负责表示整个图的结构。我们通过传入一个状态定义来初始化这个类,这个状态定义代表了一个中心状态对象,它会在执行过程中不断更新。这个状态对象由图中的节点更新,节点会以键值对的形式,返回对状态属性的操作。

状态对象的属性可以通过两种方式更新:

1. 覆盖更新:如果一个属性需要被新的值替换,我们可以让节点返回这个新值。

2. 增量更新:如果一个属性是一个动作列表(或类似的操作),我们可以在原有的列表上添加新的动作。

在创建状态定义时,我们需要指定属性的更新方式,是覆盖还是增量。

如果StateGraph的概念不好理解,可以想象一下你正在组织一次旅行。你设定了旅行的一些基本信息,比如确定目的地、预定航班和预定酒店。这些信息就像是一个中心状态对象,随着你计划的进展,它会不断更新。比如,你可能会添加新的活动到你的行程中,或者修改你的预算。这些更新就像是图中的节点,它们对你的旅行计划状态对象进行操作。

在LangGraph中,StateGraph类就是这样的旅行计划,而节点就像是规划旅行的不同步骤,比如确定目的地、预定航班和预定酒店。每个步骤都会更新你的旅行计划,可能是完全替换旧的计划,也可能是添加新的信息到现有的计划中。

Nodes(节点)

说完了StateGraph,我们来关注图的节点部分。在创建了StateGraph之后,我们需要向其中添加Nodes(节点)。添加节点是通过`graph.add_node(name, value)`语法来完成的。

其中,`name`参数是一个字符串,用于在添加边时引用这个节点。`value`参数应该可以是函数或者LCEL(LangChain Expression Language)可运行的实例,它们将在节点被调用时执行。它们可以接受一个字典作为输入,这个字典的格式应该与State对象相同,在执行完毕之后也会输出一个字典,字典中的键是State对象中要更新的属性。说白了,Nodes(节点)的责任是“执行”,在执行完毕之后会更新StateGraph的状态。

接着,上面旅行计划的例子,Nodes(节点)就好像旅行计划中需要完成的任务,例如:预定航班、预订酒店。Nodes(节点)接受旅行计划(State对象)作为输入,并输出一个更新后的任务状态,例如:完成酒店的预订。

换句话说了完成复杂任务,我们会在StateGraph中添加很多Nodes(节点)。每个节点都代表一个任务,它们执行的结果会影响StateGraph的状态。这些节点通过边相互连接,形成了一个有向无环图(DAG),确保了任务的正确执行顺序。

Edges(边)

说了StateGraph之后就不得不提到Edge(边)了。在LangGraph中,Edges(边)是连接Nodes(节点)并定义StateGraph(状态图)中节点执行顺序的关键部分。添加节点后,我们可以添加边来构建整个图。边有几种类型:

  • 起始边(Starting Edge):这个边确定了图的开始,比如在旅行计划中,起始边就是确定你的目的地。一旦目的地被确定,你的旅行计划就可以开始执行了。
  • 普通边(Normal Edges):这些边表示一个节点总是要在另一个节点之后被调用。在旅行计划中,普通边就像是确定了任务执行的顺序。例如,在找到合适的航班之后,你可能会决定预订酒店。这个顺序确保了任务的有序执行。
  • 条件边(Conditional Edges):使用函数(通常由LLM提供)来确定首先调用哪个节点。在旅行计划中,条件边就像是根据你的喜好或者天气情况来决定你的下一步行动。比如,如果你发现没有合适的航班,你可能会选择推迟预订酒店,而去查找火车车票。条件边提供了灵活性,使得系统可以根据不同的情况来调整执行的顺序。

在LangGraph中,边(Edges)是连接节点(Nodes)并定义图(Graph)中节点执行顺序的关键部分。边可以看作是对节点的控制和链接,它们确保了图中的任务按照预定的顺序执行。

在LangGraph中,边定义了节点之间的依赖关系和执行顺序。起始边确定了图的开始,普通边确保了任务的正确执行顺序,而条件边则根据特定的条件来决定下一步的操作。

LangGraph 实战

前面对LangGraph的设计原理以及基本组成部分有了简单的了解, 接下来,我们通过一个例子来感受一下,如何实际使用LangGraph查询北京2024年春节的旅游情况。熟悉大模型的朋友可能知道,大模型的短板就是对实时的信息一无所知,如果要摄入新的知识必须经过新数据集的训练才行。因此,我们会使用LangGraph调用网络搜索功能获取实时信息。

创建LangChain 代理

在LangChain中代理是利用大模型作为推理引擎来确定采取的行动序列,与在链中硬编码的一系列行动不同。说白了就是执行这次任务的“关键人物”, 他作为“查询北京2024年春节的旅游情况”任务的总负责,最后给用户提供结果。

# 从langchain包中导入hub对象,该对象用于内容管理和检索
from langchain import hub
# 从langchain包中导入创建OpenAI函数代理的函数
from langchain.agents import create_openai_functions_agent
# 从langchain_openai包中导入ChatOpenAI类,用于与OpenAI聊天模型交互
from langchain_openai.chat_models import ChatOpenAI
# 从langchain_community包中导入TavilySearchResults类,提供搜索功能
from langchain_community.tools.tavily_search import TavilySearchResults

# 创建一个工具列表,其中包含TavilySearchResults实例,限制最大搜索结果为1
tools = [TavilySearchResults(max_results=1)]
# 通过hub对象的pull方法检索语句提示,langchain hub 维护了很多prompt,这些prompt 是针对不同应用场景而创建的
# 作为用户,你也可以在hub中上传你构建的prompt
prompt = hub.pull("hwchase17/openai-functions-agent")
# 打印获取的提示
print(prompt)
# 初始化一个Large Language Model(LLM)聊天实例,使用GPT-3.5 Turbo模型,并启用流模式和自定义API基础URL
llm = ChatOpenAI(model="gpt-3.5-turbo-1106", streaming=True)
# 使用LLM,工具和提示信息创建OpenAI函数代理,形成一个可运行的代理
agent_runnable = create_openai_functions_agent(llm, tools, prompt)

分享说明:转发分享请注明出处。

    热点图讯
    最新图讯
    相关图讯
    网站简介  |   联系我们  |   广告服务  |   监督电话
    本网站由国科网运营维护 国科网讯(北京)技术有限公司版权所有  咨询电话:010-88516927
    地址:北京市海淀区阜石路甲69号院1号楼1层一单元114
    ICP备案号:京ICP备15066964号-8   违法和不良信息举报电话:010-67196565
    12300电信用户申诉受理中心   网络违法犯罪举报网站   中国互联网举报中心   12321网络不良与垃圾信息举报中心   12318全国文化市场举报网站
    代理域名注册服务机构:阿里巴巴云计算(北京)有限公司