AI创想

标题: LangGraph详解:专注推理流程,让AI Agent“会思考、能落地” [打印本页]

作者: 米落枫    时间: 9 小时前
标题: LangGraph详解:专注推理流程,让AI Agent“会思考、能落地”
作者:CSDN博客
在AI智能体(Agent)技术快速迭代的今天,单一的“检索+生成”模式已难以满足企业级复杂任务的落地需求——当智能体需要处理多步骤推理、多工具串联调用、动态决策等场景时,“思考流程混乱、行动不可控、调试难度大”等问题便会凸显。而LangGraph作为LangChain团队推出的专用推理框架,以状态机为核心,聚焦复杂AI Agent推理流程的编排,让智能体的思考和行动更有序、更可控,成为工业级智能体落地的“核心引擎”。
本文将从核心定位、技术原理、核心功能、实操示例、优缺点及适用场景六大维度,全方位拆解LangGraph,帮你彻底掌握这一框架的核心逻辑,无论是学习、开发还是面试,都能直接复用知识点。
一、核心定位

LangGraph的核心定位是:基于状态机(State Machine),构建可控制、可调试、可循环的复杂AI Agent推理流程
与LlamaIndex(专注检索增强)、AutoGen(专注多智能体协作)不同,LangGraph的核心价值的是“优化单个智能体的推理过程”——它不负责数据检索(可无缝对接LlamaIndex),也不负责多智能体分工(可对接AutoGen),而是专注于让智能体“学会有序思考、高效行动”。
简单来说,LangGraph通过“节点(Node)+ 边(Edge)”的状态机结构,将智能体的“思考、行动、观察”等步骤进行结构化编排,支持循环执行、分支判断和状态管理,让智能体能处理多步骤、高复杂度的任务,真正实现从“简单响应”到“复杂推理”的跨越,满足工业级落地的需求。
二、核心技术原理

LangGraph的核心技术围绕“状态机驱动的推理流程”展开,核心逻辑是:将智能体的推理过程拆解为“思考、行动、观察”等独立步骤(抽象为节点),再定义步骤之间的流转规则(抽象为边),通过状态层存储推理过程中的所有信息,实现步骤的循环执行、分支判断,最终构建出可控、可追溯的复杂推理流程。
其底层架构分为“状态层、节点层、边层、执行层”四层,每层各司其职、协同工作,具体拆解如下:
2.1 状态层(State Layer)—— 智能体的“记忆中枢”

状态层是LangGraph的核心,相当于智能体的“大脑记忆”,负责存储推理过程中的所有信息,确保流程的连贯性和可追溯性,解决了传统智能体“健忘、上下文断裂”的痛点。
2.2 节点层(Node Layer)—— 智能体的“思考和行动单元”

节点是LangGraph中最基础的执行单元,每个节点对应智能体的一个“思考或行动步骤”,相当于智能体的“一个个具体动作”。节点分为“普通节点”和“条件节点”两种类型,可灵活组合实现复杂推理逻辑。
2.3 边层(Edge Layer)—— 智能体的“流程流转规则”

边是节点之间的“流转关系”,定义了“一个节点执行完成后,下一步该执行哪个节点”,相当于智能体的“行动路线图”。边分为“固定边”和“条件边”两种,适配不同的流转场景。
2.4 执行层(Execution Layer)—— 智能体的“流程驱动引擎”

执行层是LangGraph的“动力核心”,负责驱动整个推理流程的运行,确保节点按边的流转规则有序执行,直到满足终止条件(done=True),输出最终结果。
三、核心功能总结

LangGraph的功能围绕“复杂推理流程编排”展开,覆盖推理、调试、扩展等全场景,核心功能可总结为8点,兼顾实用性和扩展性:
四、实操示例

本次示例基于LangGraph,实现一个“ReAct推理框架的天气查询智能体”,功能:接收用户天气查询需求→思考需调用的工具→调用天气工具→处理结果→生成回答,全程实现循环执行和状态管理,可直接复制运行。
4.1 前提准备

安装依赖包,配置OpenAI API Key(可替换为开源大模型,如Qwen、Llama):
  1. pip install langgraph langchain langchain-openai python-dotenv
复制代码
4.2 完整代码
  1. from langgraph.graph import StateGraph, END
  2. from langchain_openai import ChatOpenAI
  3. from langchain_core.prompts import ChatPromptTemplate
  4. from langchain_core.tools import tool
  5. from dotenv import load_dotenv
  6. import os
  7. import json
  8. # 1. 加载环境变量,配置大模型
  9. load_dotenv()
  10. llm = ChatOpenAI(
  11.     model="gpt-3.5-turbo",
  12.     temperature=0.1,
  13.     api_key=os.getenv("OPENAI_API_KEY")  # 替换为你的API Key
  14. )
  15. # 2. 定义工具(天气查询工具,模拟真实API调用)
  16. @tool
  17. def get_weather(city: str, date: str) -> str:
  18.     """
  19.     功能:查询指定城市指定日期的天气情况
  20.     参数:
  21.         city: 城市名称(如“北京”“上海”)
  22.         date: 日期(格式:YYYY-MM-DD,如“2025-03-15”)
  23.     返回:天气描述字符串
  24.     """
  25.     # 模拟天气数据,实际开发可对接真实天气API
  26.     weather_data = {
  27.         "北京-2025-03-15": "晴,-5℃~5℃,微风,空气质量良",
  28.         "上海-2025-03-15": "阴转小雨,8℃~12℃,东风3级,空气质量优"
  29.     }
  30.     key = f"{city}-{date}"
  31.     return weather_data.get(key, f"未查询到{city}{date}的天气信息")
  32. # 3. 定义状态(智能体的记忆,包含所有推理过程中的信息)
  33. class AgentState:
  34.     input: str          # 用户原始问题
  35.     thought: str        # 思考过程
  36.     action: dict        # 工具调用指令(JSON格式)
  37.     observation: str    # 工具调用结果
  38.     done: bool = False  # 是否完成任务
  39. # 4. 定义节点(思考、行动、观察、回答、条件节点)
  40. # 4.1 思考节点:分析当前状态,决定下一步行动
  41. def thought_node(state: AgentState) -> AgentState:
  42.     prompt = ChatPromptTemplate.from_messages([
  43.         ("system", "你是一个天气查询智能体,基于当前状态,思考下一步该做什么:\n"
  44.          "1. 如果已经获取到天气信息(observation有内容),则设置done=True,准备生成回答;\n"
  45.          "2. 如果没有获取到天气信息,需要调用get_weather工具,明确传入city和date参数;\n"
  46.          "3. 思考过程要清晰,明确说明下一步行动。"),
  47.         ("user", "用户问题:{input}\n当前观察结果:{observation}")
  48.     ])
  49.     chain = prompt | llm
  50.     response = chain.invoke({"input": state.input, "observation": state.observation})
  51.     return AgentState(
  52.         input=state.input,
  53.         thought=response.content,
  54.         action=state.action,
  55.         observation=state.observation,
  56.         done=state.done
  57.     )
  58. # 4.2 行动节点:生成工具调用指令并执行
  59. def action_node(state: AgentState) -> AgentState:
  60.     prompt = ChatPromptTemplate.from_messages([
  61.         ("system", "基于当前思考过程,生成get_weather工具的调用指令,格式为JSON:\n"
  62.          '{"name": "get_weather", "parameters": {"city": "城市名", "date": "日期"}}'),
  63.         ("user", "思考过程:{thought}\n用户问题:{input}")
  64.     ])
  65.     chain = prompt | llm
  66.     response = chain.invoke({"thought": state.thought, "input": state.input})
  67.     # 解析工具调用指令(实际开发可增加异常处理)
  68.     action = json.loads(response.content.strip())
  69.     return AgentState(
  70.         input=state.input,
  71.         thought=state.thought,
  72.         action=action,
  73.         observation=state.observation,
  74.         done=state.done
  75.     )
  76. # 4.3 观察节点:处理工具调用结果,更新状态
  77. def observation_node(state: AgentState) -> AgentState:
  78.     action = state.action
  79.     if action["name"] == "get_weather":
  80.         # 执行工具调用
  81.         observation = get_weather(** action["parameters"])
  82.         return AgentState(
  83.             input=state.input,
  84.             thought=state.thought,
  85.             action=state.action,
  86.             observation=observation,
  87.             done=state.done
  88.         )
  89.     else:
  90.         return AgentState(
  91.             input=state.input,
  92.             thought=state.thought,
  93.             action=state.action,
  94.             observation="工具调用失败,未找到对应工具",
  95.             done=state.done
  96.         )
  97. # 4.4 回答节点:生成最终自然语言回答
  98. def answer_node(state: AgentState) -> AgentState:
  99.     prompt = ChatPromptTemplate.from_messages([
  100.         ("system", "基于用户问题和工具调用结果,生成自然、清晰的回答,不要添加额外信息。"),
  101.         ("user", "用户问题:{input}\n工具调用结果:{observation}")
  102.     ])
  103.     chain = prompt | llm
  104.     response = chain.invoke({"input": state.input, "observation": state.observation})
  105.     # 将回答存入thought字段(简化处理,实际可自定义字段)
  106.     return AgentState(
  107.         input=state.input,
  108.         thought=response.content,
  109.         action=state.action,
  110.         observation=state.observation,
  111.         done=True
  112.     )
  113. # 4.5 条件节点:判断任务是否完成,决定跳转方向
  114. def conditional_node(state: AgentState) -> str:
  115.     if state.done:
  116.         return "answer"  # 任务完成,跳转至回答节点
  117.     else:
  118.         return "action"  # 任务未完成,跳转至行动节点
  119. # 5. 构建LangGraph(状态机)
  120. graph = StateGraph(AgentState)
  121. # 添加节点
  122. graph.add_node("thought", thought_node)        # 思考节点
  123. graph.add_node("action", action_node)          # 行动节点
  124. graph.add_node("observation", observation_node)# 观察节点
  125. graph.add_node("answer", answer_node)          # 回答节点
  126. # 添加边(流转规则)
  127. graph.add_edge("thought", conditional_node)    # 思考节点后进入条件判断
  128. graph.add_edge("action", "observation")        # 行动节点后进入观察节点
  129. graph.add_edge("observation", "thought")       # 观察节点后回到思考节点,形成循环
  130. graph.add_edge("answer", END)                  # 回答节点后,流程终止
  131. # 设置起始节点,编译图
  132. graph.set_entry_point("thought")
  133. app = graph.compile()
  134. # 6. 运行智能体,测试效果
  135. user_question = "查询上海2025年03月15日的天气"
  136. initial_state = AgentState(
  137.     input=user_question,
  138.     thought="",
  139.     action={},
  140.     observation="",
  141.     done=False
  142. )
  143. # 执行推理流程,获取结果
  144. result = app.invoke(initial_state)
  145. # 输出结果
  146. print("用户问题:", result.input)
  147. print("思考过程:", result.thought)
  148. print("工具调用指令:", result.action)
  149. print("工具调用结果:", result.observation)
  150. print("最终回答:", result.thought)
复制代码
4.3 运行结果说明

五、优点与缺点

LangGraph的优势和局限都非常明确,精准匹配不同场景的需求,以下总结可直接用于面试或技术选型:
5.1 优点(核心优势)

5.2 缺点(核心局限)

六、适用场景

LangGraph的核心价值是“复杂推理流程编排”,适合需要多步骤推理、高可控性、工业级落地的场景,具体可分为6类:
七、总结

LangGraph作为专注于推理流程编排的框架,填补了“复杂智能体可控性不足”的空白——它不追求“大而全”,而是聚焦“专而精”,通过状态机驱动的节点-边结构,让智能体的思考和行动更有序、更可控,成为工业级智能体落地的核心引擎。
在实际开发中,LangGraph很少单独使用,更多是与LlamaIndex(负责检索)、AutoGen(负责多智能体协作)组合,形成“检索+推理+协作”的完整智能体系统,适配更复杂的企业级需求。
如果你的需求是“快速落地简单智能体”,优先选择LlamaIndex;如果是“实现多智能体协作”,优先选择AutoGen;如果是“开发复杂、可控的工业级智能体”,LangGraph绝对是核心选择。

原文地址:https://blog.csdn.net/qq_29579625/article/details/159078702




欢迎光临 AI创想 (http://llms-ai.com/) Powered by Discuz! X3.4