模型上下文协议MCP

Anthropic(Claude 模型的母公司)  推出了模型上下文协议 MCP,该协议旨在统一大型语言模型(LLM)与外部数据源和工具之间的通信协议。

MCP 主要是为了解决当前 AI 模型因数据孤岛限制,无法充分发挥潜力的难题,MCP 使得 AI 应用能够安全地访问和操作本地及远程数据,为 AI 应用提供了连接万物的接口。

MCP架构

DeepSeek 求职助手实战_DeepSeek

当大模型选择了工具之后,需要有一个工具调用程序,去实际的进行工具的调用,例如通过 Rest API 访问墨迹天气获取天气预报等等。

DeepSeek 求职助手实战_DeepSeek_02

DeepSeek 求职助手实战_DeepSeek_03

MCP 把工具调用程序做成了一个 C-S 架构,工具的实际调用由 MCP Server 来完成。

DeepSeek 求职助手实战_DeepSeek_04

DeepSeek 求职助手实战_DeepSeek_05

当大模型选择了合适的能力后,MCP Hosts 会调用 MCP Cient 与 MCP Server 进行通信,由 MCP Server 调用工具或者读取资源后,反馈给 MCP Client,然后再由 MCP Hosts 反馈给大模型,由大模型判断是否能解决用户的问题。如果解决了,则会生成自然语言响应,最终由 MCP Hosts 将响应展示给用户。

配置MCP Server

演示一个通过  PostgreSQL MCP Server  使 DeepSeek 能够基于 PostgreSQL 中的数据来回答问题。MCP Server 支持 NodeJS 和 python 两种语言开发,本次案例使用的是 MCP 官方提供的  PostgreSQL MCP Server,其开发语言是 NodeJS ,因此大家需要根据自己的操作系统安装好 NodeJS 。Windows 用户可以点击该链接,下载安装。

DeepSeek 求职助手实战_DeepSeek_06

创建数据库表

-- 创建数据库
CREATE DATABASE achievement;-- 连接到新创建的数据库
\c achievement;-- 创建用户信息 users 表
CREATE TABLE users (user_id SERIAL PRIMARY KEY,name VARCHAR(50) NOT NULL,email VARCHAR(100) UNIQUE NOT NULL
);-- 创建绩效得分 score 表
CREATE TABLE score (score_id SERIAL PRIMARY KEY,score DECIMAL(10, 2) NOT NULL,user_id INT REFERENCES users(user_id)
);-- 插入示例数据
INSERT INTO users (name, email) VALUES
('张三', 'zs@example.com'),
('李四', 'ls@example.com'),
('王五', 'ww@example.com');INSERT INTO score (score, user_id) VALUES
(87.75, 1),
(97.50, 2),
(93.25, 3);

DeepSeek 求职助手实战_DeepSeek_07

修改MCP配置文件

{"mcpServers": {"postgres": {"command": "node","args": ["D:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npx-cli.js","-y","@modelcontextprotocol/server-postgres","postgresql://postgres:postgres@<你的postgres所在的服务器的IP>:5432/achievement"]}}
}

完成配置后,会在左侧看到已连接的 MCP Server,并且会列出支持的 Tools 和 Resources。

DeepSeek 求职助手实战_DeepSeek_08

首先,我们提问“数据库中有哪些表?

DeepSeek 求职助手实战_DeepSeek_09

尝试一个难一点的案例,提问“张三,李四,王五的绩效谁高?”在我们的数据库中有 users 和 score 两张表,users 存储了人员姓名和邮箱信息,score 表存储了人员的绩效得分,查询绩效分时需要使用 users 表的主键去查询,因此这是一个两个表联合查询的案例。输出结果如下:

DeepSeek 求职助手实战_DeepSeek_10

,DeepSeek 一开始直接尝试在 score 表中,用 name 字段去查询绩效,结果发现表中没有 name 字段,因此就开始获取 score 表的表结构。之后又查出了 users 表的数据,最后来了一个两个表的联合查询,得到了正确结果。