LangChain 最近发布的一个重要功能:LangGraph

LangGraph 是 LangChain 最近发布的一个重要功能,LangChain 进入多代理框架领域。通过建立在LangChain 之上,LangGraph 使开发人员可以轻松创建强大的代理运行时。

在这里插入图片描述

LangChain 使用其表达语言(LCEL)为开发人员构建定制链提供技术支持。从数据结构的角度来看,这样的链是一个有向无环图(DAG)。然而,在实践中,用户可能希望使用代理构建循环图。换句话说,代理可以根据模型推理在循环中被调用,直到任务完成。AutoGen就是支持这种机制的框架。

LangGraph专门设计以满足这类用户的需求。换句话说,开发人员可以使用它来构建类似于AutoGen的多代理LLM应用程序。

LangGraph 提供了一种称为状态机的技术,它可以驱动循环代理调用。因此,LangGraph具有三个关键元素:

  1. StateGraph(状态图)
  2. Node(节点)
  3. Edge(边缘)

技术交流&资料

技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。

成立了大模型技术交流群,本文完整代码、相关资料、技术交流&答疑,均可加我们的交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

方式①、微信搜索公众号:机器学习社区,后台回复:加群
方式②、添加微信号:mlc2060,备注:来自CSDN + 技术交流

通俗易懂讲解大模型系列

  • 做大模型也有1年多了,聊聊这段时间的感悟!

  • 用通俗易懂的方式讲解:大模型算法工程师最全面试题汇总

  • 用通俗易懂的方式讲解:不要再苦苦寻觅了!AI 大模型面试指南(含答案)的最全总结来了!

  • 用通俗易懂的方式讲解:我的大模型岗位面试总结:共24家,9个offer

  • 用通俗易懂的方式讲解:大模型 RAG 在 LangChain 中的应用实战

  • 用通俗易懂的方式讲解:一文讲清大模型 RAG 技术全流程

  • 用通俗易懂的方式讲解:如何提升大模型 Agent 的能力?

  • 用通俗易懂的方式讲解:ChatGPT 开放的多模态的DALL-E 3功能,好玩到停不下来!

  • 用通俗易懂的方式讲解:基于扩散模型(Diffusion),文生图 AnyText 的效果太棒了

  • 用通俗易懂的方式讲解:在 CPU 服务器上部署 ChatGLM3-6B 模型

  • 用通俗易懂的方式讲解:使用 LangChain 和大模型生成海报文案

  • 用通俗易懂的方式讲解:ChatGLM3-6B 部署指南

  • 用通俗易懂的方式讲解:使用 LangChain 封装自定义的 LLM,太棒了

  • 用通俗易懂的方式讲解:基于 Langchain 和 ChatChat 部署本地知识库问答系统

  • 用通俗易懂的方式讲解:在 Ubuntu 22 上安装 CUDA、Nvidia 显卡驱动、PyTorch等大模型基础环境

  • 用通俗易懂的方式讲解:Llama2 部署讲解及试用方式

  • 用通俗易懂的方式讲解:基于 LangChain 和 ChatGLM2 打造自有知识库问答系统

  • 用通俗易懂的方式讲解:一份保姆级的 Stable Diffusion 部署教程,开启你的炼丹之路

  • 用通俗易懂的方式讲解:对 embedding 模型进行微调,我的大模型召回效果提升了太多了

  • 用通俗易懂的方式讲解:LlamaIndex 官方发布高清大图,纵览高级 RAG技术

  • 用通俗易懂的方式讲解:为什么大模型 Advanced RAG 方法对于AI的未来至关重要?

  • 用通俗易懂的方式讲解:使用 LlamaIndex 和 Eleasticsearch 进行大模型 RAG 检索增强生成

  • 用通俗易懂的方式讲解:基于 Langchain 框架,利用 MongoDB 矢量搜索实现大模型 RAG 高级检索方法

  • 用通俗易懂的方式讲解:使用Llama-2、PgVector和LlamaIndex,构建大模型 RAG 全流程

StateGraph

StateGraph 是LangChain的一个类,表示图的数据结构并反映其状态。图的状态由将很快介绍的节点更新。

class State(TypedDict):
    input: str
    all_actions: Annotated[List[str], operator.add]

graph = StateGraph(State)

Node

图中最关键的元素之一是节点。每个LangGraph节点都有一个名称和其值,它可以是LCEL中的函数或可运行项。每个节点接收一个字典类型的数据,其结构与状态定义相同。节点返回具有相同结构的更新状态。

LangGraph定义了一个称为END的特殊节点,用于识别状态机的结束状态。

from langgraph.graph import END
graph.add_node("model", model)
graph.add_node("tools", tool_executor)

Edge

在图中,节点之间的关系通过边界定义。LangGraph定义了两种类型的边:普通边和条件边。

普通边定义了上游节点应始终调用的其他节点。

graph.add_edge("tools", "model")

条件边,使用函数(路由器)来确定下游节点。

graph.add_conditional_edge(
    "model",
    should_continue,
    {
      "end": END,
      "continue": "tools"
    }
)

如上所示,条件边需要三个元素:

  1. 上游节点:边的起点,表示转换的起始点。
  2. 路由函数:此函数根据其返回值有条件地确定应进行转换的下游节点。
  3. 状态映射:根据路由函数的返回值,此映射指定下一个目的地。它将路由函数的可能返回值与相应的下游节点相关联。

运行图
在运行图之前,有两个必要的步骤需要完成:

  1. 设置入口点,以指定图中哪个节点作为入口点
graph.set_entry_point("model")
  1. 编译
app = graph.compile()

现在,我们可以运行LangGraph应用程序如下:

app.stream(
    {
        "messages": [
            HumanMessage(content="Write a tweet about LangChain news")
        ]
    }
)

用例

这是一个示例。图包含三个节点:主管、搜索引擎和 Twitter 作者。根据需要,主管可能多次调用搜索引擎以检索所需数据,然后将数据转发给Twitter作者以撰写推文。因此,在主管和搜索引擎之间存在循环。

LangChain可以帮助开发人员轻松构建基于工具的代理,然后基于这些代理创建节点。

定义图状态

class AgentState(TypedDict):
    messages: Annotated[Sequence[BaseMessage], operator.add]
    next: str

声明工具函数

@tool("web_search")
def web_search(query: str) -> str:
    """通过查询使用Google SERP API进行搜索"""
    search = SerpAPIWrapper()
    return search.run(query)

@tool("twitter_writer")
def write_tweet(content: str) -> str:
    """根据内容编写推文。"""
    chat = ChatOpenAI()
    messages = [
        SystemMessage(
            content="您是Twitter帐户操作员。您负责根据给定的内容撰写推文。您应遵循Twitter政策,并确保每条推文不超过140个字符。"
        ),
        HumanMessage(
            content=content
        ),
    ]
    response = chat(messages)
    return response.content

辅助函数 —— 使用工具创建代理

def create_agent(llm: ChatOpenAI, tools: list, system_prompt: str):
    prompt = ChatPromptTemplate.from_messages(
        [
            (
                "system",
                system_prompt,
            ),
            MessagesPlaceholder(variable_name="messages"),
            MessagesPlaceholder(variable_name="agent_scratchpad"),
        ]
    )
    agent = create_openai_tools_agent(llm, tools, prompt)
    executor = AgentExecutor(agent=agent, tools=tools)
    return executor

辅助函数 —— 使用代理创建节点

def agent_node(state, agent, name):
    result = agent.invoke(state)
    return {"messages": [HumanMessage(content=result["output"], name=name)]}

创建主管节点

members = ["Search_Engine", "Twitter_Writer"]
system_prompt = (
    "您是一名主管,负责管理以下工作者之间的对话:{members}。给定以下用户请求,使用下一步操作进行回复。每个工作者将执行一个任务,并回复其结果和状态。完成后,使用FINISH进行回复。"
)
options = ["FINISH"] + members
function_def = {
    "name": "route",
    "description": "选择下一个角色。",
    "parameters": {
        "title": "routeSchema",
        "type": "object",
        "properties": {
            "next": {
                "title": "Next",
                "anyOf": [
                    {"enum": options},
                ],
            }
        },
        "required": ["next"],
    },
}
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", system_prompt),
        MessagesPlaceholder(variable_name="messages"),
        (
            "system",
            "根据以上对话,下一个应该采取行动的人是谁?还是我们应该结束?选择一个:{options}",
        ),
    ]
).partial(options=str(options), members=", ".join(members))
supervisor_chain = (
    prompt
    | llm.bind_functions(functions=[function_def], function_call="route")
    | JsonOutputFunctionsParser()
)

创建节点和边缘

search_engine_agent = create_agent(llm, [web_search], "您是一个网络搜索引擎。")
search_engine_node = functools.partial(agent_node, agent=search_engine_agent, name="Search_Engine")
twitter_operator_agent = create_agent(llm, [write_tweet], "您负责根据给定的内容撰写推文。")
twitter_operator_node = functools.partial(agent_node, agent=twitter_operator_agent, name="Twitter_Writer")
workflow = StateGraph(AgentState)
workflow.add_node("Search_Engine", search_engine_node)
workflow.add_node("Twitter_Writer", twitter_operator_node)
workflow.add_node("supervisor", supervisor_chain)
for member in members:
    workflow.add_edge(member, "supervisor")
conditional_map = {k: k for k in members}
conditional_map["FINISH"] = END
workflow.add_conditional_edges("supervisor", lambda x: x["next"], conditional_map)

编译

workflow.set_entry_point("supervisor")
graph = workflow.compile()

现在我们可以使用此图执行任务。让我们要求它搜索LangChain新闻并撰写一条推文:

for s in graph.stream(
    {
        "messages": [
            HumanMessage(content="Write a tweet about LangChain news")
        ]
    }
):
    if "__end__" not in s:
        print(s)
        print("----")

参考文献

  • https://ai.gopubby.com/langgraph-absolute-beginners-guide-cd4a05336312
  • https://github.com/sugarforever/LangChain-Tutorials/blob/main/langgraph_nodes_edges.ipynb

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习(7)---Diffusion Model概念讲解

文章目录 一、基本概括1.1 概念讲解1.2 Denoise模块 二、Stable Diffusion2.1 概念讲解2.2 FID2.3 CLIP 一、基本概括 1.1 概念讲解 1. Diffusion Model是一种生成模型,通过连续添加高斯噪声来破坏训练数据,然后学习反转的去噪过程来恢复数据。它分为正…

go消息队列RabbitMQ - 订阅模式-fanout

1、发布订阅 订阅模式,消息被路由投递给多个队列,一个消息被多个消费者获取。 1) 可以有多个消费者 2) 每个消费者有自己的queue(队列) 3) 每个队列都要绑定到Exchange(交换机&…

【npm】安装全局包,使用时提示:不是内部或外部命令,也不是可运行的程序或批处理文件

问题 如图,明明安装Vue是全局包,但是使用时却提示: 解决办法 使用以下命令任意一种命令查看全局包的配置路径 npm root -g 然后将此路径添加到环境变量中去,这里注意,原本NodeJS的安装路径配置的环境变量不要删除&…

Sklearn、TensorFlow 与 Keras 机器学习实用指南第三版(一)

原文:Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow 译者:飞龙 协议:CC BY-NC-SA 4.0 前言 机器学习海啸 2006 年,Geoffrey Hinton 等人发表了一篇论文,展示了如何训练一个能够以最先进的精度…

Tomcat组件架构与数据流

一、背景与简介 Tomcat我们都知道是一个开源的、实现了大部分Java EE、Servlet、JSP规范的Servlet容器, 允许我们将实现了Serlvet接口的Web程序war包进行部署运行。 但是你有对Tomcat做过细致的学习么? 我相信大部分同学和我一样,之前也是只会进行简单使用&#x…

IDEA插件ChatGPT - Easycode安装使用

IDEA插件ChatGPT - Easycode简介 ChatGPT - Easycode 是一个由 OpenAI 开发的 IntelliJ IDEA 插件,它可以利用 ChatGPT 的强大语言生成能力,帮助开发人员提高编码效率。 主要功能: 代码生成:可以根据自然语言描述生成代码&…

sqli-labs-master靶场训练笔记(21-38|精英级)

2024.1.30 level-21 (cookie 注入数据加密) 从页面上就可以看出这次的数据被 baes64 加密了 中国有句古话:师夷长技以制夷 ,用base64加密后的数据即可爆出数据 加密前: admin and updatexml(1,concat(~,(select database()),~),1) and …

ReactNative实现宽度变化实现的动画效果

效果如上图所示,通过修改设备宽度实现动画效果 import React, {useRef, useEffect, useState} from react; import {Animated, Text, View, Image} from react-native;const FadeInView props > {const fadeAnim useRef(new Animated.Value(0)).current;React…

item_get_video-获取视频详情(bili.item_get_video)

B站(Bilibili)的item_get_video API用于获取视频的详细信息。通过调用该API,您将能够获得视频的基本信息、元数据、播放链接等。这使得开发者可以轻松地将B站视频集成到自己的应用程序或网站中,为用户提供更丰富的内容和更好的体验…

vue项目集成booststrap

1.首先安装bootstrap npm install bootstrap 我安装的是4.3的版本 2.在main.js中引用bootstrap import bootstrap/dist/css/bootstrap.css import bootstrap/dist/css/bootstrap.min.css import bootstrap/dist/js/bootstrap.js import bootstrap/dist/js/bootstrap.min.…

新数据不影响原来的数据

问题描述 新数据修改时,原来的数据也会受影响 const obj1 ref({ name: slx, age: 20 })const obj2 obj1obj2.value.name hhhhconsole.log(obj1, obj1.value)console.log(obj2, obj2.value)解决方法 (仅适用于对象 在这段代码中,obj1 和 obj2 指向同…

ASP.NET Core 预防开放式重定向攻击

写在前面 为预防钓鱼网站的常用套路,在进行 Web 应用程序的开发时,原则上应该将所有由用户提交的数据视为不可信。如果应用程序中包含了基于 URL 内容重定向的功能,需要确保这种类型的重定向操作只能在应用本地完成,或者明确判断…

MQTT在linux下服务端和客户端的应用

MQTT(Message Queuing Telemetry Transport)是一种轻量级、开放标准的消息传输协议,设计用于受限设备和低带宽、不稳定网络的通信。 MQTT的一些关键特点和概念: 发布/订阅模型: MQTT采用发布/订阅(Publ…

编译原理本科课程 专题5 基于 SLR(1)分析的语义分析及中间代码生成程序设计

一、程序功能描述 本程序由C/C编写,实现了赋值语句语法制导生成四元式,并完成了语法分析和语义分析过程。 以专题 1 词法分析程序的输出为语法分析的输入,完成以下描述赋值语句 SLR(1)文法的语义分析及中间代码四元式的过程,实现…

基于tomcat的https(ssl)双向认证

一、背景介绍 某个供应商服务需要部署到海外,如果海外多个地区需要部署多个服务,最好能实现统一登录,这样可以减轻用户的使用负担(不用记录一堆密码)。由于安全问题(可能会泄露用户数据)&#x…

【大厂AI课学习笔记】1.5 AI技术领域(1)计算机视觉

人工智能的三大基础应用领域是,自然语言处理,语音识别,计算机视觉。 计算机视觉:定义、关键技术、技术发展、应用场景与商业化成功 一、计算机视觉的定义 计算机视觉,作为一个跨学科的领域,旨在研究如何让…

ArcGIS Pro 按照字段进行融合或拆分

ArcGIS Pro 按字段融合 在ArcGIS Pro中,通过使用“融合”工具可以轻松地合并具有相同字段的图层。 步骤一:打开ArcGIS Pro 启动ArcGIS Pro应用程序,确保您已经登录并打开您的项目。 步骤二:添加图层 将包含相同字段的图层添加到…

【Linux】信号-上

欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:题目解析 🌎推荐文章:【LeetCode】winter vacation training 目录 👉🏻信号的概念与产生jobs命令普通信号和实…

牛客网-------------------------长方体

解题思路: 设棱长为x,y,z;假设已知面积为a,b,c 那么,xya;yzb;xzc; 一式除二式得x/za/b x(a/b)*z 联立xzc 代入得(a/b)z^2c z^2c*b/a z根号下&…

Windows自动化实现:系统通知和任务栏图标自定义

文章目录 Windows自动化的三个小工具系统通知任务栏图标使用pystray实现使用infi.systray实现 Windows自动化的三个小工具 系统通知 import win10toastwin10toast.ToastNotifier().show_toast("eee", "休息一下", icon_path"icon.ico", durati…