一起来学 Langgraph [第一节]

langgraph系列博客总体介绍

这是一个系列博客,通过学习Langgraph官方文档自我总结而来、本篇是系列第一篇。

Langgraph是目前比较成熟的大模型应用开发框架。该框架通过节点编排的方式,可以构建非常复杂的大模型应用,强如工作流编排中的王者 n8n 在底层也用到Langgraph的相关技术。

学习该技术还有一个原因在于目前在Java领域缺少对标图编排框架,据笔者了解目前仅有 SpringAI Alibaba 模仿 Langgraph 做出来了一个类似的项目 Spring AI Alibaba Graph 读者也可以通过 这篇文章了解一下,两者的设计思路几乎一致,如果后续读者有需要,也可以单出一期来介绍下Spring AI Alibaba Graph 的相关内容。

读者在阅读系列博客之前请确保对python的装饰器、推导式、类型注解有基本的知识储备

系列博客使用的大模型依然是阿里的通义千问(qwen-max),而不是OpenAI,需要读者自己申请一个千问的API-Key,如何申请这个key在笔者之前的博客都有介绍。Langgraph官方文档给出的案例大多是基于国外大模型的,本文博客则是全程使用通义千问模型相信这会对国内开发大模型的开发者而言使用门槛会更低一点。系列博客也会把使用到的国产大模型时遇到的一些问题给出个人研究的解决方案。

如果系列博客对读者有帮助欢迎点赞、评论一起交流。

一、引言

本节主要介绍langGraph的基本概念,并以一个例子为例介绍如何使用langGraph以及langGraph对应的调试工作台 langGraph-studio,

二、基本概念

LangGraph 将Agent 工作流的开发 建模为图,使用三个关键组件来定义Agent的工作流

  • State 代表您应用程序当前快照的共享数据结构。它可以任何 Python 类型,但通常是 TypedDict 或 MessagesState ,我们开发智能体工作流第一步就是要定义State,这个有点类似Java编程中的上下文对象的概念
  • Nodes Python 函数,用于编码您的代理的逻辑。它们接收当前的 State 作为输入,执行一些业务逻辑,并返回一个被更新的 State 。
  • Edges Python 函数,根据当前的 State 确定下一个要执行的 Node 。它们可以是条件分支或固定转换。

上述三个组件是构建复杂Agent的基石,下面直接展示一个例子说明上述组件的作用,langGraph提供了脚手架工具,可以直接快速创建一个Agent工程

三、langGraph代码脚手架和langGraph-studio使用

第一步:安装langGraph代码脚手架工具

commandline 复制代码
pip install --upgrade "langgraph-cli[inmem]"

第二步:使用langGraph代码脚手架工具创建一个Agent工程

commandline 复制代码
langgraph new path/to/your/app --template react-agent-python

上面的命令需要你把路径改为你需要创建工程的路径,模版你可以指定也可以不指定,如果不指定模版,后续会让你选择使用哪个模板创建项目,如下图所示

第三步:安装依赖

进到项目目录下执行如下命令安装依赖

commandline 复制代码
pip install -e .

第四步:修改配置文件

生产的项目中存在一个.env.example 文件,需要修改成.env文件,内容也需要做下修改 本文使用qwen-max模型,所以需要追加通义千问的API-key,此外由于我们后面需要使用lang-smith追踪大模型调用细节,这里还额外配置了lang-smith的API-Key,当然不配置这个API-key也不影响项目启动

properties 复制代码
# To separate your traces from other application
LANGSMITH_PROJECT=new-agent

OPENAI_API_KEY=sk-xxx
DASHSCOPE_API_KEY=sk-xxxxxxxx
LANGSMITH_API_KEY=lsv2_xxxxx

第五步:了解项目结构

最终生成的目录结构如下

红色框线标注的文件是我们需要关注的重点,下面做下简单的解释:

  • src:源码目录,是写python代码的位置
  • .env:记录项目环境变量信息,API-Key一般写在这个文件中
  • pyproject.toml:记录项目依赖
  • langgraph.json:langGraph-studio 核心配置文件,一个典型配置如下,最重要的配置是graphs,一个项目里面可能有多个图,langGraph-studio会读取graphs配置,进行图的结构切换
json 复制代码
{
  "dockerfile_lines": [], 
  "graphs": {
    "simple_graph": "./simple.py:graph",
    "router": "./router.py:graph",
    "agent": "./agent.py:graph"
  },
  "env": ".env",
  "python_version": "3.11",
  "dependencies": [
    "."
  ]
}

第六步:启动项目

默认情况下langgraph项目启动后langgraph-studio会占用2024端口,可以使用下面的命令指定运行端口

commandline 复制代码
langgraph dev --port 8000

页面效果如下

至此项目准备完毕,接下来我们开始编写代码,后续还会继续介绍这个langGraph-studio和smith的使用。

在langgraph-studio中,我们可以直观的看到这个图的结构,但是我们也可以直接在代码中生成这个图的png文件,代码如下:

python 复制代码
from langchain_core.runnables.graph import MermaidDrawMethod
# graph = workflow.compile(checkpointer=memory)
png_bytes = graph.get_graph().draw_mermaid_png(draw_method=MermaidDrawMethod.API)
with open("graph.png", "wb") as f:
    f.write(png_bytes)

执行上面的代码会在本地项目目录下面直接生成 graph.png 文件

四、强大的Langgraph学习助手【重要】

在过去我们想要学习一门技术最大的问题就是如果遇到官方文档中不理解的地方就只能自己检索大量资料,缺少一名老师为我们答疑解惑,但是现在学习Langgraph一切都变得不一样了。Langgraph官方为我们设计了一个AI辅助我们学习相关技能

链接地址为: chat.langchain.com/

界面如下:

这种学习助手对于快速掌握一门技术真的非常好用,真希望国内一些中间件的开发厂商或者框架设计者也能学习Langgraph的这种思路,开发一个助手应用辅助开发者快速掌握框架的基本用法。

五、开发第一个helloWorld

我们修改agent目录下的graph.py 文件,改成下面的内容:

python 复制代码
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict


# 定义输入模式
class InputState(TypedDict):
    question: str


# 定义输出模式
class OutputState(TypedDict):
    answer: str


# 定义State 
class OverallState(InputState, OutputState):
    pass


# 定义节点
def answer_node(state: InputState):
    return {"answer": "bye", "question": state["question"]}


# 构建图结构
builder = StateGraph(OverallState, input=InputState, output=OutputState)
builder.add_node(answer_node)  # Add the answer node
builder.add_edge(START, "answer_node") 
builder.add_edge("answer_node", END) 
graph = builder.compile()  

#  调用图
print(graph.invoke({"question": "hi"}))

在这个入门例子里我们发现Langgraph可以通过 add_node 向图中添加节点, add_edge 来向图中添加边,还可以通过State来进行参数传递。

执行 langgraph dev 运行项目后浏览器自动打开 langsmith studio (smith.langchain.com/studio/?bas... 效果如下:

我们可以在输入框输入任意内容,最终图会给出输出"bye"

上面的例子只是一个基本的使用案例,甚至连大模型节点都没有使用上,但是万丈高楼平地起,从这个案例开始我们将逐步学习更多内容,在后面的博客中,我们还会学习工具调用、会话记忆、会话中断、人为干预等一系列内容。

相关推荐
考虑考虑1 小时前
Springboot3.5.x结构化日志新属性
spring boot·后端·spring
涡能增压发动积1 小时前
一起来学 Langgraph [第三节]
后端
sky_ph2 小时前
JAVA-GC浅析(二)G1(Garbage First)回收器
java·后端
涡能增压发动积2 小时前
一起来学 Langgraph [第二节]
后端
hello早上好2 小时前
Spring不同类型的ApplicationContext的创建方式
java·后端·架构
roman_日积跬步-终至千里2 小时前
【Go语言基础【20】】Go的包与工程
开发语言·后端·golang
00后程序员3 小时前
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
后端
HyggeBest3 小时前
Mysql的数据存储结构
后端·架构
TobyMint4 小时前
golang 实现雪花算法
后端
G探险者4 小时前
【案例解析】一次 TIME_WAIT 导致 TPS 断崖式下降的排查与优化
后端