引言

在上一篇文章中,我们初步探讨了 Spring AI MCP(Model Context Protocol)的基础概念,并通过操作本地文件的示例,展示了如何使用 MCP 让 AI 模型理解和处理文件内容。本文将进一步深入,探讨 MCP 的进阶应用 —— 通过 Chat2DB 实现与数据库的自然语言交互。

相比于文件操作,数据库交互往往涉及更复杂的结构和更严格的安全要求。通过 Chat2DB 和 MCP 的结合,我们将展示如何安全、高效地实现 AI 驱动的数据库查询功能。让我们一起看看如何将自然语言查询能力扩展到数据库领域。

什么是 Chat2DB?

Chat2DB 是一个创新的数据库交互方式,它允许我们使用自然语言来查询和操作数据库。通过结合大语言模型(LLM)的能力,Chat2DB 使得与数据库的交互变得更加直观和高效。用户可以用日常语言提问,系统会自动将这些问题转换为相应的数据库查询语句。

MCP (Model Context Protocol) 简介

MCP(Model Context Protocol)是一个专门设计的协议,用于为大语言模型提供数据库访问能力。它的主要特点包括:

  • 提供只读数据库访问接口
  • 允许 LLM 检查数据库架构
  • 支持执行只读查询
  • 确保数据安全性

在 PostgreSQL 场景中,MCP 服务器充当了数据库和 LLM 之间的桥梁,使得 AI 模型能够安全地理解和查询数据库结构。

Spring AI 集成实现

依赖配置

首先,需要在项目中添加必要的依赖:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.experimental</groupId>
    <artifactId>spring-ai-mcp</artifactId>
    <version>0.4.1</version>
</dependency>

模型信息配置

笔者这里使用 deepseek v3 模型,只需要在 application.properties 中添加以下配置:

spring.ai.openai.chat.options.model=deepseek-chat
spring.ai.openai.base-url=https://api.deepseek.com
spring.ai.openai.api-key=sk-XXX

核心配置实现

以下是实现 MCP 客户端和聊天功能的核心代码:

@Bean
public CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilder,
        List<McpFunctionCallback> functionCallbacks, ConfigurableApplicationContext context) {
    return args -> {
        var chatClient = chatClientBuilder
                .defaultFunctions(functionCallbacks.toArray(new McpFunctionCallback[0]))
                .build();
        String question1 = "你能链接我的postgres数据库,然后告诉我这个数据库有多少张表吗?";
        System.out.println("ASSISTANT: " + chatClient.prompt(question1).call().content());

        String question2 = "你能链接我的postgres数据库,然后告诉我这个商品表里面哪个车最贵吗?";
        System.out.println("ASSISTANT: " + chatClient.prompt(question2).call().content());
        context.close();
    };
}

@Bean
public List<McpFunctionCallback> functionCallbacks(McpSyncClient mcpClient) {
    return mcpClient.listTools(null)
            .tools()
            .stream()
            .map(tool -> new McpFunctionCallback(mcpClient, tool))
            .toList();
}

@Bean(destroyMethod = "close")
public McpSyncClient mcpClient() {
    var stdioParams = ServerParameters.builder("npx")
            .args("-y", "@modelcontextprotocol/server-postgres",
                  "postgresql://postgres:lengleng@localhost:5432")
            .build();

    var mcpClient = McpClient.using(new StdioClientTransport(stdioParams))
            .requestTimeout(Duration.ofSeconds(10)).sync();

    var init = mcpClient.initialize();
    System.out.println("MCP Initialized: " + init);
    return mcpClient;
}

业务表如下

测试执行

工作原理

  1. MCP 服务器初始化

    • 通过 McpSyncClient 建立与数据库的连接
    • 配置连接参数和超时设置
    • 初始化 MCP 协议
  2. 功能回调注册

    • 获取可用的数据库工具
    • 将工具转换为功能回调
    • 注册到聊天客户端
  3. 自然语言交互

    • 用户提供自然语言问题
    • Spring AI 处理并转换为数据库查询
    • 通过 MCP 执行查询并返回结果

使用场景

Chat2DB 结合 Spring AI MCP 特别适用于以下场景:

  • 数据分析师快速查询数据
  • 开发人员数据库探索
  • 非技术人员数据库访问
  • 数据库结构审查

安全考虑

在使用 Chat2DB 和 MCP 时,需要注意以下安全事项:

  • MCP 默认只提供只读访问
  • 建议使用专门的只读数据库账户
  • 定期审查访问日志
  • 设置适当的超时限制

执行流程分析

以下是 Spring AI MCP 与数据库交互的详细执行流程:

执行步骤详解

  1. 初始化阶段

    • Spring 应用启动
    • MCP Client 初始化,使用协议版本 2024-11-05
    • 服务器信息:example-servers/postgres v0.1.0
  2. 工具注册阶段

    • 注册 query 工具,用于执行只读 SQL 查询
    • 设置查询超时时间为 10 秒
  3. 数据库交互阶段

    • 执行数据库连接检查
    • 获取数据库表结构信息
    • 执行用户查询并返回结果
  4. 响应处理阶段

    • 将数据库查询结果转换为结构化 JSON
    • AI 模型处理结果并生成自然语言回答
    • 返回格式化的响应给用户

示例查询执行

-- 查询表数量
SELECT COUNT(*) as count FROM information_schema.tables 
WHERE table_schema = 'public';

-- 查询表结构
SELECT column_name, data_type 
FROM information_schema.columns 
WHERE table_name = 'products';

-- 查询商品数据
SELECT id, name, price 
FROM products 
ORDER BY price DESC;

这个执行流程展示了 Spring AI MCP 如何无缝地将自然语言查询转换为数据库操作,并将结果转换回用户友好的格式。整个过程是自动化的,用户无需了解底层的 SQL 查询细节。

总结

Chat2DB 配合 Spring AI MCP 为数据库交互提供了一个革新性的解决方案。通过自然语言处理和安全的协议设计,它既保证了易用性,又确保了数据安全。这种方案特别适合需要频繁数据库查询但希望降低技术门槛的场景。