news 2026/10/3 19:28:46

大模型——基于Spring AI服务,开发MCP服务并接入TaoToken统一通道

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大模型——基于Spring AI服务,开发MCP服务并接入TaoToken统一通道

1. 从本地 Spring AI 到 MCP 服务:为什么模型端点要统一走 TaoToken

如果你已经用 Spring AI 在本地跑通过一个能对话的 Demo,接下来大概率会碰到一个很现实的问题:MCP 服务注册好了,工具也能被客户端发现,但模型请求这一环总是散落在各处。客户端一套 Key,服务端一套 Key,SSE 服务里再写一套,时间一长自己都记不清哪个配置文件对应哪个环境。更麻烦的是,不同模型供应商的 Base URL、鉴权头、模型名格式都不一样,Spring AI 的OpenAiApi默认又只认 OpenAI 那套规范,一旦要换模型就得改代码。

我这次要做的,就是把 Spring AI 搭出来的 MCP 服务端,模型调用端点统一改到 TaoToken 的 API 通道上。TaoToken 是一个面向开发者的模型统一接入通道,它把多家模型的调用收敛成一套 OpenAI 兼容的接口,你只需要一个 Key、一个 Base URL,就能在 Spring AI 里用同一份配置切换不同模型。对于正在做 MCP 工具注册、又不想在模型接入上反复折腾的 Java 开发者来说,这个组合能省掉大量适配工作。

MCP 本身是 Model Context Protocol,你可以把它理解成“让模型知道有哪些工具可用”的协议。Spring AI 从 1.0 版本开始提供了spring-ai-mcp-server相关 starter,支持 stdio 和 SSE 两种传输方式。stdio 适合本地命令行进程,SSE 适合 HTTP 长连接。无论哪种,服务端最终都要调用模型来完成推理,而这一步正是我们要接到 TaoToken 的地方。

这篇文章面向的是本地已经跑通 Spring AI 的 Java 开发者,目标是一次性打通 MCP 工具注册与模型请求链路。我会给出可复制的application.yml配置片段、MCP 服务端启动命令,以及用 curl 验证工具列表与对话返回的检查动作。整个过程不需要你改 Spring AI 的源码,只靠配置和少量 Bean 调整就能完成。

先说清楚整体链路:客户端(比如 Cline、Trae 这类支持 MCP 的工具)通过 stdio 或 SSE 连接到你的 Spring AI MCP 服务端;服务端启动时向客户端暴露工具列表;当客户端发起对话时,服务端把请求转发给 TaoToken 的/v1/chat/completions,拿到模型返回后再回传给客户端。模型端点统一之后,你换模型只需要改application.yml里的model字段,不用动任何 Java 代码。

这里有个容易踩的坑:Spring AI 的 MCP 服务端和模型客户端是两个独立的自动配置。很多人只配了 MCP 的spring.ai.mcp.server,却忘了配spring.ai.openai,结果服务能启动、工具能注册,但一对话就报找不到 API Key。所以下面的配置我会把这两块分开写清楚,避免你漏配。

2. TaoToken 前置准备:拿 Key、认端点、选模型

在动 Spring AI 配置之前,先把 TaoToken 这边的三样东西准备好:API Key、Base URL、Model ID。这三样是后面所有配置的基础,缺一个都跑不通。

API Key 的获取入口在控制台的 API Keys 页面,地址是https://taotoken.net/api-keys。登录后新建一个 Key,复制出来保存好。注意这个 Key 只在创建时完整显示一次,关掉页面就看不到了,所以建议直接贴到你的密码管理器或者临时文件里。Key 的格式通常是一串以sk-开头的字符串,长度比较长,别手动截断。

Base URL 这块要特别小心。TaoToken 的 API 根地址是https://taotoken.net/api,但在 Spring AI 的 OpenAI 配置里,base-url需要写到/v1这一层,也就是https://taotoken.net/api/v1。如果你只写到/api,Spring AI 拼接出来的请求路径会变成/api/chat/completions,少了一层/v1,服务端会返回 404。这个细节我在第一次配置时就踩过,日志里看到 404 还以为是 Key 的问题,排查了半天。

Model ID 取决于你想用哪个模型。TaoToken 的模型列表可以在模型对话页面查看,地址是https://taotoken.net/chat。你可以在那里先手动发一条消息,确认模型能正常返回,然后再把对应的模型名填到 Spring AI 配置里。常见的模型名格式类似gpt-4o、claude-3-5-sonnet这种,具体以你账号下可用的为准。如果你打算长期做编码类 Agent,可以关注 Coding Plan 页面https://taotoken.net/coding-plan,那里有针对代码场景的套餐说明。

把这三样东西整理成一张表,方便后面配置时对照:

配置项值说明
API Keysk-xxxxxxxx控制台创建,只显示一次
Base URLhttps://taotoken.net/api/v1注意带/v1
Model ID如gpt-4o以模型对话页可用为准

这里要提醒一句:不要把 Key 硬编码到 Java 代码里,也不要把带 Key 的application.yml提交到 Git。推荐用环境变量注入,Spring AI 支持${TAOTOKEN_API_KEY}这种占位符写法。下面配置片段里我会用环境变量方式,你本地设置好TAOTOKEN_API_KEY就行。

另外,TaoToken 的接入文档在https://taotoken.net/doc,里面有各语言 SDK 的调用示例。虽然 Spring AI 用的是自己的OpenAiApi封装,但请求体和响应体格式跟 OpenAI 一致,所以文档里的 curl 示例可以直接拿来对照排查。如果你在 Spring AI 里遇到返回结构解析问题,用文档里的 curl 先验证一遍,能快速定位是通道问题还是代码问题。

准备好这三样之后,就可以进入 Spring AI 的配置环节了。下一节我会给出完整的application.yml和必要的 Bean 配置,你可以直接复制到自己的项目里改。

3. 可复制配置:application.yml 与 MCP 服务端启动

这一节是整篇文章的核心,我会把 Spring AI 接入 TaoToken 的配置拆成三块:模型客户端配置、MCP 服务端配置、以及启动命令。你按顺序复制即可。

先看application.yml的完整片段。假设你的项目是spring-ai-mcp-stdio-server模块,配置文件放在src/main/resources/application.yml:

spring: application: name: spring-ai-mcp-stdio-server main: web-application-type: none banner-mode: off ai: openai: api-key: ${TAOTOKEN_API_KEY} base-url: https://taotoken.net/api/v1 chat: options: model: gpt-4o temperature: 0.7 mcp: server: name: addOrMinus-service version: 1.0.0 stdio: true type: SYNC

这里有几个关键点。spring.ai.openai.api-key用环境变量注入,避免明文。base-url必须写到/v1。spring.ai.openai.chat.options.model填你在 TaoToken 模型对话页确认可用的模型名。spring.ai.mcp.server.stdio: true表示用标准输入输出传输,适合被 Cline、Trae 这类客户端以子进程方式拉起。type: SYNC表示同步工具调用,如果你用的是响应式编程,可以改成ASYNC。

如果你用的是 SSE 服务端模块,配置会略有不同,主要是把stdio换成sse,并指定端口:

spring: ai: mcp: server: name: querweather-sse-mcp version: 1.0.0 sse: enabled: true endpoint: /sse server: port: 9090

注意 SSE 模式下web-application-type不能是none,要保留默认的 servlet 类型,否则端口不会监听。

接下来是 MCP 工具的注册。Spring AI 用@Tool注解标记方法,然后在配置类里把工具 Bean 注册进去。下面是一个加法工具的示例:

@Component public class MathTools { @Tool(description = "计算两个整数相加的结果") public int add(int a, int b) { return a + b; } @Tool(description = "计算两个整数相减的结果") public int minus(int a, int b) { return a - b; } }

然后在 MCP 服务端配置里注册这个工具提供者:

@Configuration public class McpServerConfig { @Bean public ToolCallbackProvider mathToolCallbackProvider(MathTools mathTools) { return MethodToolCallbackProvider.builder() .toolObjects(mathTools) .build(); } }

这样服务端启动时就会把add和minus两个工具暴露给客户端。客户端在对话时如果问到“3 加 5 等于几”,模型会决定调用add工具,服务端执行后把结果回传。

启动命令这块,如果你打包成了可执行 JAR,直接用java -jar启动:

java -jar target/spring-ai-mcp-stdio-server.jar

但 stdio 模式下,服务端是等着客户端通过标准输入发消息的,你直接在终端跑会看到它“卡住”不动,这是正常的。真正的启动方式是在 MCP 客户端的配置文件里声明,由客户端拉起子进程。以 Cline 或 Trae 的mcp.json为例:

{ "mcpServers": { "addOrMinus-service": { "disabled": false, "timeout": 30, "type": "stdio", "command": "java", "args": [ "-jar", "D:/mcp/spring-ai-mcp-demo-master/spring-ai-mcp-stdio-server/target/spring-ai-mcp-stdio-server.jar" ], "cwd": "D:/mcp/spring-ai-mcp-demo-master/spring-ai-mcp-stdio-server/target", "env": { "TAOTOKEN_API_KEY": "sk-你的Key", "TIMEZONE": "Asia/Shanghai", "spring.ai.mcp.server.stdio": "true", "spring.main.web-application-type": "none", "spring.main.banner-mode": "off" } } } }

注意env里把TAOTOKEN_API_KEY传进去了,这样 Spring AI 启动时能读到。如果你不想在mcp.json里写明文 Key,可以先在系统环境变量里设置好,然后这里省略。

SSE 模式的启动就简单了,直接跑 Spring Boot 应用:

mvn spring-boot:run -pl spring-ai-mcp-sse-server

启动后监听9090端口,客户端用 URL 方式连接:

{ "mcpServers": { "querweather-sse-mcp": { "url": "http://localhost:9090/sse", "transportType": "sse", "autoApproval": false, "requireManualConfirmation": true } } }

配置到这里就完成了。下一节我会用 curl 验证工具列表和对话返回,确认整条链路真的通了。

4. 验证请求:用 curl 检查工具列表与对话返回

配置写完之后,别急着在客户端里点来点去,先用 curl 把服务端和 TaoToken 通道分别验证一遍。这样出问题时能快速定位是哪一段的毛病。

先验证 TaoToken 通道本身是否可用。这一步不经过 Spring AI,直接打 API:

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", "messages": [ {"role": "user", "content": "只回复两个字:通了"} ] }'

如果返回的 JSON 里choices[0].message.content是“通了”,说明 Key、Base URL、模型名都没问题。如果返回 401,检查 Key 是否复制完整;如果返回 404,检查 URL 是不是漏了/v1;如果返回模型不存在的错误,去模型对话页确认模型名。

通道验证通过后,再验证 MCP 服务端的工具列表。SSE 模式下,MCP 协议的工具列表通过 JSON-RPC 暴露,你可以用 curl 发一个tools/list请求:

curl -X POST http://localhost:9090/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {} }'

返回结果里应该能看到add和minus两个工具,每个工具带name、description、inputSchema。如果返回空列表,说明ToolCallbackProvider没注册成功,检查McpServerConfig里的 Bean 是否被扫描到。

stdio 模式下没法直接用 curl,因为它是标准输入输出。你可以写一个简单的测试脚本,往进程的标准输入里写 JSON-RPC 消息:

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | java -jar target/spring-ai-mcp-stdio-server.jar

正常的话,标准输出会打印工具列表的 JSON。如果没有任何输出,检查spring.ai.mcp.server.stdio是否为true,以及spring.main.web-application-type是否为none。

工具列表验证通过后,再验证一次完整的对话链路。在客户端里问“3 加 5 等于几”,观察服务端日志。你应该能看到类似这样的流程:客户端发送对话请求 → 服务端调用 TaoToken 的 chat completions → 模型返回工具调用意图 → 服务端执行add(3, 5)→ 把结果回传给模型 → 模型生成最终回答“8”。

如果日志里看到Tool execution相关的记录,说明工具调用成功了。如果模型直接回答“8”而没有走工具,可能是模型没理解工具描述,试着把@Tool的description写得更明确,比如“当用户询问两个数相加时使用此工具”。

还有一个验证技巧:在 TaoToken 的模型对话页面手动发一条同样的消息,对比返回。如果那边正常、Spring AI 这边不正常,问题就在 Spring AI 配置;如果两边都不正常,问题在通道或模型本身。

验证通过后,你就可以在客户端里正常使用 MCP 工具了。下一节我会列出几个常见的报错和排查方法,都是我在配置过程中真实遇到过的。

5. 常见报错排查:401、local proxy failed、reading choices、OAuth

这一节按报错信息来组织,你遇到哪个就查哪个。每个报错我都会给出触发场景和排查步骤。

401 Unauthorized。这个最常见,通常是 Key 没传对。先确认TAOTOKEN_API_KEY环境变量在当前 shell 里能echo出来。如果是在mcp.json的env里传的,注意 JSON 里不能有注释,Key 字符串不能带多余空格。还有一种情况是 Key 被撤销了,去控制台 API Keys 页面确认状态是“启用”。如果 Key 没问题,检查base-url是否写成了https://taotoken.net/api(少了/v1),有些网关对路径敏感,会返回 401 而不是 404。

local proxy failed。这个报错通常出现在客户端侧,意思是客户端尝试连接本地 MCP 服务端时失败了。先确认服务端进程是否真的起来了。stdio 模式下,客户端会拉起子进程,如果command或args路径写错,子进程起不来就会报这个。检查mcp.json里的args路径是否指向真实存在的 JAR 文件,Windows 下路径用正斜杠或双反斜杠。SSE 模式下,确认9090端口没有被占用,用netstat -ano | findstr 9090查一下。如果端口被占,改server.port或者杀掉占用进程。

reading choices 相关报错。这个一般出现在 Spring AI 解析 TaoToken 返回结果时,报错信息里带reading choices或Cannot deserialize。原因是返回的 JSON 结构和 Spring AI 预期的ChatCompletion结构不完全一致。排查方法:先用第 4 节的 curl 命令看原始返回,确认choices字段存在且是数组。如果返回里多了或少了字段,可能是模型或通道的兼容性问题。这时候可以尝试换一个模型,或者在 Spring AI 里自定义OpenAiApi的ResponseErrorHandler。另一个常见原因是流式和非流式混用,spring.ai.openai.chat.options里如果开了stream: true,但客户端不支持流式解析,也会报这个。先关掉流式试试。

OAuth 相关报错。如果你在日志里看到OAuth或token endpoint字样,说明某个环节在尝试走 OAuth 鉴权。TaoToken 的 API Key 方式是 Bearer Token,不需要 OAuth 流程。出现这个报错通常是 Spring AI 的某个 starter 默认启用了 OAuth 客户端自动配置。检查pom.xml里是否引入了spring-boot-starter-oauth2-client,如果有,排除掉或者设置spring.security.oauth2.client.registration为空。另外,spring.ai.openai的配置里不要写client-id、client-secret这类字段,只保留api-key和base-url。

除了这四个,还有一个配置层面的坑:JDK 版本。Spring AI 1.0 要求 JDK 17 及以上,如果你本地是 JDK 11,编译会报“无效的目标发行版”。检查pom.xml里的maven.compiler.source和target是否为 17。用java -version确认运行时版本一致。如果之前用 JDK 21 编译过、现在换回 17,记得先mvn clean清掉旧的 class 文件。

排查的时候,日志是你的第一手资料。把 Spring AI 的日志级别调到DEBUG,在application.yml里加:

logging: level: org.springframework.ai: DEBUG io.modelcontextprotocol: DEBUG

这样能看到请求体、响应体、工具调用的详细过程。如果请求体里的model字段和你配置的不一致,说明配置没生效,检查是否有多个application.yml或者 profile 覆盖。

最后提醒一句:如果你在mcp.json里同时配了 stdio 和 SSE 两个服务,注意它们的name不能重复,否则客户端会混淆。每个服务的env是独立的,Key 要分别传。

6. 统一通道之后:模型切换与长期编码场景的接入建议

模型端点统一到 TaoToken 之后,最直接的好处是换模型不用改代码。你只需要改application.yml里的model字段,重启服务端,客户端那边完全无感。我试过在同一个 MCP 服务里,上午用gpt-4o做通用对话,下午换成claude-3-5-sonnet做代码审查,切换成本就是改一行配置。

对于长期做编码类 Agent 的场景,建议把 MCP 工具按领域拆成多个服务端。比如一个服务端专门放文件操作工具,一个放 Git 操作工具,一个放数据库查询工具。每个服务端独立配置模型,这样你可以让文件操作走便宜快速的模型,让代码生成走能力更强的模型。TaoToken 的 Coding Plan 页面https://taotoken.net/coding-plan有针对编码场景的套餐说明,如果你打算长期跑 Agent,可以去看看额度规则。

接入文档在https://taotoken.net/doc,里面除了 curl 示例,还有错误码说明。遇到不认识的返回码,先查文档,比在日志里猜要快。模型对话页面https://taotoken.net/chat适合做快速验证,改完配置后先在那里发一条消息,确认模型可用,再去客户端里测。

如果你还没创建 Key,入口在https://taotoken.net/api-keys。创建时建议按用途命名,比如mcp-stdio-dev、mcp-sse-prod,方便后面排查是哪个环境在用。Key 泄露了要立刻撤销重建,不要觉得本地开发无所谓。

最后说一个实际经验:MCP 服务端的超时设置要和模型响应时间匹配。mcp.json里的timeout默认是 30 秒,如果你用的模型响应较慢,或者工具执行本身耗时,客户端会提前断开。把timeout调到 60 或 120,同时在 Spring AI 侧设置spring.ai.openai.chat.options.timeout。两边都设,避免一边等另一边超时。

配置改完之后,记得用第 4 节的 curl 再验证一遍工具列表和对话返回。确认无误后,就可以在 Cline 或 Trae 里正常提问了。整个链路打通后,你后续加新工具只需要写@Tool方法并注册 Bean,模型端点这块不用再动。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 19:24:56

备孕可以养宠物吗?

邵阳不少小夫妻家里都养着猫或者狗,一开始备孕,家里长辈就反复说“养猫养狗会导致胎儿畸形,必须把宠物送走”,很多人夹在舍不得宠物和担心宝宝健康之间两难,甚至因为养宠物的事和家人闹矛盾,邵阳汇恩生殖健…

作者头像 李华
网站建设 2026/10/3 19:17:34

大数据挖掘驱动下的网红餐厅舆情分析与影响机理研究设计与实现

一、课题研究背景与意义 (一)研究背景随着移动互联网、社交媒体与短视频平台的高速发展,餐饮行业迎来数字化转型浪潮,网红餐厅成为餐饮消费领域的新兴业态。网红餐厅依托抖音、小红书、大众点评、美团等新媒体平台快速传播&#x…

作者头像 李华
网站建设 2026/10/3 19:12:35

DeepSeek企业落地全指南:从选型到部署的实战经验

1. 为什么是DeepSeek——企业选型逻辑与技术底座拆解1.1 从一次选型评审说起:企业到底需要什么样的大模型今年上半年,我参与了好几个企业级AI项目的选型评审。有意思的是,几乎每个项目的开始,团队都会列出一长串候选模型&#xff…

作者头像 李华