从一个常见困惑说起

接触LangChain生态时,很多人会被LangChain、LangGraph、Deep Agents三个词绕晕:它们是递进框架吗?该从哪个入手?为什么LangChain官网一会儿说自己是框架,一会儿又冒出运行时和套件?

这套困惑的根源在于:官方把产品分类和依赖层次混在一起讲。官方将Agent开发生态分为三类——Runtime(运行时)、Framework(框架)、Harness(套件),LangChain自家三个产品正好各占其一:LangGraph对应Runtime,LangChain对应Framework,Deep Agents SDK对应Harness。

但落到依赖关系上,事情变了。因为LangChain不是一个整块,它被LangGraph从中间劈成了两半。

三层产品,四层依赖

官方按产品数分是三类,但按依赖关系看是四层:

langchain-core(积木:messages / tools / models / bind_tools)
    ↑ 依赖
LangGraph(运行时:图、状态、Checkpoint、流式、HITL)
    ↑ 依赖
create_agent + middleware(LangChain薄壳)
    ↑ 依赖
deepagents / create_deep_agent(Deep Agents套件)

多出来的那一层,正是把LangChain劈开的结果:langchain-core在LangGraph之下,是LangGraph的地基;create_agent+中间件在LangGraph之上,是LangGraph的一层封装。

这里有一条关键铁律:不要把LangChain画成一整块叠在LangGraph之上。很多人在这栽过跟头,后果是讲create_agent时逻辑对不上——它明明包着LangGraph,怎么会和垫着LangGraph的langchain-core是同一个东西?

四层逐层拆解

第1层:积木(langchain-core)

最底层,提供最小原子能力:

  • messages:消息对象(Human / AI / Tool / System)
  • tools:工具的声明与描述
  • models:大模型的统一调用接口
  • bind_tools:把工具绑到模型上,让模型知道能调用什么
  • 检索组件(Document / Embedding / Retriever等)

这一层不关心Agent怎么循环、怎么记忆、怎么中断,只关心一个消息长什么样、一个工具怎么声明、一次模型调用怎么发。LangGraph自己就建立在这层之上——Agent场景下StateGraph里流动的状态通常是MessagesState(一组messages),节点里调用的就是models和tools。

第2层:运行时(LangGraph)

LangGraph是执行引擎,回答Agent每一步该怎么走:

  • 图/节点/边:把Agent拆成节点(调用模型、调用工具),用边串成执行流
  • 状态(State):每一步的输入输出、累积的对话历史,存在显式状态对象里
  • Checkpoint:每一步中间状态可持久化,支持断点恢复,官方称时间旅行
  • 流式(stream):把执行过程以token/节点为单位推出来
  • Human-in-the-loop:在任意节点暂停,等人类确认再继续

一句话:积木是零件,运行时是流水线。LangGraph决定零件按什么顺序、在什么状态驱动下流转。

第3层:薄壳(create_agent + middleware)

LangGraph已经能跑Agent,但手写StateGraph太啰嗦——一个调模型→调工具→再调模型的最简Agent,要自己写节点、条件边、循环终止。

LangChain提供了create_agent工厂:一行代码生成标准的模型+工具循环图,还附带中间件栈,让你在模型调用前/调用后、工具调用时等时机插入自定义逻辑。

薄壳的薄是刻意的:它不改变LangGraph的执行语义,只在外面包了一层更省事的API。要控制得更细,随时可以下沉回LangGraph。

第4层:套件(Deep Agents)

最顶层,最省力。create_deep_agent在create_agent基础上再打包一层:把写计划、读写文件、执行代码、管理长期记忆、人在环这些生产级Agent几乎都要用的东西,作为内置中间件栈预先装好。

套件和薄壳的关系,就像薄壳和运行时:套件是薄壳的薄壳,薄壳是运行时的薄壳。从第4层起步,需要什么控制力就逐层往下沉。

调用链全景

假设写下这样一行代码:

from deepagents import create_deep_agent
agent = create_deep_agent(...)

背后是自上而下的依赖调用:

你的代码
    │ 调用
    ▼
create_deep_agent(...)          ← 第4层 套件
    │ 内部调用
    ▼
create_agent(...) + middleware  ← 第3层 薄壳
    │ 内部调用
    ▼
StateGraph(nodes / edges / state) ← 第2层 运行时
    │ 依赖
    ▼
langchain-core(messages / tools / models / bind_tools) ← 第1层 积木

记这张图抓两点:

  1. 方向是自上而下的依赖。上层调用下层,下层不反过来依赖上层。create_deep_agent不认识你的业务,它只调用create_agent;create_agent不认识写计划,它只构建StateGraph;StateGraph不关心Agent,它只流转messages。

  2. LangChain横跨两层。create_agent(薄壳)在LangGraph之上,langchain-core(积木)在LangGraph之下。这就是三类产品/四层的由来——Framework这一个产品,拆出了两个依赖位置。

选型定位:该落到哪一层

拿到需求或报错,能立刻判断该由哪一层负责,是排查问题和架构评审时最高频的动作。

场景A:要一个能调工具、带记忆、能写文件的Agent,最好明天就能演示。
→ 落第4层(套件)。create_deep_agent一行搞定,规划、文件、记忆都是内置的。别手写StateGraph——那是把明天要演示的活干成下周。

场景B:要在每次调用模型之前,注入一段动态系统提示(比如按用户等级加载不同人设)。
→ 落第3层(薄壳)。这是create_agent中间件的before_model干的活。用第4层做不了这么细的卡点,用第2层又太重。

场景C:要一个多智能体编排,一个supervisor派单给几个子Agent。
→ 落第2层(运行时)。多智能体编排需要显式控制图的拓扑结构,create_agent的标准循环不够用,需要直接操作StateGraph的节点和边。

场景D:要自定义消息序列化格式,或对接非标准模型接口。
→ 落第1层(积木)。这是langchain-core的messages和models该管的事,上层框架都建立在这套原子能力之上。

工程化要点:双向认知

理解四层架构,核心是建立双向认知:

自顶向下:从套件起步,快速验证想法。需要更多控制力时,逐层下沉——套件→薄壳→运行时→积木。每一层都是下一层的封装,下沉意味着放弃便利性换取控制力。

自底向上:从积木理解原子能力,再往上理解运行时如何编排这些原子,薄壳如何简化编排,套件如何打包常用模式。每一层都建立在下层之上,理解下层才能理解上层的边界。

企业级Agent架构的落地,关键不在于选最上层还是最下层,而在于清楚每一层能做什么、不能做什么,以及当需求变化时该往哪个方向移动。

需要核验的技术论断

社区原文中部分论断需要结合官方最新文档核验:

  1. 官方产品分类(Runtime / Framework / Harness)的具体定义和边界,建议以LangChain官方文档为准。
  2. Deep Agents SDK的内置中间件栈具体包含哪些能力,需查阅官方README确认。
  3. create_agent的中间件钩子(before_model等)的完整列表和触发时机,以官方API文档为准。
  4. LangGraph的Checkpoint持久化后端选项和配置方式,需参考官方文档。
  5. 多智能体编排在LangGraph中的推荐实现模式,官方可能有更新。

以上论断在具体项目落地前,建议对照官方最新文档逐一核验,避免因版本迭代导致认知偏差。