深入浅出LangGraph AI Agent智能体开发教程(八)—LangGraph底层API实现ReACT智能体

前言

本系列前七篇文章:

通过上期分享我们掌握了利用LangGraph搭建条件分支图、条件循环图等复杂图的能力,本期分享我们深入利用LangGraph底层API实现多轮问答机器人,并复现create_react_agent方法的ReACT图结构智能体。

本系列分享是笔者结合自己学习工作中使用LangChain&LangGraph经验倾心编写的,力求帮助大家体系化快速掌握LangChain&LangGraph AI Agent智能体开发的技能!笔者的LangChain系列教程暂时更完,后面也会实时补充工作实践中的额外知识点,建议大家在学习LangGraph分享前先学习LangChain的基本使用技巧。大家感兴趣可以关注笔者掘金账号和系列专栏。更可关注笔者同名微信公众号: 大模型真好玩 , 每期分享涉及的代码均可在公众号私信: LangChain智能体开发获得。

一、LangGraph多轮对话机器人搭建

首先通过使用LangGraph底层API搭建多轮对话机器人来学习如何将大语言模型作为节点加入到LangGraph图中。

  1. 构建图的第一步首先要定义图的结构化状态State,代码如下。使用TypedDict创建具有特定键值类型的字典类来规范状态结构,其中messages键是一个列表,我们通过Annotated注解指定使用add_messages函数来处理消息的累积更新。
python 复制代码
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph
from langgraph.graph.message import add_messages


class State(TypedDict):
    messages: Annotated[list, add_messages]

graph_builder = StateGraph(State)

大家可能对这里使用的add_messages函数感到好奇,这个函数有什么作用呢? 为什么不用append直接向消息列表中增加消息呢?因为LangGraph图运行时有一套单独的逻辑,直接使用append有可能产生bug, 且不易调试。add_messages是LangGraph预定义的一个函数,核心逻辑是合并两个消息列表,默认状态为仅附加。add_messages函数接收两个参数,一个是消息的基本列表(比如上述的messages),另一个是要合并到基本列表中的消息列表(或单个消息)。值得注意的是: LangGraph对每条消息都使用ID进行编号,如果add_messages合并的列表中包含ID相同的消息,add_messages默认行为是使用要合并列表中的新消息替换掉基本列表中相同ID的消息。

  1. 第二步要添加一个大模型节点,我们命名为chatbot,同时定义边连接开始节点START与大模型节点chatbot。这里初始化大模型使用我们之前讲到的init_chat_model方法,大家不熟悉可参考系列文章深入浅出LangGraph AI Agent智能体开发教程(二)---LangGraph预构建图API快速创建Agent
python 复制代码
from langchain.chat_models import init_chat_model
from langgraph.constants import START

model = init_chat_model(
    model="deepseek-chat",
    model_provider="deepseek",
    api_key='你注册的deepseek api key'
)

def chatbot(state: State):
    return {"messages": [model.invoke(state["messages"])]}

# 添加节点
graph_builder.add_node("chatbot", chatbot)

# 添加边
graph_builder.add_edge(START, "chatbot")

以上代码构造的图结构如下,是不是非常简单:

  1. 第三步编译创建好的图,并通过graph.invoke()向图结构发送请求,图结构运行完成后返回最终的state, 我们可以通过state['messages']获取本次图运行的消息列表,也可通过state['messages'][-1]得到图结构最后的输出:
python 复制代码
graph = graph_builder.compile()
final_state = graph.invoke({"messages": ["你好,我叫陈明,好久不见。"]})
print(final_state['messages'])
  1. 单轮对话的例子我们已经完成,多轮对话也不在话下。LangGraph多轮对话的原理和LangChain一样,也是通过构造消息列表实现多轮对话的功能,大家可参考文章深入浅出LangChain AI Agent智能体开发教程(四)---LangChain记忆存储与多轮对话机器人搭建, 这里不再赘述, 修改代码如下:
python 复制代码
from langchain_core.messages import AIMessage, HumanMessage
messages_list = [
    HumanMessage(content="你好,我叫大模型真好玩,好久不见。"),
    AIMessage(content="你好呀!我是苍老师,是一名女演员。很高兴认识你!"),
    HumanMessage(content="请问,你还记得我叫什么名字么?"),
]
final_state = graph.invoke({"messages": messages_list})
print(final_state['messages'])

二、LangGraph底层API复现create_react_agent预构建图

上述分享我们掌握了将大模型接入LangGraph底层图结构的方法,对今天的分享来说以上内容只是开胃小菜,本期分享的终极目标是使用LangGraph 底层 API 复现高级API create_react_agent 预构建ReACT图。

  1. 定义图状态: 第一步还是定义图状态,它同样只包含一个消息列表,需要用到add_messages方法。
python 复制代码
from typing import (
    Annotated,
    TypedDict,
)

from langgraph.graph import StateGraph
from langgraph.graph.message import add_messages


class AgentState(TypedDict):
    messages: Annotated[list, add_messages]

graph_builder = StateGraph(AgentState)
  1. 定义模型和工具: 智能体构建的三大要素:提示词,模型和工具,我们这里先准备模型和工具函数, 模型同样使用deepseek-chat, 工具函数访问心知天气API获得当前城市的天气情况。注意需要手动调用model.bind_tools方法绑定大模型和工具函数。LangGraph定义工具函数并绑定模型的方法与LangChain一致,前面内容已经详细分享过。大家不熟悉可参考深入浅出LangChain AI Agent智能体开发教程(五)---LangChain接入工具基本流程
python 复制代码
from langchain.chat_models import init_chat_model
from langchain_core.tools import tool
from pydantic import BaseModel, Field
import requests

# 定义工具
class WeatherQuery(BaseModel):
    loc: str = Field(description="城市名称")


@tool(args_schema=WeatherQuery)
def get_weather(loc):
    """
        查询即时天气函数
        :param loc: 必要参数,字符串类型,用于表示查询天气的具体城市名称,\
        :return:心知天气 API查询即时天气的结果,具体URL请求地址为:"https://api.seniverse.com/v3/weather/now.json"
        返回结果对象类型为解析之后的JSON格式对象,并用字符串形式进行表示,其中包含了全部重要的天气信息
    """
    url = "https://api.seniverse.com/v3/weather/now.json"
    params = {
        "key": "你注册的心知天气api key",
        "location": loc,
        "language": "zh-Hans",
        "unit": "c",
    }
    response = requests.get(url, params=params)
    temperature = response.json()
    return temperature['results'][0]['now']

# 定义模型
model = init_chat_model(
    model='deepseek-chat',
    model_provider='deepseek',
    api_key='你注册的deepseek api key'
)

tools = [get_weather]
model = model.bind_tools(tools)
  1. 定义节点和边: ReACT图结构包含两个节点, 一个用于调用模型call_model,一个用于使用工具ToolNodecall_model节点函数中给大模型提供提示词,使其具备调用天气函数的能力。ToolNode函数我们首次利用LangGraph三层结构中中间层的ToolNode节点。大家可以看结构图进行定位:

ReACT图结构除了两个节点外,还需要大模型来判断是直接输出结果还是调用工具函数,很显然需要一个判断条件来构造条件分支图。这里还需要定义should_continue方法返回条件来判断结束还是调用工具,如果大模型节点返回结果中包含tool_calls键,则说明要调用相关函数,否则结束。添加代码如下:

python 复制代码
from langchain_core.messages import SystemMessage
from langgraph.prebuilt import ToolNode

def call_model(
    state: AgentState,
):
    system_prompt = SystemMessage(
        "你是一个AI助手,可以依据用户提问产生回答,你还具备调用天气函数的能力"
    )
    response = model.invoke([system_prompt] + state["messages"])
    return {"messages": [response]}

tool_node = ToolNode(tools)

def should_continue(state: AgentState):
    messages = state["messages"]
    last_message = messages[-1]
    if not last_message.tool_calls:
        return "end"
    else:
        return "continue"
  1. 定义图: 定义好所有的节点和判断条件后,我们参考ReACT图来定义并编译图。将call_modeltool_node节点加入图中并关联相应边,随后调用graph.compile方法编译可执行图。
python 复制代码
from langgraph.graph import StateGraph, START, END
graph = StateGraph(AgentState)

graph.add_node("agent", call_model)
graph.add_node("tools", tool_node)

graph.add_edge(START, "agent")
graph.add_edge("tools", "agent")
graph.add_conditional_edges(
    "agent",
    should_continue,
    {
        "continue": "tools",
        "end": END,
    },
)

graph = graph.compile()
  1. 执行ReACT代理: 这部分代码简单不加赘述,执行结果如下,我们可以看到图成功调用了工具函数并返回结果,一个自定义的ReACT图就完成啦!
python 复制代码
final_state = graph.invoke({"messages": ["请问上海天气如何?"]})
print(final_state['messages'])

三、总结

本期内容分享如何使用底层API构建多轮对话机器人和复现ReACT图结构智能体。通过定义状态、添加模型节点和工具节点,结合条件分支图实现ReACT图的工具调用与决策循环,并通过天气助手实例演示完整的开发流程,帮助大家掌握LangGraph的灵活性与强大功能。目前的图结构还有很多需要优化的点,例如如何让智能体优雅的保存记忆,如何实现智能体的流式调用提升交互体验等等,我们下期内容继续分享,大家期待一下吧~

本系列分享预计会有20节左右的规模,保证大家看完一定能够掌握LangChain&LangGraph的开发能力,大家感兴趣可关注笔者掘金账号和专栏,更可关注笔者的同名微信公众号:大模型真好玩 , 本系列分享的全部代码均可在微信公众号私信笔者: LangChain智能体开发 免费获得。

相关推荐
IT_陈寒2 小时前
告别低效!用这5个Python技巧让你的数据处理速度提升300% 🚀
前端·人工智能·后端
北京耐用通信3 小时前
神秘魔法?耐达讯自动化Modbus TCP 转 Profibus 如何为光伏逆变器编织通信“天网”
网络·人工智能·网络协议·网络安全·自动化·信息与通信
居7然3 小时前
如何高效微调大模型?LLama-Factory一站式解决方案全解析
人工智能·大模型·llama·大模型训练·vllm
FullmetalCoder3 小时前
一文搞懂智能体
人工智能
zzywxc7873 小时前
AI 行业应用:AI 在金融、医疗、教育、制造业等领域的落地案例
人工智能·spring·金融·prompt·语音识别·xcode
六月的可乐3 小时前
Vue接入AI聊天助手实战
前端·vue.js·人工智能
赴3353 小时前
dlib库关键点定位和疲劳检测
人工智能·opencv·计算机视觉·关键点·疲劳检测·dlib
汀丶人工智能4 小时前
AI Compass前沿速览:Qwen3-Max、Mixboard、Qwen3-VL、Audio2Face、Vidu Q2 AI视频生成模型、Qwen3-Liv
人工智能