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) 重放
相关推荐
GuWenyue16 小时前
不用第三方SDK!Vue3原生Fetch实现DeepSeek流式输出,90%前端都会踩的分片解析坑一次性解决
前端·人工智能·llm
电化学仪器白超16 小时前
禹衡光栅长度计精度评测:基于国标0级氧化锆量块的校正与数据分析
python·单片机·嵌入式硬件·物联网·自动化
喜欢的名字被抢了16 小时前
langgraph教程系列-07-让人介入-人在回路
langgraph
小玮看世界17 小时前
[Python]自动驾驶感知与决策练习题 (1-10)
开发语言·python·自动驾驶
昵称好难啊17 小时前
ClaudeCode: 怎么规划任务
llm·agent
Ming_studying17 小时前
Python + SQLite FTS5 构建本地文档全文搜索器:增量索引、中文检索与高亮
jvm·数据库·python·sqlite
凉凉的知识库17 小时前
MCP 协议迎来重大升级:2026-07-28 新版核心变化速览
llm·claude·mcp
玉鸯17 小时前
让 Agent 面向用户:AG-UI 协议构建 Agent 前端
前端·python·agent
人生百态,人生如梦17 小时前
每日论文解读 (8.3) 1——DeepResearch Agent System:稀疏激活架构驱动的自主深度研究Agent
架构·llm·agent·deepresearch
小白学大数据17 小时前
把 Modbus 轮询塞进 Trio 的异步循环:内存映射与定时采集实战
网络·python·搜索引擎