LangGraph基础知识点

第一章:核心认知与基础概念

1.1 LangGraph 的定位

  • 本质 :Agent Server 的"操作系统内核"。它不关心具体模型或提示词,专门解决构建复杂 AI 应用时的底层工程难题:状态管理、流程编排、持久化、人工监督
  • 三大超能力
    • 记忆大师:自动保持多轮对话上下文,支持跨会话记忆。
    • 流程指挥官:将复杂任务拆解为可控的步骤(图结构)。
    • 容错卫士:支持故障恢复、人工中断、生产级持久化。

1.2 核心概念区分

  • 工作流(Workflow):流程固定、步骤预设(如客服工单处理)。
  • 智能体(Agent):由 LLM 动态控制流程走向,灵活应对开放问题。
  • LangGraph 的核心 :本质是构建工作流图(Graph),但可通过条件路由模拟智能体行为。

1.3 图计算三要素

  • 节点(Node):处理步骤(函数)。
  • 边(Edge):流转路径(固定或条件)。
  • 状态(State):节点间共享的数据容器。

第二章:图构建核心实操

2.1 定义状态(State)与 Reducer(归约器)

知识点 :所有节点共享 State。Annotated + operator.add 实现列表追加/数值累加,而非覆盖。

python 复制代码
from typing import TypedDict, Annotated
import operator

class OverallState(TypedDict):
    # 列表使用 operator.add,每次更新会追加,而非替换
    messages: Annotated[list, operator.add]  
    # 普通字段默认覆盖(替换)
    user_name: str                           
    # 数值使用 operator.add,实现累加
    total_score: Annotated[int, operator.add] 

2.2 定义节点与边(固定边 + 条件边)

知识点 :节点是接收 state 返回部分更新的函数。START 是入口,END 是终止。条件边通过路由函数动态选择下一节点。

python 复制代码
from langgraph.graph import StateGraph, START, END

# 1. 定义节点函数
def step_a(state: OverallState):
    # 返回的字典会根据 Reducer 规则合并
    return {"messages": ["A 节点执行"], "total_score": 10}

def step_b(state: OverallState):
    return {"messages": ["B 节点执行"], "total_score": 20}

# 2. 构建图
builder = StateGraph(OverallState)
builder.add_node("step_a", step_a)
builder.add_node("step_b", step_b)

# 固定边:START -> A -> B
builder.add_edge(START, "step_a")
builder.add_edge("step_a", "step_b")

# 条件边:根据分数决定是否提前结束
def route_decision(state: OverallState) -> str:
    if state.get("total_score", 0) > 100:
        return "step_b"   # 继续到 B
    return END            # 直接结束

builder.add_conditional_edges("step_a", route_decision)

# 3. 必须编译才能运行
graph = builder.compile()

2.3 高级状态管理

2.3.1 使用 Overwrite 绕过 Reducer

场景:重置聊天记录或强制覆盖列表。

python 复制代码
from langgraph.types import Overwrite

def reset_node(state: OverallState):
    # 强制覆盖 messages 列表,忽略 operator.add 的追加逻辑
    return {"messages": Overwrite(["系统重置,历史已清空"])}
2.3.2 定义独立的输入/输出模式

场景:对外只接收用户问题,只返回最终答案;内部可存储敏感中间变量(不暴露给外部)。

python 复制代码
# 外部只需传入这个
class InputState(TypedDict):
    user_query: str

# 内部全量状态(包含输入 + 私有字段)
class PrivateState(InputState, TypedDict):
    internal_id: str    # 内部使用,不对外暴露
    final_answer: str

# 对外只返回这个
class OutputState(TypedDict):
    final_answer: str

builder = StateGraph(
    state_schema=PrivateState,   # 内部使用
    input_schema=InputState,     # 校验输入
    output_schema=OutputState    # 过滤输出
)
2.3.3 私有状态(节点间传递敏感数据)

知识点:不同节点返回的字段若未在总 State 中定义,仅在该链路中临时传递,不会污染全局输出。


第三章:工作流常见模式

3.1 模式概览

模式 特点 适用场景
提示链 线性流水线,前一步输出是下一步输入 内容创作(大纲→初稿→润色)
并行化 多任务同时执行,最后汇总 多维度分析(市场、竞品、技术)
路由 根据输入动态分流到专用处理器 智能客服(售前/售后/技术)
协调者-工作者 运行时动态生成子任务并并行执行 文档拆分翻译、动态任务分配
评估器-优化器 循环生成→评估→改进,直到达标 代码质量迭代、内容优化

3.2 路由模式(智能分流)代码示例

核心:条件边返回字符串,直接映射到预定义分支节点。

python 复制代码
def classify_intent(state: dict) -> str:
    if "价格" in state["query"]:
        return "sales_handler"
    elif "报错" in state["query"]:
        return "tech_handler"
    return "default_handler"

builder.add_conditional_edges(
    "classifier_node", 
    classify_intent, 
    ["sales_handler", "tech_handler", "default_handler"]
)

3.3 协调者-工作者模式(动态并行)代码示例

核心 :条件边返回 Send 对象列表,实现运行时动态生成 n 条并行任务。

python 复制代码
from langgraph.types import Send

class State(TypedDict):
    sections: list[str]   # 协调者动态生成的章节列表
    results: list[str]

def assign_workers(state: State):
    # 为每个章节动态创建一个工作者任务
    return [Send("worker_node", {"section": sec}) for sec in state["sections"]]

# 协调者节点后接条件边,动态发散到 worker_node
builder.add_conditional_edges("orchestrator", assign_workers, ["worker_node"])

第四章:持久化(记忆、检查点与人机交互)

4.1 Checkpointer(状态持久化)

知识点 :编译时必须传入 checkpointer,图才会在每个步骤后自动保存状态快照。

内存存储(开发测试)
python 复制代码
from langgraph.checkpoint.memory import InMemorySaver

memory = InMemorySaver()
graph = builder.compile(checkpointer=memory)
PostgreSQL 存储(生产推荐)
python 复制代码
# 需先安装: pip install langgraph-checkpoint-postgres
from langgraph.checkpoint.postgres import PostgresSaver

DB_URI = "postgresql://user:pass@host:5432/db"
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
    checkpointer.setup()  # 仅首次需要初始化建表
    graph = builder.compile(checkpointer=checkpointer)

4.2 Thread(线程)与短期记忆

知识点 :通过 thread_id 隔离不同会话。相同 thread_id 会自动加载历史状态,实现多轮记忆。

python 复制代码
# 第一次对话(创建新线程)
config = {"configurable": {"thread_id": "user_123"}}
graph.invoke({"messages": ["我叫小明"]}, config)

# 第二次对话(程序重启后,相同 thread_id 自动恢复记忆)
result = graph.invoke({"messages": ["我叫什么名字?"]}, config)
print(result["messages"][-1])  # 输出:你叫小明

4.3 查看历史与时间旅行(Time Travel)

核心价值:定位错误节点,或修改历史状态后重放执行。

获取历史检查点
python 复制代码
# 按时间倒序返回 StateSnapshot 列表
history = list(graph.get_state_history(config))
for snap in history:
    print(f"检查点ID: {snap.config['configurable']['checkpoint_id']}")
    print(f"下一步节点: {snap.next}")        # 该时刻即将执行的节点
    print(f"当时状态值: {snap.values}")
修改历史状态并从该点重放
python 复制代码
# 假设 history[1] 是某一步的中间快照
old_snapshot = history[1]

# 修改该快照中的状态值(会生成新分支)
new_config = graph.update_state(
    old_snapshot.config,
    {"user_name": "修改后的名字"}  # 覆盖那一刻的状态
)

# 从修改后的点继续执行(输入为 None,因为状态已载入)
final_result = graph.invoke(None, config=new_config)

4.4 人机交互(中断 Interrupt)

知识点 :节点内调用 interrupt() 暂停执行,外部用 Command(resume=...) 恢复。必须配合 checkpointer 使用。

python 复制代码
from langgraph.types import interrupt, Command

def approval_node(state: dict):
    # 暂停执行,向外抛出提示,等待人工介入
    user_input = interrupt("请确认是否转账?输入 yes/no")
    if user_input == "yes":
        return {"status": "approved"}
    return {"status": "rejected"}

# 首次调用(会触发中断)
config = {"configurable": {"thread_id": "task_001"}}
result = graph.invoke({"task": "转账1000元"}, config)
print(result["__interrupt__"])  # 显示中断信息:"请确认是否转账?"

# 外部人工决策后恢复执行
final = graph.invoke(Command(resume="yes"), config)
print(final["status"])  # 输出:"approved"

4.5 跨会话持久化(Store 长期记忆)

知识点:Store 用于保存用户偏好、历史预订等跨线程数据,通过命名空间(Namespace)隔离。

python 复制代码
from langgraph.store.memory import InMemoryStore

store = InMemoryStore()
# 编译时同时传入 checkpointer 和 store
graph = builder.compile(checkpointer=memory, store=store)

# 在节点中存取长期记忆
def save_preference(state, runtime, *, store):
    user_id = runtime.context.get("user_id")
    namespace = (user_id, "preferences")
    # 存入
    store.put(namespace, "key_001", {"favorite_food": "汉堡"})
    # 读取
    results = store.search(namespace)

功能模块 关键类/方法 必须记住的原则
状态合并 Annotated[list, operator.add] 默认覆盖,用 Reducer 实现追加/累加
节点 add_node(name, func) 函数返回 部分更新,无需返回完整 State
条件路由 add_conditional_edges(src, router, targets) 路由器返回 节点名字符串Send 列表
编译 .compile(checkpointer=...) 必须编译;持久化依赖 checkpointer
会话隔离 config={"configurable":{"thread_id":"x"}} 相同 ID 自动恢复状态
中断 interrupt(prompt) + Command(resume=...) 必须配合 checkpointer,恢复时节点从头执行
时间旅行 get_state_history + update_state 修改历史快照后 invoke(None, new_config) 重放
相关推荐
Lvan的前端笔记1 小时前
python:Mac 系统 uv 完整安装+入门实战
python·macos·uv
会飞锦鲤1 小时前
基于YOLOv10的瓜果成熟度智能检测系统
人工智能·python·深度学习·yolo·flask
AOwhisky1 小时前
Python 学习笔记(第四期)——字符串:格式化、操作与文本处理——核心知识点自测与详解
开发语言·笔记·python·学习·列表·元组·字典
一次旅行2 小时前
【AI技术_工具】用 MCP 把本地工具接入 Claude_Cursor,让 AI 真正摸到你的数据
大数据·人工智能·python
AOwhisky2 小时前
Python 学习笔记(第六期)——函数:定义、参数传递与作用域
笔记·python·学习·云原生·运维开发·函数·参数传递
元Y亨H2 小时前
Skills vs MCP vs Function Calling 的介绍
llm
茗创科技2 小时前
CGE连接组:用基因表达解码脑疾病的异质性(附高分文献下载)
python·matlab·脑网络
汤米粥2 小时前
Python调用百度搜索触发安全验证
开发语言·python
杠杠的blog2 小时前
企业级提示词管理
python·agent·提示词·生产级实践