JAVA-MCP Demo 的 Spring AI 遇 403?Base URL 走 TaoToken 通道再试
2026/9/18 13:25:40 网站建设 项目流程

在 IDEA 里把 JAVA-MCP Demo 拉下来,application.properties 里的 spring.ai.anthropic.api-key 刚填好,启动 Spring Boot 后调用 /api/chat,控制台直接返回 403。栈里看不到 findBooksByAuthor 的执行日志,ChatClient 甚至还没把请求发出去,就被 Anthropic 模型端拦住了。这个报错和 TaoToken 本身没关系,但修法要从 TaoToken 开始:打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 注册并创建 API Key,再把 Spring AI 的模型通道 base-url 改成 https://taotoken.net/api,密钥位放刚创建的 Key,重启后再发同一条消息。下面按排障顺序拆一遍,重点看 application.properties、@Tool 注解和 McpServerConfig 这三处。

1. Spring AI 的 403 不是代码错,是模型通道没选对

1.1 application.properties 里那行 api-key 暴露的默认通道

原文 Demo 第 2 步是在 application.properties 里写 spring.ai.anthropic.api-key,然后提示 Anthropic 访问需要代理,否则会报 403。这句话点破了问题的位置:Spring AI 的 Anthropic Starter 默认把请求发往 api.anthropic.com,你的 Key 填得再对,只要当前网络环境被模型端判定为不可服务,返回就是 403。403 的含义不是“认证失败”,而是“服务端拒绝执行”,所以 ChatClient 在创建请求、拼装 headers 的阶段就被挡回来了。

这和业务代码没关系。BookTools 里的 findBooksByAuthor 写没写对、@ToolParam 有没有加描述、McpServerConfig 有没有注册 ToolCallbackProvider,都不影响这个 403。因为请求根本还没走到工具调用那一层。排障时先把故障域缩小:如果日志里出现 403 且没有任何 tool call 记录,先别改 Java 代码,先看模型通道配置。

1.2 403 出现的时机:ChatClient 还没发出请求

Spring AI 的调用链大致是:Controller 收到 /api/chat 请求 → ChatClient 组装 prompt → AnthropicApi 用 base-url 拼出完整 endpoint → 发起 HTTP 请求 → 模型返回 → 若模型决定调用工具,再回调 @Tool 方法。403 通常发生在第四步之前或第四步当下,也就是说,ChatClient 已经准备发请求,但模型端直接拒绝。

这种情况下,你在 Controller 里打日志只能看到“开始调用”,看不到“模型已返回”。在 BookTools.findBooksByAuthor 里打日志更是什么都看不到。判断方法很简单:把日志级别调到 DEBUG,看有没有出现POST https://api.anthropic.com/v1/messages这样的记录。如果有,且后面紧跟 403,就说明默认通道不通,需要换 Base URL。

1.3 把通道换成 TaoToken 后要改哪两行

改法不复杂,但必须改对位置。第一行是 spring.ai.anthropic.base-url,把它从默认的 api.anthropic.com 改成 https://taotoken.net/api,末尾不要加 /v1,也不要把官网落地页的 UTM 参数带进来。第二行是 spring.ai.anthropic.api-key,把原来的 Anthropic Key 换成从 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 创建的 TaoToken Key。

这里有个容易混的点:给人看的落地页是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end,用来注册、创建 Key、看模型广场和用量;填进 Spring AI 的 base-url 必须是 https://taotoken.net/api。前者带查询参数,后者不带。把落地页整串粘进 application.properties,Spring AI 会拼出错误路径,表现可能是 404,也可能是 403。改完配置后重启 Spring Boot,再发同一条“根据作者查张三”。

2. 在 application.properties 和 McpServerConfig 里接上 TaoToken

2.1 从落地页拿 Key,别把官网地址填进 base-url

准备材料只有两样:一个可用的 TaoToken Key,一个当前模型广场里存在的模型 ID。打开 TaoToken 注册并登录,在控制台创建 API Key,复制出来先放到安全的地方。Key 在配置里统一写成 YOUR_API_KEY,不要提交到 Git,也不要在日志里打印完整值。

模型 ID 不要凭记忆写。以 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 模型广场当时列表为准。有的人看旧教程填了带日期后缀的模型名,结果模型端返回 404 或“model not found”,又被误判成 403。先把模型 ID 复制准确,再进配置文件。

2.2 Spring AI Anthropic 的 base-url 与 model 怎么填

application.properties 按下面写。注意 base-url 末尾没有 /v1,Spring AI 的 Anthropic 实现会自己拼接后续路径。

spring.application.name=java-mcp-demo spring.ai.anthropic.api-key=YOUR_API_KEY spring.ai.anthropic.base-url=https://taotoken.net/api spring.ai.anthropic.chat.options.model=YOUR_MODEL_ID

如果你用的是 application.yml,对应结构是:

spring: ai: anthropic: api-key: YOUR_API_KEY base-url: https://taotoken.net/api chat: options: model: YOUR_MODEL_ID

改完后不要急着调 MCP 工具,先用最简单的一条消息确认模型通道通不通。比如在 /api/chat 里发“你好”,如果返回正常文本,说明 403 已经解决,模型通道已经走到 TaoToken。接下来再验证工具调用,故障域会清晰很多。

2.3 MCP Server 的工具注册文件长什么样

原文第 4 步会发“根据作者查张三”,观察 @Tool 标记的 findBooksByAuthor 是否被调用。要让这个链路成立,除了模型通道,工具注册也得写对。一个可运行的 Demo 结构如下,BookTools 负责声明工具,McpServerConfig 负责把工具对象注册成 ToolCallbackProvider。

@Component public class BookTools { private final BookRepository bookRepository; public BookTools(BookRepository bookRepository) { this.bookRepository = bookRepository; } @Tool(description = "根据作者姓名查询图书列表") public List<Book> findBooksByAuthor( @ToolParam(description = "作者姓名,例如:张三") String author) { return bookRepository.findByAuthor(author); } }
@Configuration public class McpServerConfig { @Bean public ToolCallbackProvider bookToolCallbackProvider(BookTools bookTools) { return MethodToolCallbackProvider.builder() .toolObjects(bookTools) .build(); } }

BookRepository 在 Demo 里可以指向本地测试库或内存数据。如果后面要接真实业务库,建议给工具方法使用只读账号,并且不要在工具内部直接执行高风险 SQL。更稳的做法是:让模型生成 SQL,由你在本地 SQL 客户端执行,再把结果贴回对话。AI 编程工具默认不能直连生产库去“执行”业务操作,Codex、Claude Code 这类工具也只能生成、解释、对照代码或 SQL,不能替你连上生产机器跑诊断语句。

3. 用 /api/chat 发「根据作者查张三」验证工具链路

3.1 请求体与控制台日志观察点

模型通道改完、工具注册完成后,用原文第 4 步的请求验证。假设 Controller 暴露的是 POST /api/chat,请求体可以写成:

{ "message": "根据作者查张三" }

对应的 curl 命令:

curl -X POST http://localhost:8080/api/chat \ -H "Content-Type: application/json" \ -d '{"message":"根据作者查张三"}'

发出去以后盯三个地方:Spring Boot 控制台有没有出现 findBooksByAuthor 的调用日志;返回 JSON 里是否包含图书列表;如果开了 Spring AI 的 tool call 日志,是否能看到工具名和参数 author=张三。只要这三处里有两处命中,就说明模型调用和 MCP 工具链路已经走 TaoToken 通道。

3.2 findBooksByAuthor 被调用的三个信号

第一个信号是日志。在 findBooksByAuthor 方法第一行加log.info("tool findBooksByAuthor author={}", author);,如果这行出现,说明模型确实决定调用工具,并且 Spring AI 成功回调了本地方法。第二个信号是返回值。接口返回的 JSON 里应该出现图书对象数组,而不是一句“我将为您查询”。第三个信号是耗时分布。模型通道正常时,整体响应会分成“模型推理耗时”和“工具执行耗时”,如果只有前者没有后者,说明工具没被触发。

如果三个信号都出现了,403 排障就结束了。后面再调 @Tool、@ToolParam 和 McpServerConfig,都属于工具质量优化,不是通道问题。比如查张三返回空列表,可能是本地测试库没有数据,不是 TaoToken 的问题。

3.3 如果只返回自然语言没调工具,先查 @ToolParam

模型返回“好的,我正在为您查询张三的图书”但没有真正调用工具,常见原因是工具描述太模糊。@Tool 的 description 要写清楚“根据作者姓名查询图书列表”,@ToolParam 要写清楚参数含义“作者姓名,例如:张三”。模型看到清晰描述,才更愿意把用户问题映射到工具调用。

另一个原因是 McpServerConfig 没注册到位。如果 ToolCallbackProvider 没有被 Spring 容器扫描到,模型端根本看不到这个工具,自然只会用自然语言回复。还有一种情况是模型本身不支持工具调用,或者当前模型 ID 在模型广场里属于纯对话模型。换一个支持 tool use 的模型 ID 再试,模型 ID 仍以 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 模型广场当时列表为准。

4. 403 之外:@Tool、@ToolParam、McpServerConfig 的排查顺序

4.1 401 和 404 分别对应哪一行配置

403 解决后,可能遇到 401 和 404。401 通常对应 spring.ai.anthropic.api-key 这一行:Key 没替换、复制时带了空格、或者用了已经删除的 Key。处理方式是回到控制台重新创建一个 Key,再写进 YOUR_API_KEY 的位置。404 通常对应 spring.ai.anthropic.base-url 这一行:末尾多写了 /v1,或者把落地页 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 整串粘进去了。正确值只有 https://taotoken.net/api。

不要同时改 Key、Base URL 和模型 ID,否则出了问题不知道是哪一行引起的。排障时一次只动一个变量:先确认 Base URL 是 https://taotoken.net/api,再确认 Key 是新建的,最后确认模型 ID 来自模型广场。每改一次重启一次,发同一条“根据作者查张三”。

4.2 工具注册了但模型不调用

工具注册了但模型不调用,按这个顺序查:第一,看 @Tool 注解是否加在 public 方法上,方法返回值是否可序列化;第二,看 @ToolParam 是否给每个参数都写了 description;第三,看 McpServerConfig 里的 ToolCallbackProvider 是否被 Spring 扫描到,可以在启动日志里搜工具名;第四,看当前模型是否支持工具调用。四个都正常,再考虑把工具描述写得更具体,比如加上“返回字段包括书名、作者、ISBN”。

不要为了让模型调用工具而在 description 里写“必须调用”。更好的方式是写清楚工具能解决什么问题,模型会根据用户意图选择。原文 Demo 的“根据作者查张三”本身就是很明确的意图,工具描述只要匹配,通常都能触发。

4.3 不要让 ChatClient 直连生产库

MCP Demo 里用本地测试库或内存数据最安全。如果想把 findBooksByAuthor 接到真实业务库,不要让 ChatClient 直接连生产库执行 SQL。正确做法是:让模型生成查询 SQL 或解释 SQL,由你在本地 SQL 客户端执行,把结果贴回对话,再让模型整理成图书列表。这样既保留了 MCP 工具链路的演示效果,又不会把生产库暴露给 AI 工具。

诊断 SQL、编译运行、regsvr32 这类操作也一样,必须由读者在本地或受控环境执行,再把报错贴回对话。Codex、Claude Code 可以帮你对照代码、生成 SQL、解释报错,但不会替你连上生产机器执行。把这条边界守住,再调 @Tool、@ToolParam 和 McpServerConfig 会更安心。

5. 跑通之后去控制台对一下这次调用

5.1 用同一把 Key 在模型对话里再发一次

Spring Boot 里看到图书列表返回后,用同一把 Key 在 TaoToken 模型对话 里发一条测试消息,确认模型 ID 和 Base URL 没填错。模型对话页面能返回正常文本,说明 Key 和模型 ID 都是有效的;如果这里也报错,就不用回去改 Java 代码了,先把 Key 和模型 ID 理顺。

5.2 长期写代码看 Coding Plan,Key 和文档位置

如果这个 JAVA-MCP Demo 只是开始,后面还要长期调试 @Tool、@ToolParam 和 McpServerConfig,可以打开 Coding Plan 看套餐是否够用。Key 在 控制台 API Keys 创建和管理。如果你平时也用 Claude Code 这类命令行工具,环境变量对照见 接入文档。把这次 Spring AI 的调用记录和控制台用量对一下,确认请求确实记到了同一个 Key 上,再继续加工具方法。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询