LangGraph 入门:多智能体工作流实战(阿里云百炼)

目录

  1. 什么是 LangGraph
  2. 为什么需要 LangGraph
  3. LangGraph vs LangChain
  4. 核心概念
  5. 环境搭建
  6. 单智能体:带记忆的 ReAct Agent
  7. 多智能体:Supervisor 模式
  8. 多智能体:Swarm 模式
  9. 实战:多智能体文档问答系统
  10. 常见问题
  11. 总结

一、什么是 LangGraph

LangGraph 是 LangChain 生态中用于构建有状态、多步骤智能体的低层编排框架。它由 LangChain 官方开发,专为生产级智能体应用设计。

官方定位:"LangGraph is a low-level orchestration framework for building, managing, and deploying long-running, stateful agents."

1.1 核心特点

特性 说明

图结构编排 用有向图(StateGraph)定义智能体的执行流程

状态管理 通过共享状态在节点间传递数据

循环支持 支持条件分支和循环,实现 ReAct 模式

持久化记忆 内置检查点机制,支持跨会话记忆

人机协作 支持 Human-in-the-Loop,可在执行中中断和恢复

1.2 应用场景

场景 说明

复杂问答系统 需要多步推理和工具调用

多智能体协作 多个专业 Agent 协同完成任务

自动化工作流 需要条件判断和循环的业务流程

长期运行任务 需要持久化状态和断点续传的 Agent

二、为什么需要 LangGraph

2.1 LangChain 的局限

用 LangChain 写 Agent 时,常见的困境是:

· 线性执行:链(Chain)只能线性执行,如果模型发现"工具返回的结果不够,还需要再查一次",线性链路就断了

· 状态管理难:多轮对话的历史存在哪里?需要写大量胶水代码来管理消息列表

· 无法循环:ReAct 模式(思考 → 行动 → 观察)需要循环,但 Chain 不支持循环

2.2 LangGraph 的解决方案

LangGraph 的核心思路是状态图:

· 把整个 Agent 的运行抽象成一张图

· 图上有节点(Node)、有边(Edge)

· 还有一块在所有节点之间流转的公共黑板------状态(State)

三、LangGraph vs LangChain

对比维度 LangChain LangGraph

执行模式 线性链(Chain) 图结构(Graph)

循环支持 ❌ 不支持 ✅ 支持条件循环

状态管理 手动管理 内置 StateGraph

多智能体 需要手写逻辑 内置 Supervisor/Swarm 模式

持久化 基础支持 内置检查点机制

适用场景 简单工作流 复杂、多步骤、有状态 Agent

一句话总结:

"LangChain 负责单次调用,LangGraph 负责把调用串成可循环、可记忆的工作流。"

四、核心概念

4.1 StateGraph(状态图)

StateGraph 是 LangGraph 的图构建器,所有节点共享一个状态对象。

python 复制代码
from langgraph.graph import StateGraph, MessagesState
from typing import TypedDict, Annotated
from operator import add

# 自定义状态
class CustomState(TypedDict):
    messages: Annotated[list, add]  # 追加模式
    user_name: str                   # 自定义字段
    current_step: str

4.2 节点(Node)

节点是图中的一个执行单元,可以是:

· 模型调用

· 工具执行

· 普通 Python 函数

python 复制代码
def call_model(state: CustomState) -> dict:
    """Agent 节点:调用大模型"""
    response = llm.invoke(state["messages"])
    return {"messages": [response]}

4.3 边(Edge)

边定义节点之间的连接:

类型 说明 示例

普通边 固定流向 graph.add_edge("tools", "agent")

条件边 动态选择去向 graph.add_conditional_edges("agent", should_continue)

起始边 设置入口 graph.add_edge(START, "agent")

4.4 检查点(Checkpoint)

检查点机制让 Agent 拥有跨轮次记忆:

python 复制代码
from langgraph.checkpoint.memory import InMemorySaver

checkpointer = InMemorySaver()
app = workflow.compile(checkpointer=checkpointer)

# 使用 thread_id 隔离不同会话的记忆
config = {"configurable": {"thread_id": "user_123"}}
result = app.invoke({"messages": [HumanMessage("你好")]}, config)

五、环境搭建

5.1 安装依赖

bash 复制代码
pip install langgraph langchain langchain-openai python-dotenv -i https://pypi.tuna.tsinghua.edu.cn/simple

5.2 配置 API Key

创建 .env 文件:

bash 复制代码
DASHSCOPE_API_KEY="你的阿里云百炼API Key"
DASHSCOPE_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"

5.3 引入阿里云百炼模型

python 复制代码
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

load_dotenv()

# 使用阿里云百炼的通义千问模型
llm = ChatOpenAI(
    model="qwen3-max",
    temperature=0,
    openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
    openai_api_base=os.getenv("DASHSCOPE_BASE_URL"),
)

六、单智能体:带记忆的 ReAct Agent

6.1 完整代码

python 复制代码
"""
LangGraph 入门:带记忆的 ReAct Agent(阿里云百炼版)
功能:根据用户问题,自动判断是否需要调用工具
"""

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.tools import tool
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode
from langgraph.checkpoint.memory import InMemorySaver
from langchain_core.messages import HumanMessage

load_dotenv()

# ========== 1. 初始化阿里云百炼模型 ==========
llm = ChatOpenAI(
    model="qwen3-max",
    temperature=0,
    openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
    openai_api_base=os.getenv("DASHSCOPE_BASE_URL"),
)

# ========== 2. 定义工具 ==========
@tool
def search(query: str) -> str:
    """模拟搜索工具,返回搜索结果"""
    if "上海" in query or "Shanghai" in query:
        return "上海今天天气:晴,25°C,空气质量良好"
    elif "北京" in query or "Beijing" in query:
        return "北京今天天气:多云,18°C,空气质量轻度污染"
    else:
        return f"未找到关于 '{query}' 的信息"

@tool
def calculator(expression: str) -> str:
    """计算数学表达式"""
    try:
        # 安全的 eval,只允许基本运算
        result = eval(expression, {"__builtins__": {}})
        return f"计算结果:{result}"
    except Exception:
        return "计算错误,请检查表达式"

tools = [search, calculator]
tool_node = ToolNode(tools)

# 将工具绑定到模型
llm_with_tools = llm.bind_tools(tools)

# ========== 3. 定义节点函数 ==========
def call_model(state: MessagesState):
    """Agent 节点:调用模型"""
    messages = state["messages"]
    response = llm_with_tools.invoke(messages)
    return {"messages": [response]}

def should_continue(state: MessagesState):
    """条件判断:是否需要调用工具"""
    messages = state["messages"]
    last_message = messages[-1]
    
    # 如果模型调用了工具,则进入 tools 节点
    if hasattr(last_message, "tool_calls") and last_message.tool_calls:
        return "tools"
    # 否则结束
    return END

# ========== 4. 构建状态图 ==========
workflow = StateGraph(MessagesState)

# 添加节点
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)

# 添加边
workflow.add_edge(START, "agent")
workflow.add_conditional_edges("agent", should_continue)
workflow.add_edge("tools", "agent")

# ========== 5. 编译并添加记忆 ==========
checkpointer = InMemorySaver()
app = workflow.compile(checkpointer=checkpointer)

# ========== 6. 运行测试 ==========
if __name__ == "__main__":
    config = {"configurable": {"thread_id": "test_user"}}
    
    print("=" * 50)
    print("单智能体 ReAct Agent 测试(阿里云百炼)")
    print("=" * 50)
    
    # 第一轮:天气查询
    print("\n第1轮对话")
    print("用户:上海的天气怎么样?")
    
    result = app.invoke(
        {"messages": [HumanMessage(content="上海的天气怎么样?")]},
        config=config
    )
    print(f"AI:{result['messages'][-1].content}")
    
    # 第二轮:测试记忆
    print("\n第2轮对话(测试记忆)")
    print("用户:我问的是哪个城市?")
    
    result = app.invoke(
        {"messages": [HumanMessage(content="我问的是哪个城市?")]},
        config=config
    )
    print(f"AI:{result['messages'][-1].content}")
    
    # 第三轮:数学计算
    print("\n第3轮对话")
    print("用户:计算 123 * 456")
    
    result = app.invoke(
        {"messages": [HumanMessage(content="计算 123 * 456")]},
        config=config
    )
    print(f"AI:{result['messages'][-1].content}")

6.2 代码解析

组件 作用 说明

ChatOpenAI 模型调用 配置阿里云百炼 API

@tool 定义工具 装饰普通函数为可调用工具

bind_tools 绑定工具 将工具绑定到模型

ToolNode 工具节点 LangGraph 内置,自动执行工具调用

MessagesState 状态模式 内置状态,包含 messages 字段

StateGraph 图构建器 创建状态图

InMemorySaver 检查点 保存状态,实现记忆

七、多智能体:Supervisor 模式

Supervisor 模式是层级式多智能体架构,由一个中央监督者协调多个专业智能体。

7.1 架构图

复制代码
┌─────────────────────────────────────────────────────────┐
│                    Supervisor Agent                      │
│                   (中央调度者)                           │
│                                                          │
│   接收用户任务 → 判断任务类型 → 分配给对应智能体             │
└─────────────────────────────────────────────────────────┘
                           │
           ┌───────────────┼───────────────┐
           ▼               ▼               ▼
    ┌────────────┐  ┌────────────┐  ┌────────────┐
    │  Research  │  │   Math     │  │  Writing   │
    │   Agent    │  │   Agent    │  │   Agent    │
    │  (研究专家) │  │  (数学专家) │  │  (写作专家) │
    └────────────┘  └────────────┘  └────────────┘

7.2 完整代码

python 复制代码
"""
LangGraph 多智能体:Supervisor 模式(阿里云百炼版)
功能:一个监督者协调多个专业智能体
"""

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END, START
from typing import TypedDict, Literal, Annotated
from langchain_core.messages import AnyMessage, HumanMessage, AIMessage
from operator import add

load_dotenv()

# ========== 1. 初始化阿里云百炼模型 ==========
llm = ChatOpenAI(
    model="qwen3-max",
    temperature=0,
    openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
    openai_api_base=os.getenv("DASHSCOPE_BASE_URL"),
)

# ========== 2. 定义专业智能体 ==========

def research_agent(state: dict) -> dict:
    """研究专家:负责信息检索和知识整理"""
    messages = state["messages"]
    last_message = messages[-1].content if messages else ""
    
    response = llm.invoke(f"作为研究专家,请回答:{last_message}")
    return {"messages": [AIMessage(content=response.content)]}

def math_agent(state: dict) -> dict:
    """数学专家:负责计算和数学推理"""
    messages = state["messages"]
    last_message = messages[-1].content if messages else ""
    
    response = llm.invoke(f"作为数学专家,请解决数学问题:{last_message}")
    return {"messages": [AIMessage(content=response.content)]}

def writing_agent(state: dict) -> dict:
    """写作专家:负责润色、总结和创作"""
    messages = state["messages"]
    last_message = messages[-1].content if messages else ""
    
    response = llm.invoke(f"作为写作专家,请优化或总结以下内容:{last_message}")
    return {"messages": [AIMessage(content=response.content)]}

# ========== 3. 定义监督者 ==========

def supervisor(state: dict) -> dict:
    """监督者:分析任务并决定使用哪个智能体"""
    messages = state["messages"]
    last_message = messages[-1].content if messages else ""
    
    # 智能体选择提示词
    prompt = f"""
分析用户的问题,选择最合适的专业智能体来处理。

用户问题:{last_message}

可选智能体:
- research:研究专家,负责信息检索、查找资料、回答问题
- math:数学专家,负责计算、数学推理
- writing:写作专家,负责润色、总结、创作

只输出智能体名称,不要输出其他内容。
"""
    
    response = llm.invoke(prompt)
    next_agent = response.content.strip().lower()
    
    # 验证返回的智能体名称是否有效
    if next_agent not in ["research", "math", "writing"]:
        next_agent = "writing"  # 默认使用写作专家
    
    return {"next": next_agent, "messages": messages}

def router(state: dict) -> Literal["research", "math", "writing", "finish"]:
    """路由函数:根据监督者决策跳转"""
    next_agent = state.get("next", "finish")
    if next_agent in ["research", "math", "writing"]:
        return next_agent
    return "finish"

def finish_agent(state: dict) -> dict:
    """结束节点:汇总最终结果"""
    messages = state["messages"]
    return {"messages": messages}

# ========== 4. 构建多智能体图 ==========
class MultiAgentState(TypedDict):
    messages: Annotated[list[AnyMessage], add]
    next: str

workflow = StateGraph(MultiAgentState)

# 添加节点
workflow.add_node("supervisor", supervisor)
workflow.add_node("research", research_agent)
workflow.add_node("math", math_agent)
workflow.add_node("writing", writing_agent)
workflow.add_node("finish", finish_agent)

# 添加边
workflow.add_edge(START, "supervisor")
workflow.add_conditional_edges("supervisor", router)
workflow.add_edge("research", END)
workflow.add_edge("math", END)
workflow.add_edge("writing", END)

app = workflow.compile()

# ========== 5. 运行测试 ==========
if __name__ == "__main__":
    print("=" * 50)
    print("多智能体 Supervisor 模式测试(阿里云百炼)")
    print("=" * 50)
    
    test_questions = [
        "帮我搜索关于人工智能的最新发展",
        "计算 25 + 17 等于多少?",
        "请润色这句话:今天天气很好,我很开心"
    ]
    
    for q in test_questions:
        print(f"\n用户:{q}")
        result = app.invoke({"messages": [HumanMessage(content=q)]})
        print(f"AI:{result['messages'][-1].content}")

八、实战:多智能体文档问答系统(RAG + Agent)

8.1 系统架构

复制代码
用户输入问题
      │
      ▼
┌─────────────────────────────────────────────────────────────┐
│                    监督者(Supervisor)                       │
│                  判断问题类型,分配任务           │
└─────────────────────────────────────────────────────────────┘
      │
      ├──────────┬──────────┬──────────┐
      ▼          ▼          ▼          ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ 检索专家 │ │ 推理专家 │ │ 代码专家 │ │ 总结专家 │
│ 查找文档 │ │ 逻辑推理 │ │ 代码生成 │ │ 结果整理 │
└─────────┘ └─────────┘ └─────────┘ └─────────┘

8.2 完整代码

python 复制代码
"""
多智能体文档问答系统(阿里云百炼版 + RAG)
功能:检索 + 推理 + 代码 + 总结 多智能体协作
"""

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_chroma import Chroma
from langgraph.graph import StateGraph, END, START
from typing import TypedDict, List
from langchain_core.messages import HumanMessage

load_dotenv()

# ========== 1. 初始化阿里云百炼模型 ==========
llm = ChatOpenAI(
    model="qwen3-max",
    temperature=0,
    openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
    openai_api_base=os.getenv("DASHSCOPE_BASE_URL"),
)

# ========== 2. 初始化 RAG 向量数据库 ==========
def init_rag():
    """初始化 RAG 检索系统"""
    # 创建示例文档
    sample_docs = [
        "LangGraph 是 LangChain 团队开发的用于构建有状态多智能体应用的框架。",
        "LangGraph 基于图结构,支持循环和条件分支,适合构建 ReAct Agent。",
        "LangGraph 内置检查点机制,可以实现跨会话的对话记忆。",
        "Supervisor 模式是多智能体架构的一种,由一个中央监督者协调多个专业智能体。",
    ]
    
    with open("temp_docs.txt", "w", encoding="utf-8") as f:
        f.write("\n".join(sample_docs))
    
    loader = TextLoader("temp_docs.txt", encoding="utf-8")
    docs = loader.load()
    
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20)
    chunks = text_splitter.split_documents(docs)
    
    embeddings = HuggingFaceEmbeddings(
        model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
    )
    vectorstore = Chroma.from_documents(chunks, embeddings)
    retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
    
    os.remove("temp_docs.txt")
    return retriever

retriever = init_rag()

# ========== 3. 定义系统状态 ==========
class RAGState(TypedDict):
    question: str
    retrieved_context: str
    reasoning_result: str
    code_result: str
    final_answer: str
    next_agent: str

# ========== 4. 定义专业智能体 ==========

def retrieval_agent(state: RAGState) -> dict:
    """检索专家:根据问题检索相关文档"""
    question = state["question"]
    print(f"\n📚 检索专家:正在搜索相关信息...")
    
    docs = retriever.invoke(question)
    context = "\n".join([doc.page_content for doc in docs])
    
    return {"retrieved_context": context, "next_agent": "reasoning"}

def reasoning_agent(state: RAGState) -> dict:
    """推理专家:基于检索结果进行逻辑推理"""
    question = state["question"]
    context = state.get("retrieved_context", "")
    
    prompt = f"""
基于以下文档内容,回答问题。

文档内容:
{context}

问题:{question}

请给出准确、简洁的回答。
"""
    response = llm.invoke(prompt)
    
    return {"reasoning_result": response.content, "next_agent": "code"}

def code_agent(state: RAGState) -> dict:
    """代码专家:生成相关代码示例(如果需要)"""
    question = state["question"]
    reasoning = state.get("reasoning_result", "")
    
    # 判断是否需要代码
    if "代码" in question or "实现" in question or "写一个" in question:
        prompt = f"""
根据问题和推理结果,生成相关的代码示例。

问题:{question}
推理:{reasoning}

只输出代码,不要解释。
"""
        response = llm.invoke(prompt)
        return {"code_result": response.content, "next_agent": "summary"}
    else:
        return {"code_result": "", "next_agent": "summary"}

def summary_agent(state: RAGState) -> dict:
    """总结专家:整合所有结果,输出最终答案"""
    reasoning = state.get("reasoning_result", "")
    code = state.get("code_result", "")
    
    if code:
        final = f"{reasoning}\n\n代码示例:\n{code}"
    else:
        final = reasoning
    
    return {"final_answer": final, "next_agent": "end"}

def end_agent(state: RAGState) -> dict:
    """结束节点"""
    return {}

# ========== 5. 构建多智能体图 ==========
def router(state: RAGState) -> str:
    """路由函数"""
    return state.get("next_agent", "end")

workflow = StateGraph(RAGState)

# 添加节点
workflow.add_node("retrieval", retrieval_agent)
workflow.add_node("reasoning", reasoning_agent)
workflow.add_node("code", code_agent)
workflow.add_node("summary", summary_agent)
workflow.add_node("end", end_agent)

# 添加边
workflow.add_edge(START, "retrieval")
workflow.add_edge("retrieval", "reasoning")
workflow.add_edge("reasoning", "code")
workflow.add_edge("code", "summary")
workflow.add_conditional_edges("summary", router)
workflow.add_edge("end", END)

app = workflow.compile()

# ========== 6. 运行测试 ==========
if __name__ == "__main__":
    print("=" * 50)
    print("多智能体文档问答系统测试(阿里云百炼 + RAG)")
    print("=" * 50)
    
    test_questions = [
        "LangGraph 是什么?",
        "LangGraph 支持哪些特性?",
        "我想了解 Supervisor 模式,请给出代码示例"
    ]
    
    for q in test_questions:
        print(f"\n用户:{q}")
        result = app.invoke({"question": q})
        print(f"AI:{result['final_answer']}")

九、常见问题

Q1:LangGraph 和 LangChain 的关系?

LangGraph 是 LangChain 生态的一部分,专门用于构建复杂的多步骤智能体。LangChain 负责单次调用,LangGraph 负责编排调用流程。

Q2:阿里云百炼支持哪些模型用于 LangGraph?

所有支持 Function Calling 的模型都可以:

· qwen3-max:能力最强,推荐用于复杂场景

· qwen3-plus:平衡之选

· qwen3-turbo:速度快,适合简单任务

Q3:如何调试 LangGraph 应用?

python 复制代码
# 开启调试模式
from langchain.globals import set_debug
set_debug(True)

# 或使用可视化
from IPython.display import Image, display
display(Image(app.get_graph().draw_png()))

Q4:多智能体和单智能体的性能差异?

对比项 单智能体 多智能体

响应速度 快 较慢(多次调用)

复杂任务 效果一般 效果好

调试难度 简单 复杂

适用场景 简单任务 复杂工作流

十、与已有技能的联系

你学过的技能 在 LangGraph 中的应用

LangChain 基础 模型调用、工具定义与之前相同

RAG 可集成到检索智能体节点中

Agent LangGraph 是 Agent 的底层实现框架

阿里云百炼 API 直接用 qwen 系列模型

记忆管理 LangGraph 内置检查点机制

十一、总结

本文完成了 LangGraph 的完整入门:

内容 状态

环境搭建(阿里云百炼) ✅

单智能体 ReAct Agent ✅

多智能体 Supervisor 模式 ✅

多智能体 RAG 问答系统 ✅

核心概念总结:

复制代码
StateGraph(状态图)
    ├── Node(节点):执行单元
    ├── Edge(边):连接方式
    ├── State(状态):共享数据
    └── Checkpoint(检查点):持久化记忆

执行流程:
START → Node1 → Conditional Edge → Node2 → END
                ↓
              (条件判断)

快速开始模板:

python 复制代码
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode
from langgraph.checkpoint.memory import InMemorySaver

# 1. 构建图
workflow = StateGraph(MessagesState)

# 2. 添加节点
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)

# 3. 添加边
workflow.add_edge(START, "agent")
workflow.add_conditional_edges("agent", should_continue)
workflow.add_edge("tools", "agent")

# 4. 编译
app = workflow.compile(checkpointer=InMemorySaver())

# 5. 调用
result = app.invoke({"messages": [HumanMessage("你好")]})

相关推荐
饭后一颗花生米1 小时前
AI算力选型全景指南:从入门到旗舰的硬核实操
人工智能
Yue栎廷1 小时前
邪修:Markdown加粗语法**本土化改造
前端·javascript·人工智能
2301_815279521 小时前
实战分享LangChain WebUI 部署智能客服:从零搭建到生产环境优化
人工智能·langchain
三维频道1 小时前
柔性材料3D数字化:蓝光扫描在内衣胸垫设计与质检中的应用
人工智能·3d·逆向工程·蓝光3d扫描仪·服装数字化·内衣设计·柔性材料检测
科研前沿1 小时前
镜像视界浙江科技有限公司的核心引擎关键技术有哪些?
人工智能·数码相机·计算机视觉
帅次1 小时前
Android AI 面试速刷版
人工智能·深度学习·神经网络·机器学习·语言模型·自然语言处理·数据分析
生物信息与育种1 小时前
全基因组重测序及群体遗传与进化分析技术服务指南
人工智能·深度学习·算法·数据分析·r语言
MediaTea1 小时前
Scikit-learn:preprocessing 模块
人工智能·深度学习·机器学习·计算机视觉·scikit-learn
Ares-Wang1 小时前
Flask》》Flask-Caching缓存插件
python·缓存·flask