20251231_153417_大语言模型实战(九)——从零到一:搭建基于_MCP_的_RA

1. 引言

在这个教程中,我将向您展示如何搭建一个完整的 RAG(检索增强生成) 系统,使用 MCP(Model Context Protocol) 协议和 通义千问 LLM 模型。通过这个项目,您将深入理解向量检索、LLM 集成以及 MCP 协议的实际应用。

1.1 什么是 RAG?

RAG 是 Retrieval-Augmented Generation 的缩写,它结合了两个关键能力:

  • 检索(Retrieval):从知识库中查找相关的信息
  • 生成(Generation):使用 LLM 根据检索的信息生成回答

RAG 相比纯 LLM 的优势:

  • ✅ 可以处理模型未见过的最新信息
  • ✅ 回答基于真实数据,降低幻觉风险
  • ✅ 支持添加自定义知识库
  • ✅ 更精准和可信的回答

1.2 什么是 MCP?

MCP 是一个标准化协议,允许应用与 LLM 模型进行安全的交互。通过 MCP,我们可以:

  • 定义自定义工具供 LLM 调用
  • 实现客户端-服务器架构
  • 标准化人类与 AI 的交互流程

1.3 项目架构概览

┌─────────────────┐                    ┌──────────────────┐│  LLM Client     │  ←→ MCP Protocol ←→ │  MCP Server      ││ (通义千问 API)   │                    │ (文档索引/检索)   │└─────────────────┘                    └──────────────────┘        ↓                                        ↓    用户查询                          FAISS向量数据库

2. 环境准备

2.1 系统要求

  • 操作系统:Linux/Mac/Windows
  • Python 版本:Python 3.8+
  • 包管理器:Conda(推荐)或 pip

2.2 安装 Conda

如果还未安装 Conda,请从 Anaconda 官网 下载并安装。

2.3 创建虚拟环境

# 创建名为 mcp 的 conda 环境conda create -n mcp python=3.10# 激活环境conda activate mcp

2.4 安装核心依赖

# 安装必要的 Python 包pip install faiss-cpu mcp openai python-dotenv

依赖说明:

版本用途
faiss-cpu≥1.10.0向量索引和相似度搜索
mcp≥1.6.0MCP 协议支持
openai≥1.75.0OpenAI 兼容 API 客户端
python-dotenv≥1.1.0环境变量管理

3. API 密钥配置

3.1 获取阿里云 API Key

  1. 访问 阿里云 DashScope 官网
  2. 登录或注册账户
  3. 创建 API Key
  4. 复制您的 API Key

3.2 配置环境变量

创建 .env 文件,配置 API 密钥:

# 文件路径:/home/swpucwf/llm-study/.env# 通义千问 API 配置QWEN_API_KEY=your-api-key-hereQWEN_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1# 阿里百炼嵌入模型配置DASHSCOPE_API_KEY=your-api-key-here  # 通常与 QWEN_API_KEY 相同

注意:通常 QWEN_API_KEYDASHSCOPE_API_KEY 可以使用同一个 API Key。

3.3 验证配置

测试是否能正确加载环境变量python -c “from dotenv import load_dotenvimport osload_dotenv()print(‘QWEN_API_KEY:’, ‘OK’ if os.getenv(‘QWEN_API_KEY’) else ‘Missing’)print(‘DASHSCOPE_API_KEY:’, ‘OK’ if os.getenv(‘DASHSCOPE_API_KEY’) else ‘Missing’)”


4. 项目结构

4.1 项目文件树

02-mcp-rag/├── rag-server/│   ├── server-ali.py          # 📌 Server 主程序(使用阿里百炼)│   ├── pyproject.toml│   └── uv.lock├── rag-client/│   ├── client-qwen-ali.py     # 📌 Client 主程序(推荐)│   ├── client-qwen-ali-optimized.py  # 性能优化版│   ├── pyproject.toml│   └── uv.lock├── start-server.sh            # Server 启动脚本├── start-client.sh            # Client 启动脚本├── RUN_GUIDE.md               # 快速启动指南└── BLOG_MCP_RAG_TUTORIAL.md   # 本文件

4.2 核心文件说明

4.2.1 Server 端:server-ali.py

Server 负责:

  • 维护文档的向量索引
  • 提供检索工具给 Client
  • 使用 FAISS 进行高效的相似度搜索
4.2.2 Client 端:client-qwen-ali.py

Client 负责:

  • • 与用户交互,获取查询
  • • 调用 Server 的检索工具
  • • 与通义千问 LLM 通信
  • • 生成最终的回答

5. Server 端实现详解

5.1 Server 核心代码

# server-ali.pyfrom fastmcp import mcpimport numpy as npimport faissfrom openai import OpenAIclassRagServer:    def__init__(self):        # 向量存储        self._index = None        self._docs = []                # 初始化嵌入模型客户端        self.client = OpenAI(            api_key=os.getenv("DASHSCOPE_API_KEY"),            base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"        )        asyncdefembed_text(self, texts: List[str]) -> np.ndarray:        """使用阿里百炼模型生成文本嵌入向量"""        resp = self.client.embeddings.create(            model="text-embedding-v4",            input=texts,            dimensions=1536        )        return np.array([d.embedding for d in resp.data], dtype='float32')        @mcp.tool()    asyncdefindex_docs(self, docs: List[str]) -> str:        """索引文档到向量库中"""        self._docs = docs        embeddings = awaitself.embed_text(docs)                # 创建 FAISS 索引        dimension = embeddings.shape[1]        self._index = faiss.IndexFlatL2(dimension)        self._index.add(embeddings)                returnf"✅ 已索引 {len(docs)} 篇文档"        @mcp.tool()    asyncdefretrieve_docs(self, query: str, top_k: int = 3) -> str:        """检索最相关的文档"""        query_embedding = awaitself.embed_text([query])        distances, indices = self._index.search(query_embedding, top_k)                results = []        for i, idx inenumerate(indices[0]):            if idx < len(self._docs):                results.append(f"[{i}] {self._docs[idx]}")                return"\n".join(results)
```![](http://cdn.zhipoai.cn/a67d7e3c.jpg)

### 5.2 关键概念详解

#### 5.2.1 文本嵌入(Embedding)

嵌入是将文本转换为数值向量的过程:

```plaintext
文本: "糖尿病的症状"     ↓ (文本嵌入模型)向量: [0.23, 0.45, -0.12, ..., 0.89]  (1536 维)

为什么需要嵌入?

  • 计算机可以计算向量的相似度
  • 相似的文本会有接近的向量
  • 可以进行快速的向量搜索
5.2.2 FAISS 索引

FAISS(Facebook AI Similarity Search)是高效的向量搜索库:

# IndexFlatL2:使用欧几里得距离(L2)进行精确搜索index = faiss.IndexFlatL2(1536)  # 1536 维向量# 添加向量index.add(embeddings)# 搜索相似向量distances, indices = index.search(query_vector, top_k=3)

FAISS 的优势:

  • ✅ 处理百万级向量无压力
  • ✅ GPU 加速支持
  • ✅ 多种搜索算法(精确、近似等)

6. Client 端实现详解

6.1 Client 核心代码

# client-qwen-ali.pyfrom mcp import ClientSessionfrom mcp.client.stdio import stdio_client, StdioServerParametersfrom openai import OpenAIclassRagClient:    def__init__(self):        self.session = None        self.client = OpenAI(            api_key=os.getenv("QWEN_API_KEY"),            base_url=os.getenv("QWEN_BASE_URL")        )        asyncdefconnect(self, server_script: str):        """建立 MCP 连接"""        params = StdioServerParameters(            command=sys.executable,            args=[server_script],        )                transport = stdio_client(params)        self.stdio, self.write = await transport.__aenter__()        self.session = await ClientSession(            self.stdio,             self.write        ).__aenter__()        awaitself.session.initialize()        asyncdefquery(self, q: str):        """执行 RAG 查询流程"""        # 步骤 1:检索相关文档        result = awaitself.session.call_tool(            "retrieve_docs",            {"query": q, "top_k": 3}        )                # 步骤 2:使用 LLM 生成回答        response = self.client.chat.completions.create(            model="qwen-plus",            messages=[                {                    "role": "system",                    "content": "你是一个专业的医学助手..."                },                {                    "role": "user",                    "content": f"问题:{q}\n\n相关文档:\n{result}"                }            ]        )                return response.choices[0].message.content

6.2 RAG 查询流程


7. 快速启动指南

7.1 启动 Server

第一个终端中:

# 激活环境conda activate mcp# 进入项目目录cd /home/swpucwf/llm-study/mcp-demo/mcp-in-action-master/02-mcp-rag/rag-server# 启动 Serverpython server-ali.py

预期输出:

load_dotenv

Server 启动后会等待 Client 连接。

7.2 启动 Client

第二个终端中:

# 激活环境conda activate mcp# 进入项目目录cd /home/swpucwf/llm-study/mcp-demo/mcp-in-action-master/02-mcp-rag/rag-client# 启动 Clientpython client-qwen-ali.py ../rag-server/server-ali.py

预期输出:

============================================================🚀 启动 RAG 系统(通义千问 + 阿里百炼)============================================================📡 正在连接到 RAG Server...✅ 可用工具: ['index_docs', 'retrieve_docs']✅ 系统连接成功📚 正在索引医学文档库...✅ 已索引 6 篇文档,总文档数:6============================================================💬 开始对话(输入 '退出' 结束)============================================================❓ 请输入您要查询的医学问题:>
```![](http://cdn.zhipoai.cn/654409b6.jpg)

### 7.3 使用启动脚本(可选)

也可以使用提供的启动脚本:

```plaintext
# Serverbash /home/swpucwf/llm-study/mcp-demo/mcp-in-action-master/02-mcp-rag/start-server.sh# Clientbash /home/swpucwf/llm-study/mcp-demo/mcp-in-action-master/02-mcp-rag/start-client.sh
```![](http://cdn.zhipoai.cn/3b50ae5d.jpg)

---

8. 交互示例
-------

![](http://cdn.zhipoai.cn/9cf72bbc.jpg)

### 8.1 基本查询

### 8.2 支持的输入类型

* • ✅ **中文输入**:`糖尿病的症状`
* • ✅ **英文输入**:`What is diabetes`
* • ✅ **混合输入**:`diabetes 症状`
* • ✅ **退出命令**:`退出` / `exit` / `quit`

---

9. 深入理解 MCP 协议
--------------

### 9.1 MCP 的客户端-服务器模型

```plaintext
┌─────────────────────────────────────────────────────┐│  Client(CLI 应用)                                  ││  ┌──────────────────────────────────────────────┐   ││  │  使用 ClientSession 与 Server 通信           │   ││  │  - 列出可用工具                              │   ││  │  - 调用工具                                  │   ││  │  - 处理响应                                  │   ││  └──────────────────────────────────────────────┘   │└─────────────────────────────────────────────────────┘                      ↕ (stdio)┌─────────────────────────────────────────────────────┐│  Server(MCP 服务进程)                              ││  ┌──────────────────────────────────────────────┐   ││  │  使用 @mcp.tool() 装饰器定义工具             │   ││  │  - index_docs:索引文档                      │   ││  │  - retrieve_docs:检索文档                   │   ││  └──────────────────────────────────────────────┘   │└─────────────────────────────────────────────────────┘

9.2 @mcp.tool() 装饰器详解

@mcp.tool()async def retrieve_docs(query: str, top_k: int = 3) -> str:    """检索最相关的文档        这个装饰器让函数变成一个可被 LLM 调用的工具。        参数:        query: 查询文本        top_k: 返回的文档数        返回:        检索到的文档字符串    """    # 实现...

装饰器的作用:

  • 自动注册工具到 MCP Server
  • 解析函数签名生成工具定义
  • 处理客户端的工具调用请求

9.3 工具调用流程

Client 端:  1. 解析用户输入  2. 调用 session.call_tool("retrieve_docs", {...})  3. 等待响应MCP 通信:  {    "jsonrpc": "2.0",    "id": 1,    "method": "tools/call",    "params": {      "name": "retrieve_docs",      "arguments": {        "query": "糖尿病",        "top_k": 3      }    }  }Server 端:  1. 接收工具调用请求  2. 验证参数  3. 执行 retrieve_docs 函数  4. 返回结果MCP 响应:  {    "jsonrpc": "2.0",    "id": 1,    "result": {      "content": [{        "type": "text",        "text": "[0] 糖尿病是一种慢性代谢性疾病..."      }]    }  }

10. 关键技术点总结

10.1 向量相似度搜索

# 原理:使用向量距离度量相似度距离越小 → 相似度越高query_vector = [0.1, 0.2, 0.3, ...]doc1_vector = [0.1, 0.2, 0.4, ...]  # 距离小 → 相关性高doc2_vector = [0.8, 0.7, 0.2, ...]  # 距离大 → 相关性低

10.2 异步编程

# 使用 async/await 进行非阻塞 I/Oasync def query(self, q: str):    # 异步调用工具(不阻塞)    result = await self.session.call_tool(...)    # 异步调用 API(不阻塞)    response = await self.client.chat.completions.create(...)

10.3 中文输入处理

# 直接使用 input() 函数处理中文query = input("> ")  # 支持中文输入# 关键:避免在线程池中运行 input()# ✅ 正确:query = input("> ")# ❌ 错误:query = await loop.run_in_executor(None, input, "> ")

如何学习大模型 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大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。

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

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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值