LangChain 与 LangGraph 完全指南:核心组件、架构原理、编排机制与 LlamaIndex 集成

LangChain 与 LangGraph 完全指南:核心组件、架构原理、编排机制与 LlamaIndex 集成 -- pd的后端笔记

文章目录

    • [LangChain 与 LangGraph 完全指南:核心组件、架构原理、编排机制与 LlamaIndex 集成 -- pd的后端笔记](#LangChain 与 LangGraph 完全指南:核心组件、架构原理、编排机制与 LlamaIndex 集成 -- pd的后端笔记)
  • [🎯 先别急着背概念:为什么很多人一学 Agent 就开始乱?](#🎯 先别急着背概念:为什么很多人一学 Agent 就开始乱?)
  • [🧠 一、先建立一个正确视角:LLM 应用不是"调个模型"这么简单](#🧠 一、先建立一个正确视角:LLM 应用不是“调个模型”这么简单)
    • [📌 先记一个总判断](#📌 先记一个总判断)
  • [📊 二、从系统分层看这三个框架,各自到底在管什么](#📊 二、从系统分层看这三个框架,各自到底在管什么)
    • [💡 这一层最容易形成的误区](#💡 这一层最容易形成的误区)
  • [🚀 三、LangChain 到底是什么?不要再把它只理解成"链式调用库"了](#🚀 三、LangChain 到底是什么?不要再把它只理解成“链式调用库”了)
    • [1. 它不只关心"怎么调模型"](#1. 它不只关心“怎么调模型”)
    • [2. 它不只服务"问答 Demo"](#2. 它不只服务“问答 Demo”)
    • [🔍 一个更贴近工程的类比](#🔍 一个更贴近工程的类比)
    • [✅ 小结](#✅ 小结)
  • [🔧 四、LangChain 的核心组件,应该放在一套系统里去理解](#🔧 四、LangChain 的核心组件,应该放在一套系统里去理解)
    • [🧩 1. Models:模型抽象层](#🧩 1. Models:模型抽象层)
      • [一个最小的 LangChain Agent 例子](#一个最小的 LangChain Agent 例子)
    • [🗂️ 2. Messages / Context:消息与上下文层](#🗂️ 2. Messages / Context:消息与上下文层)
    • [🛠️ 3. Tools:工具层](#🛠️ 3. Tools:工具层)
      • [再看一个带 `@tool` 的例子](#再看一个带 @tool 的例子)
    • [📦 4. Structured Output:结构化输出层](#📦 4. Structured Output:结构化输出层)
    • [🧱 5. Middleware:中间件层](#🧱 5. Middleware:中间件层)
    • [🤖 6. Agents:Agent 封装层](#🤖 6. Agents:Agent 封装层)
  • [🏗️ 五、LangChain 的核心架构,为什么说它本质上是"应用层框架"](#🏗️ 五、LangChain 的核心架构,为什么说它本质上是“应用层框架”)
    • [1. 能力接入层](#1. 能力接入层)
    • [2. 上下文组织层](#2. 上下文组织层)
    • [3. 决策与输出层](#3. 决策与输出层)
    • [4. 运行时承接层](#4. 运行时承接层)
    • [📌 一个最容易忽略的架构事实](#📌 一个最容易忽略的架构事实)
  • [⚠️ 六、为什么 LangGraph 会出现?因为复杂 Agent 根本不是一条直线](#⚠️ 六、为什么 LangGraph 会出现?因为复杂 Agent 根本不是一条直线)
    • [💥 为什么说"复杂 Agent 不是直线"很重要?](#💥 为什么说“复杂 Agent 不是直线”很重要?)
  • [🚦 七、LangGraph 到底是什么?它本质上是在把 Agent 运行时状态机化](#🚦 七、LangGraph 到底是什么?它本质上是在把 Agent 运行时状态机化)
    • [它和普通 DAG / 工作流工具有什么不一样?](#它和普通 DAG / 工作流工具有什么不一样?)
    • [✅ 一个更准确的一句话定义](#✅ 一个更准确的一句话定义)
  • [🧠 八、LangGraph 的编排原理,到底在编排什么](#🧠 八、LangGraph 的编排原理,到底在编排什么)
    • [📌 1. State:整个图的共享状态中心](#📌 1. State:整个图的共享状态中心)
    • [🧩 2. Node:处理状态的逻辑节点](#🧩 2. Node:处理状态的逻辑节点)
    • [🔀 3. Edge:决定接下来去哪](#🔀 3. Edge:决定接下来去哪)
    • [🪢 4. Reducer:解决状态合并问题](#🪢 4. Reducer:解决状态合并问题)
    • [💾 5. Checkpoint / Persistence:让流程可以中断和恢复](#💾 5. Checkpoint / Persistence:让流程可以中断和恢复)
    • [👤 6. Human-in-the-loop:让人工介入成为流程一部分](#👤 6. Human-in-the-loop:让人工介入成为流程一部分)
    • [📌 一个官方概念里很实用的点:MessagesState](#📌 一个官方概念里很实用的点:MessagesState)
  • [📈 九、用一张图彻底看懂 LangGraph 的执行机制](#📈 九、用一张图彻底看懂 LangGraph 的执行机制)
  • [⚖️ 十、LangChain 和 LangGraph 的区别,到底该怎么讲才不混乱](#⚖️ 十、LangChain 和 LangGraph 的区别,到底该怎么讲才不混乱)
    • [1. 抽象层级不同](#1. 抽象层级不同)
    • [2. 设计目标不同](#2. 设计目标不同)
    • [3. 适用场景不同](#3. 适用场景不同)
    • [4. 两者关系不是替代,而是上下层协作](#4. 两者关系不是替代,而是上下层协作)
    • [📌 一个非常实用的选型建议](#📌 一个非常实用的选型建议)
  • [📚 十一、那 LlamaIndex 应该放在哪?它更像 RAG 系统里的"数据层专家"](#📚 十一、那 LlamaIndex 应该放在哪?它更像 RAG 系统里的“数据层专家”)
  • [🔗 十二、LlamaIndex 如何和 LangChain 结合?最常见的是这三种方式](#🔗 十二、LlamaIndex 如何和 LangChain 结合?最常见的是这三种方式)
    • [1. LangChain 做应用与 Agent,LlamaIndex 做检索与查询](#1. LangChain 做应用与 Agent,LlamaIndex 做检索与查询)
    • [2. 在 LlamaIndex 里复用 LangChain 的 LLM 适配](#2. 在 LlamaIndex 里复用 LangChain 的 LLM 适配)
    • [3. 在 LlamaIndex 里复用 LangChain 的 Embeddings](#3. 在 LlamaIndex 里复用 LangChain 的 Embeddings)
    • [4. 一个更贴近项目落地的组合姿势](#4. 一个更贴近项目落地的组合姿势)
  • [🏢 十三、如果把三者放进一套企业系统里,最合理的架构通常长什么样](#🏢 十三、如果把三者放进一套企业系统里,最合理的架构通常长什么样)
    • [🔍 这套架构为什么更稳?](#🔍 这套架构为什么更稳?)
  • [⚠️ 十四、真正落地时最容易踩的坑,不在框架本身,而在边界设计](#⚠️ 十四、真正落地时最容易踩的坑,不在框架本身,而在边界设计)
  • [✅ 十五、最后再把你最关心的几个问题,压缩成一张速答表](#✅ 十五、最后再把你最关心的几个问题,压缩成一张速答表)
  • [💡 十六、总结](#💡 十六、总结)
    • [📌 最后给一个落地建议](#📌 最后给一个落地建议)
    • [🔗 参考资料](#🔗 参考资料)

🎯 先别急着背概念:为什么很多人一学 Agent 就开始乱?

如果你最近在做 LLM 应用,大概率会经历一个很典型的过程:

  • 一开始,只想先把模型调通
  • 接着,开始加 Prompt、加 Tools、加聊天记忆
  • 再往后,又想接知识库、做多步骤推理、加人工审核、支持失败恢复
  • 最后你会发现:系统能跑,但结构越来越乱

这时候,很多人脑子里会同时冒出几个名词:

  • LangChain
  • LangGraph
  • LlamaIndex

然后新的困惑就来了:

  • LangChain 到底是什么?
  • 它的核心组件有哪些?
  • LangGraph 又是干什么的?
  • 它和 LangChain 到底是什么关系?
  • 如果我要做 RAG,LlamaIndex 又该放在哪一层?

很多文章的问题,不是讲得不多,而是讲得太像"问答串烧":

  • 先解释一个名词
  • 再解释一个名词
  • 再做一个生硬对比
  • 最后给你一张表结束

结果就是:

每个问题好像都答了,但你仍然没形成一张完整的系统地图。

所以这篇文章,我们不按你提问的顺序机械作答,而是按一条更符合工程理解的主线来讲:

先看 LLM 应用为什么会复杂,再看 LangChain 解决了什么,再看 LangGraph 为什么会出现,最后再看 LlamaIndex 怎么接进整套系统。

你只要沿着这条主线读下去,前面那些问题自然都会被串起来。


🧠 一、先建立一个正确视角:LLM 应用不是"调个模型"这么简单

很多人第一次做 AI 应用,会把系统想成这样:

text 复制代码
用户问题 -> Prompt -> LLM -> 返回答案

这个模型本身没错,但它只适合最小 Demo。

一旦你做的是稍微真实一点的业务系统,链路马上就会膨胀:
用户请求
应用层封装
模型调用
上下文管理
工具调用
知识库检索
状态持久化
人工审核 / 中断恢复
文档索引 / 向量库

也就是说,真正的 LLM 系统,至少会同时碰到 4 类问题:

问题类型 你会碰到什么事 本质挑战
模型调用 不同 provider、不同模型切换 抽象统一接口
应用编排 Prompt、Tools、输出结构化、消息上下文 如何高效开发
流程控制 分支、循环、重试、恢复、人审 如何把复杂流程跑稳
数据检索 私有知识、索引构建、检索召回 如何把外部知识接进来

看到这里,你就会明白一个关键点:

LangChain、LangGraph、LlamaIndex 之所以经常一起出现,不是因为它们"长得像",而是因为它们通常落在同一套系统的不同层。

很多人一上来就问"我到底该学哪个",其实这个问题本身就有点偏。

更准确的问法应该是:

  • 我现在缺的是应用开发抽象吗?
  • 我现在缺的是复杂流程运行时吗?
  • 我现在缺的是私有知识的数据层能力吗?

当你从这个角度切入,三者的关系会清晰很多。

📌 先记一个总判断

如果你现在还没有完整地图,可以先记住这三句话:

  • LangChain 更像应用层框架
  • LangGraph 更像流程运行时框架
  • LlamaIndex 更像 RAG 数据层框架

后面我们就沿着这个分层逐步拆开。


📊 二、从系统分层看这三个框架,各自到底在管什么

如果你让我用最工程化的方式来描述这三个框架,我会这样拆:

层级 主要问题 更常见的框架
应用开发层 怎么把模型、Prompt、Tools、消息、输出组织起来 LangChain
流程编排层 怎么把多步骤 Agent 作为有状态流程稳定运行 LangGraph
数据检索层 怎么把企业文档、知识库、索引、查询引擎接进系统 LlamaIndex

很多人最容易混淆的地方,在于把"应用开发"和"流程编排"当成一回事。

但这两个层其实完全不同:

  • 应用开发层 更关心开发体验:怎么快速搭起来、怎么复用组件、怎么让接口友好
  • 流程编排层 更关心运行稳定性:怎么处理中断、怎么持久化状态、怎么做条件分支、怎么让人工介入

而数据检索层又是第三套问题域,它关注的是:

  • 文档怎么接入
  • 数据怎么清洗
  • 索引怎么构建
  • 查询怎么组织
  • 检索结果怎么返回给上层 Agent

所以很多时候,它们并不是替代关系,而是组合关系。
用户 / 外部系统
LangChain 应用层
LangGraph 编排层
LlamaIndex 数据层
向量库 / 文档源 / 检索系统

💡 这一层最容易形成的误区

很多文章会把三者写成"横向竞品对比表",但真实项目里,它们更像纵向分层:

  • LangChain 不一定替代 LangGraph
  • LangGraph 也不一定替代 LlamaIndex
  • LlamaIndex 通常也不是在替代 LangChain

真正成熟的理解不是"谁比谁强",而是:

谁更适合放在这一层。

下面我们先看 LangChain,因为它往往是大多数人最先接触的一层。


🚀 三、LangChain 到底是什么?不要再把它只理解成"链式调用库"了

LangChain 早期给很多人的印象,是"把几个步骤串起来"的 chain 框架。

这个印象不是完全错,但今天如果你还停在这一步,就会明显低估它。

从当前官方文档来看,LangChain 的定位已经更清晰了:

LangChain 是一个用于构建 LLM 应用和 Agent 的开发框架。

这个定义看起来普通,但它背后至少包含了两层意思。

1. 它不只关心"怎么调模型"

它还关心:

  • 怎么组织消息
  • 怎么管理上下文
  • 怎么做工具调用
  • 怎么做结构化输出
  • 怎么把这些能力封装成 Agent

也就是说,它不是只解决 API 调用问题,而是想把 LLM 应用开发过程中的一组高频能力统一抽象出来。

2. 它不只服务"问答 Demo"

它真正想解决的是:

如何把大模型能力,封装成一套可复用、可组合、可进工程系统的开发能力。

这也是为什么现在你再只用"LangChain 就是链式框架"去理解它,已经不够了。

它更像一个围绕 LLM 应用开发展开的"应用层工具箱"。

🔍 一个更贴近工程的类比

如果用 Web 开发做类比:

  • 模型 provider SDK 像数据库驱动或第三方 SDK
  • LangChain 更像"把这些能力统一到一套应用开发方式里"的框架
  • 它让你不用每次都手搓一套 Prompt + Tool + Memory + Output 管线

所以 LangChain 的价值,从来不只是"少写几行代码",而是:

  • 降低心智负担
  • 提高组合效率
  • 让模型能力更容易进入业务系统

✅ 小结

如果你要一句话回答"什么是 LangChain",更推荐这样说:

LangChain 是一个面向 LLM 应用和 Agent 开发的高层框架,它把模型、消息、工具、结构化输出和 Agent 能力统一到一套开发抽象里。


🔧 四、LangChain 的核心组件,应该放在一套系统里去理解

如果只把 LangChain 的核心组件当名词背下来,很容易记完就忘。

更推荐的做法是:把它们放进一条应用链路里理解。
用户输入
Messages / Context
Prompt / Agent Logic
Model
Tools
Structured Output
Middleware
业务系统消费结果

这张图里,几乎就包含了 LangChain 的核心组件。

🧩 1. Models:模型抽象层

这一层负责统一不同模型提供商的调用方式。

它的价值不只是"写起来方便",更重要的是:

  • 业务代码不需要深度耦合某一个厂商 SDK
  • 更容易切换 provider
  • 更容易做路由、降级、兜底和成本控制

如果没有这一层,系统很容易走向一个结局:

  • 前期接 OpenAI 很快
  • 中期想接 Anthropic 或本地模型时发现全链路都要改
  • 最后模型切换成本高得离谱

这就是"抽象统一接口"的工程价值。

一个最小的 LangChain Agent 例子

下面这个例子来自 LangChain 官方文档的思路,重点不是天气查询本身,而是看它如何把 模型 + 工具 + system prompt 收敛到一个 agent 创建入口里:

python 复制代码
from langchain.agents import create_agent


def get_weather(city: str) -> str:
    """Get weather for a given city."""
    return f"It's always sunny in {city}!"


agent = create_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[get_weather],
    system_prompt="You are a helpful assistant",
)

result = agent.invoke(
    {
        "messages": [
            {"role": "user", "content": "what is the weather in sf"}
        ]
    }
)

这个例子虽然简单,但已经体现出 LangChain 的第一层价值:

  • 模型不是直接裸调 SDK
  • 工具不是散落在业务代码里
  • 对话入口不是你自己手拼一个 while 循环

也就是说,它帮你把"最常见的 Agent 开发骨架"先搭出来了。

🗂️ 2. Messages / Context:消息与上下文层

这部分非常关键。

因为 LLM 应用不是发一个字符串就结束了,真实系统往往要维护:

  • system message
  • user message
  • assistant message
  • 会话历史
  • 运行时上下文
  • 短期记忆

这层真正解决的问题是:

模型这次回答之前,到底应该看到哪些上下文。

这不是小问题,因为上下文管理几乎直接决定:

  • 回答是否准确
  • token 成本是否可控
  • 多轮对话是否会跑偏
  • 工具调用是否还保留前置信息

很多 Agent"看起来像是笨",其实不是模型笨,而是上下文喂错了。

比如:

  • 该保留的业务上下文没保留
  • 不该保留的历史垃圾全部塞进去
  • 检索结果和会话消息重复拼接
  • 用户权限和会话状态没有进入上下文

所以这层真正考验的是"上下文工程",而不只是"消息列表怎么拼"。

🛠️ 3. Tools:工具层

Tool 是 LangChain 非常核心的能力。

它让模型不只是"会说",而是能"调用外部能力"。

典型工具包括:

  • 数据库查询
  • 搜索引擎
  • 内部 HTTP API
  • 工单系统
  • 日历、邮件、审批接口
  • 知识库检索器

所以 Tool 的本质不是"插件",而是:

让模型从语言生成器,升级成带决策能力的任务执行器。

官方文档里还特别强调了几个现实能力:

  • 多次工具调用
  • 动态工具选择
  • 工具错误处理
  • 状态持久化下的工具调用

这就意味着 Tool 不是一个孤立能力,而是 Agent 运行逻辑的一部分。

再看一个带 @tool 的例子

python 复制代码
from langchain.agents import create_agent
from langchain.tools import tool


@tool

def search(query: str) -> str:
    """Search for information."""
    return f"Results for: {query}"


@tool

def get_weather(location: str) -> str:
    """Get weather information for a location."""
    return f"Weather in {location}: Sunny, 72F"


agent = create_agent(
    model="openai:gpt-5",
    tools=[search, get_weather],
)

这里的重点不是语法,而是它体现出的能力边界:

  • Tool 有明确输入输出
  • Tool 有明确语义描述
  • Agent 运行时可以决定调哪个工具

这正是现代 Agent 和早期"纯 Prompt 调用"的分水岭。

📦 4. Structured Output:结构化输出层

这一层是很多工程项目里最容易被低估,但最不能少的一层。

因为业务系统要的往往不是一段"差不多能懂"的话,而是:

  • JSON
  • Schema 对象
  • 分类标签
  • 路由结果
  • 参数提取结果

如果输出不结构化,就会出现一个很典型的问题:

  • 人看着像对的
  • 系统接起来全是错的

所以结构化输出,本质上是在解决:

如何让 LLM 的结果可被程序稳定消费。

这在下面这些场景里尤其明显:

  • 让模型给流程选下一步节点
  • 让模型返回 API 调用参数
  • 让模型给工单打标签
  • 让模型提取时间、地点、实体、优先级

一旦进入这些场景,"自由文本"往往就不是朋友,而是风险点。

🧱 5. Middleware:中间件层

这一层的意义,在生产环境特别明显。

因为真实系统里,几乎一定会碰到这些横切需求:

  • 日志埋点
  • 权限控制
  • Prompt 注入
  • 成本统计
  • 审计追踪
  • 限流与熔断
  • 动态选择模型
  • 动态过滤工具

如果这些逻辑都散落在业务代码里,系统会越来越难维护。

所以 Middleware 的价值,就是把这类通用治理能力抽出来。

一个很有代表性的官方模式:动态选模型

官方 Agents 文档给过一个很典型的例子:根据消息长度切换不同模型。

python 复制代码
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
from langchain_openai import ChatOpenAI

basic_model = ChatOpenAI(model="gpt-4.1-mini")
advanced_model = ChatOpenAI(model="gpt-4.1")


@wrap_model_call
def dynamic_model_selection(request: ModelRequest, handler) -> ModelResponse:
    message_count = len(request.state["messages"])

    if message_count > 10:
        model = advanced_model
    else:
        model = basic_model

    return handler(request.override(model=model))


agent = create_agent(
    model=basic_model,
    tools=[],
    middleware=[dynamic_model_selection],
)

这个例子特别能说明 LangChain 的工程思路:

  • 不是把所有逻辑写死在 Agent 本体里
  • 而是通过 middleware 把"横切控制"抽出去

这也是为什么 LangChain 不只是"提示词工具箱",而越来越像一个完整应用框架。

🤖 6. Agents:Agent 封装层

Agent 是很多人使用 LangChain 的入口。

但你要注意,Agent 不只是"让模型自己想一想"。

一个更工程化的理解是:

  • 读取用户输入
  • 理解当前上下文
  • 判断要不要调工具
  • 决定调哪个工具
  • 根据工具结果继续推理
  • 满足条件后结束
  • 最后输出结果

这其实已经不是单次模型调用,而是一种"带决策能力的运行逻辑"。

也正因为如此,官方现在明确指出:

LangChain 的 agents 构建在 LangGraph 之上。

这句话非常关键,因为它说明了:

  • LangChain 负责开发体验
  • LangGraph 负责底层运行时编排

到这里,其实"LangChain 的核心组件有哪些"这个问题,已经自然回答完了。

如果你要压缩成一句话,就是:

Models、Messages/Context、Tools、Structured Output、Middleware、Agents,构成了 LangChain 的核心能力骨架。


🏗️ 五、LangChain 的核心架构,为什么说它本质上是"应用层框架"

理解完组件之后,我们再往上提一层,看它的架构。

LangChain 的核心架构,不应该只看成一条调用链,而应该看成一个应用层分层系统。
用户请求 / 外部事件
LangChain 应用层
消息与上下文管理
Prompt / Agent 决策
Tools 调用
结构化输出
Middleware 治理
LangGraph 运行时
Model Abstraction
数据库 / 搜索 / 业务 API
State / Checkpoint / Human-in-the-loop

这张图里,可以把 LangChain 架构理解成 4 层。

1. 能力接入层

负责接模型、接工具、接外部系统。

重点不是业务逻辑,而是统一接口和抽象边界。

这一层最像"能力适配器层"。

2. 上下文组织层

负责把消息历史、运行时上下文、记忆、系统提示词组织起来。

这一层直接决定模型"看到了什么"。

很多人调 Prompt 调了半天,实际上问题不在 Prompt,而在上下文边界乱了。

3. 决策与输出层

负责推理、工具选择、输出控制、结果结构化。

这是应用真正"智能"的地方。

但你要注意,所谓"智能"在工程上并不神秘,它通常只是:

  • 让模型做判断
  • 让模型给出结构化结果
  • 让结果进入后续系统节点

所以智能和工程并不是两回事,它们在这一层恰好会合。

4. 运行时承接层

负责把 Agent 作为流程稳定跑起来。

注意:

这一层在今天已经越来越依赖 LangGraph。

也就是说,LangChain 的高层架构里,已经天然包含了一个事实:

它虽然是应用开发框架,但复杂 Agent 的运行时能力,正在更多地交给 LangGraph。

这也解释了为什么很多人一开始只学 LangChain,后来还是得回头补 LangGraph。

📌 一个最容易忽略的架构事实

LangChain 的强项,从来不是"最底层最可控",而是"高层抽象足够顺手"。

所以:

  • 当你想快速搭起来,LangChain 很舒服
  • 当你要强控制复杂流程,单靠 LangChain 的高层抽象就会不够

这就是 LangGraph 出场的原因。


⚠️ 六、为什么 LangGraph 会出现?因为复杂 Agent 根本不是一条直线

如果你的应用只是:

  • 单轮问答
  • 简单分类
  • 一次工具调用

那么 LangChain 基本就够用了。

但一旦你开始做下面这些场景,问题马上就来了:

  • 先规划,再执行
  • 根据结果决定分支
  • 调工具失败后重试
  • 多轮反思与修正
  • 长时间运行后恢复
  • 某一步需要人工确认

这时候,如果你还把流程写成简单函数链,系统很快就会变得非常难维护。

因为复杂 Agent 的真实形态更像这样:


输入任务
规划节点
是否需要工具?
工具节点
结果写回状态
重新规划
总结输出
结束

这已经不是"调用顺序"问题了,而是"流程编排"问题。

很多团队在这里会经历一个很典型的演化过程:

  1. 先用一层函数调用串起来
  2. 发现需要 if / else 分支
  3. 再加 while 循环
  4. 再加异常重试
  5. 再加数据库状态记录
  6. 再加人工审核节点
  7. 最后代码像一团湿毛线

也正是在这个背景下,LangGraph 的价值才真正凸显出来。

💥 为什么说"复杂 Agent 不是直线"很重要?

因为很多问题本质上不是"模型更聪明一点"就能解决,而是流程本身具有下面这些特征:

  • 非确定性
  • 多轮反馈
  • 外部依赖
  • 中断恢复
  • 审批介入
  • 状态演进

而这类问题,天然适合用图和状态机来建模,而不是单纯用"链"来堆。


🚦 七、LangGraph 到底是什么?它本质上是在把 Agent 运行时状态机化

LangGraph 可以理解成一个专门面向 stateful agents 的编排框架。

它不是单纯帮你"画流程图",而是在解决下面这个核心问题:

如何把复杂、多步骤、可分支、可循环、可恢复的 Agent,作为一个有状态系统稳定跑起来。

所以你可以把 LangGraph 理解成:

  • 不是高层"应用开发糖衣"
  • 而是更底层的"流程运行时骨架"

如果用一句最直白的话概括:

LangGraph 就是把 AI Workflow 从函数链升级成状态图。

它和普通 DAG / 工作流工具有什么不一样?

很多人会问:

  • 这不就是个流程图引擎吗?

表面上有点像,但关键差异在于:

  • 它不是只编排静态步骤
  • 它还编排状态更新
  • 它天然面向消息与 Agent 推理循环
  • 它强调持久化、人工介入和恢复执行

也就是说,它不是只关心"下一步是谁",还关心:

  • 当前状态是什么
  • 这一步对状态做了什么更新
  • 如果中断了,下一次从哪恢复
  • 如果人工改了状态,后续怎么继续

这就是它比"把几个函数连起来"更工程化的地方。

✅ 一个更准确的一句话定义

如果你被问"什么是 LangGraph",最推荐的回答不是"画图的框架",而是:

LangGraph 是一个面向有状态 Agent 的低层编排框架,它通过 state、node、edge、reducer 和 checkpoint 来驱动复杂流程执行。


🧠 八、LangGraph 的编排原理,到底在编排什么

说 LangGraph 是"图编排",很多人第一反应是:

  • 有节点
  • 有边
  • 能跳转

这当然没错,但还不够。

LangGraph 真正编排的,不只是节点顺序,而是:

状态如何流动,节点如何读取状态、更新状态,以及流程如何基于状态继续演进。

这就是它和普通工作流工具的关键区别。

📌 1. State:整个图的共享状态中心

State 是 LangGraph 里最核心的对象之一。

它通常承载:

  • 当前输入
  • 消息历史
  • 中间推理结果
  • 工具调用结果
  • 审核状态
  • 最终输出

也就是说,流程不是靠函数一个个传参数,而是围绕一份共享状态逐步推进。

这件事看起来抽象,但工程价值巨大:

  • 状态统一,参数不会满天飞
  • 节点之间解耦更清晰
  • 中断恢复时有明确落点
  • 人工介入时也知道该改哪一块状态

🧩 2. Node:处理状态的逻辑节点

每个节点做一件相对清晰的事,例如:

  • 规划
  • 检索
  • 调工具
  • 校验
  • 人工审批
  • 最终整理结果

节点通常读取 state,并返回对 state 的更新。

这个设计的好处是:

  • 节点职责单一
  • 节点更容易测试
  • 节点更容易替换或重组

如果一个节点里又做规划、又调接口、又格式化输出、又写数据库,那后面几乎一定会很难维护。

🔀 3. Edge:决定接下来去哪

边的作用不是"连接起来这么简单",而是决定:

  • 固定往下走
  • 走条件分支
  • 回到前面循环
  • 动态路由到别的节点

所以边的本质,是流程调度规则。

很多复杂 Agent 的真正复杂度,并不在单个节点里,而在"下一步到底怎么走"。

🪢 4. Reducer:解决状态合并问题

这是 LangGraph 一个非常值得注意的点。

当多个节点都可能更新同一份 state 时,就必须明确:

  • 覆盖谁
  • 合并谁
  • 追加谁
  • 哪些字段怎么拼

Reducer 就是在干这件事。

官方 Graph API 文档里也强调了:每个 state key 都有自己的 reducer;如果你不显式指定,默认就是覆盖。

这意味着:

  • 简单字段默认覆盖没问题
  • 列表、消息历史、多轮结果这些字段往往要更谨慎

尤其是消息列表,如果你只是简单覆盖,很容易把上下文冲掉。

💾 5. Checkpoint / Persistence:让流程可以中断和恢复

这是 LangGraph 非常核心的工程能力。

因为真实 Agent 流程经常不是几百毫秒就结束,有时候会:

  • 跑很久
  • 中途失败
  • 等待人类输入
  • 需要下次再继续

如果没有 checkpoint,这种流程一旦中断就只能重来。

所以 LangGraph 的持久化,不是锦上添花,而是很多业务落地的前提。

👤 6. Human-in-the-loop:让人工介入成为流程一部分

很多高风险场景根本不能全自动。

例如:

  • 金融审批
  • 合同修改确认
  • 代码变更审核
  • 生产环境操作放行

LangGraph 很强调:流程可以暂停、等待人类输入、然后继续执行。

这意味着它服务的不是"纯自动机器人",而是更真实的企业级智能流程。

📌 一个官方概念里很实用的点:MessagesState

LangGraph 官方 Graph API 里还提供了一个很常见的预置状态:MessagesState

它的意义在于:

  • 很多图都会维护 messages
  • 而消息列表的更新不能只是简单覆盖
  • 需要用合适的 reducer 来追加、更新和反序列化消息

所以官方提供了 MessagesState,本质上是在帮你把"消息作为图状态"这件高频需求标准化。


📈 九、用一张图彻底看懂 LangGraph 的执行机制

Human Review Tool Node Planner Node Shared State LangGraph Runtime 用户/事件源 Human Review Tool Node Planner Node Shared State LangGraph Runtime 用户/事件源 alt [需要人工审核] 提交任务 初始化状态 执行规划节点 写入计划 根据状态判断下一条边 调用工具节点 写入工具结果 判断是否继续循环 暂停并等待输入 提交审核结果 更新审核状态 从 checkpoint 继续执行 返回最终结果

这张图背后,其实就是 LangGraph 编排原理的核心步骤:

  1. 初始化 state
  2. 执行 node
  3. node 更新 state
  4. runtime 根据 edge 和当前状态决定下一步
  5. 在关键节点保存 checkpoint
  6. 必要时暂停、恢复、人工介入
  7. 最后流转到结束节点

所以,LangGraph 编排的原理,最本质的一句话就是:

用 State + Nodes + Edges + Reducers + Checkpoint 驱动一个可分支、可循环、可恢复的 Agent 工作流。

一个更贴近代码的最小示意

下面这段代码不是为了炫 API,而是让你看到:LangGraph 的核心不是"节点函数本身",而是 节点只返回状态更新,图来负责状态演进

python 复制代码
from operator import add
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END


class State(TypedDict):
    user_input: str
    plan: str
    tool_results: Annotated[list[str], add]
    final_answer: str


def planner_node(state: State):
    return {"plan": f"Need to answer: {state['user_input']}"}



def tool_node(state: State):
    # 这里用伪结果代替真实工具调用,重点是观察状态更新方式
    return {"tool_results": ["retrieved context from external tool"]}



def final_node(state: State):
    answer = f"Plan: {state['plan']}\nEvidence: {state['tool_results']}"
    return {"final_answer": answer}


builder = StateGraph(State)
builder.add_node("planner", planner_node)
builder.add_node("tool", tool_node)
builder.add_node("final", final_node)

builder.add_edge(START, "planner")
builder.add_edge("planner", "tool")
builder.add_edge("tool", "final")
builder.add_edge("final", END)

graph = builder.compile()
result = graph.invoke({"user_input": "What is LangGraph?", "tool_results": []})

这段代码有两个非常重要的观察点:

  • 节点不需要返回整个状态,只返回更新部分
  • tool_resultsAnnotated[list[str], add] 指定了合并方式,不是默认覆盖

这正是 reducer 的价值所在。

再看一个官方概念味更浓的状态写法

如果你的流程就是围绕消息展开,那么 MessagesState 会更自然:

python 复制代码
from langgraph.graph import MessagesState


class State(MessagesState):
    documents: list[str]

这个例子虽然很短,但它非常有代表性:

  • 消息历史作为状态一等公民
  • 你可以在此基础上继续加自己的业务字段

这也是为什么说 LangGraph 不是"画图工具",而是"有状态运行时"。


⚖️ 十、LangChain 和 LangGraph 的区别,到底该怎么讲才不混乱

这是一个非常高频、但也最容易答虚的问题。

最常见的错误回答是:

  • LangChain 做链
  • LangGraph 做图

这不算错,但太浅了。

更推荐的讲法,是从"抽象层级"和"设计目标"两个角度说。

1. 抽象层级不同

  • LangChain 更高层:关注开发体验、组件组合、Agent 封装
  • LangGraph 更底层:关注状态流转、执行控制、流程持久化

2. 设计目标不同

  • LangChain 重点是"怎么更快开发 AI 应用"
  • LangGraph 重点是"怎么把复杂 Agent 稳定跑起来"

3. 适用场景不同

场景 更适合谁
简单问答、摘要、分类、轻量工具调用 LangChain
多步骤规划、复杂分支、长任务恢复、人机协同 LangGraph

4. 两者关系不是替代,而是上下层协作

这是最重要的一点。

官方文档已经很明确:

LangChain 的 agents 是建立在 LangGraph 之上的。

所以更准确的理解应该是:

  • LangChain 提供上层开发抽象
  • LangGraph 提供底层流程运行时

也就是说,它们不是二选一,而更像:

一个偏"写起来方便",一个偏"跑起来可靠"。

📌 一个非常实用的选型建议

如果你现在的需求是:

  • 先把应用搭出来
  • 工具不多
  • 分支不复杂
  • 暂时不做人审和恢复

那 LangChain 往往就够了。

但如果你已经出现下面这些信号:

  • 工具调用要循环很多轮
  • 会话任务可能跨很长时间
  • 需要节点级状态控制
  • 需要失败后从中间恢复
  • 需要人工接管某一步

那你就该认真进入 LangGraph 了。


📚 十一、那 LlamaIndex 应该放在哪?它更像 RAG 系统里的"数据层专家"

讲到这里,就该轮到 LlamaIndex 了。

如果说 LangChain 和 LangGraph 解决的是"应用与流程"问题,那么 LlamaIndex 更擅长解决的是:

如何把外部知识、企业文档、检索索引、查询引擎接进 LLM 系统。

所以它最适合放在 RAG 的数据层。

它通常更强的地方在于:

  • 数据接入(ingestion)
  • 文档解析
  • 索引构建
  • Retriever / Query Engine 抽象
  • RAG 查询链路组织

很多团队在做企业知识库时会有一个典型痛点:

  • 模型能力和 Agent 流程都已经接好了
  • 但数据入口很乱
  • 索引构建和查询逻辑也没有统一抽象

这时候,LlamaIndex 往往正好补上的是"数据层能力缺口"。

为什么说它是"数据层专家"?

因为它更聚焦这些事情:

  • 文档从哪里来
  • 文档怎么切块
  • 元数据怎么组织
  • 索引怎么建立
  • 查询时怎么拿到适合上层应用消费的结果

而这些问题,本来就不应该全塞进 LangChain Agent 节点里。

所以 LlamaIndex 的合理位置,不是"替代整个 Agent 框架",而是:

作为上层 Agent / Workflow 的知识检索后端。


🔗 十二、LlamaIndex 如何和 LangChain 结合?最常见的是这三种方式

1. LangChain 做应用与 Agent,LlamaIndex 做检索与查询

这是最常见、也最自然的一种组合。
用户问题
LangChain Agent / App
LlamaIndex Retriever / Query Engine
索引 / 向量库 / 文档源
答案输出

在这个模式里:

  • LangChain 负责 Agent、提示词、工具路由、结构化输出
  • LlamaIndex 负责文档摄取、索引构建、检索、查询引擎

这就是最典型的"应用层 + 数据层"分工。

2. 在 LlamaIndex 里复用 LangChain 的 LLM 适配

LlamaIndex 官方提供了 LangChain LLM 适配器,所以你可以在 LlamaIndex 中复用 LangChain 已经统一好的模型接入。

python 复制代码
from langchain_openai import ChatOpenAI
from llama_index.llms.langchain import LangChainLLM

lc_llm = ChatOpenAI(model="gpt-4.1-mini", temperature=0)
llm = LangChainLLM(llm=lc_llm)

这种方式适合:

  • 你已经用 LangChain 统一了模型层
  • 但检索和查询逻辑希望交给 LlamaIndex

这样做的好处是:

  • 模型配置只维护一份
  • 数据层不会自己再维护另一套 LLM 接入逻辑
  • 上下游边界更清晰

3. 在 LlamaIndex 里复用 LangChain 的 Embeddings

LlamaIndex 也提供了 LangChain Embeddings 适配器。

python 复制代码
from llama_index.core import Settings
from llama_index.embeddings.langchain import LangchainEmbedding

# lc_embedding 按你的 LangChain provider 创建
Settings.embed_model = LangchainEmbedding(lc_embedding)

这个模式适合:

  • 公司已经统一了 embedding 服务
  • 但索引构建、检索层仍然想使用 LlamaIndex

本质上,它是在做一件很工程化的事:

模型层和数据层各用所长,但底层能力不要重复配置。

4. 一个更贴近项目落地的组合姿势

除了上面两个 adapter,真正项目里更常见的写法是:

  • 用 LlamaIndex 构建查询引擎
  • 再把这个查询引擎包装成 LangChain 可调用工具
  • 最后交给 LangChain Agent 或 LangGraph 流程使用

下面这个示例偏工程示意,重点看职责分层,不强调逐行可运行:

python 复制代码
from langchain.tools import tool

# 假设你已经在 LlamaIndex 里构建好了 query_engine
# query_engine = index.as_query_engine()


@tool
def kb_search(question: str) -> str:
    """Search enterprise knowledge base."""
    response = query_engine.query(question)
    return str(response)


agent = create_agent(
    model="openai:gpt-5",
    tools=[kb_search],
)

这个组合非常典型,因为它体现了清晰边界:

  • LlamaIndex 负责查知识
  • LangChain 负责决定"什么时候去查"
  • LangGraph 负责把整条复杂流程稳定跑完

这三层一旦边界清楚,系统维护成本会低很多。


🏢 十三、如果把三者放进一套企业系统里,最合理的架构通常长什么样

如果你要做的是企业知识库助手、文档问答系统、流程型 Agent,比较推荐的分层通常是这样:

层级 负责内容 更常见的选择
接口层 Web / API / Chat UI 前端、FastAPI、网关
应用层 Prompt、工具、结构化输出、Agent 入口 LangChain
编排层 分支、循环、状态持久化、人机协同 LangGraph
数据层 文档接入、索引、检索、查询引擎 LlamaIndex
基础设施层 向量库、对象存储、日志监控 Milvus、pgvector、S3、可观测系统

用图看会更直观:


用户请求
LangChain 应用层
LangGraph 编排层
是否需要外部知识?
LlamaIndex 数据层
文档索引 / 向量库
直接调用工具 / 模型
状态持久化 / 人工审核
最终结果

这套架构的好处是:

  • 组件职责清晰
  • Agent 逻辑不会和检索实现缠在一起
  • 检索系统能单独优化
  • 流程系统能单独治理
  • 更适合后期扩展与多人协作

🔍 这套架构为什么更稳?

因为它遵守了一个常被忽略的原则:

把变化频率不同的东西拆开。

举个例子:

  • 模型选择可能经常变
  • 检索策略可能也经常变
  • 但审批流程和业务状态机不一定天天变

如果这些东西全写在同一层,系统一改就会牵一大片。

而分层之后:

  • 想换 embedding,不一定动 Agent 流程
  • 想改审批分支,不一定重写知识库检索
  • 想换模型,不一定推翻整个数据层

这就是架构边界的真正价值。


⚠️ 十四、真正落地时最容易踩的坑,不在框架本身,而在边界设计

很多团队不是不会用框架,而是不会做边界设计。

最容易踩坑的地方,通常有下面这些:

坑点 典型表现 更推荐的做法
把 LangChain 当成全栈解决方案 检索、状态、流程全塞在一起 明确应用层与流程层边界
把 LangGraph 当成"画图工具" 图很漂亮,但没有真正利用持久化与恢复 按运行时系统思维设计
把 LlamaIndex 逻辑写死在 Agent 节点里 一改检索策略就全链路受影响 用 Retriever / Query Engine 抽象隔离数据层
State 设计过大 什么都往状态里塞 只保留流程必需数据
上下文重复拼接 消息历史和检索结果不断叠加 统一上下文组装策略
没有退出条件 Agent 一直循环调用工具 明确最大轮次、失败策略与人工兜底

再把这些坑翻译成人话

很多系统最后出问题,不是因为选错框架,而是因为:

  • 本来该是数据层的逻辑,被写进 Agent 提示词里了
  • 本来该由状态机控制的流程,被塞进一堆 if/else 里了
  • 本来该结构化输出的节点,还在回自由文本
  • 本来该中断恢复的长流程,只能失败重来

所以你会发现,真正难的从来不是"会不会调框架 API",而是:

你能不能把系统拆成应用层、流程层、数据层这几个清晰边界。

✅ 一个很实用的自检清单

如果你想判断自己的设计是不是已经有点混了,可以快速问自己 5 个问题:

  1. 这个逻辑到底属于应用层、编排层,还是数据层?
  2. 这个状态应该存在图状态里,还是只存在单次调用上下文里?
  3. 这个返回结果是给人看的,还是给程序消费的?
  4. 如果这里中断了,我能从中间恢复吗?
  5. 如果我要替换检索实现,需要改多少上层代码?

如果这 5 个问题里有 3 个回答不清楚,说明你的边界大概率已经开始混了。


✅ 十五、最后再把你最关心的几个问题,压缩成一张速答表

到这里,前面的问题其实都已经融在正文里讲完了。

如果你想最后快速复习,可以直接看这张表。

问题 简洁回答
什么是 LangChain? 一个面向 LLM 应用和 Agent 开发的高层框架,不只是"链式调用库"
LangChain 的核心组件有哪些? Models、Messages/Context、Tools、Structured Output、Middleware、Agents
LangChain 核心架构是什么样的? 本质上是"应用开发层"架构:统一模型与工具接入、组织上下文、控制输出,并把复杂运行时交给 LangGraph
什么是 LangGraph? 一个面向有状态、多步骤、可恢复 Agent 的图编排框架
LangGraph 编排的原理是什么? 用 State、Nodes、Edges、Reducers、Checkpoint 驱动流程演进
LangChain 和 LangGraph 有什么区别? LangChain 偏应用开发抽象,LangGraph 偏流程运行时编排;两者更像上下层关系
LlamaIndex 如何与 LangChain 结合? 通常由 LangChain/LangGraph 负责应用和流程,LlamaIndex 负责 RAG 数据接入、索引与检索

如果只允许你记一句话,那我建议你记这个版本:

LangChain 解决"怎么开发 AI 应用",LangGraph 解决"怎么让复杂 Agent 稳定运行",LlamaIndex 解决"怎么把私有知识高质量接进系统"。


💡 十六、总结

最后我们把整篇文章收一下。

很多人一开始学这几个框架,会觉得它们名字都很像,能力边界也很容易混。

但如果你站在系统分层的角度看,逻辑其实非常清晰:

  • LangChain 主要解决应用开发问题
  • LangGraph 主要解决流程编排与运行时问题
  • LlamaIndex 主要解决 RAG 数据接入与检索问题

所以真正成熟的选型思路,不是问"我到底该选谁",而是问:

  • 我现在缺的是应用开发抽象?
  • 还是复杂流程运行时?
  • 还是私有知识的数据层能力?

想清楚这个问题,你对这三个框架的理解,就已经超过很多只会背定义的人了。

📌 最后给一个落地建议

如果你现在正准备做项目,我会给你一个很实用的起步顺序:

  1. 先用 LangChain 把最小应用跑起来
  2. 当流程复杂度上来后,再把关键链路迁到 LangGraph 思维里
  3. 一旦涉及企业知识库或 RAG,再引入 LlamaIndex 做数据层抽象

这个顺序的好处是:

  • 不会一开始就学得太重
  • 也不会在复杂度上来之后被迫重写全部系统

换句话说:

先搭应用,再稳流程,最后把数据层做扎实。

这往往比一开始追求"最全框架组合拳"更现实。


🔗 参考资料

以下为本文整理时参考的官方资料:

相关推荐
Ancelin安心2 小时前
西工大noj(C/C++)100题参考题解及注意事项(2024)
c语言·c++·ide·windows·vscode·算法
倒酒小生2 小时前
4月10日算法总结
图像处理·算法·计算机视觉
alphaTao2 小时前
LeetCode 每日一题 2026/4/6-2026/4/12
python·算法·leetcode
李日灐2 小时前
【优选算法3】二分查找经典算法面试题
开发语言·c++·后端·算法·面试·二分查找·双指针
PD我是你的真爱粉2 小时前
AI Agent 完全指南:LangChain Agent、ReAct、Copilot-Agent 模式、Manus、Computer Use 与记忆机制
人工智能·react.js·langchain
独孤--蝴蝶2 小时前
leetcode-动态规划三种问题的异同点
算法·leetcode·动态规划
迷你可可小生2 小时前
二叉树知识点
python·算法
Z1Jxxx2 小时前
C++ P1151 子数整数
开发语言·c++·算法
飞翔的SA2 小时前
EmDash:WordPress 精神继承者,重构内容管理系统(CMS) 安全与现代架构
安全·重构·架构·cms