ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

大模型之Spring AI实战系列(二十二):Spring AI + MCP + SQLite 数据库实战指南(TaoToken 统一 Key 接入版)

大模型之Spring AI实战系列(二十二):Spring AI + MCP + SQLite 数据库实战指南(TaoToken 统一 Key 接入版) 1. 为什么要在 Spring AI 里把 SQLite 接成 MCP 工具先说清楚这件事到底解决什么问题。你手上有一个本地 SQLite 文件里面存着订单、产品、日志之类的结构化数据。传统做法是写一堆 DAO 和 Service再写死几个查询接口。但如果你想让大模型自己决定查哪张表、用什么条件、怎么聚合写死接口就不够了。MCPModel Context Protocol的价值就在这里它把数据库能力包装成一组标准工具模型在对话过程中按需调用你不需要为每个问题提前写好 SQL。Spring AI 从 1.0 版本开始正式支持 MCP 客户端通过spring-ai-starter-mcp-client这个 starter可以把任意符合 MCP 协议的 Server 挂载成 ChatClient 的工具集。SQLite 这边社区已经有现成的mcp-server-sqlite用uvx一条命令就能拉起来。两者一拼就得到一条自然语言 → 工具调用 → SQL 执行 → 自然语言回答的完整链路。这套组合适合谁我总结了三类一是本地做 AI 应用原型的开发者不想为了查个数据就搭一套微服务二是做数据分析助手的产品同学希望用户用大白话问数三是教学场景MCP 的调用过程非常直观适合讲清楚工具调用到底怎么发生。需要提前说明的是本文的模型调用统一走 TaoToken 的 OpenAI 兼容接口一个 Key 就能覆盖对话模型省去多平台注册的麻烦。下面从环境准备一路走到跑通验证每一步都给可复制的命令和配置。2. TaoToken 前置准备一个 Key 打通模型调用在写 Spring AI 代码之前先把模型侧的凭证准备好。TaoToken 提供 OpenAI 兼容的 API所以 Spring AI 的spring-ai-starter-model-openai可以直接对接不需要改任何客户端代码只改 base-url 和 api-key 两个配置项。第一步打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册账号。注册流程很常规邮箱加密码即可这里不展开。第二步进入控制台创建 API Key。地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 在 API Keys 页面点新建复制生成的 Key。这个 Key 只显示一次建议立刻存到密码管理器里。第三步确认你要用的模型 ID。在模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 可以先手动试一下看看当前可用的模型列表。常见的对话模型 ID 类似gpt-4o-mini、claude-3-5-sonnet这类命名具体以控制台展示为准。选一个支持工具调用function calling / tool use的模型这点很关键因为 MCP 的本质就是工具调用不支持工具的模型接上去也调不动。第四步把 Key 和 base-url 写进环境变量。API 地址是 https://taotoken.net/api 注意这个地址不带任何查询参数直接作为 base-url 使用。在 Linux/macOS 下export TAOTOKEN_API_KEYsk-你的Key export TAOTOKEN_BASE_URLhttps://taotoken.net/apiWindows PowerShell$env:TAOTOKEN_API_KEYsk-你的Key $env:TAOTOKEN_BASE_URLhttps://taotoken.net/api这里有个容易踩的坑Spring AI 的 OpenAI starter 会在 base-url 后面自动拼/v1/chat/completions之类的路径。所以 base-url 到底写https://taotoken.net/api还是https://taotoken.net/api/v1取决于服务端的路由设计。实测下来写https://taotoken.net/api即可starter 会补全后续路径。如果你写成了带/v1的可能会变成/v1/v1/...导致 404。遇到 404 先检查这里。另外如果你打算长期做编码类、Agent 类项目可以了解一下 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 它针对高频调用场景做了额度优化比按量计费更划算。本文的示例用按量 Key 就够了。3. 可复制配置Maven 依赖、application.yml 与 MCP Server 启动这一节是全文的核心所有配置都给完整片段你直接抄进项目即可。3.1 Maven 依赖新建一个 Spring Boot 3.x 项目JDK 17。pom.xml 里加两个关键依赖并用 BOM 统一版本dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.0.0/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-client/artifactId /dependency /dependenciesspring-ai-starter-model-openai负责模型调用spring-ai-starter-mcp-client负责 MCP 客户端和 STDIO 传输。两个都引入后Spring AI 会自动装配McpSyncClient相关的 Bean。3.2 application.ymlserver: port: 8000 spring: application: name: spring-ai-mcp-sqlite main: web-application-type: none ai: openai: api-key: ${TAOTOKEN_API_KEY} base-url: ${TAOTOKEN_BASE_URL} chat: options: model: gpt-4o-mini temperature: 0.2web-application-type: none是因为这个示例是命令行跑完即退不需要 Web 容器。如果你要暴露 HTTP 接口把它改成servlet即可。temperature调低一点让模型在生成 SQL 时更稳定。3.3 SQLite 建表脚本准备一个test.db用 sqlite3 命令行执行下面的脚本CREATE TABLE IF NOT EXISTS products ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, category TEXT, price REAL NOT NULL, stock INTEGER DEFAULT 0, created_at TEXT DEFAULT (datetime(now)) ); INSERT INTO products (name, category, price, stock) VALUES (机械键盘, 外设, 399.00, 120), (无线鼠标, 外设, 129.00, 300), (27寸显示器, 显示设备, 1599.00, 45), (USB-C 扩展坞, 配件, 259.00, 88), (降噪耳机, 音频, 899.00, 60);执行方式sqlite3 test.db init.sql验证一下sqlite3 test.db SELECT category, COUNT(*), AVG(price) FROM products GROUP BY category;能看到按分类聚合的结果说明数据就位。3.4 MCP Server 启动参数SQLite 的 MCP Server 通过uvx拉起命令是uvx mcp-server-sqlite --db-path 你的db路径。在 Spring AI 里用ServerParameters构造var stdioParams ServerParameters.builder(uvx) .args(mcp-server-sqlite, --db-path, dbPath) .build();dbPath建议用绝对路径相对路径在不同工作目录下启动会找不到文件。Windows 下写成D:\\data\\test.db这种双反斜杠形式。3.5 主启动类与 ChatClient 装配SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } Bean public CommandLineRunner runner(ChatClient.Builder builder, ListMcpSyncClient mcpClients, ConfigurableApplicationContext ctx) { return args - { var chatClient builder .defaultToolCallbacks(new SyncMcpToolCallbackProvider(mcpClients)) .build(); String q 帮我看看 products 表里有哪些分类每个分类的平均价格是多少; System.out.println(问题: q); System.out.println(回答: chatClient.prompt(q).call().content()); ctx.close(); }; } Bean(destroyMethod close) public McpSyncClient mcpClient() { var params ServerParameters.builder(uvx) .args(mcp-server-sqlite, --db-path, D:\\data\\test.db) .build(); var client McpClient.sync(new StdioClientTransport(params)) .requestTimeout(Duration.ofSeconds(30)) .build(); System.out.println(MCP 初始化: client.initialize()); return client; } }SyncMcpToolCallbackProvider是关键它把 MCP Server 暴露的所有工具list_tables、describe_table、query 等注册成 ChatClient 可调用的工具。模型在回答时会自动决定调哪个。4. 验证请求跑通一次自然语言查询 SQLite配置写完直接运行。用 Maven 打包后执行mvn clean package -DskipTests java -jar target/spring-ai-mcp-sqlite-0.0.1-SNAPSHOT.jar控制台会先打印 MCP 初始化信息类似MCP 初始化: InitializeResult[protocolVersion2024-11-05, capabilities..., serverInfoServerInfo[namesqlite, version0.1.0]]这说明 MCP Server 已经通过 STDIO 连上了。接着模型开始处理问题你会看到它先调用list_tables确认表名再调用describe_table看字段最后调用query执行聚合 SQL。最终输出类似回答: products 表中共有 4 个分类 - 外设平均价格 264.00共 2 件 - 显示设备平均价格 1599.00共 1 件 - 配件平均价格 259.00共 1 件 - 音频平均价格 899.00共 1 件到这里端到端链路就跑通了。你可以换几个问题继续验证比如库存低于 100 的产品有哪些、价格最高的三个产品是什么模型会生成不同的 SQL。如果你想先单独验证模型侧是否正常可以打开模型对话 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 手动问一句确认 Key 和模型 ID 没问题再回到代码里排查 MCP 部分。这样能把模型不通和MCP 不通两类问题分开。关于工具调用的细节Spring AI 会把 MCP 工具的 JSON Schema 一起发给模型。模型返回的 tool_calls 里包含工具名和参数SyncMcpToolCallbackProvider负责把参数透传给 MCP Server拿到结果后再塞回对话上下文。整个过程对业务代码是透明的你只看到最终回答。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节按真实报错来遇到哪个查哪个。401 Unauthorized。最常见的原因是 Key 没读到。检查环境变量名是否和 yml 里的${TAOTOKEN_API_KEY}一致注意大小写。如果你在 IDE 里运行IDE 可能没继承 shell 的环境变量需要在 Run Configuration 里手动加。还有一种情况是 Key 复制时带了空格或换行重新复制一次。确认无误后用 curl 直接打一下接口curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:gpt-4o-mini,messages:[{role:user,content:hi}]}返回正常说明 Key 没问题问题在 Spring 配置。local proxy failed / Connection refused。这个报错通常出现在 MCP Server 启动阶段。原因一般是uvx没装或者不在 PATH 里。先单独在终端跑uvx mcp-server-sqlite --db-path test.db看能不能起来。如果提示 command not found装一下 uvpip install uv。如果起来了但 Spring 里报错检查ServerParameters.builder(uvx)里的命令名是否和终端一致Windows 下有时需要写uvx.exe或完整路径。reading choices 相关报错。这类错误一般出现在解析模型响应时比如Cannot deserialize value of type ... from Object value (token JsonToken.START_OBJECT)或者提示 choices 字段为空。根因通常是 base-url 配错请求打到了非 OpenAI 兼容的端点返回了 HTML 或错误 JSON。回到第 2 节检查 base-url 是否写成了https://taotoken.net/api不要多加/v1。另外确认模型 ID 拼写正确不存在的模型会返回错误结构。OAuth / 认证方式不匹配。如果你看到类似OAuth token或invalid_grant的提示说明请求被路由到了需要 OAuth 的端点。TaoToken 的 API 用的是 Bearer Key不需要 OAuth 流程。检查是不是误配了其他 provider 的 base-url。把spring.ai.openai.base-url明确写成https://taotoken.net/api即可。工具没被调用。模型回答得很流畅但完全没查数据库说明工具没注册上。检查defaultToolCallbacks是否传了mcpClients以及mcpClients列表是否为空。如果为空说明McpSyncClientBean 没创建成功往上翻日志找初始化异常。另外确认你选的模型支持工具调用部分轻量模型不支持 function calling。SQL 执行报 no such table。MCP Server 用的 db 路径和你建表的路径不是同一个。--db-path必须指向你执行过 init.sql 的那个文件。用绝对路径最稳。排查顺序建议先 curl 验 Key再单独跑 uvx 验 MCP Server最后跑 Spring 应用。分层定位比一上来就盯着 Java 日志快得多。6. 继续深入把 MCP SQLite 用到真实项目里跑通 demo 只是起点。真实项目里我会做几件事让它更稳。第一把 db 路径和模型配置外置到application-{profile}.yml本地用 test.db测试环境指向另一份数据避免误操作生产库。MCP 直连生产库是明确要避免的SQLite 这种文件库尤其要注意权限只读挂载是个好习惯。第二给 MCP Server 加超时和重试。requestTimeout设 30 秒是保守值复杂聚合查询可能更久。如果查询经常超时考虑在 SQLite 侧建索引而不是一味加大超时。第三工具调用的可观测性。Spring AI 支持注册ToolCallback的监听把每次工具名、参数、耗时打到日志里。这样出问题时能快速定位是模型没调、还是调了但 SQL 报错。第四多 MCP Server 并存。ListMcpSyncClient天然支持多个你可以同时挂 SQLite 和文件系统两个 Server模型会根据问题自动选。这也是 MCP 协议设计的初衷——工具即插即用。如果你打算把这套东西做成长期运行的 Agent 服务建议看看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 额度模型更适合高频工具调用场景。API Key 管理在控制台 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 接入细节可以对照文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。最后留一个我踩过的坑SQLite 的 MCP Server 默认对写操作也是开放的模型有可能生成 INSERT/UPDATE。如果你只想让它查在系统提示词里明确只允许 SELECT或者在数据库层用只读连接。这个细节在 demo 阶段无所谓上线前一定要处理。
返回列表