很多人的误区:「用了 LangChain 大模型才会 ToolCall」「MCP 会替代 ToolCall」——这两个都是错的。今天用一张图、几段代码、几个比喻,把 LLM、LangChain、ToolCall、MCP 四者的关系彻底讲清楚。

先抛结论:它们根本不在同一层

把这四样东西放到一张层级图里,关系一目了然:

┌─────────────────────────────────────────────┐
│  你的应用后端(Agent 系统)                    │
│  ┌───────────────────────────────────────┐  │
│  │  LangChain / LangGraph                │  │  ← 编排层:循环、记忆、状态、异常处理
│  │  (循环调度 / Memory / RAG / 解析)    │  │
│  └──────────────────┬────────────────────┘  │
│                     │ 发请求 / 收结果          │
│  ┌──────────────────▼────────────────────┐  │
│  │  LLM(大模型 API)                     │  │  ← 决策层:思考、输出 ToolCall
│  │  只负责"想",输出一段 JSON 意图         │  │
│  └──────────────────┬────────────────────┘  │
│                     │ ToolCall(JSON 文本)   │
│  ┌──────────────────▼────────────────────┐  │
│  │  MCP / 自写胶水代码                    │  │  ← 执行层:鉴权、调接口、查库、容错
│  │  真正去干活,把结果回传给 LLM           │  │
│  └───────────────────────────────────────┘  │
└─────────────────────────────────────────────┘

一句话:LLM 负责"想"(决策),框架负责"串"(编排),MCP/胶水代码负责"干"(执行)。 ToolCall 是夹在中间的那张"指令纸条",它本身不是能力,是一种通信约定。

下面逐层拆开讲。


第一层:LLM 和 LangChain——大脑与神经系统

LLM = 大脑:聪明,但健忘、不会动手、不会循环

大模型确实强:能理解、能推理、能判断、能输出文字、甚至能输出 ToolCall。但你仔细想,它有一个致命特性——它是无状态的单次输入输出

你给它一句话,它回你一段话,结束。它不会:

  • 记住你三句话前说过什么(每次请求都是全新会话);
  • 自己判断"这事没干完,我得再来一轮"(它不会自己循环);
  • 真正发起一个 HTTP 请求、查一次数据库(它只输出"我建议调用这个工具"的文本)。

打个比方:LLM 是一个绝顶聪明但严重健忘、还没长手脚的人。你问他问题,他能想明白,但他不会自己去查资料、不会自己把一个复杂任务拆成五步循环干完,干完上一步就把上一步忘了。

LangChain = 神经系统 + 手脚调度

既然大脑这么"残",就得给它配一套神经系统。LangChain 干的就是这件事——在大模型外面包一层代码,把模型零散的能力串成完整流程。它核心做四件事:

1. 编排循环(Agent Runtime)
实现 ReAct 循环:提问 → 模型思考该用哪个工具 → 执行工具 → 把结果丢回模型 → 继续思考……自动多轮迭代。

LLM 只会单次决策,不知道要循环几次;LangChain 控制循环次数、终止条件,防止死循环。

2. 记忆管理(Memory)
把对话历史、任务状态做裁剪、摘要、持久化,解决上下文溢出。

3. RAG 流水线封装
文档加载 → 切分 chunk → 向量化 → 向量库检索 → 组装 Prompt 喂给大模型。这些 IO 和文档处理,大模型干不了,是框架的活。

4. 工具/提示词封装、状态管理
统一封装工具接口,维护 Agent 状态(LangGraph 就是状态图组件),处理模型输出 JSON 解析失败、格式异常等容错。

极简比喻

LLM = 聪明但健忘、没手脚的人;
LangChain = 给他配了个秘书:帮记笔记、排步骤、跑腿查资料、循环推进、处理各种异常。
大脑负责判断,秘书负责工程调度。

关键边界(面试高频)

组件角色在哪运行
LLM推理、决策、生成 ToolCall模型服务端 API
LangChain流程编排、记忆、循环、工具调度、异常处理你的应用后端

注意一句容易被忽略的话:ToolCall 是模型输出的"消息格式",LangChain 并不懂业务思考,它只是解析模型输出、去调用函数、再把结果回传给 LLM。思考永远是 LLM 的活。


第二层:ToolCall 到底是什么?——一个最容易踩的坑

很多人卡在这里:「LLM 不是能通过 ToolCall 调用外部接口吗?那还要 LangChain 干嘛?」

你说得对,LLM 确实能直接输出 ToolCall。但这里有个关键混淆点:模型只负责输出"调用意图",并不真正执行网络请求

一个例子讲透

用户问:"查杭州今天天气。"

第一步,LLM 输出:

{"tool": "get_weather", "args": {"city": "杭州"}}

✅ 这就是 ToolCall,模型完成了思考、决定了调用什么。
❌ 但大模型不会发 HTTP 请求,不会访问天气接口,拿不到返回结果。它只是吐出了一段 JSON 文本。

第二步,谁来干活?

  • 不用 LangChain:你自己写代码——解析这段 JSON → 发起 HTTP 调用 → 拿到天气 → 拼成 Prompt → 再次请求 LLM → 判断要不要继续干 → 自己控制最大轮次防死循环 → 自己处理 JSON 解析报错、工具超时。
  • 用 LangChain:你注册工具描述,框架内部自动完成上面全部胶水逻辑。

两种开发模式对比

裸 API(无框架)——胶水全手写:

resp = llm.chat(messages)
tool_call = parse_json(resp.tool_calls)          # 自己解析
tool_result = http.request(tool_call.name, tool_call.args)  # 自己调用接口
messages.append(tool_result)
resp2 = llm.chat(messages)                        # 再次请求模型
# 还要自己控制循环、容错、状态……

LangChain —— 框架兜底:

agent = create_openai_tools_agent(llm, tools, prompt)
agent_executor.invoke({"input": "查询杭州天气"})
# 内部自动完成解析 → 执行 → 拼接 → 循环 → 终止 → 异常处理

一句话总结这一层

LLM 知道"我该调用什么工具",但不会真正调用;ToolCall 只是它表达意图的语言。LangChain 就是把这套意图翻译成实际动作的运行时。

最大的误区:

❌ 「用了 LangChain 模型才会 ToolCall」
✅ 错。模型原生就支持 ToolCall,LangChain 只是帮你省掉大量胶水代码。


第三层:ToolCall 和 MCP——决策层与执行层

讲到这儿,MCP 的位置就清楚了。它们俩是上下游依赖,不是替代关系

分工一句话

  • ToolCall:大模型说"我要调用 XX 工具,参数是 XX"(决策层,模型输出)。
  • MCP:收到指令,真正去干活,做鉴权、执行、异常捕获,把结果还回大模型(执行层、通信协议)。

ToolCall 是大脑想好要干什么,MCP 是手去完成这件事。

最小伪代码,直观看分工

# ========== 大模型层:只做思考、输出 ToolCall 决策(不执行任何工具)==========
user_query = "帮我查 2025 年杭州 GDP"

# 大模型输出 ToolCall:决定调用哪个工具、传什么参数
tool_call = llm.generate_tool_call(
    user_prompt=user_query,
    available_tools=["query_database", "http_request"]
)
"""
tool_call 只是一段 JSON 决策,不会真正执行:
{
  "tool_name": "query_database",
  "arguments": {"sql": "select gdp from econ where year=2025 and city='杭州'"}
}
"""

# ========== MCP 层:接收 ToolCall,负责真实执行 ==========
# MCP 职责:权限校验、参数校验、调用外部资源、捕获异常、返回结果给大模型
mcp_client = MCPClient()

# 把大模型产出的 tool_call 交给 MCP 执行,模型本身不碰数据库
tool_result = mcp_client.execute(tool_call)

# MCP 把执行结果回传给大模型,模型再整理成自然语言回答
final_answer = llm.generate_answer(user_query, tool_result)
print(final_answer)

为什么要有 MCP?没有它不行吗?

可以没有 MCP——你完全可以自己写代码解析 ToolCall JSON、手写调用逻辑。但代价是:鉴权、工具管理、多模型适配全部自己造轮子。

MCP 的价值在于标准化:它把"工具怎么被发现、怎么被调用、怎么鉴权、怎么返回结果"这套东西做成开放协议。任何模型都能输出 ToolCall,任何工具都能接 MCP,于是模型与工具解耦,消除厂商锁定。你换一个模型,工具层不用动;你换一套工具,模型层不用动。


全景图:四者怎么串起来

把三层合在一起,一次完整的 Agent 调用长这样:

用户提问
   │
   ▼
LangChain 编排层:组装 Prompt + 历史记忆,发给 LLM
   │
   ▼
LLM 思考,输出 ToolCall(一段 JSON 意图)  ← 决策层
   │
   ▼
LangChain 解析 ToolCall,交给 MCP 执行
   │
   ▼
MCP 鉴权 → 调接口/查库 → 拿到结果 ← 执行层
   │
   ▼
LangChain 把结果拼回 messages,再次请求 LLM
   │
   ▼
LLM 看到结果,继续思考:还要再调工具吗?
   │  ├─ 要 → 回到"输出 ToolCall"那步,循环
   │  └─ 不要 → 输出最终答案
   ▼
返回用户

你看,LLM 只在两个节点出现(思考出 ToolCall、看到结果再思考),其余全链条都是 LangChain + MCP 在跑。LLM 是大脑,框架是神经和手脚,缺一不可。


面试速记卡

「LLM、LangChain、ToolCall、MCP 是什么关系?」

它们不在同一层。LLM 是决策层,负责思考、输出 ToolCall;LangChain 是编排层,负责循环、记忆、状态、异常处理;MCP 是执行层协议,负责真正调用工具、鉴权、容错。ToolCall 是 LLM 和执行层之间的通信约定,不是一种"能力"。用了 LangChain 不是 LLM 才有 ToolCall,模型原生就支持,框架只是省胶水代码。

高频追问预判:

  • Q:没有 MCP 可以用 ToolCall 吗?
    A:可以。自己写代码解析 ToolCall JSON、手写调用逻辑。缺点是要自己实现鉴权、工具管理、多模型适配;MCP 把这一套标准化,避免重复开发。

  • Q:MCP 会替代 ToolCall 吗?
    A:不会。MCP 是传输执行协议,ToolCall 是模型输出的指令,二者上下游依赖,不是替代关系。

  • Q:LangChain 能被替代吗?
    A:能,且很常见。它的本质是"胶水框架",你可以用裸 API + 自己写循环,也可以换成别的编排框架。LLM 不能被替代(它是核心能力),MCP 是协议标准(生态绑定),而 LangChain 是工程选择(可换)。


写在最后

记住一个判断框架,以后再看到类似概念就不会乱:

概念一句话定位层级
LLM会想、但健忘没手脚决策层(服务端)
ToolCallLLM 表达意图的 JSON 纸条通信约定
LangChain帮大脑记笔记、排步骤、跑腿、循环编排层(你的后端)
MCP标准化的"手脚执行协议"执行层

大脑负责想,纸条负责传话,秘书负责排活儿,手负责干活——四个东西,四种角色,谁也替代不了谁。

理解到这一层,你就不会再说"LangChain 让模型有了 ToolCall"或"MCP 替代 ToolCall"这种话了。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐