【langgraph 从入门到精通graphApi 篇】LangGraphAPI 方式调用 - 初识与核心概念

文章目录

    • [第 1 章:LangGraph 初识与核心概念](#第 1 章:LangGraph 初识与核心概念)
      • [1.1 本章目标](#1.1 本章目标)
      • [1.2 核心概念](#1.2 核心概念)
        • [LangGraph 是什么?](#LangGraph 是什么?)
        • [LangGraph 在 AI 生态中的位置](#LangGraph 在 AI 生态中的位置)
        • [第一个 Graph 的内部结构](#第一个 Graph 的内部结构)
      • [1.3 实战:你的第一个 LangGraph 程序](#1.3 实战:你的第一个 LangGraph 程序)
      • [1.4 API 速查](#1.4 API 速查)
      • [1.5 错误与避坑指南](#1.5 错误与避坑指南)
        • [坑 1:忘记导入 START 和 END](#坑 1:忘记导入 START 和 END)
        • [坑 2:节点函数返回 None 而非 dict](#坑 2:节点函数返回 None 而非 dict)
        • [坑 3:返回的 key 不在 State 中](#坑 3:返回的 key 不在 State 中)
        • [坑 4:混淆 invoke() 的参数](#坑 4:混淆 invoke() 的参数)
      • [1.6 最佳实践总结](#1.6 最佳实践总结)

第 1 章:LangGraph 初识与核心概念

1.1 本章目标

学完本章你将能够:

  1. 理解 LangGraph 在 AI 开发生态中的定位
  2. 掌握 State、Node、Edge、Graph 四大核心概念
  3. 独立编写并运行第一个 LangGraph 程序

1.2 核心概念

LangGraph 是什么?

在计算机科学中,图(Graph)由节点(Node)和边(Edge)组成。节点是执行任务的单元,边是连接节点的线,决定了任务执行的先后顺序。就像地铁线路图------每个站点是节点,连接站点的轨道是边。

LangGraph 是一个有状态的多步骤 AI 应用编排框架。你可以把它想象成一个智能工厂的流水线:

概念 比喻(工厂流水线) 技术定义
Graph(图) 整个工厂的布局图 定义了所有节点和边的有向图结构
State(状态) 在流水线上流转的零件 在节点间共享的数据结构,每个节点可以读取和修改
Node(节点) 每个工位 执行具体操作的函数(LLM 调用、工具执行、数据处理)
Edge(边) 连接工位的传送带 定义节点间的执行顺序和条件

核心公式Nodes 做工作,Edges 决定流程,State 是纽带

LangGraph 在 AI 生态中的位置

#mermaid-svg-kamBW7feidFCXmzY{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kamBW7feidFCXmzY .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kamBW7feidFCXmzY .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kamBW7feidFCXmzY .error-icon{fill:#552222;}#mermaid-svg-kamBW7feidFCXmzY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kamBW7feidFCXmzY .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kamBW7feidFCXmzY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kamBW7feidFCXmzY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kamBW7feidFCXmzY .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kamBW7feidFCXmzY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kamBW7feidFCXmzY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kamBW7feidFCXmzY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kamBW7feidFCXmzY .marker.cross{stroke:#333333;}#mermaid-svg-kamBW7feidFCXmzY svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kamBW7feidFCXmzY p{margin:0;}#mermaid-svg-kamBW7feidFCXmzY .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-kamBW7feidFCXmzY .cluster-label text{fill:#333;}#mermaid-svg-kamBW7feidFCXmzY .cluster-label span{color:#333;}#mermaid-svg-kamBW7feidFCXmzY .cluster-label span p{background-color:transparent;}#mermaid-svg-kamBW7feidFCXmzY .label text,#mermaid-svg-kamBW7feidFCXmzY span{fill:#333;color:#333;}#mermaid-svg-kamBW7feidFCXmzY .node rect,#mermaid-svg-kamBW7feidFCXmzY .node circle,#mermaid-svg-kamBW7feidFCXmzY .node ellipse,#mermaid-svg-kamBW7feidFCXmzY .node polygon,#mermaid-svg-kamBW7feidFCXmzY .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kamBW7feidFCXmzY .rough-node .label text,#mermaid-svg-kamBW7feidFCXmzY .node .label text,#mermaid-svg-kamBW7feidFCXmzY .image-shape .label,#mermaid-svg-kamBW7feidFCXmzY .icon-shape .label{text-anchor:middle;}#mermaid-svg-kamBW7feidFCXmzY .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kamBW7feidFCXmzY .rough-node .label,#mermaid-svg-kamBW7feidFCXmzY .node .label,#mermaid-svg-kamBW7feidFCXmzY .image-shape .label,#mermaid-svg-kamBW7feidFCXmzY .icon-shape .label{text-align:center;}#mermaid-svg-kamBW7feidFCXmzY .node.clickable{cursor:pointer;}#mermaid-svg-kamBW7feidFCXmzY .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kamBW7feidFCXmzY .arrowheadPath{fill:#333333;}#mermaid-svg-kamBW7feidFCXmzY .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kamBW7feidFCXmzY .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kamBW7feidFCXmzY .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kamBW7feidFCXmzY .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kamBW7feidFCXmzY .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kamBW7feidFCXmzY .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kamBW7feidFCXmzY .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kamBW7feidFCXmzY .cluster text{fill:#333;}#mermaid-svg-kamBW7feidFCXmzY .cluster span{color:#333;}#mermaid-svg-kamBW7feidFCXmzY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kamBW7feidFCXmzY .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kamBW7feidFCXmzY rect.text{fill:none;stroke-width:0;}#mermaid-svg-kamBW7feidFCXmzY .icon-shape,#mermaid-svg-kamBW7feidFCXmzY .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kamBW7feidFCXmzY .icon-shape p,#mermaid-svg-kamBW7feidFCXmzY .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kamBW7feidFCXmzY .icon-shape .label rect,#mermaid-svg-kamBW7feidFCXmzY .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kamBW7feidFCXmzY .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kamBW7feidFCXmzY .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kamBW7feidFCXmzY :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 基础设施
模型层
编排层
AI 应用层
你的 AI 应用
LangGraph

状态编排 + 流程控制
LangChain

模型调用 + 工具集成 + 提示词
LLM 模型

OpenAI / Claude / DeepSeek / ...
持久化

Checkpoint / Store
外部工具

搜索 / 计算 / API

第一个 Graph 的内部结构

#mermaid-svg-CTCHCFilF4nUaDx4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CTCHCFilF4nUaDx4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CTCHCFilF4nUaDx4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CTCHCFilF4nUaDx4 .error-icon{fill:#552222;}#mermaid-svg-CTCHCFilF4nUaDx4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CTCHCFilF4nUaDx4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CTCHCFilF4nUaDx4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CTCHCFilF4nUaDx4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CTCHCFilF4nUaDx4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CTCHCFilF4nUaDx4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CTCHCFilF4nUaDx4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CTCHCFilF4nUaDx4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CTCHCFilF4nUaDx4 .marker.cross{stroke:#333333;}#mermaid-svg-CTCHCFilF4nUaDx4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CTCHCFilF4nUaDx4 p{margin:0;}#mermaid-svg-CTCHCFilF4nUaDx4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-CTCHCFilF4nUaDx4 .cluster-label text{fill:#333;}#mermaid-svg-CTCHCFilF4nUaDx4 .cluster-label span{color:#333;}#mermaid-svg-CTCHCFilF4nUaDx4 .cluster-label span p{background-color:transparent;}#mermaid-svg-CTCHCFilF4nUaDx4 .label text,#mermaid-svg-CTCHCFilF4nUaDx4 span{fill:#333;color:#333;}#mermaid-svg-CTCHCFilF4nUaDx4 .node rect,#mermaid-svg-CTCHCFilF4nUaDx4 .node circle,#mermaid-svg-CTCHCFilF4nUaDx4 .node ellipse,#mermaid-svg-CTCHCFilF4nUaDx4 .node polygon,#mermaid-svg-CTCHCFilF4nUaDx4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CTCHCFilF4nUaDx4 .rough-node .label text,#mermaid-svg-CTCHCFilF4nUaDx4 .node .label text,#mermaid-svg-CTCHCFilF4nUaDx4 .image-shape .label,#mermaid-svg-CTCHCFilF4nUaDx4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-CTCHCFilF4nUaDx4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CTCHCFilF4nUaDx4 .rough-node .label,#mermaid-svg-CTCHCFilF4nUaDx4 .node .label,#mermaid-svg-CTCHCFilF4nUaDx4 .image-shape .label,#mermaid-svg-CTCHCFilF4nUaDx4 .icon-shape .label{text-align:center;}#mermaid-svg-CTCHCFilF4nUaDx4 .node.clickable{cursor:pointer;}#mermaid-svg-CTCHCFilF4nUaDx4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CTCHCFilF4nUaDx4 .arrowheadPath{fill:#333333;}#mermaid-svg-CTCHCFilF4nUaDx4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CTCHCFilF4nUaDx4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CTCHCFilF4nUaDx4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CTCHCFilF4nUaDx4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CTCHCFilF4nUaDx4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CTCHCFilF4nUaDx4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CTCHCFilF4nUaDx4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CTCHCFilF4nUaDx4 .cluster text{fill:#333;}#mermaid-svg-CTCHCFilF4nUaDx4 .cluster span{color:#333;}#mermaid-svg-CTCHCFilF4nUaDx4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CTCHCFilF4nUaDx4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CTCHCFilF4nUaDx4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-CTCHCFilF4nUaDx4 .icon-shape,#mermaid-svg-CTCHCFilF4nUaDx4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CTCHCFilF4nUaDx4 .icon-shape p,#mermaid-svg-CTCHCFilF4nUaDx4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CTCHCFilF4nUaDx4 .icon-shape .label rect,#mermaid-svg-CTCHCFilF4nUaDx4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CTCHCFilF4nUaDx4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CTCHCFilF4nUaDx4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CTCHCFilF4nUaDx4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 开始
完成
START
greet 节点

生成问候语
END

1.3 实战:你的第一个 LangGraph 程序

让我们从一个最简单的例子开始:输入一个人的名字,输出一句问候语。

python 复制代码
# ============================================
# 第 1 步:导入必要的模块
# ============================================
from typing import TypedDict
from langgraph.graph import StateGraph, START, END


# ============================================
# 第 2 步:定义 State(状态)------ 图中流转的数据结构
# ============================================
class State(TypedDict):
    """
    State 是图中所有节点共享的数据结构。
    使用 TypedDict 定义,提供类型安全和 IDE 提示。
    
    这里定义了两个字段:
    - name: 用户输入的名字
    - greeting: 生成的问候语(初始为空)
    """
    name: str
    greeting: str

# TypedDict 是 Python 的类型提示工具,它定义了字典中每个键对应的值类型。
# LangGraph 用 TypedDict 来声明 State 的结构,这样 IDE 可以自动补全字段名,
# 也能在编写代码时检查类型错误。

# ============================================
# 第 3 步:定义 Node(节点)------ 执行具体操作的函数
# ============================================
def greet(state: State) -> dict:
    """
    节点函数签名规则:
    - 参数:接收当前 State 作为输入
    - 返回值:返回一个 dict,包含要更新的 State 字段
    
    注意:只需返回要更新的字段,不需要返回完整 State!
    LangGraph 会自动将返回值合并到当前 State 中。
    """
    print(f"   [greet 节点] 收到名字: {state['name']}")
    # 从 State 中读取 name,生成问候语,返回更新
    return {"greeting": f"你好, {state['name']}!"}


# ============================================
# 第 4 步:构建 Graph(图)------ 把节点和边组合起来
# ============================================
# 创建 StateGraph 构建器,传入 State 类型
builder = StateGraph(State)

# 注册节点:给 greet 函数起名为 "greet"
builder.add_node("greet", greet)

# 添加边(流程控制):
# START → greet → END
# 表示从图入口开始,执行 greet 节点,然后结束
builder.add_edge(START, "greet")
builder.add_edge("greet", END)

# 编译图:将构建器"冻结"为可执行的图对象
graph = builder.compile()


# ============================================
# 第 5 步:运行 Graph
# ============================================
print("=== 执行 Graph ===")
# invoke() 方法传入初始状态,返回最终状态
result = graph.invoke({"name": "小明"})
print(f"=== 结果: {result['greeting']}")


# ============================================
# 运行输出:
# === 执行 Graph ===
#    [greet 节点] 收到名字: 小明
# === 结果: 你好, 小明!
# ============================================

代码执行流程解析:

  1. graph.invoke({"name": "小明"}) --- 传入初始 State(只有 namegreeting 为默认值 ""
  2. 图从 START 出发,找到第一条边 START → greet
  3. 执行 greet 节点函数,传入当前 State,函数返回 {"greeting": "你好, 小明!"}
  4. 图将返回值合并到 State 中,State 变为 {"name": "小明", "greeting": "你好, 小明!"}
  5. 找到下一条边 greet → END,图结束
  6. invoke() 返回最终的完整 State

1.4 API 速查

API 完整签名 入参说明 返回值 说明
StateGraph(state_schema) StateGraph(state_schema: Type[StateT]) state_schema: State 类型(TypedDict/dataclass/Pydantic) StateGraph 构建器对象 创建状态图构建器
.add_node(name, action) add_node(node: str, action: Callable) node: 节点名(str); action: 节点函数 Self(支持链式调用) 注册一个节点
.add_edge(start, end) add_edge(start_key: str, end_key: str) start_key: 源节点名; end_key: 目标节点名 Self 添加一条普通边
.compile() compile(checkpointer, interrupt_before, interrupt_after, ...) 可选参数见后续章节 CompiledStateGraph 编译图使之可执行
.invoke(input) invoke(input: dict, config: dict = None) input: 初始 State 字典; config: 运行配置(可选) dict 最终 State 同步执行图

1.5 错误与避坑指南

坑 1:忘记导入 START 和 END
python 复制代码
# ❌ 错误写法
from langgraph.graph import StateGraph  # 只导入了 StateGraph
builder = StateGraph(State)
builder.add_edge(START, "my_node")  # NameError: name 'START' is not defined

# ✅ 正确写法
from langgraph.graph import StateGraph, START, END  # 同时导入 START 和 END
坑 2:节点函数返回 None 而非 dict
python 复制代码
# ❌ 错误写法
def bad_node(state: State):
    print("处理中...")
    # 忘记返回值,隐式返回 None
    # → LangGraph 收到 None,无法更新 State,可能报错或静默失败

# ✅ 正确写法
def good_node(state: State) -> dict:
    print("处理中...")
    return {"some_field": "new_value"}  # 必须返回 dict
坑 3:返回的 key 不在 State 中
python 复制代码
class State(TypedDict):
    name: str
    greeting: str

# ❌ 错误写法
def bad_node(state: State) -> dict:
    return {"message": "hello"}  # "message" 不在 State 中定义,运行时报错

# ✅ 正确写法
def good_node(state: State) -> dict:
    return {"greeting": "hello"}  # "greeting" 在 State 中定义
坑 4:混淆 invoke() 的参数
python 复制代码
# ❌ 错误写法
graph.invoke("hello")  # 传入字符串而非 dict

# ✅ 正确写法
graph.invoke({"name": "小明"})  # 传入 dict,key 对应 State 的字段

1.6 最佳实践总结

  1. 使用 TypedDict 定义 State:类型安全,IDE 有完整提示,出错时容易定位问题
  2. 节点函数保持单一职责:一个节点只做一件事(如"搜索"、"生成回复"、"调用工具"),不要在一个节点里做太多事
  3. 始终从 START 到 END 形成完整路径:确保每个节点都有入口和出口,避免"死胡同"
  4. 节点返回值只包含变更字段:不需要返回完整 State,LangGraph 自动合并,减少冗余代码
  5. 先画图再写代码:复杂流程先用 Mermaid 画出图结构,再着手实现,思路更清晰

相关推荐
念雨思11 小时前
HarmonyOS AI 应用开发实战:短视频选题灵感 —— AI 驱动的内容创作引擎
人工智能·学习·华为·harmonyos·鸿蒙
FourAu11 小时前
2026 前端突围指南:从 ESR 边缘渲染到封装 Web AI SDK,聊聊 AI 时代的职业进化
前端·人工智能
前端开发江鸟11 小时前
模型返回了 JSON,为什么还不能调用工具?Runtime 的结构化输出校验链路
人工智能
Urbano11 小时前
卫衣生产工艺科普与智能自动化设备应用解析
大数据·运维·人工智能
kp0000011 小时前
Prompt注入攻击(Prompt Injection Attack)
人工智能·安全·网络安全·信息安全·ai安全
这张生成的图像能检测吗11 小时前
(论文速度)RE-NET递归事件网络:时态知识图上的自回归结构推理
人工智能·图神经网络·时序模型
TlSfoward11 小时前
TLSFOWARD TLS指纹
开发语言·数据库·爬虫·搜索引擎·https·php
larance11 小时前
机器学习特征预处理之删移除无关特征
人工智能·机器学习·数据挖掘
️学习的小王11 小时前
MySQL 实战:从建表到索引管理的完整指南
数据库·mysql·oracle