上周有同学在群里问了一个很典型的问题:“我看了好几个 LangChain 教程,跟着写了不少代码,但一碰到 Agent 就懵了。LangGraph 又出来了,MCP 又是干嘛的?我是不是要全学一遍?”
这个问题问得很实在,但它背后藏着一个更大的误区:把 LangChain、LangGraph、Agent、RAG、MCP 当成五个并列的新技术,逐个学过去,最后学成了五个孤岛。实际上,这几样东西根本不在同一个抽象层级上。LangChain 是一层通用开发框架,LangGraph 是它生态里的流程编排引擎,Agent 是一种程序结构,RAG 是一种知识接入方式,MCP 是一个工具连接协议。把它们放在一起,真正要回答的是一个大问题:怎么用最少的心智负担,构建一个能调用工具、能查资料、能稳定执行多步任务的 AI 应用。
这篇文章不打算再给你刷一遍“从入门到放弃”的教程目录。我想换一种方式,把这几块东西到底解决什么问题、为什么存在、怎么组合、怎么避坑、从零开始怎么走一条最短路径讲清楚。
1. 先想明白:LangChain 到底是干嘛的,LangGraph 又补了什么
1.1 LangChain 的本质是一层“脚手架”
很多新手第一次打开 LangChain 文档,看到 Model、Prompt、Output Parser、Memory、Retriever、Tool 各种概念,第一反应是“好复杂”。但换个角度,LangChain 其实是在帮你做一件事:把一个大模型应用里反复出现的胶水代码,收拢成统一接口。
比如,你要调用一个模型,你需要拼接 Prompt、传参数、处理返回结果、处理超时和报错。你自己写也能写,但每个模型厂商的 API 风格都不一样。LangChain 做的事情是:给你一个统一的模型封装,把切换模型这件事从“改全部代码”变成“改一行配置”。同样,Prompt 模板管理、输出格式解析、聊天记录存储、文档切分、向量库接入,这些都不是大模型本身的能力,而是一个应用必须配套的“外围设施”。LangChain 的价值,就是把这些外围设施标准化。
这也是为什么很多人说“不用 LangChain 也能开发”,这句话没毛病。你自己搭脚手架完全可以。但当你从写一个 demo 变成维护一个项目时,会发现自己写得越多,越像在重复造一个不太完整的 LangChain。与其如此,不如直接理解它的设计思路。
1.2 LangGraph 不是 LangChain 的替代品
LangGraph 的定位很多人搞错了,它不是“比 LangChain 更牛的框架”,而是“在 LangChain 生态里负责流程控制的那块拼图”。
LangChain 最早版本的 Agent 实现,更多是走一条固定的 ReAct 循环:模型思考一下,调一个工具,再思考,再调工具。这种循环看着简单,但一碰到真实业务就窘迫:如果模型连续调了五次工具还没结束怎么办?如果中间某一步需要人工审批怎么办?如果某一步失败后需要重试而不是从头再来怎么办?这些问题,本质上是“图流程”才能解决的。
LangGraph 干的事情,就是让你把整个执行流程画成一张图。每个节点是一个函数,每条边是节点之间的流转规则。你可以用条件边表达“如果模型判断该结束,就进入结束节点;如果还想调工具,就进入工具节点”。你还可以在一条边上设置递归深度限制、设置超时、设置人工确认节点。
所以,LangChain 和 LangGraph 的真正关系是:LangChain 给你一套工具,LangGraph 给你一套流程控制逻辑。绝大部分场景下,你会同时用到两者,而不是二选一。
1.3 一张表看懂五者关系
很多人学到最后浑浑噩噩,就是因为脑子里没有一个“地图”。我整理过一张关系表,对新手特别有用:
| 概念 | 层级 | 解决什么问题 | 一句话理解 |
|---|---|---|---|
| LangChain | 开发框架 | 模型、Prompt、输出、检索、记忆的封装 | 搭积木的工具箱 |
| LangGraph | 编排引擎 | 有状态、可循环、可回退的流程控制 | 流水线的控制面板 |
| Agent | 应用结构 | 模型在循环中自己决定下一步做什么 | 让流程具备动态决策能力 |
| RAG | 知识接入方式 | 外部知识检索后拼进上下文再生成 | 给模型开卷考试 |
| MCP | 连接协议 | 标准化模型与外部工具/数据源的连接方式 | 工具接入的通用插座 |
这个表格值得反复看。你学的不是一个一个孤立的功能,而是一个分工明确的组合体系。
2. Agent 的真正难点,从来不是“让模型思考”,而是“让流程可控”
2.1 Agent 到底是个什么样的程序
如果你拆过 Agent 的代码,会发现它的核心逻辑其实异常简单:一个循环,循环里做两件事,一是把当前状态和可用的工具清单交给模型,二是让模型决定下一步是调用工具还是输出最终答案。拿到模型决策后,如果它要调工具,就执行工具,把结果塞回对话记录,然后进入下一轮。
这个结构很清晰,但本质上是把控制权交给了模型。模型有多聪明、多稳定,直接决定了 Agent 的行为有多可靠。这也是为什么很多人第一次跑通 Agent 时觉得惊艳,真正放到业务里又觉得不踏实:因为它每一次执行,都可能走一条不同的路径。
2.2 为什么 LangGraph 能解决过去不好解决的问题
在没有图编排能力之前,想做 Agent 流程控制,通常靠的是写一大段while循环代码:max_iterations设多少、工具结果怎么附加、历史记录怎么裁剪、异常怎么捕获。写着写着,代码就成了一团乱麻。
LangGraph 的思路是完全不同的。它不关心每一步内部怎么实现,它关心的是节点之间的流转关系。把“模型判断”“调用工具”“检索知识库”“生成最终回答”分别抽象成节点,再用边把这些节点连接起来,整个 Agent 流程就从一段难以维护的循环代码,变成了一张看得见、能改、能监控的图。
这个变化的影响很现实:你可以给“调用工具”这个节点单独加重试逻辑,而不用影响其他节点;你可以在“调用工具”和“模型判断”之间加一个人工确认节点,而不用大改代码;你甚至可以在流程运行到一半时,把当前状态存下来,下次接着跑。
2.3 实际开发时最容易裂开的三个地方
有一些问题,几乎所有 Agent 开发者在早期都会遇到,我先把它们列出来,免得你以后边写代码边怀疑人生。
第一,递归深度不受控。模型在一个问题上反复调用同一个工具,几次之后上下文异常庞大,或者直接触发深度限制。解决办法不是在 Prompt 里祈求模型住手,而是在图边上设置明确的recursion_limit,同时把历史记录做裁剪。
第二,模型返回了不存在的工具名或错误格式。大模型是概率模型,它可能突然“幻想”出一个不在清单里的工具。工程上要做的是解析容错:先验证工具名是否存在,再尝试调用;调用返回的不是 JSON 就做格式化修复,而不是直接把异常抛给用户。
第三,上下文被工具输出撑爆。一个工具可能返回几十万字符,全塞进上下文,下一轮模型就废了。解决思路是在工具节点做“输出摘要”或“按需截断”,只让模型看到它真正需要的关键字段。
实际开发经验:一个稳定的 Agent 系统,往往不是靠模型更聪明,而是靠外面这一层工程兜底。图流程、限流、重试、输出裁剪、人工确认,才是你真正花时间的地方。
3. RAG 从朴素版到 Agentic 版,真正进阶的是“检索策略”
3.1 先跑通朴素 RAG,别急着追新概念
RAG 全网教程很多,但新手的失败路径往往高度一致:上来就追 Agentic RAG,结果基础链路没跑通,最后问题都不知道出在哪一层。
朴素 RAG 的链路是固定的:把文档切块,做向量化,存进向量库;用户提问时,把问题向量化,检索最相似的几个文档块;把这些文档块拼进 Prompt,交给模型生成答案。这个流程跑通并不难,难的是让它回答得靠谱。
真正影响 RAG 效果的不是模型,而是上游的文档处理和检索质量。比如切块太小,语义被腰斩;切块太大,检索出来的内容一半是无关信息。再比如用同一个 embedding 模型处理所有文档,没有针对领域微调或选择合适的检索策略,效果就会非常平庸。这些都是工程问题,不是模型问题。
在我见过的项目里,第一步跑通朴素 RAG 之后,最值得做的是拿二三十个真实问题去做一次效果抽样,看看失败案例集中在哪些类型。是检索没找到相关内容,还是找到了但模型没用上,还是 Prompt 格式让模型忽略了你给的资料。定位了失败类型,才知道该优化哪一层。
3.2 检索策略:多路召回和重排序才是提升效果的关键
网上经常出现 dense vector search 这个术语。它指的是把文本变成高维向量,在向量空间里找最相似的文档块。这是现代 RAG 的主力检索手段,但它不是唯一手段。同一个知识库里,有些问题适合用向量搜索,比如含义相近但字面完全不同的表述;有些问题适合用关键词搜索,比如产品名、型号、专有名词、精确编号。向量搜索对这类词往往会匹配到一大批含义相似但完全不对的文本。
所以,很多成熟的 RAG 系统会引入“多路召回”:同时用向量检索和关键词检索,把两路结果都拿出来,再经过一个重排序模型(reranker),把真正和问题相关的文档块排到前面。这个设计的道理很简单:先保证“别漏掉”,再保证“排到前面”。
这一层听起来不难,但落地时要注意的事情很多。不同检索器的返回数量怎么设置;重排序模型要不要单独部署,延迟多少;两路结果里如果有互相矛盾的文档,模型会怎么取舍。这些都需要在自己的数据集上反复测试,没有一个普适参数。
3.3 Agentic RAG:检索从一个固定步骤变成一个动态决策
Agentic RAG 最近讨论很多,它和朴素 RAG 的区别,不在于是不是用了 Agent 框架,而在于:检索行为是否由模型动态决定。
朴素 RAG 是笨办法:无论用户问了什么,系统都先检索,再把结果发给模型。但实际场景里,很多问题根本不需要检索。比如“你好”“你是谁”“帮我总结一下你的能力”这种问题,你硬要去检索一遍文档,纯属浪费时间,还增加了错误引导的风险。
Agentic RAG 的做法是:把“要不要检索”“检索什么”“是否需要追问用户”“要不要再查一次”都交给模型在循环里决定。模型先判断问题是否需要外部知识,需要的话再决定检索词和检索范围,如果结果不够好还可以换个方式再查一次,直到它认为信息充分才生成答案。这个过程在新术语里被叫做 “agentic retrieval”, 也就是说检索成为流程里的一个智能决策节点,而不是按部就班的固定步骤。
这确实更聪明,但代价是复杂度明显上升。你需要处理好递归限制、工具调用的判停、多轮检索后的上下文管理。我的建议是:如果你的场景只是“单知识库、单轮问答、问题类型固定”,先做朴素 RAG,把召回质量调好,就已经能满足大多数需求。Agentic RAG 更适合问题开放、知识库分散、需要多轮确认或需要混合多个来源才能回答的场景。
4. MCP:让 Agent 从“会说话”变成“能干活”
4.1 MCP 解决的是一个很痛的集成问题
Agent 最大的价值,不只是生成一段文字,而是能真正操作外部工具:查数据库、发消息、改文件、调用设计软件、操作浏览器。但这里有一个绕不开的麻烦:每个外部工具都有自己的 API、鉴权方式、数据格式,如果你每接一个工具就要写一套适配代码,那这个 Agent 系统永远接不了几个工具。
MCP(Model Context Protocol)的思路是:把“模型怎么用工具”这件事标准化。工具提供方只要实现一个 MCP Server,把自己的能力通过统一格式暴露出来;模型这边通过 MCP Client 去发现这些能力、按统一格式调用。对接新工具,变成了一种“配置”而不是“开发”。
如果类比的话,MCP 不需要你为每个设备重新买一根专用线。它更像是在接口标准上定义一个通用规范,一旦协议对了,新设备插上就能用。对于 Agent 生态来说,这一步的意义很关键:只有几乎不需要额外开发成本,Agent 才能在大量真实工具互相连接之间跑起来。
4.2 你会在什么场景里遇到 MCP
从最近社区各种讨论和项目现象来看,MCP 的落地场景已经不只是数据库和文件操作。设计工具、3D 建模软件、游戏引擎、UI 设计平台、代码编辑器、办公套件,都在陆续出现接入 MCP 的尝试。比如有人在讨论某个 UI 设计工具支持了 MCP 服务,有人分享在 3D 建模软件里通过 MCP 接收 Agent 指令,也有人尝试用一个 MCP Server 让 Agent 直接查询业务数据库。
这给普通开发者带来的机会是:你完全可以先踩着别人写好的 MCP Server 跑通一个具体场景,而不是从零造一套工具接入方案。比如想让 Agent 查一个数据库,先找一个现成的 MCP 实现,配置好连接信息,验证一下能不能完成“Agent 问一个问题、MCP Server 查一次库、模型根据查询结果生成回答”的最小循环。这个循环跑通之后,你再考虑是不是要自己写一个 MCP Server 暴露内部工具。
4.3 用 MCP 的几个工程提醒
虽然 MCP 把“接入”这件事变简单了,但工程风险不会自动消失。有几个地方是你上生产环境前必须考虑的。
第一,所有 MCP Server 都应该有明确的权限边界。Agent 通过 MCP 访问数据库不是问题,问题是它能不能只读某些库表、能不能执行删除、能不能访问客户敏感字段。这部分不能全指望模型自律,一定要在 MCP Server 层做权限控制。
第二,MCP Server 的超时和故障要单独处理。工具请求可能长时间无响应,或者返回非法数据。你的 Agent 流程里要有超时保护、失败重试和异常捕获,不能因为一次工具调用失败就把整个会话搞崩溃。
第三,日志和审计要留好。Agent 调用某个工具、传了什么参数、返回了什么结果,这些都应该有记录。这不只是为了排查,更是为了你在模型行为失控时能回溯和分析。
第四,MCP 生态还在很快地演化演进中,不同 Server 的质量参差不齐。从一个看起来维护活跃、文档清晰、使用者够多的 Server 开始,或者先用自己内部最简单的 Server 验证,先跑通主链路,不要一上来就把全套生态接入。
建议:MCP 带来的是接口层的便利,它不解决工具本身是否可信的问题。接口再标准,工具该有权限边界还是要有。
5. 从零基础到能上手,我总结出的最短学习路径
5.1 不要让教程长度骗了你,你缺的是一次最小闭环
市面上很多“全套教程”都会给人一种错觉:只要把所有课时刷完,我就能掌握这些技术了。但真实世界的学习链条不是“看完-学会”,而是“跑通-理解-改写-沉淀”。你需要的不是再看一个 LangChain 教学的单元,而是亲手把一个最小项目跑起来。
我给零基础的朋友建议的是这样一条五步路径,每一层都会产生一个看得见的结果,并且每一层都是下一层的脚手架:
- 跑通一个最简单的 LangChain 程序。调用一个模型,给一个 Prompt 模板,完成一次输入输出。目标不是学完所有模块,而是理解“一个 LLM 应用的最小骨架长什么样”。
- 加入一个简单的工具调用。写一个函数,比如 num_days 或 get_current_time,让模型在回答时调用它。目标不是用多复杂的工具,而是理解模型是如何决定调用工具的、工具返回结果是怎么回到模型手里的。
- 用 LangGraph 改造这个 Agent。把“模型判断”和“工具调用”变成两个节点,连成一张图。目标不是做大系统,而是体会“图编排”和“裸写循环”在代码组织方式上的差异。
- 给系统加一个知识库。用一个文档集,完成切块、向量化、检索、生成,做出一个简单的 RAG 问答。目标不是拼一堆新词,而是理解检索结果的质量对最终回答的影响方式。
- 把外部工具通过 MCP 接入。换掉你之前手写的工具调用,让 Agent 通过 MCP Server 调用某个真实服务。目标是用最低成本体会一次标准协议接入的感觉。
走完这五步,你对标题里的每一条都会有真实的体验,而不只是知道这些名词是什么。
5.2 每一步的“完成标准”怎么判断
很多人不知道自己学到什么程度算“会了”,这里给一个很直接的判断标准:每一步,你都能在没有参考代码的前提下,从一张空白文件开始,把功能写出来,并且知道如果需求变化一小点,该改哪个环节。
比如第三步,如果我问你:把工具调用改成先调用一次搜索、再把搜索结果交给模型总结,你要改动的是哪个节点?你能立刻指出,说明你对 LangGraph 的理解已经到位了。
5.3 不需要一开始就学的部分
新手最容易掉进的坑是想把每个概念都学深。我建议暂时先不要碰:LangSmith 的复杂监控配置、LangChain 里你不常用的所有第三方集成、各类深度优化的 embedding 模型微调、以及一上来就自己设计一套 MCP 协议。
这些不是没用,而是它们都不在你建立“最小全局认知”的路径上。等主链路跑通了、有自己的真实场景了,你自然会知道该往哪一层深入。
5.4 实践要点:在环境与版本上的谨慎姿态
LangChain、LangGraph、MCP 这些生态的 API 更新特别快。一个视频或一篇教程里给出的 API 调用方式,可能过了几个月就变了。所以跑代码的时候,不要照抄 API 名,优先看你本地安装的版本对应的官方文档。
遇到 API 不存在、参数名对不上、调用结果和预期不一致,先做的事是查版本,而不是怀疑自己写错。我见过太多人卡在 API 差异上,把大量时间浪费在调整一段本应直接跑通的示例代码。
经验:把环境锁定为当前教程所使用的依赖版本,这是最稳妥的做法。如果你在写一个长期维护的项目,显式指定版本而不是用“最新版”,会少掉很多无妄之灾。
6. 一个实战排查链路:报错、卡死、回答异常时按这个顺序来
6.1 看现象,不要急着改代码
很多新手遇到 agent execution terminated due to error 就会整段懵掉。其实这类兜底报错往往只告诉你“流程终止于某一步”,真正的病灶藏在它前面的日志里。
所以遇到任何问题,先走这五步排查链路:
- 看现象:是报错中断、一直循环不结束、还是正常结束但回答不对。不同现象指向完全不同的故障点。
- 看输入:你的查询、工具返回、检索结果到底是什么。这一步尤其重要,很多 Agent 回答错,不是流程逻辑错,而是它吃了错误的输入。
- 看状态和上下文:当前状态里保存了什么,模型能看到多少轮对话,上下文是否已经被大量日志或工具输出污染。
- 看环境配置:依赖版本、API Key、权限、网络、路径这些外围配置。报错如果只出现在某一个环境,而另一个环境是好的,优先怀疑这一层。
- 看配置参数:温度、最大Token、递归深度、检索条数、超时时间这些参数,有没有设置得过于极端。
6.2 从真实故障里反推常见原因
我自己在实际项目里遇到过不少次 Agent 流程的异常,最常出现的几类问题,基本都是边界问题:
- 工具返回了超长结果,下一轮模型无法处理。解决办法是对输出做摘要或按需截断。
- 模型在对话历史中找不到工具调用的返回结果,于是“幻想”出一个结果继续往下编。这是很典型的状态管理问题,要检查历史消息的结构。
- LangGraph 流程里,某个节点的边写错了,导致模型无论怎么决策,都会走到同一个节点。这类问题通常不会报错,但会让你看到模型行为诡异。
- 检索出来的文档块太杂,模型不知道重点是谁,于是回答得既像对又像不对。解决办法是重排序,或者在 Prompt 里强调“优先使用与问题最相关的部分”。
6.3 “先跑通再优化”的顺序也适用于排查
排查的时候最忌讳的是同时改三个地方。正确的做法是:先保证一个最小路径能跑通,再逐步加回复杂条件。比如 Agent 流程出错了,先把工具节点替换成一个固定返回,看看主流程是否正常;如果主流程正常,再怀疑工具内部的问题。RAG 回答不对,先用固定的检索结果跑一次生成,看看是检索的问题还是生成的问题;如果固定结果生成没问题,再回到检索这一层去调。
排查的过程,本质上就是不断缩小问题边界的过程。
结尾
回到文章开头那位同学的困惑。LangChain、LangGraph、Agent、RAG、MCP 并不是五个互不相干的技术点,它们其实是同一个问题的不同侧面:如何把一个“能与模型对话的程序”升级成一个“能完成真实任务的系统”。
学这套东西的最快路径,不是按五个概念逐个学,而是先跑通一个最小闭环,然后在闭环上不停地加节点、加知识、加工具。每加一层,你遇到的新问题都会逼着你去理解下一层。
如果你现在还在犹豫从哪里开始,我的建议很简单:找一台能跑 Python 的电脑,装好环境,先写一个只调用模型的 LangChain 脚本,然后让这个脚本能调用一个函数。这就是你绕开所有教程焦虑的最小起点。后面的事情,等这个小软件跑出第一行输出,你自然会知道下一步该做什么。