Python——学习LangGraph智能体(一)

引言——LangGraph

Langgraph,官网网址:https://langgraph.com.cn/index.html

核心优势

LangGraph 为任何长时间运行、有状态的工作流或智能体提供底层支持基础设施。LangGraph 不抽象提示或架构,并提供以下核心优势:
持久执行:构建能够抵御故障并长时间运行的智能体,可从上次中断的地方自动恢复。
人机协作:在执行的任何时间点检查和修改智能体状态,无缝地融入人工监督。
全面记忆:创建真正有状态的智能体,既具备用于持续推理的短期工作记忆,也具备跨会话的长期持久记忆。
使用 LangSmith 进行调试:利用可视化工具深入了解复杂的智能体行为,这些工具可以追踪执行路径、捕获状态转换并提供详细的运行时指标。
生产就绪部署:利用可扩展的基础设施,自信地部署复杂的智能体系统,该基础设施旨在处理有状态、长时间运行工作流的独特挑战。

LangGraph 的生态系统

虽然 LangGraph 可以独立使用,但它也能与任何 LangChain 产品无缝集成,为开发人员提供构建智能体所需的全套工具。为了改进您的 LLM 应用程序开发,请将 LangGraph 与以下产品搭配使用:
LangSmith — 有助于智能体评估和可观察性。调试性能不佳的 LLM 应用程序运行、评估智能体轨迹、在生产环境中获得可见性,并随着时间的推移提高性能。
LangGraph 平台 — 使用专为长时间运行、有状态工作流设计的部署平台,轻松部署和扩展智能体。在团队之间发现、重用、配置和共享智能体 — 并在LangGraph Studio中通过可视化原型快速迭代。
LangChain – 提供集成和可组合组件,以简化 LLM 应用程序开发。

环境——前期准备

Python环境:3.12 (推荐3.9+)

pip install langgraph langchain langchain-openai langchain-community python-dotenv

python-dotenv依赖主要是为了读取根目录.env中配置(也可在项目中直接赋值)

.env文件配置

在根目录创建.env文件(本人使用的是智谱的APIkey,阿里云百炼的亦可用,后面只需要对应修改base-url即可

# 智谱 API Key
ZHIPUAI_API_KEY=这里填写apikey

搭建简单智能体

创建py文件:langgraph-base.py文件,附上全部代码,如下:(工作流程大概就是,如果提示词中存在“上海”或者“Shanghai”,则调用工具,workflow.add_edge(“tools”, “agent”)这一句代码即是如果调用了工具,那么就要再次回答agent节点。
附上流图(虚线为条件边,实现为普通边,如图在tools被调用之后,那么必定会调用agent
在这里插入图片描述

import os
from typing import Literal
from langchain_core.messages import HumanMessage
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
load_dotenv()  #使用此方法是为了刷新.env环境配置中的apikey,以防止下方初始化模型失败
from langgraph.checkpoint.memory import MemorySaver #类似于上下文存储,存放的记忆节点
from langgraph.graph import StateGraph, START, END, MessagesState   # 对应的langgraph的边,图思想
from langgraph.prebuilt import ToolNode

@tool
def search(query: str):
    """模拟一个搜索工具"""
    if "上海" in query.lower() or "Shanghai" in query.lower():
        return "现在30度,有雾"
    return "现在是35度,阳光明媚"


# 将工具函数放入工具列表
tools = [search]

# 创建工具节点
tool_node = ToolNode(tools)

# 1.初始化模型和工具,定义并绑定工具到模型
# 初始化智谱模型
model = ChatOpenAI(
    model="glm-4.7", #如果使用的火山方舟或者阿里云百炼,则对应修改,注意填写的是对应的模型编码
    openai_api_key=os.getenv("ZHIPUAI_API_KEY"),
    openai_api_base="https://open.bigmodel.cn/api/paas/v4/", #如果使用的火山方舟或者阿里云百炼,则对应修改
    temperature=0,
).bind_tools(tools)


# 定义函数,决定是否继续执行
def should_continue(state: MessagesState) -> Literal["tools", END]:
    messages = state['messages']
    last_message = messages[-1]
    if last_message.tool_calls:
        return "tools"
    return END

# 定义调用模型的函数
def call_model(state: MessagesState):
    messages = state['messages']
    response = model.invoke(messages)
    return {"messages": [response]}

# 2.初始化图,定义一个新的状态图
workflow = StateGraph(MessagesState)

# 3.定义图节点,定义我们将循环的两个节点
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)


# 4.定义入口点和图边
# 设置入口点为agent
# 这意味着是第一个被调用的节点
workflow.set_entry_point("agent")

# 添加条件边
workflow.add_conditional_edges(
    # 首先,定义起始节点,我们使用 “agent”
    # 这意味着这些边是在调用 "agent "节点后采取的
    "agent",
    #接下来,传递决定下一个调用节点的函数
    should_continue,
)

# 添加从"tools" 到"agent"的普通边
# 这意味着每次调用 "tools "节点后,都会调用 "agent "节点
workflow.add_edge("tools", "agent")

# 初始化内存以在图运行之前持久化状态
checkpointer = MemorySaver() #可以存redis或者是MongoDB

# 5.编译图
# 这将其编译成一个LangChain可运行对象
# 这意味着你可以像使用其他可运行对象一样使用它
# 注意,我们(可选的)在编译图时传递内存
app = workflow.compile(checkpointer=checkpointer) #做一个预检查

# 6.执行图,使用可运行对象
final_state = app.invoke(
    {"messages":[HumanMessage(content="上海的天气怎么样?")]},
    config={"configurable":{"thread_id":42}} #相同的线程id可以记录记忆
)

# 从final_state 中获取最后一条消息的内存
result = final_state["messages"][-1].content
print(result)


print("-----第二轮对话-----")
# 继续对话
final_state = app.invoke(
    {"messages":[HumanMessage(content="我问的哪个城市")]},
    config={"configurable":{"thread_id":42}}
)
result = final_state["messages"][-1].content
print(result)


#将生成的图片保存到文件(为了看到智能体的工作流图)后续附上
graph_png = app.get_graph().draw_mermaid_png()
with open("langgraph_base.png", "wb") as f:
    f.write(graph_png)

程序输出

使用了两次对话,去测试记忆节点。(thread_id去控制,如果thread_id不相同,则没有记忆),针对小型项目,可以结合redis中去,存放数据库专门去存储这些数据,后续学习或有更好的处理方式

根据最新的天气信息,上海现在的天气情况是:

- **温度**:30度
- **天气状况**:有雾

天气比较温暖,不过有雾,出行时请注意交通安全,能见度可能较低。建议您根据这个天气情况合理安排出行和着装。
-----第二轮对话-----
您问的是上海这个城市。

注意事项

即使代码都一模一样,但是第二次回答却没有记忆的话,原因:
1)查看一下两次对话通过invoke发出时,设置的config的thread_id是否一致,不一致的话,会话不相同,则无记忆。
2)仅有可能是模型能力的问题,导致上下文丢失(作者出现过的问题:使用glm-4-flash这个模型,那么始终都无法得到正确的上下文对话,随后使用了glm-4.7或者是glm-4.6,最后得以解决。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐