对于最新版本的LangChain,我们可以利用LangGraph以“图”的形式编排一个具有复杂交互流程的Agent。工厂函数内部本质上也是利用的这种方式。由于Agent从执行层面来看就是一个Pregel对象,一个由节点和通道构建而成的Actor模型。综上所述,利用构建的Agent,其实也可以利用其他两种方式来创建。接下来我们就使用三种不同的编程模式构建一个等效的Agent。
我们直接使用前面演示的“天气查询”的例子。下面演示的是利用工厂函数针对Agent的构建。Agent使用的模型是基于“gpt-5.2-chat”的(相关设置定义在.env文件中,利用dotenv加载到环境变量)。注册的工具用于提供指定城市的天气信息。
执行程序会输出如下所示的交互消息列表(由于temperature默认值为0.7,LLM每次返回的结构具有差异):
我们采用单纯的LangGraph编程Agent 智能体模式改写了上面的例子。我们利用函数定义了代表模型的model节点和用于执行所有工具的tools节点。我们使用作为全局状态,它同时也作为Agent的输入和输出,我们只用到定义其中的字段成员。工具(目前只用到这个单一工具)被注册到表示的字典中,并同时绑定到作为LLM的对象上。
代表model节点的函数执行的时候会将状态对象承载的消息列表作为输入调用,返回的AIMessage被组装成一个但元素列表被置于model函数返回的字典,对应的Key为“messages”,意味着这个最终被被添加到的列表中。
model节点执行后是直接结束整个流程还是执行tools节点,取决于但会的中是否携带,后者提供了待执行的工具。这个路由逻辑被定义在path函数中。用于执行工具的tools节点被执行的时候,它会从的列表中提取最后一个消息(),并提取所有的,然后从中提取对应的工具对象予以执行,执行结构被封装成。所有的合并的列表同样被置于tools函数返回的字典中,最终被添加到的列表中。简单起见,我们这里采用按顺序同步执行的方式,实际上所有的工具是并发执行的。
两个节点定义好之后,我们将它们添加到创建的StateGraph对象中,并将model节点作为入口节点。我们添加了从model节点到tools或者”end“节点的“条件边”,路由条件为path函数。由于tools节点提供的总是需要提交给model节点处理,我们添加了它们之间的边。在编译StateGraph得到Agent之后,我们按照原来的方式调用它,同样会得到类似的结果:
如下的程序演示了直接定义作为Agent的对象。整个Pregel对象由两个节点(model和tools)和三个通道,其中通道类型为,用于存储消息列表,通道model和tools则作为对应节点的驱动通道。
利用构建的model节点会订阅model驱动通道,并从输入通道中读取消息列表。当它执行的时候会调用作为LLM的(预先绑定了注册的工具)。由于只有返回的携带的前提下它才会写入tools节点的驱动通道,所以我们将这个动态的逻辑定义在map函数中,该函数返回的二元组列表被用于创建,后者用于通道的写入。
函数会从messages通道中提取消息列表,如果最后一个包含,它会返回针对tools和messages通道的两个二元组,意味着model执行后除了将生成的写入messages通道之外,它还会写入tools通道驱动执行tools节点。否则它只返回针对messages通道的二元组,意味着被写入messages通道之后,两个驱动通道都没有变化,整个执行流程结束。
tools节点执行的时候,它会从messages通道中提取消息列表,并从最后一个中提取所有的,然后从中提取对应的工具对象予以执行。所有工具执行的结构被封装成后,统一写入messages通道,然后写入model通道驱动执行model节点。
我们针对定义的节点和通道将Pregel对象创建出来。由于model是入口节点,所以我们将model和messages作为输入通道,messages作为输出通道返回消息列表。按照相同的方式执行Pregel对象后,我们同样会得到类似的输出:
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/273003.html原文链接:https://javaforall.net
