Skip to content

LangChain、LangGraph 和 Deep Agent 基础概念详解

这些概念是构建智能代理系统的核心构建块,从简单函数到复杂多代理协作,每一层都有明确分工,帮助你从新手快速进阶到构建生产级应用。

想象你正在构建一个智能助手,它能帮你查天气、发邮件、管理日程。这个助手不是一个"全能超人",而是一个高效团队:每个人负责特定任务,通过清晰的沟通协作完成复杂工作。


LangChain 1.x 架构全景

用户输入 → create_agent() → [Middleware层] → LangGraph执行图

                    [Agent循环: LLM → Tools → 判断继续/结束]

                    [节点: llm_node | tools_node | 自定义节点]

                    [子图: Subgraphs作为节点,支持多层嵌套]

详细概念对比(LangChain 1.x)

概念定义作用域LangChain 1.x实现示例场景
函数最基础的执行单元代码层普通Python函数multiply(a, b) 计算乘法
工具原子能力,LLM调用的函数Agent内@tool装饰器,bind_tools()绑定get_weather(city)、数据库查询
节点图执行单元,单步函数图内部StateGraph.add_node(name, func)llm_node(决策)、tools_node(执行)
Agent完整智能体,LLM+工具+状态管理顶层入口create_agent(model, tools, middleware)财务分析代理:查询数据→计算→生成报告
ReAct Agent思考+行动循环代理顶层入口create_agent() 默认模式数学解题、代码调试
Subagent子代理,独立执行单元图内节点Subgraph(独立StateGraph,作为主图节点)研究代理→调用"数据清洗子代理"
Supervisor团队领导,协调多代理顶层入口主Agent调用子Agent工具个人助理分发任务给天气/日程专家
Deep Agent深度思考代理顶层入口内置规划、文件系统、子代理复杂项目规划、行程安排

🛠️ 1. 函数 (Functions) - 团队里的"执行工"

函数是最基础的"执行单元",就像工厂里的工人,接收指令、完成具体任务、返回结果。

在 LangChain/LangGraph 中,函数是所有复杂系统的原子单位。它们可以是:

  • 简单的计算:加减乘除
  • 外部API调用:天气查询、数据库操作
  • 文件处理:读写JSON、调用Shell命令

为什么重要? 复杂代理 = 多个简单函数的组合。函数做好"单一职责",代理才能高效协作。

通俗比喻

用户说:"帮我算 15 * 3"

函数就像计算器,按下按钮,输出"45"

代理拿到结果,继续下一步

简单案例:计算器函数

python
from langchain.tools import tool  # @tool 装饰器让函数变成"智能工具"

@tool  # 自动生成工具描述,LLM能理解
def multiply(a: int, b: int) -> int:
    """两个数的乘法计算。输入两个整数,返回乘积。

    Args:
        a: 第一个数
        b: 第二个数
    """
    return a * b

@tool
def add(a: int, b: int) -> int:
    """两个数的加法计算。输入两个整数,返回和。"""
    return a + b

# 测试
result = multiply(15, 3)
print(result)  # 输出: 45

关键点:

  • @tool 装饰器让普通函数变成LLM能调用的工具
  • 类型注解int)自动生成输入 schema,防止LLM传错参数
  • Docstring 是给LLM的"使用说明书"

🔧 2. 工具 (Tools) - 函数的"智能包装"

工具 = 函数 + LLM友好描述 + 输入验证,是代理与世界的接口。

函数只是代码,工具是让LLM"理解并安全调用"的封装。就像手机App:函数是底层代码,工具是用户界面。

工具 vs 函数对比

区别函数工具
LLM能否调用❌ 需要手动绑定✅ 自动识别
输入验证❌ 容易传错参数✅ 类型检查
描述信息❌ 无✅ Docstring指导
错误处理❌ 容易崩溃✅ 标准化返回

完整工具案例:天气查询工具

python
import requests
from pydantic import BaseModel, Field
from langchain_core.tools import tool
from typing import Literal

class WeatherInput(BaseModel):  # 复杂输入schema
    """天气查询输入格式"""
    city: str = Field(..., description="城市名称,如:北京、上海")
    units: Literal["celsius", "fahrenheit"] = Field(
        default="celsius", description="温度单位"
    )

@tool(args_schema=WeatherInput)  # Pydantic验证输入
def get_weather(city: str, units: str = "celsius") -> str:
    """获取指定城市的实时天气。

    记住:始终返回结构化结果,包括温度、天气状况、湿度。
    """
    # 模拟API调用
    fake_data = {
        "city": city,
        "temp": 25 if units == "celsius" else 77,
        "condition": "晴天",
        "humidity": "60%"
    }
    return f"{city} 当前天气:{fake_data['temp']}°{units[0].upper()}{fake_data['condition']},湿度{fake_data['humidity']}"

# LLM看到这个工具:
# {
#   "name": "get_weather",
#   "description": "获取指定城市的实时天气...",
#   "inputSchema": {...}
# }

Q: 为什么工具的描述(docstring)这么重要?

A: LLM 不会执行代码,它只能"阅读"工具的描述来决定用不用。就像招聘时看简历:

❌ 差的描述:def calculate(x)  # LLM 不知道这是干嘛的
✅ 好的描述:def calculate(expression: str) -> float:
             """计算数学表达式,支持 + - * / 和括号"""

🎯 3. 节点 (Nodes) - LangGraph的"工作站"

节点是LangGraph图中的执行单元,每个节点专注一个任务,状态在节点间传递。

LangGraph把复杂流程变成"有向图":节点=工作站,边=数据流。就像流水线工厂,每个工位处理一部分,最终组装成品。

节点核心概念

状态(State) → 节点A → 更新状态 → 节点B → ... → 最终输出

节点 vs 工具的区别

概念比喻谁调用例子
工具技能LLM 决定调用get_weather("北京")
节点流程步骤图的边决定执行顺序llm_nodetools_node

简单计算器图案例

python
from typing_extensions import TypedDict, Annotated
from langgraph.graph import StateGraph, START, END
import operator
from langchain_core.tools import tool

# 1. 定义状态:图中传递的数据结构
class CalculatorState(TypedDict):
    input: str              # 用户输入
    result: float           # 计算结果
    operations: list[str]   # 执行历史
    messages: Annotated[list, operator.add]  # 对话历史(自动追加)

# 2. 定义节点:接收状态,返回更新
def calculator_node(state: CalculatorState):
    """计算节点:解析输入,调用工具"""
    input_str = state["input"]

    # LLM决定调用哪个工具(简化版)
    if "乘" in input_str or "*" in input_str:
        nums = extract_numbers(input_str)  # 提取数字
        result = multiply(*nums)
        return {
            "result": result,
            "operations": state["operations"] + [f"乘法: {nums} = {result}"]
        }
    # ... 其他运算

# 3. 构建图
workflow = StateGraph(CalculatorState)
workflow.add_node("calculator", calculator_node)  # 添加节点
workflow.add_edge(START, "calculator")           # 从开始到计算器
workflow.add_edge("calculator", END)             # 计算完结束

graph = workflow.compile()

节点参数详解:

python
def my_node(
    state: CalculatorState,      # 当前图状态
    config: RunnableConfig,      # 配置(thread_id, tags等)
    runtime: Runtime             # 运行时上下文(可选)
) -> dict:  # 返回状态更新
    pass

🤖 4. Agent - "智能决策者"

Agent = LLM + 工具 + 循环决策,是"会思考的执行者"。

代理的核心循环:

观察环境 → LLM思考 → 选择工具/回应 → 执行 → 观察新状态 → 重复

🎭 用"公司"来理解 Agent 架构

想象一家公司的运作方式:

┌─────────────────────────────────────────────────────────────────┐
│                         🏢 公司 = Agent                          │
│                                                                 │
│   CEO(LLM)                                                     │
│     │                                                           │
│     ├── 📋 决策:分析问题,决定谁来做什么                           │
│     ├── 🛠️ 工具 = 员工的技能(打电话、发邮件、查数据库)              │
│     ├── 📊 节点 = 工作流程的每个步骤                               │
│     └── 🏢 子公司 = Subagent(独立运作,汇报结果)                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Agent类型对比

类型特点适用场景
简单Agent单轮调用工具天气查询、翻译
ReAct Agent思考+行动循环数学解题、代码调试
Supervisor协调多子代理团队协作任务
Deep Agent规划+文件+子代理复杂项目、行程规划

基础Agent案例

python
from langchain_openai import ChatOpenAI
from langchain import create_agent

llm = ChatOpenAI(model="gpt-4o-mini")

# 工具集
tools = [multiply, add, get_weather]

# 创建代理
agent = create_agent(
    model=llm,
    tools=tools,
    system_prompt="你是数学&天气助手。用中文回答。"
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "15乘3是多少?北京天气如何?"}]
})

Agent 和普通的 LLM 调用有什么区别?

普通 LLM 调用Agent
一问一答多轮思考
只能生成文本可以调用工具
无记忆有状态管理
人类决定下一步自主决定下一步
python
# 普通调用
response = llm.invoke("北京天气如何?")  # 只能瞎猜

# Agent 调用
result = agent.invoke("北京天气如何?")
# Agent 会:1. 识别需要查天气 2. 调用 get_weather 3. 整理结果回答

🔄 5. ReAct Agent - "思考+行动"循环代理

ReAct = Reasoning (思考) + Acting (行动),最经典的代理架构。

ReAct思想: LLM不直接回答,而是思考→行动→观察→重复,直到解决问题。

ReAct执行流程图

用户:"帮我算 (15+3)*4"

LLM思考:"先加15+3=18,再乘4"
↓ 行动:调用add(15,3)
↓ 观察:结果18
↓ 思考:"现在18*4"
↓ 行动:调用multiply(18,4)
↓ 观察:结果72
↓ 最终回答:"答案是72"

ReAct完整代码

python
from langchain import create_agent
from langchain_core.messages import HumanMessage

agent = create_agent(
    model=llm,
    tools=[add, multiply, get_weather],
    system_prompt="""你是一个精确的计算助手。

    遵循ReAct模式:
    1. 先思考需要什么步骤
    2. 调用工具执行
    3. 根据结果继续思考
    4. 直到得出最终答案"""
)

result = agent.invoke({
    "messages": [HumanMessage("计算 (15+3)*4,然后告诉我结果")]
})
print(result["messages"][-1].content)  # "经过计算,(15+3)*4 = 72"

🧠 6. Deep Agent - "深度思考代理" (LangChain v1新特性)

Deep Agent是处理复杂多步任务的"高级大脑",内置规划、文件系统、子代理生成。

Deep Agent三大超能力:

  1. 自动规划write_todos工具,自动分解复杂任务
  2. 文件系统ls/read/write/edit工具,管理长期记忆
  3. 子代理task工具,生成专家子代理

Deep Agent使用场景

普通Agent: "查北京天气" → 直接调用工具
Deep Agent: "帮我规划一周北京行程" →
    1. 写todo:查天气/订酒店/安排景点
    2. 生成天气子代理/酒店子代理
    3. 写文件保存行程表
    4. 汇总最终方案

Deep Agent快速开始

python
from deepagents import create_deep_agent  # 新库!

deep_agent = create_deep_agent(
    model="claude-sonnet-4-5",  # 推荐强推理模型
    # 自动包含todo/file/subagent中间件
)

result = deep_agent.invoke({
    "messages": [{"role": "user", "content": "帮我规划北京3天行程"}]
})

Deep Agent自动生成的Todo示例:

1. ✅ 查询北京3天天气预报
2. 🔄 推荐3个必去景点(基于天气)
3. 🔄 制定每日行程表
4. 🔄 计算大致预算
5. 🔄 输出最终方案到文件

Deep Agent 状态管理机制

DeepAgent 的状态管理基于 LangGraph 的标准机制,默认使用 TypedDict 状态 schema + MemorySaver checkpointer 自动持久化,支持完全手动管理,并能与 Supervisor 无缝协同。

DeepAgent 是基于 LangGraph 的高级代理库,默认包含 TodoListMiddlewareFilesystemMiddlewareSubAgentMiddleware,构建在标准 LangGraph state 之上。

1. 默认状态管理方式

python
from typing_extensions import TypedDict, Annotated
from langgraph.graph.message import add_messages
from langgraph.checkpoint.memory import MemorySaver

# 默认状态 schema(TypedDict)
class AgentState(TypedDict):
    messages: Annotated[list[AnyMessage], add_messages]  # 对话历史
    todos: list[str]                                    # 待办列表(TodoListMiddleware)
    filesystem: dict                                    # 文件系统状态(FilesystemMiddleware)

# 默认使用 MemorySaver 自动持久化
checkpointer = MemorySaver()
agent = create_deep_agent(model="claude-sonnet-4-5-20250929", checkpointer=checkpointer)

默认行为:

  • 短时状态todosfilesystem 等存储在当前 thread 的 graph state
  • 长时内存:通过 StoreBackend 持久化到 /memories/ 路径,支持跨 thread
python
# 长时内存配置(CompositeBackend)
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
store = InMemoryStore()  # 或 PostgresStore 等

backend = CompositeBackend(
    default=StateBackend(runtime),      # 临时状态
    routes={"/memories/": StoreBackend(runtime)}  # 持久化内存
)

2. 手动状态管理

完全支持手动控制,通过 LangGraph API:

python
# 自定义状态 schema
class CustomDeepAgentState(TypedDict):
    messages: Annotated[list[AnyMessage], add_messages]
    todos: list[str]
    research_data: dict                    # 自定义研究数据
    user_preferences: dict                 # 用户偏好

# 手动编译 graph
graph = StateGraph(CustomDeepAgentState)
graph.add_node("deep_agent", deep_agent_node)
graph.add_edge(START, "deep_agent")

# 手动管理 checkpointer
checkpointer = MemorySaver()
compiled_graph = graph.compile(checkpointer=checkpointer)

# 手动获取/更新状态
config = {"configurable": {"thread_id": "user_123"}}
state = compiled_graph.get_state(config)  # 获取当前状态

# 手动更新状态
updated_state = compiled_graph.update_state(
    config,
    {"research_data": {"key": "value"}}
)

# 手动调用
result = compiled_graph.invoke({"messages": [...]}, config)

3. DeepAgent 与 Supervisor 协同

DeepAgent 天然就是 Supervisor,通过内置 SubAgentMiddlewaretask 工具调用子代理:

python
# DeepAgent(主管)配置子代理
deep_supervisor = create_deep_agent(
    model="claude-sonnet-4-5-20250929",
    middleware=[
        SubAgentMiddleware(
            subagents=[
                {
                    "name": "researcher",           # 研究子代理
                    "description": "进行深入研究",
                    "tools": [web_search, read_file],
                    "system_prompt": "你是研究专家..."
                },
                {
                    "name": "coder",                # 编码子代理
                    "description": "编写和调试代码",
                    "tools": [write_file, shell_exec],
                    "system_prompt": "你是资深工程师..."
                }
            ]
        )
    ]
)

# DeepAgent 自动调用子代理(上下文隔离)
result = deep_supervisor.invoke({
    "messages": [{"role": "user", "content": "研究并实现用户认证系统"}]
})

双向协同(Supervisor 调用 DeepAgent):

python
# 传统 Supervisor 将 DeepAgent 作为工具
@tool("deep_research", "调用深度研究代理")
def call_deep_agent(query: str) -> str:
    deep_agent = create_deep_agent(...)  # 独立的 DeepAgent
    result = deep_agent.invoke({"messages": [{"role": "user", "content": query}]})
    return result["messages"][-1].content

supervisor = create_agent(
    model="gpt-4o",
    tools=[call_deep_agent, other_tools]
)

4. 状态共享模式

共享状态(推荐用于协同):

python
class SharedState(TypedDict):
    messages: Annotated[list[AnyMessage], add_messages]
    todos: list[str]
    research_findings: dict  # DeepAgent 研究结果

# Supervisor 和 DeepAgent 共享状态
supervisor_graph.add_node("deep_research", deep_agent_graph)

隔离状态(DeepAgent 子代理默认):

python
# SubAgentMiddleware 默认隔离子代理状态
# Supervisor 只接收最终结果,中间状态不污染主上下文

状态管理总结:

模式说明
默认TypedDict + MemorySaver 自动管理
手动完整 LangGraph API 控制
协同DeepAgent 内置 Supervisor 能力,或被 Supervisor 作为工具调用
灵活短时状态(graph state)+ 长时内存(StoreBackend)

相关文档:


👑 7. Supervisor - "团队领导"

Supervisor是多代理系统的"总指挥",不亲自干活,只负责任务分配和结果整合。

🏢 用"公司"来理解 Supervisor

如果 Agent 是公司,Subagent 是子公司,那么 Supervisor(主管)就是总公司的高层管理团队,负责协调多个子公司完成复杂任务。

在 LangChain/LangGraph 的多代理系统中,Supervisor Agent 是一个中央协调代理,它将子代理(Subagents,通常作为 LangGraph 中的 Subgraphs 实现)当作工具来调用。Supervisor 接收用户请求,根据任务需求决定调用哪个子代理,收集结果后决定下一步或结束。

Supervisor架构:

用户 → Supervisor → 选择专家(工具) → 专家工作 → 结果回传 → Supervisor整合 → 用户

Supervisor完整案例:个人助理系统

python
# 1. 创建专家子代理(作为工具)
weather_expert = create_agent(model=llm, tools=[get_weather])
calendar_expert = create_agent(model=llm, tools=[schedule_event])

# 2. 包装成Supervisor工具
@tool
def ask_weather_expert(query: str):
    """天气专家:处理所有天气相关问题"""
    return weather_expert.invoke({"messages": [query]})

@tool
def ask_calendar_expert(query: str):
    """日程专家:处理会议、日历问题"""
    return calendar_expert.invoke({"messages": [query]})

# 3. Supervisor总控
supervisor = create_agent(
    model=llm,
    tools=[ask_weather_expert, ask_calendar_expert],
    system_prompt="""你是个人助理主管。

    根据用户需求分发给:
    - 天气专家:天气、温度查询
    - 日程专家:会议、日历安排
    - 需要两个都用时,顺序调用"""
)

# 测试
result = supervisor.invoke({
    "messages": [{"role": "user", "content": "明天北京天气如何?帮我安排10点会议"}]
})

执行流程:

Supervisor思考:"需要天气+日程两个专家"
↓ 调用ask_weather_expert("明天北京天气")
↓ 得到:"晴天22°"
↓ 调用ask_calendar_expert("安排10点会议")
↓ 得到:"已安排10点会议"
↓ 整合:"明天北京晴天22°,10点会议已安排"

🏢 8. Subagent(子代理)- 子公司/外包团队

当任务太复杂时,主 Agent 可以把部分工作"外包"给专门的子 Agent。

主Agent(综合助手)

    ├── 子Agent1:数据分析专家
    ├── 子Agent2:文档撰写专家
    └── 子Agent3:代码审查专家

为什么需要 Subagent?

  1. 专业分工:每个子 Agent 专注一个领域
  2. 状态隔离:子 Agent 有自己的记忆,不污染主 Agent
  3. 复用性:同一个子 Agent 可以被多个主 Agent 调用

Subagent实现:子图作为节点

python
from langgraph.graph import StateGraph, START, END

# === Subagent状态(可独立) ===
class SubState(TypedDict):
    query: str
    result: str
    confidence: float

# === Subagent:天气专家子图 ===
def weather_llm(state: SubState):
    """子代理LLM节点"""
    return {"result": f"专业分析: {state['query']} 晴天,置信度0.95"}

def should_continue(state: SubState):
    return END  # 子图简单,直接结束

sub_weather = StateGraph(SubState)\
    .add_node("llm", weather_llm)\
    .add_edge(START, "llm")\
    .add_conditional_edges("llm", should_continue)\
    .compile()

# === 在主代理中调用Subagent ===
async def subagent_node(state: AgentState):
    """主代理节点:调用天气子代理"""
    sub_input = {"query": "东京", "confidence": 0.9}
    sub_result = await sub_weather.ainvoke(sub_input)
    return {
        "messages": [f"子代理返回: {sub_result['result']}"],
        "calculations": state.get("calculations", [])
    }

什么时候用 Subagent?

使用场景

  1. 任务太复杂:需要多个专家协作
  2. 需要隔离:子任务不应该看到主任务的所有信息
  3. 可复用:同一个子 Agent 被多处调用
python
# 示例:研究 Agent 调用多个子 Agent
主Agent(研究协调员)
    ├── 调用 "文献搜索子Agent" → 返回相关论文
    ├── 调用 "数据分析子Agent" → 返回统计结果
    └── 调用 "报告撰写子Agent" → 生成最终报告

🎮 完整实战:智能旅行规划系统

把所有概念组合,构建生产级应用:

python
# 1. 基础工具
tools = [get_weather, search_flights, book_hotel]

# 2. 专家子代理
travel_expert = create_agent(model=llm, tools=tools)

# 3. Deep Supervisor(带规划)
deep_supervisor = create_deep_agent(
    model="claude-sonnet-4-5",
    subagents=[{
        "name": "travel_expert",
        "description": "专业旅行规划师",
        "tools": tools
    }]
)

# 4. 执行复杂任务
result = deep_supervisor.invoke({
    "messages": [{"role": "user", "content": "帮我规划北京3天商务旅行,预算5000元"}]
})

# Deep Agent自动:
# - 写todo分解任务
# - 调用天气/航班/酒店专家
# - 生成详细行程文件
# - 支持人类介入修改

📊 概念关系总览图

用户输入

[Deep Agent] ← 规划/文件/子代理
   ↓ 分发任务
[Supervisor] ← 协调专家
   ↓ 工具调用
[ReAct Agent] ← 思考+行动循环
   ↓ 执行原子操作
[节点/工具/函数] ← 具体工作
   ↓ 返回结果
[状态传递] ← 图结构流转
最终输出

完整LangGraph主代理(节点+子图)

python
from typing_extensions import TypedDict, Annotated
from langchain_core.messages import add_messages

# === 主代理状态 ===
class FullState(TypedDict):
    messages: Annotated[list, add_messages]
    subagent_results: list[str]  # 子代理结果

# === 主代理节点 ===
async def main_llm_node(state: FullState):
    """主LLM决策节点"""
    messages = state["messages"] + [
        f"已有子代理结果: {state.get('subagent_results', [])}"
    ]
    result = await llm.bind_tools(tools).ainvoke(messages)
    return {"messages": [result]}

async def tools_node(state: FullState):
    """工具执行节点"""
    # LangGraph标准工具节点逻辑
    pass

# === 组装完整代理 ===
graph = StateGraph(FullState)
graph.add_node("main_llm", main_llm_node)
graph.add_node("tools", tools_node)
graph.add_node("weather_subagent", subagent_node)  # Subagent作为节点

graph.add_edge(START, "main_llm")
# 条件路由:LLM决定调用工具或子代理
graph.add_conditional_edges("main_llm", lambda s: "tools" if s["messages"][-1].tool_calls else "weather_subagent")
graph.add_edge("tools", "main_llm")
graph.add_edge("weather_subagent", "main_llm")

full_agent = graph.compile()

执行流程图解

用户: "东京天气?计算(23+17)*3"

[create_agent主循环]

Middleware.before_model()  # 动态工具过滤

main_llm_node()  # LLM: "先查天气,再计算"

→ tools_node()  # 调用get_weather("东京")

→ weather_subagent()  # 调用子图

main_llm_node()  # LLM: "天气晴,计算60*3=180"

→ tools_node()  # 调用calculator("(23+17)*3")

Middleware.after_model()  # 保存结果

最终回答: "东京晴天,计算结果180"

🆚 三大框架对比(2025 年 12 月更新)

LangChain 1.x vs LangGraph 1.x vs DeepAgents

抽象层次(从低到高):

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│   DeepAgents (Agent Harness)                                    │
│   ├── 开箱即用的完整代理                                          │
│   ├── 内置规划、文件系统、子代理                                   │
│   └── 类似 Claude Code 的通用版                                  │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   LangChain 1.x (Agent Framework)                               │
│   ├── create_agent() 高级 API                                   │
│   ├── Middleware 机制                                           │
│   └── 快速构建标准 Agent                                         │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   LangGraph 1.x (Agent Runtime)                                 │
│   ├── 底层图执行引擎                                              │
│   ├── 状态持久化、断点续传                                        │
│   └── 完全控制每个节点                                            │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

详细对比表

特性LangChain 1.xLangGraph 1.xDeepAgentsClaude Agent SDK
定位Agent 框架Agent 运行时Agent 脚手架Agent 脚手架
核心 APIcreate_agent()StateGraphcreate_agent() + 增强Agent
学习曲线⭐⭐ 简单⭐⭐⭐⭐ 较陡⭐ 极简⭐⭐ 简单
灵活性中等极高低(开箱即用)中等
内置规划write_todos
文件系统✅ 内置✅ 内置
子代理SubgraphSubgraphtask 工具
模型支持多模型多模型默认 Claude仅 Claude
适用场景标准 Agent复杂工作流复杂任务、编码文件操作、编码

如何选择?

你的需求是什么?

     ├── 快速原型 + 标准工具调用
     │   └── ✅ LangChain 1.x create_agent()

     ├── 复杂工作流 + 完全控制
     │   └── ✅ LangGraph 1.x

     ├── 类似 Claude Code 的通用代理
     │   └── ✅ DeepAgents

     └── 需要文件操作 + 安全审批
         └── ✅ Claude Agent SDK

它们可以混合使用!

python
# LangChain Agent 底层就是 LangGraph
agent = create_agent(model, tools)  # 高级 API

# 需要更多控制时,可以获取底层图
graph = agent.get_graph()  # 获取 LangGraph 图
graph.add_node("custom", custom_node)  # 添加自定义节点

# DeepAgents 也是基于 LangGraph
from deepagents import create_agent as create_deep_agent
deep_agent = create_deep_agent(model)

LangChain 1.x vs 旧版本对比

特性LangChain <1.0LangChain 1.x (create_agent)
代理创建create_react_agentcreate_agent()(更简单)
自定义逻辑手动StateGraphMiddleware(before/after钩子)
状态管理TypedDictstate_schema + Middleware扩展
工具错误处理手动try-catchwrap_tool_call middleware
流式输出手动配置开箱即用(节点名为model
子代理手动subgraphSubgraph节点 + Middleware支持

🎯 Middleware 机制详解

什么是 Middleware?

通俗解释:Middleware 就像机场的安检——在乘客(请求)登机(到达 LLM)之前和下机之后,都要经过检查站。

用户输入

┌─────────────────────────┐
│  Middleware 1: 权限检查  │  ← before_model()
└─────────────────────────┘

┌─────────────────────────┐
│  Middleware 2: 敏感词过滤 │  ← before_model()
└─────────────────────────┘

    🧠 LLM 处理

┌─────────────────────────┐
│  Middleware 2: 日志记录  │  ← after_model()
└─────────────────────────┘

┌─────────────────────────┐
│  Middleware 1: 结果缓存  │  ← after_model()
└─────────────────────────┘

最终输出

常见 Middleware 用途

python
middleware = [
    # 1. 长对话自动总结(防止 token 超限)
    summarization_middleware(max_tokens=4000),

    # 2. 权限控制(某些工具只有管理员能用)
    permission_middleware({
        "delete_file": ["admin"],
        "send_email": ["admin", "manager"]
    }),

    # 3. 重试机制(模型调用失败自动重试)
    ModelRetryMiddleware(max_retries=3),

    # 4. 人机交互(敏感操作需要人工确认)
    human_approval_middleware(tools=["delete_*", "send_*"])
]

生产级特性(1.x独有)

python
# === Middleware示例:权限控制 ===
middleware = [
    # 1. 用户权限过滤工具
    permission_middleware({
        "send_email": ["admin"],  # 仅管理员
        "delete_data": ["superadmin"]
    }),
    # 2. 自动总结长对话
    summarization_middleware(max_tokens=4000),
    # 3. PII脱敏
    pii_redaction_middleware(patterns=["phone", "email"])
]

agent = create_agent(model, tools, middleware=middleware)

🔄 状态管理深入理解

为什么状态管理很重要?

想象你和朋友聊天:

  • 没有状态:每次说话对方都忘了之前聊过什么
  • 有状态:对方记得整个对话历史
python
# LangGraph 的状态定义
class AgentState(TypedDict):
    messages: Annotated[list, add_messages]  # 对话历史(自动累加)
    user_info: dict                          # 用户信息
    task_progress: list[str]                 # 任务进度

add_messages 是什么?

这是一个 reducer 函数,告诉 LangGraph 如何合并新旧状态:

python
# 没有 reducer:新值覆盖旧值
state["count"] = 5  # 下次赋值会直接覆盖

# 有 add_messages reducer:新消息追加到列表
state["messages"] = [new_msg]  # 实际效果:old_messages + [new_msg]

🚀 新手进阶路线

  1. Week1:掌握函数+工具 → 构建简单计算器
  2. Week2:理解节点+状态 → LangGraph Hello World
  3. Week3:ReAct Agent → 数学解题助手
  4. Week4:Supervisor → 多专家系统
  5. Month2:Deep Agent → 生产级复杂任务

记住核心原则:

  • 函数做计算,工具给LLM用
  • 节点专注单责,状态全局共享
  • Agent管决策,Supervisor管协调
  • Deep Agent搞规划,解决真问题

💡 常见问题解答

Q1: create_agent() vs StateGraph,用哪个?

你需要什么?

     ├── 标准的 ReAct Agent(思考→行动→观察循环)
     │   └── ✅ create_agent()  更简单

     ├── 自定义工作流(多分支、并行、人工审批)
     │   └── ✅ StateGraph  更灵活

     └── 两者结合
         └── ✅ 先用 create_agent(),需要时获取底层图

Q2: 什么时候用 Subagent?

  1. 任务太复杂:需要多个专家协作
  2. 需要隔离:子任务不应该看到主任务的所有信息
  3. 可复用:同一个子 Agent 被多处调用

📚 延伸阅读

官方资源

框架对比


最后更新:2025 年 12 月作者:Bryce Wang

基于 MIT 许可证发布。内容版权归作者所有。