智能问答系统

基于FastMCP和Milvus构建的智能问答系统,集成知识库检索(RAG)和Web搜索功能,适用于技术支持和信息查询场景。

  • by leichangqing
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 leichangqing/mcp-agentic-rag

使用说明

MCP Agentic RAG 系统

基于 FastMCP 和 Milvus 构建的智能问答系统,集成了知识库检索(RAG)和 Web 搜索功能。

📋 目录


🏗️ 技术架构

核心技术栈

┌─────────────────────────────────────────────────────────┐
│                     FastAPI 服务层                       │
├─────────────────────────────────────────────────────────┤
│  FastMCP Server  │  /mcp 端点  │  自动工具路由          │
├─────────────────────────────────────────────────────────┤
│         工具层 (Tool Layer)                              │
│  ┌──────────────────┐      ┌──────────────────────┐   │
│  │ Python FAQ Tool  │      │ Web Search Tool      │   │
│  │   (RAG 检索)     │      │  (Firecrawl API)     │   │
│  └──────────────────┘      └──────────────────────┘   │
├─────────────────────────────────────────────────────────┤
│                   AI 服务层                              │
│  ┌──────────────────┐      ┌──────────────────────┐   │
│  │ Xinference       │      │ Xinference           │   │
│  │ Embedding Model  │      │ LLM (Qwen2.5-14B)    │   │
│  │ (bge-large-zh)   │      │                      │   │
│  └──────────────────┘      └──────────────────────┘   │
├─────────────────────────────────────────────────────────┤
│                 向量数据库层                             │
│              Milvus (分布式向量数据库)                   │
│         IVF_FLAT 索引 + Inner Product 距离              │
└─────────────────────────────────────────────────────────┘

技术组件

组件 技术 版本 说明
Web 框架 FastAPI >=0.115.0 高性能异步 Web 框架
MCP 服务器 FastMCP >=0.5.0 Model Context Protocol 服务器框架
向量数据库 Milvus 2.x 分布式向量数据库,支持大规模检索
Embedding 模型 bge-large-zh-v1.5 - 中文向量化模型(1024 维)
大语言模型 Qwen2.5-14B-Instruct - 阿里千问大模型
Web 搜索 Firecrawl API - 智能网页抓取与搜索服务
Python 客户端 pymilvus >=2.6.0 Milvus Python SDK

✨ 功能说明

1. 智能路由系统

系统采用两级智能路由机制:

用户查询
    ↓
检查 FAQ 知识库
    ↓
有匹配 ────→ Python FAQ Tool ────→ LLM 生成答案
    ↓
无匹配 ────→ Web Search Tool ────→ 返回搜索结果

2. Python FAQ 检索工具

功能特性:

  • 🔍 向量语义检索:使用 Milvus 向量数据库进行语义相似度匹配
  • 🎯 智能阈值过滤:相似度 >= 0.5 才返回结果
  • 🤖 LLM 增强回答:检索结果通过 Qwen2.5-14B 模型生成自然语言答案
  • 📚 知识库内容:预置 10 个常见 Python 问题(列表/元组、装饰器、GIL、魔术方法等)

技术实现:

1. 查询向量化:使用 bge-large-zh-v1.5 将用户问题转换为 1024 维向量
2. 向量检索:在 Milvus 中使用 Inner Product (IP) 距离计算相似度
3. 结果过滤:只返回相似度 >= 0.5 的前 3 条结果
4. LLM 生成:将检索上下文和问题发送给 Qwen2.5-14B 生成答案

3. Web 搜索工具

功能特性:

  • 🌐 实时 Web 搜索:当知识库无法回答时,自动调用 Firecrawl API
  • 📄 智能网页解析:自动提取网页标题、URL 和 Markdown 格式内容
  • 🇨🇳 中文友好输出:搜索结果以中文格式展示(标题、网址)
  • 🔗 多源信息:返回多个搜索结果供用户参考

输出格式:

标题:Polars — DataFrames for the new era
网址:https://pola.rs/

[Markdown 格式的网页内容]

🔧 环境配置

1. 创建 .env 文件

# Milvus 配置
MILVUS_HOST=
MILVUS_PORT=19530
MILVUS_USER=root
MILVUS_PASSWORD=

# Xinference LLM 配置
LLM_API_BASE=http://127.0.0.1:9997/v1
LLM_MODEL=Qwen2.5-14B-Instruct
LLM_API_KEY=sk-
LLM_TEMPERATURE=0.1
LLM_MAX_TOKENS=1000
LLM_TIMEOUT=60

# Xinference Embedding 配置
EMBEDDING_API_BASE=http://127.0.0.1:9997/v1
EMBEDDING_MODEL=bge-large-zh-v1.5
EMBEDDING_API_KEY=sk-

# Firecrawl API 配置
FIRECRAWL_API_KEY=fc-9c17402e585b4dd28d7a792eb4232da9

2. 系统要求

  • Python >= 3.8
  • Milvus 服务器(已部署)
  • Xinference 服务器(已部署 LLM 和 Embedding 模型)
  • Firecrawl API 密钥

📦 安装部署

1. 克隆项目

git clone <repository_url>
cd mcp-agentic-rag

2. 安装依赖

pip install -r requirements.txt

3. 配置环境变量

复制并编辑 .env 文件(参考上面的环境配置)

4. 启动服务

python mcp_server.py

服务将在 http://0.0.0.0:8080 启动


📖 使用说明

方法 1:直接调用 /mcp 端点

# Python FAQ 查询(中文)
curl -X POST http://127.0.0.1:8080/mcp \
    -H "Content-Type: application/json" \
    -d '{
      "messages": [
        {
          "role": "user",
          "content": "Python 中的 GIL 是什么?"
        }
      ]
    }'

# Web 搜索查询(英文)
curl -X POST http://127.0.0.1:8080/mcp \
    -H "Content-Type: application/json" \
    -d '{
      "messages": [
        {
          "role": "user",
          "content": "What is the new Polars DataFrame library?"
        }
      ]
    }'

方法 2:通过 MCP 客户端调用工具

Python FAQ Tool

{
  "tool": "python_faq_retrieval_tool",
  "arguments": {
    "query": "什么是 Python 装饰器?"
  }
}

Web Search Tool

{
  "tool": "firecrawl_web_search_tool",
  "arguments": {
    "query": "latest Python features 2024"
  }
}

🔌 API 接口

1. /mcp 端点(智能路由)

请求格式:

{
  "messages": [
    {
      "role": "user",
      "content": "用户问题"
    }
  ]
}

响应格式:

{
  "messages": [
    {
      "role": "assistant",
      "tool_calls": [
        {
          "id": "call_xxxxx",
          "type": "function",
          "function": {
            "name": "python_faq_retrieval_tool",
            "arguments": "{\"query\": \"用户问题\"}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "tool_call_id": "call_xxxxx",
      "name": "python_faq_retrieval_tool",
      "content": "生成的答案内容"
    }
  ]
}

2. /mcp-server 端点(FastMCP 工具)

标准 MCP 协议端点,支持工具列表查询和直接调用。


📁 项目结构

mcp-agentic-rag2/
├── mcp_server.py           # 主服务器文件(FastAPI + FastMCP)
├── rag_app.py              # RAG 引擎(Milvus + Xinference)
├── requirements.txt        # Python 依赖包
├── .env                    # 环境配置文件
└── README.md              # 项目文档

核心文件说明

mcp_server.py

  • FastAPI 应用初始化
  • FastMCP 服务器配置
  • 工具注册(FAQ Tool、Web Search Tool)
  • /mcp 端点智能路由逻辑
  • Xinference LLM 客户端

rag_app.py

  • FAQEngine 类:向量检索引擎
  • XinferenceEmbedding 类:向量化客户端
  • Milvus 连接和 Collection 管理
  • 向量检索和相似度过滤

🚀 执行流程

场景 1:FAQ 知识库命中

┌──────────────────┐
│ 用户查询:       │
│ "Python 中的     │
│  GIL 是什么?"   │
└────────┬─────────┘
         │
         ↓
┌────────────────────────────────────┐
│ 1. 向量化查询                      │
│    bge-large-zh-v1.5              │
│    → 1024 维向量                  │
└────────┬───────────────────────────┘
         │
         ↓
┌────────────────────────────────────┐
│ 2. Milvus 向量检索                │
│    - Collection: python_faq_cn    │
│    - 相似度阈值: 0.5              │
│    - Top K: 3                     │
└────────┬───────────────────────────┘
         │
         ↓ (匹配成功)
┌────────────────────────────────────┐
│ 3. 调用 python_faq_retrieval_tool │
│    - 检索到相关上下文              │
└────────┬───────────────────────────┘
         │
         ↓
┌────────────────────────────────────┐
│ 4. LLM 生成答案                    │
│    Qwen2.5-14B-Instruct           │
│    - 系统提示:中文回答            │
│    - 输入:问题 + 上下文           │
└────────┬───────────────────────────┘
         │
         ↓
┌────────────────────────────────────┐
│ 5. 返回中文答案                    │
│    "GIL 是一个互斥锁..."          │
└────────────────────────────────────┘

场景 2:知识库未命中,触发 Web 搜索

┌──────────────────┐
│ 用户查询:       │
│ "What is the     │
│  Polars library?"│
└────────┬─────────┘
         │
         ↓
┌────────────────────────────────────┐
│ 1. 向量化查询                      │
│    bge-large-zh-v1.5              │
└────────┬───────────────────────────┘
         │
         ↓
┌────────────────────────────────────┐
│ 2. Milvus 向量检索                │
│    - 无匹配结果 (< 0.5)           │
└────────┬───────────────────────────┘
         │
         ↓ (无匹配)
┌────────────────────────────────────┐
│ 3. 调用 firecrawl_web_search_tool │
│    - Firecrawl API 搜索           │
└────────┬───────────────────────────┘
         │
         ↓
┌────────────────────────────────────┐
│ 4. 解析搜索结果                    │
│    - 提取标题、URL、内容          │
│    - 格式化为中文输出              │
└────────┬───────────────────────────┘
         │
         ↓
┌────────────────────────────────────┐
│ 5. 返回搜索结果                    │
│    标题:Polars — DataFrames...   │
│    网址:https://pola.rs/         │
│    [网页内容]                      │
└────────────────────────────────────┘

🔍 技术细节

Milvus Collection 配置

Collection Schema:
- id: VARCHAR(100) [Primary Key]
- context: VARCHAR(65535) [FAQ 文本]
- vector: FLOAT_VECTOR(1024) [向量]

Index:
- Type: IVF_FLAT
- Metric: IP (Inner Product)
- Params: {"nlist": 128}

Search Params:
- Metric: IP
- Params: {"nprobe": 10}
- Top K: 3
- Score Threshold: 0.5

向量检索原理

  1. 向量化:用户查询 → bge-large-zh-v1.5 → 1024 维向量
  2. 相似度计算:使用 Inner Product (IP) 计算查询向量与库中向量的相似度
  3. 排序与过滤:按相似度排序,只返回 >= 0.5 的结果
  4. 上下文提取:获取匹配文档的原始文本作为上下文

📝 常见问题

Q1: 如何添加新的 FAQ 内容?

编辑 rag_app.py 中的 PYTHON_FAQ_TEXT,然后:

  1. 修改 mcp_server.py 中的 COLLECTION_NAME(或删除旧 collection)
  2. 重启服务,系统会自动创建新 collection 并导入数据

Q2: 如何调整检索灵活度?

修改 rag_app.py 中的 answer_question 方法:

  • score_threshold:降低阈值(如 0.3)可增加召回,但可能降低精度
  • top_k:增加返回结果数量

Q3: 如何更换 LLM 模型?

修改 .env 文件中的 LLM_MODEL 为其他 Xinference 支持的模型。


📄 参考

Milvus LLM之RAG实战(五十九)| 基于MCP构建Agentic RAG教程

📄 许可证

MIT License


👥 贡献

欢迎提交 Issue 和 Pull Request!


📮 联系方式

如有问题,请通过 GitHub Issues 联系。