langchain入门系列之八 langgraph多agent示例

news2024/9/28 5:30:55

在之前的文章中我们介绍了langgraph,并且用它做了一个小小的示例,在本文中,我们将使用智普清言来构建多agent 系统。百度千帆对langgraph支持较差(尤其是强制要求奇数偶数的role设置,传入messages的奇数偶数要求,让人有点怀疑人生)
在这里插入图片描述

如果想快速学习langgraph建议优先使用open ai,其次是glm4也就是智普清言,官网链接,当然glm4并不是完美的,例如它现在对langchain中的ToolMessage支持还不是很好,但相对而言已经胜出qianfan太多。一家之言,听听就好。

在阅读本文之前,需要你对langgraph中的一些概念有所了解,不然阅读起来会很吃力。如下是ai生成的langgraph的一些基本知识:
LangGraph 是一个用于构建基于复杂工作流的大型语言模型(LLM)应用的开发库。它通过将任务的节点和关系以图形结构定义,支持更多样化和复杂的应用场景。
以下是 LangGraph 的一些基本概念:

状态图(StateGraph):这是 LangGraph 的核心,代表整个状态图的基础类。状态图维护一个中央状态对象,会根据节点的跳转不断更新,状态包含的属性可自行定义。
节点(Nodes):节点是 LangGraph 的基本构建块,每个节点代表一个特定的功能或计算步骤,如处理输入、做出决策或与外部 API 交互。节点可以是一个独立的操作,每个节点可以和一个方法关联起来。
边(Edges):边连接图中的节点,定义计算的流程。LangGraph 支持普通边和条件边。普通边代表上一个节点运行完成后立即进入下一个节点,而条件边则根据条件函数的返回来决定下游节点。
条件边(Conditional Edges):条件边是 LangGraph 中的一种特殊边,它根据条件函数的返回值来决定下一个执行的节点。这种边不仅需要上游节点、下游节点,还需要一个条件函数。
状态信息(State Information):在多个节点之间执行操作时,需要保持状态,这就需要用到状态信息。状态信息可以在节点之间传递和更新。
编译(Compile):对工作流进行编译,将定义好的图转换成可执行的应用。
执行(Execution):传参、执行工作流,触发工作流按预定义顺序执行相关操作。
多智能体系统(Multi-Agent System):LangGraph 支持构建多智能体系统,即多个 AI 智能体构成的系统,通过相互关联与协作共同完成任务。
工具节点(Tool Nodes):在 LangGraph 中,工具节点代表可以被调用的工具,执行特定的工具操作,如调用 API 或执行特定服务。
入口点(Entry Point):在状态图中设置的起始节点,计算将从这个节点开始。
这些概念共同构成了 LangGraph 的框架,使其能够支持复杂的 LLM 应用开发,如增强的 RAG 应用、自修复代码助手、多智能体系统构建等。通过 LangGraph,开发者可以创建具有循环计算、状态执行和条件逻辑的智能体应用。
本次主题是将英国最近5年的gpd化成图

安装依赖

%pip install -U langchain zhipuai langsmith pandas langchain_experimental matplotlib langgraph langchain_core
1、引入包,设置环境,这里需要注意的是,我们在这里设置了langsmith 和zhipu的相关参数,langsmith可以方便我们调试和监控langchain流程,TAVILY_API_KEY这个需要自己去TavilySearch官网注册一个账号使用。
import os
from langchain_community.chat_models import ChatZhipuAI
from langchain_core.messages import (
    BaseMessage,
    HumanMessage,
    ToolMessage,
)
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langgraph.graph import END, StateGraph, START
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.tools import tool
from langchain_experimental.utilities import PythonREPL
from langgraph.prebuilt import ToolNode
from IPython.display import Image, display
import operator
from typing import Annotated, Sequence, TypedDict
from typing import Literal
import functools
from langchain_core.messages import AIMessage


# 设置API
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = ""
os.environ["LANGCHAIN_ENDPOINT"] = "https://api.smith.langchain.com"
os.environ["LANGCHAIN_PROJECT"] = 'default'
os.environ["TAVILY_API_KEY"] = ""
os.environ["ZHIPUAI_API_KEY"] = ""

2、这里我们首先定义了agent的创建,再然后定义了两个工具,一个是使用@tool的语法糖自定义了一个执行python代码的工具,还有一个是TavilySearch,这个需要自己去TavilySearch官网注册一个,一个月有1000次免费的使用量。

读过前面文章的朋友对这里的llm创建应该没有问题,如果有困扰,可以在这个函数里输出prompt看一下。

def create_agent(llm, tools, system_message: str):
    """创建agent"""
    prompt = ChatPromptTemplate.from_messages(
        [
            (
                "system",
                "You are a helpful AI assistant, collaborating with other assistants."
                " Use the provided tools to progress towards answering the question."
                " If you are unable to fully answer, that's OK, another assistant with different tools "
                " will help where you left off. Execute what you can to make progress."
                " If you or any of the other assistants have the final answer or deliverable,"
                " prefix your response with FINAL ANSWER so the team knows to stop."
                " You have access to the following tools: {tool_names}.\n{system_message}",
            ),
            MessagesPlaceholder(variable_name="messages"),
        ]
    )
    prompt = prompt.partial(system_message=system_message)
    prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))
    # lecl
    return prompt | llm.bind_tools(tools)

@tool
def python_repl(
    code: Annotated[str, "The python code to execute to generate your chart."],
):
    """执行python代码"""
    try:
        result = repl.run(code)
    except BaseException as e:
        return f"Failed to execute. Error: {repr(e)}"
    result_str = f"Successfully executed:\n```python\n{code}\n```\nStdout: {result}"
    return (
        result_str + "\n\nIf you have completed all tasks, respond with FINAL ANSWER."
    )


tavily_tool = TavilySearchResults(max_results=5)
repl = PythonREPL()
3、定义agent的state结构体
class AgentState(TypedDict):
    """agent state 结构体定义"""
    messages: Annotated[Sequence[BaseMessage], operator.add]
    sender: str
4、定义agent 执行任务的函数,最后返回的结果,就是上面定义的结构体。
def agent_node(state, agent, name):
    messages = state["messages"]
    last_message = messages[-1]
    # glm4 agent 还不支持tool message,这里做一下转换
    if isinstance(last_message, ToolMessage):
        message_dict = {
            "role": "tool",
            "content": last_message.content,
            "tool_call_id": last_message.tool_call_id,
        }
        state["messages"][-1] = AIMessage(**message_dict)
    result = agent.invoke(state)
    # 将代理输出转换成适合附加到全局状态的格式
    if isinstance(result, ToolMessage):
        pass
    else:
        result = AIMessage(**result.dict(exclude={"type", "name"}), name=name, role="assistant")
    result = [result]

    return {
        "messages": result,
        "sender": name,
    }
5、实例化llm
llm = ChatZhipuAI(
    model="glm-4",
    temperature=0.01
)

6、定义agent和node

需要稍加注意的是tool_node,它包含了两种工具,后面看流程图就知道为啥它要包含两种tool。

research_agent = create_agent(
    llm,
    [tavily_tool],
    system_message="You should provide accurate data for the chart_generator to use.",
)
research_node = functools.partial(agent_node, agent=research_agent, name="Researcher")

chart_agent = create_agent(
    llm,
    [python_repl],
    system_message="Any charts you display will be visible by the user.",
)
chart_node = functools.partial(agent_node, agent=chart_agent, name="chart_generator")

tools = [tavily_tool, python_repl]
tool_node = ToolNode(tools)
7、定义路由,也就是做判断选择执行哪个流程
def router(state) -> Literal["call_tool", "__end__", "continue"]:
    # 条件路由
    messages = state["messages"]
    last_message = messages[-1]
    if last_message.tool_calls:
        # 前一个代理正在调用一个工具
        return "call_tool"
    if "FINAL ANSWER" in last_message.content:
        # 流程结束
        return "__end__"
    if len(state["messages"]) % 2 == 0:
        state["messages"].append(AIMessage(content="nothing, go on.", role="user"))
    return "continue"
8、创建工作流
# 加入node
workflow = StateGraph(AgentState)
workflow.add_node("Researcher", research_node)
workflow.add_node("chart_generator", chart_node)
workflow.add_node("call_tool", tool_node)

# 添加条件边
workflow.add_conditional_edges(
    "Researcher",
    router,
    {"continue": "chart_generator", "call_tool": "call_tool", "__end__": END},
)
workflow.add_conditional_edges(
    "chart_generator",
    router,
    {"continue": "Researcher", "call_tool": "call_tool", "__end__": END},
)

workflow.add_conditional_edges(
    "call_tool",
    lambda x: x["sender"],
    {
        "Researcher": "Researcher",
        "chart_generator": "chart_generator",
    },
)
# 添加起始边
workflow.add_edge(START, "Researcher")
graph = workflow.compile()
9、画出graph流程图
try:
    display(Image(graph.get_graph(xray=True).draw_mermaid_png()))
except Exception:
    # This requires some extra dependencies and is optional
    pass

在这里插入图片描述

10、执行工作流
events = graph.stream(
    {
        "messages": [
            HumanMessage(
               content="Fetch the UK's GDP over the past 5 years,"
                " then draw a line graph of it."
                " Once you code it up, finish."
            )
        ],
    },
    # 迭代限制
    {"recursion_limit": 150},
)


for s in events:
    print(s)
    print("-----")

结果绘图:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用好外呼机器人,帮助企业提升客户管理效率

外呼机器人,作为现代科技与企业管理的结合体,正在企业客户管理领域掀起革命性的变化。随着人工智能技术的不断进步,外呼机器人不仅实现了自动化呼叫,还能根据客户的语音情感进行相应的反馈和操作,极大地提高了客户满意…

AI大模型编写多线程并发框架(六十三):监听器优化·上

系列文章目录 文章目录 系列文章目录前言一、项目背景二、第七轮对话-补充异步执行代码三、第八轮对话-增加累计完成等字眼四、第九轮对话-线程安全优化五、第十轮对话-增加运行时数据七、参考文章 前言 在这个充满技术创新的时代,AI大模型正成为开发者们的新宠。它…

SpringBoot+Vue的图书管理系统【包含运行步骤】

SpringBootVue图书管理系统 一、项目介绍1. 图书信息管理2. 图书类型管理3. 图书借阅管理4. 用户管理 二、技术选型后端技术选型前端技术选型 三、运行步骤后端启动前端启动 四、项目演示源码获取方式 五、总结与展望 大家好,这里是程序猿代码之路!随着信…

Linux基础1-基本指令7(其他常用指令,shell简介)

目录 1.uname 2.常用小指令 3.查看系统信息的其他指令 4.shell命令及其原理 4.1这里我们简单了解一下shell 4.2 shell存在的意义? 1.uname 如何查看计算机体系架构? uname -a,查看详细信息 uname -r 查看简要信息 2.常用小指令 TAB&#x…

Socket编程---UDP篇

目录 一. UDP协议 二. Socket编程 2.1 sockaddr家族 2.2 接口介绍 三. 服务端实现 四. 服务端调用实现 五. 客户端实现 六. 效果展示 一. UDP协议 何为UDP协议的含义,上篇粗略提及了一下TCP与UDP的区别: TCP: •…

将军百战死,程序十年成

将军百战死,程序十年成 十年前的 2014.8.3 我释出了动词算子式通用代码生成器的第一个完整版本 InfinityGPGenerator 0.6.5,即无垠式通用代码生成器 0.6.5。这是一个重大的里程碑。十年后,通用代码生成器已经是一个大家族。昨天,…

插入排序的动画展示与实现

排序学习思路:先实现单趟逻辑,在实现整体逻辑;先解决普遍情况,再解决特殊情况。 什么是插入排序 回忆下自己玩扑克牌的时候是怎么把手上的牌理顺的吧!其实那就是插入排序,从左边往右边,把一张张…

强烈推荐!大模型辅助软件开发

图书推荐 作者介绍 很喜欢作者在书上的这句话了:是人类工程师的能力,而不是大模型的能力,决定了大模型协作式开发的上限。 本书内容 软件开发正在经历一场前所未有的范式变革。人工智能的飞速发展,特别是大型语言模型所取得的成…

【Python篇】Python 类和对象:详细讲解(上篇)

文章目录 Python 类和对象:详细讲解1. 什么是类(Class)类的定义 2. 什么是对象(Object)创建对象 3. 属性和方法属性(Attributes)方法(Methods)在类中定义属性和方法使用对…

使用facebook开源prophet模型预测上证指数etf股价

可以图个乐,没有那么准确,可能还需要更深入的研究分析 蓝线是预测的2024年的走势,绿线是实际走势,红线是历史和未来的分界线。结果上有蛮多差异的。 # 测试预测2024年 coded by luke 伊玛目的门徒 import akshare as ak impor…

基于Java的心灵治愈交流平台

你好呀,我是计算机学姐码农小野!如果有相关需求,可以私信联系我。 开发语言:Java 数据库:MySQL 技术:Java语言;Spring Boot框架 工具:IDEA/Eclipse、Navicat 系统展示 首页 心…

美畅物联丨实时通信新篇章:Spring Boot与WebSocket的深度融合实践

在当今 Web 应用开发领域,实时通信功能已跃升为不可或缺的基石,特别是在即时消息传递、沉浸式在线游戏体验以及精准实时数据监控等关键领域。WebSocket协议,凭借其独特的全双工通讯机制,在单个持久连接上实现了服务器与客户端之间…

软件测试面试题「值得收藏」

1、B/S架构和C/S架构区别? 1、架构不同:B/S架构是浏览器/服务器架构,C/S架构是客户端/服务器架构。 2、客户端不同:B/S架构的客户端是浏览器,C/S架构的客户端是客户端程序。 3、功能不同:B/S架构主要用于…

PhpStorm2024版设置自动换行(软换行)

Settings > Editor > General > Soft Wraps 选中并加上对应的文件

链动2+1小程序定制开发在餐饮品牌重塑中的应用探索——以“妈妈饺子馆”为例

摘要:随着互联网技术的飞速发展,餐饮业正经历着前所未有的变革。传统餐饮企业如何在激烈的市场竞争中脱颖而出,成为行业关注的焦点。本文以“妈妈饺子馆”为例,探讨链动21小程序定制开发在餐饮品牌重塑中的应用,特别是…

8 大模型微调

大部分接触大模型的同学大家可能都受限于资源的限制,无法对大模型重新训练。那么如何解决这一困境?我们暂且假定大模型为通用化模型,但是在某一方面的专业领域知识却不强,如果使用专业领域知识重新训练调整,这对资源还…

如何选到好的宠物空气净化器?有没有推荐的品牌?

从最初的手忙脚乱、对宠物养护知识一无所知的新手小白,到如今能够游刃有余地处理各种宠物问题、养宠多年的资深铲屎官,这么久,我也积累了不少的经验,就是希望能为自家的毛孩子提供最健康、最适合的生活。 这么久的养猫历程遇见的…

tcp/udp 可视化 调试工具; tcp/udp 发送客户端;查看tcp连接;netassist;packet sender;tcp view;

前言 最近对接物联设备,物联设备会往java端传送数据,在联调前,问厂商要来了样例数据,然后就找到了netassist和packetsender两款tcp发送工具,来模拟请求;还用tcpview来查看建立的连接。 netassist netass…

BERT:Pre-training of Deep Bidirectional Transformers forLanguage Understanding

个人觉着BERT是一篇读起来很爽的论文 摘要 我们引入了一种新的语言表示模型BERT,它代表Bidirectional Encoder Representations from Transformers。与最近的语言表示模型不同(Peters et al., 2018a;Radford et al., 2018), BER…

52.x86游戏实战-XXX获取房间坐标

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 工具下载: 链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…