资讯动态

Spring AI 1.1.2 跑 MCP 功能验证:Key 用 TaoToken,getWeather 后核对 token 用量

发布时间:2026/9/16 20:44:14 来源:尧图企业网站定制
TaoToken 接入 Spring AI 1.1.2 的 MCP 验证先把 Key 从 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 创建Base URL 填 https://taotoken.net/api。MCP 侧代码保持原文不变Server 用 spring-ai-starter-mcp-server-webmvc 暴露 WeatherService 的 Tool getWeatherClient 用 spring-ai-starter-mcp-client 通过 SSE 连到 Server最后由 ChatClient 带着 toolCallbacks 发起“三亞氣溫是多少”。原文验证时 getWeather 返回 19.7SimpleLoggerAdvisor 里能同时打出 promptTokens、completionTokens、totalTokens。这次把模型通道切到 TaoToken想确认 MCP 工具调用的模型请求确实由新通道承接token 消耗也仍然可见。如果你也在为官方 Key 额度、多把 Key 管理和模型切换头疼这套工程只需要动两个配置项。1. Spring Boot 3.5.10 Spring AI 1.1.2依赖替换是 MCP 验证的前提1.1 OpenAI 依赖从 M6 改名到 1.1.2Spring AI 从 1.0.0-M6 升到 1.1.2最直接的改动是 OpenAI 相关的 starter 换了坐标。M6 时代常用spring-ai-openai-spring-boot-starter1.1.2 里统一改为spring-ai-starter-model-openai。这个改名意味着 Spring AI 把模型接入从「厂商专属 starter」改成「模型 starter 通道配置」的形态后面我们要换 TaoToken 通道正是搭这趟车。parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.5.10/version /parent properties java.version17/java.version spring-ai.version1.1.2/spring-ai.version /properties dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-server-webmvc/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-client/artifactId /dependency /dependenciesSpring Boot 需要跟着升到 3.5.10原文特别提醒过这一点。如果项目里还在用 Spring Cloud也要对应升到 2025.0.0否则依赖版本仲裁可能把 Spring AI 的自动配置“压”到不兼容的版本上。1.2 MCP 为什么选 webmvc 而不是 stdio企业级应用走 MCP 时优先用spring-ai-starter-mcp-server-webmvc。stdio 方式虽然本地联调简单但 Client 与 Server 必须跑在同一台服务器上进程管理和日志收集都别扭而 webmvc 方式通过 SSE 暴露 MCP 端点Client 可以跨机器访问也方便和现有 Spring Boot 网关、鉴权体系整合。原文这点判断我认同所以下面的验证全都按「Server 一个进程、Client 一个进程」来跑。2. MCP Server 端spring-ai-starter-mcp-server-webmvc 暴露 getWeather2.1 Server 的配置与 SSE 端点先准备 MCP Server 工程端口固定为 6999这样 Client 配置里可以直接指向它。关键配置是spring.ai.mcp.server.sse-endpoint/sse和消息端点/mcp/messagesSpring AI 会自动把这些端点注册到 Spring MVC 里。server.port6999 spring.application.namedemo-mcp-server spring.ai.mcp.server.namedemo-mcp-server spring.ai.mcp.server.version1.0.0 spring.ai.mcp.server.typeSYNC spring.ai.mcp.server.instructionsEnterprise MCP tool server spring.ai.mcp.server.sse-endpoint/sse spring.ai.mcp.server.sse-message-endpoint/mcp/messages spring.ai.mcp.server.capabilities.tooltrue spring.ai.mcp.server.capabilities.resourcetrue spring.ai.mcp.server.capabilities.prompttrue logging.level.org.springframework.ai.mcpDEBUG logging.level.io.modelcontextprotocolDEBUGsse-message-endpoint是服务端接收 messages 的地址keep-alive可以按需配置不配也能跑。日志级别打开后工具发现和工具调用过程都会打到 DEBUG 里后面验证 token 用量时这些日志就是线索。2.2 WeatherService 与 Tool 定义WeatherService 是 MCP 暴露的工具载体。原来的实现里有个一天温度曲线的模拟函数这里为了让验证结果稳定复现我直接把温度固定成 19.7保留Tool的描述信息。温度值本身不是验证重点重点是它能不能被 Client 发现、调用并返回。import java.math.BigDecimal; import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Service; Service public class WeatherService { private static final BigDecimal SAMPLE_TEMP new BigDecimal(19.7); Tool(description Get weather information by city name) public String getWeather(String cityName) { return cityName : SAMPLE_TEMP.toPlainString(); } }Tool注解来自org.springframework.ai.tool.annotation.Tool在 Spring AI 1.1.x 里是标准写法。Spring 会扫描到带有Tool的 public 方法把它注册成可被 MCP 协议列出的工具。2.3 启动类注入 ToolCallbackProvider工具要被 MCP Server 暴露出去需要在启动类里把WeatherService包装成ToolCallbackProvider。原文项目里用了 MyBatis所以保留了MapperScan如果你不需要删掉即可。import java.util.TimeZone; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.ai.tool.method.MethodToolCallbackProvider; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; SpringBootApplication ComponentScan(basePackages com.example.demo) public class DemoApplication { public static void main(String[] args) { TimeZone.setDefault(TimeZone.getTimeZone(Asia/Shanghai)); SpringApplication.run(DemoApplication.class, args); } Bean public ToolCallbackProvider weatherTools(WeatherService weatherService) { return MethodToolCallbackProvider.builder() .toolObjects(weatherService) .build(); } }这里不用手动写 MCP 的 JSON-RPC 协议spring-ai-starter-mcp-server-webmvc会自动在/sse上处理握手并在tools/list时把getWeather的 schema 返回给 Client。3. MCP Client 端SSE 连接与 ChatClient 发起“三亞氣溫是多少”3.1 Client 配置连到 6999MCP Client 工程通过 SSE 去拉取工具列表。配置里server1是这个连接的别名url指向 Server 的根地址Spring AI 的 SSE 客户端默认会拼上/sse所以url不要自己再加路径。spring.application.namedemo-mcp-client spring.ai.mcp.client.enabledtrue spring.ai.mcp.client.namedemo-mcp-client spring.ai.mcp.client.version1.0.0 spring.ai.mcp.client.typeSYNC spring.ai.mcp.client.request-timeout30s spring.ai.mcp.client.sse.connections.server1.urlhttp://localhost:6999 logging.level.org.springframework.ai.mcpDEBUG logging.level.io.modelcontextprotocolDEBUG如果你习惯显式写 SSE 端点也可以加spring.ai.mcp.client.sse.connections.server1.sse-endpoint/sse效果一样。3.2 ChatClient 带 toolCallbacks 发起提问Client 这边的核心是构造ChatClient并注入SyncMcpToolCallbackProvider。SyncMcpToolCallbackProvider会从 MCP Server 拿到所有工具回调交给 ChatClient 后模型就能在回答“三亞氣溫是多少”时自动触发getWeather。import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.mcp.SyncMcpToolCallbackProvider; import org.springframework.ai.tool.ToolCallback; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; RestController CrossOrigin(origins *, maxAge 3600) public class DemoController { private final ChatClient chatClient; private final SyncMcpToolCallbackProvider toolCallbackProvider; public DemoController( ChatClient.Builder chatClientBuilder, SyncMcpToolCallbackProvider toolCallbackProvider) { this.chatClient chatClientBuilder .defaultAdvisors(new SimpleLoggerAdvisor()) .build(); this.toolCallbackProvider toolCallbackProvider; } PostMapping(/a/chat) public String chat() { ToolCallback[] toolCallbacks toolCallbackProvider.getToolCallbacks(); return chatClient .prompt(三亞氣溫是多少) .toolCallbacks(toolCallbacks) .call() .content(); } }3.3 SimpleLoggerAdvisor 的关键作用SimpleLoggerAdvisor是一个轻量 Advisor它会在 ChatClient 发出请求前和拿到响应后各打印一行日志。响应日志里带着完整的metadata其中usage字段就是我们要核对 token 用量的地方。原文验证时getWeather返回“三亞:19.7”模型把工具结果组织成一句完整回复整个过程从 DEBUG 日志里看得一清二楚。4. 给 ChatClient 配 TaoToken拿 Key、改 base-url、对模型 ID4.1 创建 API Key现在进入本文的改造点MCP 的 Server、Client、WeatherService 全都不用动只改模型通道。先打开 TaoToken 注册并登录在控制台创建你的 API Key。这个 Key 就是 ChatGPT 官方 Key 的替身Spring AI 只认api-key和base-url两个配置不关心 Key 是哪家签发的。创建完成后把 Key 复制出来保存到环境变量里不要直接写进代码。4.2 application.properties 里只改两行在 Client 工程的application.properties中原有 OpenAI 配置替换成下面这段spring.ai.model.chatopenai spring.ai.openai.api-key${TAOTOKEN_API_KEY} spring.ai.openai.base-urlhttps://taotoken.net/api spring.ai.openai.chat.options.model${SPRING_AI_OPENAI_MODEL}注意这里 Base URL 是https://taotoken.net/api末尾没有/v1。Spring AI 的 OpenAI 客户端会自动补全请求路径多写一个/v1反而会 404。4.3 模型 ID 以模型广场为准SPRING_AI_OPENAI_MODEL这个环境变量需要填你在模型广场上实际看到的模型 ID。原文章的日志里写的是gpt-5-mini但模型列表会变动所以不要凭印象硬填。打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 的模型广场页从列表里选一个当前可用的模型把它的 ID 配置进去。启动前设置环境变量export TAOTOKEN_API_KEYYOUR_API_KEY export SPRING_AI_OPENAI_MODEL模型广场上的模型IDWindows 用户改成set语法即可。配置完成后ChatClient 发起的所有模型请求都会走 TaoToken 通道而 MCP 的工具发现、SSE 连接、工具回调仍然走原来的localhost:6999两边互不干扰。5. 验证调用 getWeather 后核对 SimpleLoggerAdvisor 里的 usage5.1 启动顺序与调用方式先启动 MCP Server 工程确认 6999 端口处于监听状态再启动 MCP Client 工程。然后向 Client 发起接口调用curl -X POST http://localhost:8080/a/chat返回内容应该是模型组织好的中文回答例如“三亞目前氣溫約 19.7°C”。5.2 关键日志长什么样在 Client 控制台里能看到这几段关键输出。首先是 MCP 工具列表成功拉取o.s.a.m.t.DefaultToolCallingManager - Executing tool call: getWeather i.m.spec.McpClientSession - Received response: ... text:\三亞:19.7\然后是SimpleLoggerAdvisor打印的响应元数据o.s.a.c.c.a.SimpleLoggerAdvisor - response: { metadata : { id : chatcmpl-..., model : ..., usage : { promptTokens : 308, completionTokens : 318, totalTokens : 626 } } }上面这组 308 / 318 / 626 是原文那次验证的数据。换成 TaoToken 通道后只要模型 ID、上下文长度不同数值就会变化但usage字段结构不变promptTokens是输入 token 数completionTokens是输出 token 数totalTokens是本次请求总消耗。5.3 怎么确认这次请求真的走了 TaoToken光看日志还不够还要回到 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 的控制台在 API Key 对应的用量页里找到刚才那笔请求。如果你在SimpleLoggerAdvisor里看到的totalTokens和控制台用量记录对得上就说明两件事同时成立MCP 工具调用链路是通的模型请求也确实由 TaoToken 通道承接并完成计量。这一步的验证价值在于后面再把更多业务工具挂进 MCP Server 时你可以用同一套方法核对每个工具调用到底烧了多少 token而不是“大概齐”。6. Spring AI 1.1.2 跑 MCP 的报错对照与下一步路径6.1 常见报错与处理现象原因处理方式401 UnauthorizedTAOTOKEN_API_KEY没填对或未创建到 TaoToken 控制台重新复制 Key404 Not Foundbase-url 写了/v1改成https://taotoken.net/apiModel not found模型 ID 不是模型广场上的实际 ID打开模型广场复制可用 IDMCP connection refusedServer 没启动或端口不是 6999先启动 Server确认 6999 被监听tools 列表为空ToolCallbackProvider没注入检查启动类里MethodToolCallbackProviderBean大多数问题集中在 Base URL 和模型 ID 上。Base URL 末尾多一个/v1是最高频的 404 原因模型 ID 则是另一个高频雷区不要拿网上旧教程里的 ID 直接填。6.2 跑通之后去控制台对一下这次调用配置保存好后可以在 TaoToken 模型对话 里用同一把 Key 发一条消息确认模型 ID 和 Base URL 没有填错。如果需要长时间跑 AI 编程或自动化任务打开 Coding Plan 看看套餐够不够用Key 的管理和用量明细都在 控制台 API Keys 页面。如果你平时也用 Claude Code 写代码TaoToken 的 Claude Code 接入文档 里是另一套环境变量写法和 Spring AI 的base-url配置别混用。MCP 这套工程以后可以一直复用换模型时只改环境变量Server 端和 Client 端代码不需要再动。等你把更多业务工具注册成Tool每次调用的 token 增量也就都能在SimpleLoggerAdvisor里对上了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价