【LangGraph】图结构智能体框架核心特性

文章目录

LangGraph技术详细解析:图结构智能体框架核心特性

前言

若对您有帮助的话,请点赞收藏加关注哦,您的关注是我持续创作的动力!有问题请私信或联系邮箱:funian.gm@gmail.com

在大语言模型(LLM)应用开发中,简单的"输入-输出"线性流程已无法满足复杂场景需求------比如多步骤数据分析、跨系统协作、需要循环迭代的任务(如报告优化)、分支决策的业务流程(如客服工单分配)。LangGraph 作为 LangChain 生态下的图结构智能体框架,通过"节点-边-状态"的图模型,完美解决了线性流程的局限性,支持循环执行、分支路由、状态持久化、多智能体协作等核心能力,成为构建复杂 LLM 应用的首选工具。

一、LangGraph 核心优势

LangGraph 基于 LangChain 构建,专注于"复杂流程建模",其核心优势围绕"图结构"展开,精准解决线性 LLM 应用的痛点:

核心优势 具体说明
图结构流程建模 用"节点(任务)+ 边(流转规则)"描述复杂流程,支持循环、分支、并行等任意拓扑结构
内置状态管理 统一维护全局状态(任务上下文、中间结果、历史交互),无需手动传递数据
循环与迭代支持 支持任务重复执行(如答案优化、数据校验),突破线性流程的单次执行限制
分支决策能力 基于状态动态选择执行路径(如"是否需要调用工具""是否需要人工审核")
多智能体协作 支持多个智能体作为节点交互(如"分析智能体→写作智能体→审核智能体")
LangChain 生态兼容 无缝集成 LangChain 的 LLM 模型、工具、向量库、记忆组件,降低开发成本
可视化与调试 内置图结构可视化工具,支持流程轨迹追踪,便于复杂流程调试
状态持久化 支持将全局状态存储到外部数据库(如 Redis、PostgreSQL),支持任务中断恢复

二、LangGraph 生产级目录结构

LangGraph 没有强制目录规范,但生产级项目需遵循"模块化、高内聚低耦合"原则,结合 LangChain 生态特点,以下是经过实践验证的标准目录结构(适用于中大型智能体应用):

复制代码
langgraph-project/
├── .env                # 环境变量(LLM API密钥、数据库地址等,不提交Git)
├── .env.example        # 环境变量示例(提交Git,指导部署)
├── .gitignore          # Git忽略文件
├── requirements.txt    # 项目依赖
├── main.py             # 项目入口(FastAPI部署、图实例初始化)
├── src/                # 核心源代码目录
│   ├── api/            # 接口层(FastAPI路由,对外提供服务)
│   │   ├── endpoints/  # 接口端点(如智能体调用、任务查询)
│   │   │   └── agent.py
│   │   └── router.py   # 路由汇总
│   ├── graphs/         # 图结构定义(核心目录)
│   │   ├── base_graph.py  # 基础图类(封装通用逻辑,如持久化、可视化)
│   │   ├── data_analysis_graph.py  # 数据分析智能体图
│   │   └── customer_service_graph.py  # 客服智能体图
│   ├── agents/         # 智能体节点(图中的核心执行单元)
│   │   ├── analyzer_agent.py  # 分析智能体(数据处理、逻辑推理)
│   │   ├── writer_agent.py    # 写作智能体(结果生成、格式优化)
│   │   └── reviewer_agent.py  # 审核智能体(结果校验、风险控制)
│   ├── tools/          # 工具定义(智能体可调用的外部工具)
│   │   ├── base_tool.py  # 基础工具类(统一工具调用接口)
│   │   ├── database_tool.py  # 数据库查询工具
│   │   └── file_tool.py  # 文件读写工具
│   ├── schemas/        # 数据模型(Pydantic,状态、请求/响应校验)
│   │   ├── state.py    # 图全局状态模型
│   │   └── request.py  # 接口请求/响应模型
│   ├── core/           # 核心配置(全局常量、LLM初始化、持久化配置)
│   │   ├── config.py   # 配置加载(从.env读取)
│   │   ├── llm.py      # LLM模型初始化(OpenAI/本地化模型)
│   │   └── storage.py  # 状态持久化(Redis/PostgreSQL)
│   └── utils/          # 工具函数(日志、异常处理、格式转换)
│       ├── logger.py   # 日志配置
│       └── exceptions.py  # 自定义异常
└── tests/              # 单元测试与集成测试
    ├── test_graph_flow.py  # 图流程测试
    └── test_agent_tool.py  # 智能体工具调用测试

核心目录说明(表格汇总)

目录/文件 核心作用 关键注意点
src/graphs 图结构定义(节点、边、状态流转规则) 每个业务场景对应一个独立图文件,复用基础图逻辑
src/agents 智能体节点(图的执行单元,封装LLM+业务逻辑) 单个智能体专注单一职责(如仅负责分析/写作)
src/tools 外部工具封装(数据库、文件、API等) 遵循LangChain Tool接口规范,便于智能体调用
src/schemas/state.py 全局状态模型(图的核心数据载体) 用Pydantic定义,明确状态字段(如input、output、history)
src/core/storage 状态持久化(支持任务中断恢复) 生产环境推荐Redis(高性能)或PostgreSQL(结构化存储)
src/api 对外提供HTTP接口(如FastAPI) 封装图的运行逻辑,提供同步/异步调用接口

目录设计原则

  1. 单一职责:每个智能体/工具/图仅负责特定功能(如分析智能体不负责写作);
  2. 可复用性:基础图类、工具基类封装通用逻辑,避免重复代码;
  3. 可扩展性:支持新增智能体节点、工具、图结构,不影响现有功能;
  4. 可调试性:日志、状态追踪、图可视化能力贯穿整个目录设计。

三、LangGraph 核心概念与快速入门

核心概念拆解

LangGraph 的核心是"图(Graph)",由三个基础组件构成:

组件 作用说明
节点(Node) 执行单元(智能体、工具调用、数据处理函数),输入状态,输出新状态
边(Edge) 节点间的流转规则(条件分支、固定流转、循环流转),决定"下一步执行哪个节点"
状态(State) 全局数据载体(Pydantic模型),存储任务上下文、中间结果、历史记录,所有节点共享

快速入门:最小化图示例(问答+记忆功能)

以下示例实现一个"接收问题→LLM回答→存储历史"的简单图,覆盖核心流程:

步骤1:安装依赖
bash 复制代码
pip install langgraph langchain openai pydantic python-dotenv  # 核心依赖
pip install fastapi uvicorn  # 可选,用于接口部署
步骤2:定义全局状态(src/schemas/state.py)
python 复制代码
from pydantic import BaseModel
from typing import List, Optional

# 全局状态模型:所有节点共享和修改该状态
class QAMemoryState(BaseModel):
    question: Optional[str] = None  # 用户问题
    answer: Optional[str] = None    # LLM回答
    history: List[tuple] = []       # 对话历史((question, answer))
步骤3:定义节点函数(src/agents/qa_agent.py)
python 复制代码
from langchain_openai import ChatOpenAI
from src.schemas.state import QAMemoryState
from src.core.config import settings

# 初始化LLM(从环境变量读取API密钥)
llm = ChatOpenAI(
    model="gpt-3.5-turbo",
    api_key=settings.OPENAI_API_KEY,
    temperature=0.7
)

# 节点1:LLM回答问题
def answer_node(state: QAMemoryState) -> QAMemoryState:
    """接收问题,生成回答,更新状态"""
    # 构建提示词(包含历史对话)
    history_str = "\n".join([f"Q: {q}\nA: {a}" for q, a in state.history])
    prompt = f"""
    你是一个问答助手,基于历史对话和当前问题生成回答:
    历史对话:{history_str}
    当前问题:{state.question}
    """
    # 调用LLM
    response = llm.invoke(prompt)
    # 更新状态
    return QAMemoryState(
        question=state.question,
        answer=response.content,
        history=state.history + [(state.question, response.content)]  # 追加历史
    )

# 节点2:结束节点(无实际逻辑,标记流程结束)
def end_node(state: QAMemoryState) -> QAMemoryState:
    """流程结束节点"""
    print(f"流程结束,最终回答:{state.answer}")
    return state
步骤4:构建图结构(src/graphs/qa_graph.py)
python 复制代码
from langgraph.graph import Graph, END
from src.schemas.state import QAMemoryState
from src.agents.qa_agent import answer_node, end_node

# 1. 初始化图(指定状态模型)
qa_graph = Graph(QAMemoryState)

# 2. 添加节点(节点名称→节点函数)
qa_graph.add_node("answer", answer_node)  # 回答节点
qa_graph.add_node("end", end_node)        # 结束节点

# 3. 定义边(流转规则)
qa_graph.add_edge("answer", "end")  # 回答节点执行后,直接进入结束节点
qa_graph.set_entry_point("answer")  # 设置入口节点(流程开始于answer节点)

# 4. 编译图(生成可运行的图实例)
qa_graph_compiled = qa_graph.compile()

# 5. 可视化图(生成Mermaid语法,可在https://mermaid-js.github.io/渲染)
def visualize_graph():
    return qa_graph_compiled.get_graph().draw_mermaid()
步骤5:运行图(测试流程)
python 复制代码
# main.py 测试代码
from src.graphs.qa_graph import qa_graph_compiled
from src.schemas.state import QAMemoryState

if __name__ == "__main__":
    # 输入初始状态
    initial_state = QAMemoryState(question="什么是LangGraph?")
    # 运行图(同步执行)
    result = qa_graph_compiled.invoke(initial_state)
    # 输出结果
    print(f"用户问题:{result.question}")
    print(f"LLM回答:{result.answer}")
    print(f"对话历史:{result.history}")
运行结果
复制代码
用户问题:什么是LangGraph?
LLM回答:LangGraph是LangChain生态下的图结构智能体框架,用于构建复杂的LLM应用...
对话历史:[('什么是LangGraph?', 'LangGraph是LangChain生态下的图结构智能体框架...')]
流程结束,最终回答:LangGraph是LangChain生态下的图结构智能体框架...

四、LangGraph 关键特性深度解析(含代码示例)

1. 循环执行:支持任务迭代优化

核心场景:需要反复优化结果(如报告修改、答案精炼)、重复校验数据(如数据准确性校验)。

代码示例:循环优化回答
python 复制代码
from langgraph.graph import Graph, END
from src.schemas.state import QAMemoryState
from src.agents.qa_agent import llm

# 新增节点:判断是否需要继续优化
def should_optimize(state: QAMemoryState) -> str:
    """根据当前回答判断是否继续优化(返回下一个节点名称)"""
    prompt = f"""
    请判断以下回答是否满足要求(准确、详细、逻辑清晰):
    回答:{state.answer}
    要求:1. 解释清楚核心概念;2. 给出应用场景;3. 说明优势。
    若满足要求,返回"end";否则返回"optimize"。
    """
    response = llm.invoke(prompt)
    return response.content.strip().lower()

# 新增节点:优化回答
def optimize_node(state: QAMemoryState) -> QAMemoryState:
    """优化现有回答"""
    prompt = f"""
    请优化以下回答,满足要求:1. 解释清楚核心概念;2. 给出应用场景;3. 说明优势。
    原始回答:{state.answer}
    优化后回答:
    """
    optimized_answer = llm.invoke(prompt).content
    # 更新状态(保留历史,替换当前回答)
    return QAMemoryState(
        question=state.question,
        answer=optimized_answer,
        history=state.history[:-1] + [(state.question, optimized_answer)]  # 替换最后一条历史
    )

# 构建带循环的图
optimize_graph = Graph(QAMemoryState)
optimize_graph.add_node("answer", answer_node)       # 初始回答
optimize_graph.add_node("optimize", optimize_node)   # 优化节点
optimize_graph.add_node("should_optimize", should_optimize)  # 决策节点
optimize_graph.add_node("end", end_node)            # 结束节点

# 定义边(核心:根据决策结果流转)
optimize_graph.add_edge("answer", "should_optimize")  # 初始回答后进入决策
optimize_graph.add_conditional_edges(
    "should_optimize",  # 决策节点
    lambda x: x  # 决策函数的输出直接作为下一个节点名称
)
optimize_graph.add_edge("optimize", "should_optimize")  # 优化后再次进入决策
optimize_graph.add_edge("should_optimize", "end")  # 满足要求则结束

# 入口节点
optimize_graph.set_entry_point("answer")
optimize_graph_compiled = optimize_graph.compile()

# 运行图
initial_state = QAMemoryState(question="什么是LangGraph?")
result = optimize_graph_compiled.invoke(initial_state)
核心亮点
  • add_conditional_edges实现"决策-流转"逻辑;
  • 循环次数可通过max_steps限制(避免无限循环):optimize_graph_compiled.invoke(initial_state, config={"max_steps": 3})

2. 分支决策:基于状态动态选择流程

核心场景:根据任务类型分配不同智能体(如"技术问题→技术客服""订单问题→售后客服")、根据输入条件选择是否调用工具(如"是否需要查询数据库")。

代码示例:客服工单分支路由
python 复制代码
from langgraph.graph import Graph, END
from pydantic import BaseModel
from typing import Optional

# 定义客服场景状态
class SupportTicketState(BaseModel):
    ticket_content: str  # 工单内容
    ticket_type: Optional[str] = None  # 工单类型(技术问题/订单问题/其他)
    reply: Optional[str] = None  # 客服回复

# 节点1:分类工单类型
def classify_ticket(state: SupportTicketState) -> SupportTicketState:
    """判断工单类型"""
    prompt = f"请将以下工单分类为:技术问题、订单问题、其他。工单内容:{state.ticket_content}"
    ticket_type = llm.invoke(prompt).content.strip()
    return SupportTicketState(
        ticket_content=state.ticket_content,
        ticket_type=ticket_type,
        reply=state.reply
    )

# 节点2:技术客服回复
def tech_support_node(state: SupportTicketState) -> SupportTicketState:
    """技术问题回复"""
    prompt = f"作为技术客服,回复以下工单:{state.ticket_content}"
    reply = llm.invoke(prompt).content
    return SupportTicketState(**state.dict(), reply=reply)

# 节点3:售后客服回复
def order_support_node(state: SupportTicketState) -> SupportTicketState:
    """订单问题回复"""
    prompt = f"作为售后客服,回复以下工单:{state.ticket_content}"
    reply = llm.invoke(prompt).content
    return SupportTicketState(**state.dict(), reply=reply)

# 节点4:通用客服回复
def general_support_node(state: SupportTicketState) -> SupportTicketState:
    """其他问题回复"""
    prompt = f"作为通用客服,回复以下工单:{state.ticket_content}"
    reply = llm.invoke(prompt).content
    return SupportTicketState(**state.dict(), reply=reply)

# 构建分支图
support_graph = Graph(SupportTicketState)
support_graph.add_node("classify", classify_ticket)
support_graph.add_node("tech_support", tech_support_node)
support_graph.add_node("order_support", order_support_node)
support_graph.add_node("general_support", general_support_node)
support_graph.add_node("end", end_node)

# 定义边:分类后根据类型跳转不同客服节点
support_graph.add_edge("classify", "tech_support", cond=lambda x: x.ticket_type == "技术问题")
support_graph.add_edge("classify", "order_support", cond=lambda x: x.ticket_type == "订单问题")
support_graph.add_edge("classify", "general_support", cond=lambda x: x.ticket_type == "其他")

# 所有客服节点执行后进入结束节点
support_graph.add_edge("tech_support", "end")
support_graph.add_edge("order_support", "end")
support_graph.add_edge("general_support", "end")

# 入口节点
support_graph.set_entry_point("classify")
support_graph_compiled = support_graph.compile()

# 运行图
initial_state = SupportTicketState(ticket_content="我的订单支付成功但没收到货,怎么处理?")
result = support_graph_compiled.invoke(initial_state)
print(f"工单类型:{result.ticket_type}")
print(f"客服回复:{result.reply}")

3. 工具调用:集成外部系统能力

核心场景:智能体需要查询数据库、调用API、读写文件等外部操作(LangGraph 无缝集成 LangChain 工具)。

代码示例:智能体调用数据库工具
python 复制代码
from langchain.tools import tool
from langgraph.graph import Graph, END
from src.schemas.state import DataQueryState
from src.core.config import settings

# 1. 定义LangChain工具(数据库查询)
@tool
def query_database(sql: str) -> str:
    """
    调用数据库执行SQL查询,仅用于查询数据(SELECT语句)
    参数:sql - 合法的SQL SELECT语句
    """
    # 模拟数据库查询(实际项目用SQLAlchemy/数据库驱动)
    import sqlite3
    conn = sqlite3.connect(settings.DB_PATH)
    cursor = conn.cursor()
    try:
        cursor.execute(sql)
        results = cursor.fetchall()
        columns = [desc[0] for desc in cursor.description]
        return f"查询结果:{columns}\n{results}"
    except Exception as e:
        return f"查询失败:{str(e)}"
    finally:
        conn.close()

# 2. 定义状态模型
class DataQueryState(BaseModel):
    user_query: str  # 用户自然语言查询
    sql: Optional[str] = None  # 生成的SQL语句
    query_result: Optional[str] = None  # 数据库查询结果
    final_answer: Optional[str] = None  # 最终自然语言回答

# 3. 节点1:自然语言转SQL
def nl2sql_node(state: DataQueryState) -> DataQueryState:
    """将用户自然语言查询转换为SQL"""
    prompt = f"""
    数据库表结构:users(id INT, name TEXT, email TEXT, register_time DATETIME)
    请将以下自然语言查询转换为SQL SELECT语句,仅返回SQL,不包含其他内容:
    用户查询:{state.user_query}
    """
    sql = llm.invoke(prompt).content.strip()
    return DataQueryState(**state.dict(), sql=sql)

# 4. 节点2:调用数据库工具
def tool_call_node(state: DataQueryState) -> DataQueryState:
    """调用数据库工具执行SQL"""
    if not state.sql:
        return DataQueryState(**state.dict(), query_result="SQL生成失败")
    # 调用LangChain工具
    query_result = query_database.invoke({"sql": state.sql})
    return DataQueryState(**state.dict(), query_result=query_result)

# 5. 节点3:生成最终回答
def answer_generation_node(state: DataQueryState) -> DataQueryState:
    """根据查询结果生成自然语言回答"""
    prompt = f"""
    用户查询:{state.user_query}
    数据库查询结果:{state.query_result}
    请将查询结果转换为自然语言回答,简洁明了:
    """
    final_answer = llm.invoke(prompt).content
    return DataQueryState(**state.dict(), final_answer=final_answer)

# 6. 构建图
data_query_graph = Graph(DataQueryState)
data_query_graph.add_node("nl2sql", nl2sql_node)
data_query_graph.add_node("tool_call", tool_call_node)
data_query_graph.add_node("answer_generation", answer_generation_node)
data_query_graph.add_node("end", end_node)

# 定义边
data_query_graph.add_edge("nl2sql", "tool_call")
data_query_graph.add_edge("tool_call", "answer_generation")
data_query_graph.add_edge("answer_generation", "end")
data_query_graph.set_entry_point("nl2sql")
data_query_graph_compiled = data_query_graph.compile()

# 运行图
initial_state = DataQueryState(user_query="查询2024年注册的用户数量")
result = data_query_graph_compiled.invoke(initial_state)
print(f"生成SQL:{result.sql}")
print(f"查询结果:{result.query_result}")
print(f"最终回答:{result.final_answer}")

4. 多智能体协作:节点间交互完成复杂任务

核心场景:需要多个智能体分工协作(如"数据分析→报告写作→合规审核""产品经理→开发→测试")。

代码示例:多智能体报告生成流程
python 复制代码
from langgraph.graph import Graph, END
from src.schemas.state import ReportState

# 状态模型
class ReportState(BaseModel):
    topic: str  # 报告主题
    data_analysis: Optional[str] = None  # 数据分析结果
    draft_report: Optional[str] = None  # 报告草稿
    reviewed_report: Optional[str] = None  # 审核后报告

# 节点1:数据分析智能体
def data_analyst_node(state: ReportState) -> ReportState:
    """分析报告主题相关数据"""
    prompt = f"作为数据分析师,分析以下主题的核心数据和趋势:{state.topic},输出分析结果(300字内)"
    data_analysis = llm.invoke(prompt).content
    return ReportState(**state.dict(), data_analysis=data_analysis)

# 节点2:写作智能体
def writer_node(state: ReportState) -> ReportState:
    """基于数据分析结果生成报告草稿"""
    prompt = f"基于以下数据分析结果,生成一份结构化报告(包含标题、核心发现、趋势预测):{state.data_analysis}"
    draft_report = llm.invoke(prompt).content
    return ReportState(**state.dict(), draft_report=draft_report)

# 节点3:审核智能体
def reviewer_node(state: ReportState) -> ReportState:
    """审核报告的合规性和准确性"""
    prompt = f"作为合规审核员,审核以下报告是否存在虚假信息、违规内容,若有问题请修正:{state.draft_report}"
    reviewed_report = llm.invoke(prompt).content
    return ReportState(**state.dict(), reviewed_report=reviewed_report)

# 构建多智能体协作图
report_graph = Graph(ReportState)
report_graph.add_node("data_analyst", data_analyst_node)
report_graph.add_node("writer", writer_node)
report_graph.add_node("reviewer", reviewer_node)
report_graph.add_node("end", end_node)

# 定义流转顺序:分析→写作→审核→结束
report_graph.add_edge("data_analyst", "writer")
report_graph.add_edge("writer", "reviewer")
report_graph.add_edge("reviewer", "end")
report_graph.set_entry_point("data_analyst")
report_graph_compiled = report_graph.compile()

# 运行图
initial_state = ReportState(topic="2024年AI行业发展趋势")
result = report_graph_compiled.invoke(initial_state)
print(f"最终报告:{result.reviewed_report}")

五、生产级实践:关键功能集成

1. 状态持久化(支持任务中断恢复)

生产环境中,任务可能因网络异常、服务重启中断,LangGraph 支持将状态存储到外部数据库,实现中断恢复。

代码示例:Redis 状态持久化
python 复制代码
# src/core/storage.py
from langgraph.checkpoint.redis import RedisSaver
from src.core.config import settings

# 初始化Redis持久化器
def init_redis_checkpointer() -> RedisSaver:
    return RedisSaver(
        redis_url=settings.REDIS_URL,  # 从.env读取:redis://:password@localhost:6379/0
        namespace="langgraph:checkpoints"  # 命名空间,避免key冲突
    )

# src/graphs/base_graph.py
from langgraph.graph import Graph
from src.core.storage import init_redis_checkpointer

# 基础图类(封装持久化能力)
class PersistentGraph(Graph):
    def __init__(self, state_schema, use_checkpoint=True):
        super().__init__(state_schema)
        self.checkpointer = init_redis_checkpointer() if use_checkpoint else None

    def compile(self):
        """编译图时启用持久化"""
        return super().compile(checkpointer=self.checkpointer)

# 使用基础图类构建带持久化的图
report_graph = PersistentGraph(ReportState)
# ... 添加节点和边 ...
report_graph_compiled = report_graph.compile()

# 运行图时指定任务ID(用于恢复)
task_id = "report-2024-ai-trend"  # 自定义任务ID
initial_state = ReportState(topic="2024年AI行业发展趋势")

# 首次运行(创建任务)
result = report_graph_compiled.invoke(initial_state, config={"configurable": {"thread_id": task_id}})

# 中断后恢复(根据task_id加载状态)
restored_result = report_graph_compiled.invoke(None, config={"configurable": {"thread_id": task_id}})

2. 错误处理与重试

节点执行失败(如LLM调用超时、工具调用异常)时,需支持重试、降级处理。

代码示例:节点错误重试
python 复制代码
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
from langgraph.graph import Graph
import requests.exceptions

# 带重试的LLM节点
@retry(
    stop=stop_after_attempt(3),  # 最多重试3次
    wait=wait_exponential(multiplier=1, min=2, max=10),  # 指数退避(2s→4s→8s)
    retry=retry_if_exception_type((requests.exceptions.RequestException, TimeoutError))  # 仅重试网络异常
)
def answer_node_with_retry(state: QAMemoryState) -> QAMemoryState:
    try:
        response = llm.invoke(f"回答问题:{state.question}")
        return QAMemoryState(
            question=state.question,
            answer=response.content,
            history=state.history + [(state.question, response.content)]
        )
    except Exception as e:
        print(f"节点执行失败:{str(e)},将重试...")
        raise  # 抛出异常触发重试

# 构建图时使用带重试的节点
qa_graph = Graph(QAMemoryState)
qa_graph.add_node("answer", answer_node_with_retry)
qa_graph.add_node("end", end_node)
qa_graph.add_edge("answer", "end")
qa_graph.set_entry_point("answer")

3. 图结构可视化

LangGraph 支持生成 Mermaid 语法的图结构,可在 Mermaid 在线编辑器 渲染,便于调试和文档编写。

代码示例:可视化图结构
python 复制代码
# src/graphs/qa_graph.py
def visualize_graph(graph_compiled) -> str:
    """生成Mermaid语法的图结构"""
    return graph_compiled.get_graph().draw_mermaid()

# 运行后输出Mermaid代码
if __name__ == "__main__":
    mermaid_code = visualize_graph(qa_graph_compiled)
    print("Mermaid图结构:")
    print(mermaid_code)
生成的 Mermaid 代码(示例)

answer end A

4. 部署方案(FastAPI + LangGraph)

将 LangGraph 包装为 HTTP 接口,支持外部系统调用。

代码示例:FastAPI 部署
python 复制代码
# src/api/endpoints/agent.py
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from src.graphs.report_graph import report_graph_compiled
from src.schemas.state import ReportState

router = APIRouter(prefix="/agent", tags=["智能体接口"])

# 请求模型
class ReportRequest(BaseModel):
    topic: str
    task_id: Optional[str] = None

# 响应模型
class ReportResponse(BaseModel):
    task_id: str
    report: str
    status: str = "success"

@router.post("/generate-report", response_model=ReportResponse)
async def generate_report(request: ReportRequest):
    try:
        # 生成任务ID(若未提供)
        task_id = request.task_id or f"report-{uuid.uuid4()}"
        # 初始化状态
        initial_state = ReportState(topic=request.topic)
        # 运行图
        result = report_graph_compiled.invoke(
            initial_state,
            config={"configurable": {"thread_id": task_id}}
        )
        # 返回结果
        return ReportResponse(
            task_id=task_id,
            report=result.reviewed_report
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"报告生成失败:{str(e)}")

# src/api/router.py
from fastapi import APIRouter
from src.api.endpoints import agent

api_router = APIRouter()
api_router.include_router(agent.router)

# main.py
from fastapi import FastAPI
from src.api.router import api_router

app = FastAPI(title="LangGraph 智能体服务")
app.include_router(api_router)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

六、框架对比:LangGraph vs 传统线性 LLM 应用 vs LangChain Agents

框架/方案 复杂流程支持 状态管理 循环/分支 多智能体协作 调试难度 适用场景
LangGraph 极强(图结构) 内置全局状态 原生支持 原生支持 低(可视化+轨迹追踪) 多步骤任务、循环迭代、分支决策、多智能体协作
传统线性 LLM 应用 极弱(线性流程) 手动传递 不支持 不支持 中(需手动打印日志) 简单问答、单次生成任务
LangChain Agents 中等(工具链) 有限状态 部分支持 需手动集成 高(流程黑盒) 单智能体工具调用、简单决策任务

七、总结

LangGraph 作为 LangChain 生态的核心扩展,以"图结构"为核心,彻底解决了复杂 LLM 应用的流程建模问题。其关键亮点总结如下:

  1. 核心价值:专注于"有状态、多步骤、需循环/分支"的复杂 LLM 任务,填补了线性流程与简单智能体的能力空白;
  2. 目录结构:遵循"模块化+分层架构",核心目录(graphs/agents/tools)职责清晰,支持中大型项目扩展;
  3. 关键特性:循环执行、分支决策、工具集成、多智能体协作四大核心能力,覆盖绝大多数复杂场景;
  4. 生产实践:状态持久化、错误重试、可视化调试、FastAPI 部署等能力,满足生产级稳定性与可维护性要求;
  5. 适用场景:数据分析报告、客服工单处理、多步骤问题解决、智能体协作系统、流程化业务处理(如合同审核、简历筛选)。
相关推荐
中年程序员一枚2 小时前
让postman调用python的开发接口,链接sqlite数据库,让前后联动起来
数据库·python·postman
爱写Bug的小孙2 小时前
Tools、MCP 和 Function Calling
开发语言·人工智能·python·ai·ai编程·工具调用
rgb2gray2 小时前
城市韧性与交通基础设施系统耦合协调度的时空演变及影响因素
网络·人工智能·python·ai·写作·耦合·耦合协调
初级炼丹师(爱说实话版)2 小时前
大模型部署-数据并行/模型并行
人工智能·python
中冕—霍格沃兹软件开发测试2 小时前
测试工具链的构建与团队协作:从工具集成到价值流动
人工智能·科技·测试工具·开源·appium·bug
高洁013 小时前
激活函数应该具有哪些特征
人工智能·python·深度学习·神经网络·transformer
全栈陈序员3 小时前
【Python】基础语法入门(十五)——标准库精选:提升效率的内置工具箱
开发语言·人工智能·python·学习
IT·小灰灰3 小时前
AI学会理解物理法则:OpenAI Sora 2如何重塑视频生成新范式
人工智能·python·深度学习·机器学习·数据挖掘·音视频
记忆偶然3 小时前
语音转写技术在专业服务领域的应用实践
python