对程序员和AI小白来说,大模型最迷人的能力之一,就是突破“只会聊文本”的局限,联动数据库、API、文件系统等外部工具。而实现这一切的关键“桥梁”,正是OpenAI在2024年底推出的MCP协议。今天咱们就从基础原理讲到实战代码,把这个让大模型变身“万能调度员”的核心技术彻底讲透。

一、先搞懂:MCP到底是什么?

MCP(Model Context Protocol,模型上下文协议),说白了就是大模型与外部工具之间的“通用通信规范”。它不是复杂的框架,而是一套“对话规则”,专门解决过去大模型调用外部能力时的“碎片化痛点”。

在MCP出现前,开发者想让LLM调用天气API、查订单数据,通常要走三条路:开发专属插件、用函数调用(Function Calling)、搭AI Agent中间层。但这三条路都有个大问题——没有统一标准:A工具的插件没法给B工具用,换个场景就要重新“造轮子”,既耗时又没法实现多工具协同。

而MCP的核心价值,就是提供统一标准协议:符合协议的工具,能以相同方式接入任意支持MCP的大模型;大模型也不用学“方言”,用一套逻辑就能调用所有工具。

给小白举个生活化的例子:

  • 无MCP:就像手机、平板、耳机各用各的接口(Type-C、Micro-USB、Lightning),充电必须找专属充电器,完全不兼容;
  • 有MCP:相当于所有设备统一用USB接口,不管什么设备,插一根线就能用,彻底告别“配件混乱”

二、MCP 的核心设计

MCP 并非单一功能的协议,而是通过四大能力模块,覆盖了大模型调用外部工具的全场景需求:

(1)工具调用(Tools):让大模型 “触发功能”

这是最基础的能力,类似 “函数调用” 的升级版 —— 服务端会提前将自身的核心功能 “暴露” 给大模型,大模型通过调用预设的 “工具函数”,直接触发服务端的操作。例如:调用searchFlightTickets(出发地, 目的地, 日期)查询航班、调用getRealTimeWeather(城市)获取天气、调用querySalesData(月份)调取销售报表,这些函数的参数格式、返回结果结构都由 MCP 统一规定,避免格式混乱。

(2)资源访问(Resources):让大模型 “读取数据”

如果说 “工具调用” 是 “触发动作”,那 “资源访问” 就是 “读取素材”。服务端可以将自身的数据源(如日志文件、数据库、知识库)以 “资源路径” 的形式开放,大模型能像访问本地文件一样直接读取数据,无需依赖 “将数据塞进上下文窗口” 的传统方式。例如:访问/var/log/server/error.log读取服务器错误日志、访问mongodb://user:password@host/db/orders读取订单数据库、访问knowledge_base/product_manual读取产品手册,所有资源的访问路径和权限校验规则都由 MCP 统一标准。

(3)事件推送(Events):让大模型 “被动接收信息”

过去,大模型只能 “主动查询” 外部信息,无法实时获取动态变化(比如数据库数据更新、系统出现告警)。而 MCP 的 “事件推送” 能力,让服务端可以主动向大模型推送实时事件,大模型无需持续查询,就能及时响应变化。例如:当用户下单成功时,订单数据库向大模型推送order_created(订单ID, 金额)事件;当服务器 CPU 使用率超过 90% 时,监控系统向大模型推送server_high_load(服务器IP, 使用率)事件,大模型可以基于这些实时事件触发后续操作(如发送订单通知、自动扩容服务器)。

(4)跨语言兼容(标准协议):让所有开发者都能用上

MCP 采用 JSON-RPC 作为底层通信方式 —— 这是一种轻量级的远程调用协议,基于 JSON 格式传输数据,不依赖任何特定编程语言。无论是用 Python 开发的 LLM 应用、用 Java 开发的数据库服务,还是用 Go 开发的 API 接口,只要遵循 MCP 的 JSON-RPC 规范,就能实现互联互通,极大降低了不同技术栈团队的接入门槛。

三、MCP 的应用场景:让大模型成为 “万能操作系统”

有了 MCP 的统一标准,大模型不再局限于 “文本生成”,而是能像电脑的 “操作系统内核” 一样,调度各类外部能力,落地到更多实际业务场景中:

1. 开发者效率工具:让 AI 帮你写代码、跑测试

过去,开发者需要在代码编辑器、代码仓库(Git)、测试工具、CI/CD(持续集成 / 持续部署)平台之间频繁切换;有了 MCP 后,LLM 可以直接通过 MCP 调用这些工具:比如读取 Git 仓库的代码文件、自动生成单元测试代码、触发 CI/CD 流程(如代码提交后自动运行测试、测试通过后自动部署到服务器),开发者只需用自然语言下达指令(如 “帮我检查这个项目的最新代码,修复其中的语法错误并运行测试”),LLM 就能联动所有工具完成操作。

2. 运维与监控:让 AI 成为 “智能运维助手”

传统运维中,运维人员需要盯着监控面板、手动查询日志、分析故障原因;而 MCP 让 LLM 可以深度参与运维工作:通过 MCP 订阅监控系统的告警事件(如服务器宕机、磁盘空间不足)、直接读取服务器日志文件(无需登录服务器)、调用运维工具执行故障排查(如检查网络连接、重启服务),甚至能基于历史故障数据做根因分析(如 “判断这次数据库卡顿是因为索引缺失还是查询语句优化不足”),大幅减少运维人员的重复劳动。

3. 安全的数据库查询:让 AI “合规地查数据”

很多企业担心 LLM 直接操作数据库会有数据泄露风险,而 MCP 可以作为 “安全代理层”:管理员通过 MCP 设置数据库的访问权限(如 LLM 只能查询某张表、不能修改数据,或只能查询指定用户的脱敏数据),LLM 通过 MCP 发起查询请求时,会自动经过权限校验,确保数据安全。例如,客服人员可以让 LLM “查询用户 ID 为 123 的近 3 个月订单”,LLM 通过 MCP 调用数据库,返回的结果会自动屏蔽用户手机号、身份证号等敏感信息,既提升效率又保障数据安全。

4. 自动化工作流:让 AI 联动工具实现 “流程自动化”

类似 “IFTTT(如果这样,就那样)” 的 AI 升级版,MCP 让 LLM 可以联动多个工具触发自动化流程。例如:当电商平台的 MCP 服务端推送 “用户下单成功” 事件后,LLM 会自动通过 MCP 调用物流 API(生成物流单号)、调用短信 API(向用户发送订单通知)、调用库存管理系统(扣减对应商品的库存),整个流程无需人工干预,由 LLM 基于 MCP 联动所有工具完成。

5. 知识库与文件系统:让 AI “突破上下文窗口限制”

传统 LLM 的上下文窗口有限(如 GPT-4 Turbo 的上下文窗口约为 128k tokens),无法处理超大型文档(如几百页的 PDF 手册、GB 级别的日志文件);而 MCP 让 LLM 可以直接访问外部知识库和文件系统:比如读取本地的 PDF 产品手册、访问云端的行业报告库、查询历史聊天记录文件,LLM 无需将所有内容 “塞进上下文”,而是可以按需读取指定部分,大幅提升处理长文本和海量数据的能力。

四、小结:MCP 的价值 —— 为 AI 生态搭建 “标准化接口”

MCP 本质上是 OpenAI 为大模型与外部系统的交互制定的 “通用语言”,它的核心价值不在于复杂的技术创新,而在于 “标准化” 带来的连锁效应:

  1. 降低开发成本:开发者无需为不同工具重复开发适配层,只需遵循 MCP 标准,就能让工具接入所有支持 MCP 的 LLM,大幅减少重复劳动;
  2. 打通 “信息壁垒”:过去大模型只能依赖训练数据和用户输入的上下文,而 MCP 让大模型能实时访问外部数据库、文件系统、API 接口,真正连接 “真实世界” 的数据与工具;
  3. 推动 AI Agent 生态成熟:AI Agent 的核心是 “自主调用工具解决问题”,而 MCP 的标准化接口,让不同 Agent 可以调用同一套工具,不同工具也能被不同 Agent 复用,为 AI Agent 生态的规模化发展奠定了基础。

五、一个简单的题目

场景

要求实现 MCP client、mcp server、LLM 模型调用。

可以根据用户的自然语言输入,实现汇率转换。

简单起见,输入文件在 root 目录下,用户输入.csv,内容例子如下:

user_input
我想兑换一千人民币为港元,可以兑换多少钱?
我想兑换一万美元为人民币,可以兑换多少人民币?
1.欧元可以兑换多少美元?

输出文件也是 csv。放在根目录。结果输出.csv

金额,货币,目标货币,结果金额
模型选择

很多 ai 都提供了 api 接口,http 交互即可。

我们以 deepseek 为例子。

项目结构

此处选择 springboot + maven

项目结构

│  pom.xml
│  README.md
│  用户输入.csv
│  结果输出.csv
└─src
└─main
├─java
│  └─com
│      └─example
│          └─mcp
│                  Application.java
│                  CsvProcessor.java
│                  LlmClientDeepSeek.java
│                  LlmClientOpenAi.java
│                  McpClient.java
│                  McpServerController.java
│                  RateUtils.java
│
└─resources
application.yaml
测试效果

我们启动 Applicaiton#main()

结果输出.csv 内容如下:

"user_input","amount","from","to","converted"
"我想兑换一千人民币为港元,可以兑换多少钱?","1000.0","CNY","HKD","1070.0"
"我想兑换一万美元到人民币,可以兑换多少人民币?","10000.0","USD","CNY","73000.0"
"1.欧元可以兑换多少日元?","1.0","EUR","JPY","158.7"

日志节选如下:

2025-09-16 18:47:52.015  INFO 20156 --- [           main] com.example.mcp.CsvProcessor             : 处理第2行: 我想兑换一万美元到人民币,可以兑换多少人民币?
2025-09-16 18:47:52.015  INFO 20156 --- [           main] com.example.mcp.LlmClientDeepSeek        : 发送 DeepSeek LLM 请求解析文本: 我想兑换一万美元到人民币,可以兑换多少人民币?
2025-09-16 18:47:56.706  INFO 20156 --- [           main] com.example.mcp.LlmClientDeepSeek        : DeepSeek LLM 解析结果: amount=10000.0, from=USD, to=CNY
2025-09-16 18:47:56.713  INFO 20156 --- [nio-8080-exec-8] com.example.mcp.McpServerController      : MCP Server received request: amount=10000.0, from=USD, to=CNY
2025-09-16 18:47:56.713  INFO 20156 --- [nio-8080-exec-8] com.example.mcp.McpServerController      : MCP Server calculated result: 10000.0 USD -> 73000.0 CNY
2025-09-16 18:47:56.718  INFO 20156 --- [           main] com.example.mcp.CsvProcessor             : 第2行处理完成: 10000.0 USD -> CNY = 73000.0
代码实现

接下来,我们重点介绍一些核心代码。

下面是函数调用流程,本文演示的要更加简单。

pom.xml

基本的项目依赖,主要是 http 依赖

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.14</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.9</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
CsvProcessor.java 文件处理

解析每一行用户的 csv 输入,把结果输出到 csv 文件中。

@Component
public class CsvProcessor {
private static final Logger log = LoggerFactory.getLogger(CsvProcessor.class);
private final LlmClientDeepSeek llmClient;
private final McpClient mcpClient;
public CsvProcessor(LlmClientDeepSeek llmClient, McpClient mcpClient) {
this.llmClient = llmClient;
this.mcpClient = mcpClient;
}
public void processCsv() {
File inputFile = new File("用户输入.csv");
File outputFile = new File("结果输出.csv");
if (!inputFile.exists()) {
log.error("输入文件不存在: {}", inputFile.getAbsolutePath());
return;
}
try (Reader reader = new FileReader(inputFile);
CSVReader csvReader = new CSVReader(reader);
Writer writer = new FileWriter(outputFile);
CSVWriter csvWriter = new CSVWriter(writer)) {
List<String[]> rows = csvReader.readAll();
log.info("CSV行数加载: {}", rows.size());
// 输出表头
List<String[]> result = new ArrayList<>();
result.add(new String[]{"user_input", "amount", "from", "to", "converted"});
// 从第二行开始处理(第一行为列名)
for (int i = 1; i < rows.size(); i++) {
String userInput = rows.get(i)[0];
log.info("处理第{}行: {}", i, userInput);
// 调用 LLM 解析自然语言 -> amount, from, to
ExchangeRequest req = llmClient.askModelFromText(userInput);
if (req == null) {
log.warn("第{}行 LLM 解析失败,跳过", i);
continue;
}
// 调用 MCP Server 计算兑换金额
double converted = mcpClient.convert(req.getAmount(), req.getFrom(), req.getTo());
// 写入输出 CSV
result.add(new String[]{
userInput,
String.valueOf(req.getAmount()),
req.getFrom(),
req.getTo(),
String.valueOf(converted)
});
log.info("第{}行处理完成: {} {} -> {} = {}", i, req.getAmount(), req.getFrom(), req.getTo(), converted);
}
// 写出 CSV
csvWriter.writeAll(result);
log.info("CSV处理完成,输出文件: {}", outputFile.getAbsolutePath());
} catch (Exception e) {
log.error("CSV 处理异常", e);
}
}
}
llmClient 大模型客户端

核心作用:通过用户自然语言,提取出对应的参数。

@Component
public class LlmClientDeepSeek {
private static final Logger log = LoggerFactory.getLogger(LlmClientDeepSeek.class);
private final OkHttpClient client = new OkHttpClient();
private final ObjectMapper mapper = new ObjectMapper();
@Value("${deepseek.api.key}")
private String apiKey;
private final McpClient mcpClient;
public LlmClientDeepSeek(McpClient mcpClient) {
this.mcpClient = mcpClient;
}
/**
* 从自然语言文本解析出 amount/from/to
*/
public CsvProcessor.ExchangeRequest askModelFromText(String text) throws IOException {
log.info("发送 DeepSeek LLM 请求解析文本: {}", text);
// 系统提示
String systemPrompt = "你是一个货币兑换助手。请从用户输入中提取以下信息:\n" +
"- amount: 兑换金额(数字)\n" +
"- from: 源货币(使用标准3字母代码)\n" +
"- to: 目标货币(使用标准3字母代码)\n\n" +
"常见货币映射:\n" +
"人民币/元/CNY → CNY\n" +
"港元/港币/HKD → HKD\n" +
"美元/美金/USD → USD\n" +
"欧元/EUR → EUR\n" +
"日元/JPY → JPY\n" +
"英镑/GBP → GBP\n" +
"澳元/AUD → AUD\n" +
"加元/CAD → CAD\n" +
"新加坡元/SGD → SGD\n" +
"韩元/KRW → KRW";
// 构造请求 JSON(用 Jackson 代替字符串拼接)
ObjectNode root = mapper.createObjectNode();
root.put("model", "deepseek-chat");
// messages
ArrayNode messages = root.putArray("messages");
ObjectNode sys = messages.addObject();
sys.put("role", "system");
sys.put("content", systemPrompt);
ObjectNode usr = messages.addObject();
usr.put("role", "user");
usr.put("content", text);
// tools
ArrayNode tools = root.putArray("tools");
ObjectNode tool = tools.addObject();
tool.put("type", "function");
ObjectNode function = tool.putObject("function");
function.put("name", "convert_currency");
function.put("description", "从文本中提取货币兑换信息");
// function parameters
ObjectNode parameters = function.putObject("parameters");
parameters.put("type", "object");
ObjectNode props = parameters.putObject("properties");
props.putObject("amount").put("type", "number").put("description", "兑换金额");
props.putObject("from").put("type", "string").put("description", "源货币代码(CNY,HKD,USD等)");
props.putObject("to").put("type", "string").put("description", "目标货币代码(CNY,HKD,USD等)");
parameters.putArray("required").add("amount").add("from").add("to");
// tool_choice
ObjectNode toolChoice = root.putObject("tool_choice");
toolChoice.put("type", "function");
toolChoice.putObject("function").put("name", "convert_currency");
String bodyJson = mapper.writeValueAsString(root);
log.debug("DeepSeek 请求体: {}", bodyJson);
RequestBody body = RequestBody.create(bodyJson, MediaType.get("application/json"));
Request request = new Request.Builder()
.url("https://api.deepseek.com/v1/chat/completions")
.addHeader("Authorization", "Bearer " + apiKey)
.addHeader("Content-Type", "application/json")
.post(body)
.build();
try (Response response = client.newCall(request)
.execute()) {
if (!response.isSuccessful()) {
log.error("DeepSeek LLM 请求失败,HTTP {}", response.code());
return null;
}
String resp = response.body().string();
log.debug("DeepSeek LLM 原始响应: {}", resp);
JsonNode node = mapper.readTree(resp);
// 根据 DeepSeek 返回结构取值
JsonNode toolCalls = node.at("/choices/0/message/tool_calls");
if (toolCalls.isMissingNode()) {
toolCalls = node.at("/choices/0/messages/0/tool_calls"); // 兼容另一种格式
}
if (toolCalls.isMissingNode() || !toolCalls.isArray() || toolCalls.size() == 0) {
log.warn("DeepSeek LLM 没有返回 tool_calls,尝试默认值 1/USD/USD");
return new CsvProcessor.ExchangeRequest(1.0, "USD", "USD");
}
JsonNode argumentsNode = toolCalls.get(0).get("function").get("arguments");
if (argumentsNode == null) {
log.warn("DeepSeek LLM tool_call 没有返回 arguments");
return new CsvProcessor.ExchangeRequest(1.0, "USD", "USD");
}
// arguments 可能是字符串,要转成 JSON
JsonNode args;
if (argumentsNode.isTextual()) {
args = mapper.readTree(argumentsNode.asText());
} else {
args = argumentsNode;
}
double amount = args.has("amount") ? args.get("amount").asDouble() : 1.0;
String from = args.has("from") ? args.get("from").asText().toUpperCase() : "USD";
String to = args.has("to") ? args.get("to").asText().toUpperCase() : "USD";
log.info("DeepSeek LLM 解析结果: amount={}, from={}, to={}", amount, from, to);
return new CsvProcessor.ExchangeRequest(amount, from, to);
}
}
}
McpClient 客户端

mcp 客户端的处理逻辑,调用服务端实现转换。

@Component
public class McpClient {
private static final Logger log = LoggerFactory.getLogger(McpClient.class);
private final OkHttpClient client = new OkHttpClient();
public double convert(double amount, String from, String to) throws IOException {
String url = String.format("http://localhost:8080/mcp/convert?amount=%f&from=%s&to=%s",
amount, from, to);
Request request = new Request.Builder().url(url).get().build();
try (Response response = client.newCall(request).execute()) {
String body = response.body().string();
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(body);
return node.get("converted").asDouble();
}
}
}

McpServer 服务端

真实的处理逻辑,这里只是简单的汇率转换

@RestController
@RequestMapping("/mcp")
public class McpServerController {
private static final Logger log = LoggerFactory.getLogger(McpServerController.class);
@GetMapping("/convert")
public Map<String, Object> convert(@RequestParam double amount,
@RequestParam String from,
@RequestParam String to) {
log.info("MCP Server received request: amount={}, from={}, to={}", amount, from, to);
double converted = RateUtils.getRate(from, to) * amount;
log.info("MCP Server calculated result: {} {} -> {} {}", amount, from, converted, to);
Map<String, Object> result = new HashMap<>();
result.put("amount", amount);
result.put("from", from);
result.put("to", to);
result.put("converted", converted);
return result;
}
}

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线科技企业深耕十二载,见证过太多因技术卡位而跃迁的案例。那些率先拥抱 AI 的同事,早已在效率与薪资上形成代际优势,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在大模型的学习中的很多困惑。我们整理出这套 AI 大模型突围资料包

  • ✅ 从零到一的 AI 学习路径图
  • ✅ 大模型调优实战手册(附医疗/金融等大厂真实案例)
  • ✅ 百度/阿里专家闭门录播课
  • ✅ 大模型当下最新行业报告
  • ✅ 真实大厂面试真题
  • ✅ 2025 最新岗位需求图谱

所有资料 ⚡️ ,朋友们如果有需要 《AI大模型入门+进阶学习资源包》下方扫码获取~
在这里插入图片描述

① 全套AI大模型应用开发视频教程

(包含提示工程、RAG、LangChain、Agent、模型微调与部署、DeepSeek等技术点)
在这里插入图片描述

② 大模型系统化学习路线

作为学习AI大模型技术的新手,方向至关重要。 正确的学习路线可以为你节省时间,少走弯路;方向不对,努力白费。这里我给大家准备了一份最科学最系统的学习成长路线图和学习规划,带你从零基础入门到精通!
在这里插入图片描述

③ 大模型学习书籍&文档

学习AI大模型离不开书籍文档,我精选了一系列大模型技术的书籍和学习文档(电子版),它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。
在这里插入图片描述

④ AI大模型最新行业报告

2025最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。
在这里插入图片描述

⑤ 大模型项目实战&配套源码

学以致用,在项目实战中检验和巩固你所学到的知识,同时为你找工作就业和职业发展打下坚实的基础。
在这里插入图片描述

⑥ 大模型大厂面试真题

面试不仅是技术的较量,更需要充分的准备。在你已经掌握了大模型技术之后,就需要开始准备面试,我精心整理了一份大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余

图片

以上资料如何领取?

在这里插入图片描述

为什么大家都在学大模型?

最近科技巨头英特尔宣布裁员2万人,传统岗位不断缩减,但AI相关技术岗疯狂扩招,有3-5年经验,大厂薪资就能给到50K*20薪!

图片

不出1年,“有AI项目经验”将成为投递简历的门槛。

风口之下,与其像“温水煮青蛙”一样坐等被行业淘汰,不如先人一步,掌握AI大模型原理+应用技术+项目实操经验,“顺风”翻盘!
在这里插入图片描述
在这里插入图片描述

这些资料真的有用吗?

这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。

资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。
在这里插入图片描述
在这里插入图片描述

以上全套大模型资料如何领取?

在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐