Spring AI Alibaba 1.1.2.0 实操完整记录:基础对话、流式 SSE、自建 MCP服务端互通实践

198 阅读9分钟

Spring AI Alibaba 1.1.2.0 实操完整记录:基础对话、流式 SSE、自建 MCP服务端互通实践

近期基于 Spring AI Alibaba 1.1.2.0 新版本开展实操学习,全程完整记录搭建流程、代码实现、踩坑现象与个人实操理解。本文全部内容均为本地实际运行验证后的一手记录,选用新版本核心原因是 Spring AI 各版本 API 改动幅度极大,旧版本教程参考价值较低,优先跟进新版可规避大量 API 废弃、配置失效问题。 在 AI 大模型落地场景中,大模型原生能力存在边界,企业私有化业务数据、内部工具、第三方接口无法直接让大模型访问,行业内主流两种解决方案:Function Calling、MCP 协议工具调用。 Function Calling 适用于简单本地工具封装,工具与 AI 服务耦合在同一项目;而 MCP(Model Context Protocol)支持将工具独立抽离为单独服务,实现工具服务与 AI 对话服务解耦、可多服务共享、统一注册管理,支持公共 MCP 服务直接接入使用。本次实操重点完成手动自建 MCP 服务端,并搭配 Spring AI Alibaba 实现基础对话、流式输出、跨服务 MCP 工具远程调用全流程落地。

一. 创建项目

1.1 参考页面

java2ai.com/docs/versio… 补充说明:该页面可查看 Spring AI Alibaba、原生 Spring AI、Spring Boot 三者版本对应关系,实操前务必核对版本匹配,版本不匹配会出现依赖缺失、MCP 相关 Bean 无法自动注入、SSE 流式连接失败等问题。本次选用组合:spring-ai-alibaba 1.1.2.0、spring ai 1.1.2、spring boot 3.5.16,三者完全适配。

1.2 创建项目

1.2.1 新建 SpringAIAlibaba-Demo 项目

QQ_1784270307305.png

补充:整体采用多模块 Maven 聚合工程结构,父工程统一管控全部依赖版本,避免子模块重复定义版本号,降低版本冲突风险。

1.2.2 创建SpringAI-MCP-Server和SprigAI-Demo

QQ_1784270652593.png

模块分工说明:

  1. SpringAI-Demo:客户端模块,对接阿里百炼通义千问大模型,实现对话、流式、记忆、MCP 客户端调用;
  2. SpringAI-MCP-Server:独立 MCP 工具服务端,封装天气查询工具,对外提供标准化 MCP 工具调用能力;
  3. 父工程 SpringAIAlibaba-Demo:统一管理 bom、jdk、编码等公共配置。
1.2.3 配置 SpringAIAlibaba

配置版本,spring-al-alibaba 使用比较新的 1.1.2.0 版本,对应 spring ai 版本 1.1.2,spring boot 版本 3.5.16。因为是学习,尽量使用比较新的版本,因为 ai 每个版本的变化都比较大,有时前面刚学会的,后面就变得没太大价值了。

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-ai-alibaba.version>1.1.2.0</spring-ai-alibaba.version>
        <springboot.version>3.5.16</springboot.version>
        <!--  SpringAi 的版本号      -->
        <spring-ai.version>1.1.2</spring-ai.version>
    </properties>

补充注意点:JDK 强制要求 17 及以上,Spring Boot 3.x 不再支持 JDK8,本地运行前需确认环境 JDK 版本,否则直接编译报错。

1.2.4 统一版本管控 dependencyManagement

统一引进版本

  <dependencyManagement>
        <dependencies>
            <!--   SpringAi Alibaba 的版本管理        -->
            <dependency>
                <groupId>com.alibaba.cloud.ai</groupId>
                <artifactId>spring-ai-alibaba-bom</artifactId>
                <version>${spring-ai-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--   SpringAi 的版本管理         -->
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud.ai</groupId>
                <artifactId>spring-ai-alibaba-extensions-bom</artifactId>
                <version>${spring-ai-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

补充说明:引入三层 bom 后,子模块引入对应 starter 依赖时无需指定 version,自动继承父工程统一版本,杜绝子模块依赖版本混乱、jar 包冲突、类找不到等问题。

1.2.5 SpringAI-Demo 基础配置

pom.xml 的 dependencies

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${springboot.version}</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <!-- 阿里百炼大模型服务平台 -->
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
            <version>${spring-ai-alibaba.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
        </dependency>
    </dependencies>

补充依赖说明:

  1. spring-boot-starter-web:基础 web 服务,用于普通同步对话接口;
  2. dashscope starter:阿里百炼通义大模型对接核心依赖,自动装配 DashScopeChatModel;
  3. mcp-client-webflux:MCP 客户端依赖,基于 webflux SSE 协议连接远程 MCP 服务端,流式长连接必备。

application.yml

server:
  port: 8311

logging:   # SpringBoot日志配置
  level:
    # ChatClient 监控日志的等级
    org.springframework.ai.chat.client.advisor: debug
    
spring:
  ai:
    dashscope:
      # 阿里百炼大模型服务平台 API-Key申请文档
      # https://help.aliyun.com/zh/model-studio/get-api-key
      api-key: sk-****
      chat:
        options:
          model: qwen-max

补充配置踩坑点:

  1. api-key 禁止硬编码提交代码至仓库,生产环境建议通过环境变量、配置中心注入;
  2. model 可按需替换 qwen-turbo、qwen-plus 等规格,不同模型工具调用能力、响应速度存在差异;
  3. advisor 日志设为 debug,调试对话流程、工具调用链路时可打印完整请求、返回报文,排查问题效率更高。

Springboot 启动

package vip.wayhua.ivy.ai;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AIDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(AIDemoApplication.class, args);
    }
}

启动

QQ_1784271632790.png

二. 增加 Controller 调用测试

2.1 增加 ChatController

2.1.1 两种 Chat

Spring AI 有 ChatModel 和 ChatClient,ChatModel 是标准的方式调用,而 ChatClient 是对 ChatModel 进行了一次封装,使用起来方便很多。同时这两个都是通过配置注入的。

package vip.wayhua.ivy.ai.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ChatController {

    private final ChatModel chatModel;

    private final ChatClient chatClient;

    public ChatController(ChatModel chatModel, ChatClient.Builder builder) {
        this.chatModel = chatModel;
        this.chatClient = builder.build();
    }

}

补充二者适用场景区分:

  1. ChatModel:底层原生 API,流程透明,适合学习底层调用逻辑、自定义完整 Prompt 组装、精细控制请求参数;
  2. ChatClient:高层链式封装,代码简洁,内置记忆、工具、拦截器快捷 API,业务开发优先选用。
2.1.2 ChatModel 标准调用

调用方式 message-> UserMessage-> Prompt-> call (prompt)-> 返回 ChatResponse

这是最简单的调用,并且是阻塞式的,首先是要了解调用流程

@GetMapping("/simple/chat")
    public String simpleChat() {
        // 返回结果变量
        String res = "";
        //用户输入
        String message = "在咖啡馆里,想要杯星巴克";
        UserMessage userMessage = new UserMessage(message);
        //提示词
        Prompt prompt = new Prompt(userMessage);

        //调用大模型并获取响应(文本响就)
        ChatResponse chatResponse = chatModel.call(prompt);
        if (chatResponse.getResult() != null) {
            if (chatResponse.getResult().getOutput() != null) {
                res = chatResponse.getResult().getOutput().getText();
            }
        }

        return res;
    }
2.1.3 测试

http://127.0.0.1:8311/simple/chat

QQ_1784272303857.png 现在是阻塞方式,所以时间比较长,5.59s。

补充:单次响应耗时受网络、模型负载、输入文本长度影响,多次测试耗时会浮动。

2.1.4 ChatClient 方式调用

ChatClient 调用就比较简单,都是链式调用


    @GetMapping("/simple/chatclient")
    public String simpleChatByChatClient() {

        String res = "";

        //构建prompt -> 发送到大模型 -> 获取大模型返回

        //用户输入
        String message = "在咖啡馆里,想要杯星巴克";

        //链式调用

        res = this.chatClient
                .prompt(message) //构建prompt
                .call()  //发送到大模型
                .content() //获取大模型文本返回
        ;


        return res;

    }
2.1.5 分析源码

两者效果差不多,主要在于调用,可以直接传入 message。要想了解更多,可以查看源码。

	public ChatClientRequestSpec prompt(String content) {
		Assert.hasText(content, "content cannot be null or empty");
		return prompt(new Prompt(content));
	}

再查看 Prompt

	public Prompt(String contents) {
		this(new UserMessage(contents));
	}

由于可见 ChatClient 就是封装了 ChatModel 的,主要是方便调用,效率提升可不一定,刚才测试是 9s。再测试试一下。

补充耗时差异原因:ChatClient 内部增加参数校验、默认拦截器执行逻辑,少量额外开销,单次短文本对话差距明显;长文本、工具调用场景下开销占比可忽略。

2.1.6 测试 ChatClient

QQ_1784272754125.png 两次测试,确实调用时间要比 ChatModel 的方式时间长。

2.2 流式返回 Controller

流式返回就全部使用 ChatClient,虽然有时间长的问题,但是流式返回就可以忽略了。

流式返回,要配置 produces

 @GetMapping(value = "/simple/stream",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> streamChat() {
        String message = "在咖啡馆里,想要杯星巴克";

        //链式调用

        return this.chatClient
                .prompt(message) //构建prompt
                //.call()  //发送到大模型
                .stream() //以流式响应的方式和大模型进行交互
                .content() //获取大模型文本返回
                ;
    }

QQ_1784273179091.png 补充流式优势:SSE 长连接分段返回文字,前端实时展示打字效果,用户无等待卡顿感;底层基于 WebFlux 异步非阻塞,不占用容器同步线程,支持高并发。

2.3 SSE 定时发送空数据

/**
     * 基于SSE
     * @return
     */
    @GetMapping(value = "/flux/interval",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> sseToFrontPage() {
        return Flux.interval(Duration.ofSeconds(1)) //每1秒发送SSE协议消息
                //将Map结构组装SSE协议格式消息,
                //.map(seq->"{data:{},event:{},id:{}}\\n\\n")  ;

                //通过 ServerSentEvent 组装 SSE协议格式
                .map(seq->ServerSentEvent
                        .<String>builder()
                        .event("")
                        .data("")
                        .id("")
                        .build())

                ;
    }

这个是后面的内容。

QQ_1784273531917.png 每秒接收一条空数据

2.4 保存对话到内存

 @GetMapping(value = "/chat/memory",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> chatMemory(
            @RequestParam(value="message") String message,
            @RequestParam(value="chatId") String chatId
    ) {


        //构建prompt -> 发送到大模型 -> 获取大模型返回


        //链式调用

        return this.chatClient
                .prompt(message) //构建prompt

                /* **********************
                 *
                 * advisors() 相当于Spring AOP
                 * 针对单个的 ChatClient 实例
                 *
                 * 1. 请求信息的重复性工作,安全信息验证
                 * 2. 返回信息的格式化(json格式)
                 * 3. 监控(请求以及返回信息的网络延迟,网络错误), 写入日志
                 *
                 * 内置拦截器 (advisor 机制):
                 *
                 * SimpleLoggerAdvisor:对话监控日志开启
                 * MessageChatMemoryAdvisor:多轮对话的上下文记忆开启
                 *
                 * 自定义拦截器:继承CallAdvisor, StreamAdvisor
                 *
                 *
                 * 对话管理:
                 *
                 * ChatMemory 对话历史管理对象
                 * MessageWindowChatMemory 实现了 ChatMemory接口
                 * ChatMemoryRepository:历史对话存储方式 (接口)
                 * InMemoryChatMemoryRepository 实现了 ChatMemoryRepository接口 : 将对话储存在内存
                 *
                 *
                 * *********************/

                .advisors(new Consumer<ChatClient.AdvisorSpec>() {
                    @Override
                    public void accept(ChatClient.AdvisorSpec advisorSpec) {
                        advisorSpec.param(ChatMemory.CONVERSATION_ID,chatId);
                    }
                }) //拦截器
                //.call()  //发送到大模型
                .stream() //以流式响应的方式和大模型进行交互
                .content() //获取大模型文本返回
                ;

    }

QQ_1784273628186.png 补充记忆模块不足与优化方案:

  1. 默认 InMemoryChatMemoryRepository 仅内存存储,服务重启对话记录全部丢失,生产需替换 RedisChatMemoryRepository 持久化会话;
  2. MessageWindowChatMemory 默认存在消息条数上限,可自定义窗口大小控制上下文长度,避免 token 超限;
  3. chatId 由前端传入区分不同用户会话,需做好参数防重复、非法字符校验。

三. MCP-Server

3.1 配置以及启动

3.1.1 application.yml
server:
  port: 8301

logging:   # SpringBoot日志配置
  level:
    # ChatClient 监控日志的等级
    org.springframework.ai.chat.client.advisor: debug

spring:
  application:
    name: springai-mcp-server-weather
  ai:
    mcp:
      server:
        # MCP服务器名称
        name:  springai-mcp-server-weather
        version: 0.0.1
        type: SYNC

补充配置说明:

  1. name、version 为 MCP 服务唯一标识,客户端连接时匹配名称识别服务;
  2. type=SYNC 同步模式,适合工具简单、执行耗时短场景;长耗时工具可选用 ASYNC 异步模式。
3.1.2 pom 配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>vip.wayhua.ivy</groupId>
    <artifactId>SpringAIAlibaba-Demo</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>SpringAI-MCP-Server</artifactId>
  <packaging>jar</packaging>

  <name>SpringAI-MCP-Server</name>

  <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-webflux</artifactId>
      <version>${springboot.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.ai</groupId>
      <!--

              SpringAi 1.1 基于注解(Annotations)开发MCP
              基于注解(Annotations) 引入依赖 MCP-Annotations 依赖包

              spring-ai-starter-mcp-server-webflux 这个依赖包自动引入 MCP-Annotations 依赖包

              spring-ai-starter-mcp-server-webflux 属于 SpringAi,
              不属于 SpringAi Alibaba,
              所以需要引入SpringAi

               -->
      <artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
    </dependency>

  </dependencies>
</project>

补充依赖要点:MCP 服务端强制依赖 WebFlux,基于 SSE 长连接通信,不能仅引入 spring-boot-starter-web,否则 MCP 服务暴露接口异常,客户端无法建立连接。

3.1.3 启动项目
package vip.wayhua.ivy.mcp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class McpServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(McpServerApplication.class, args);
    }
}

3.1.4 查看

QQ_1784274038448.png 补充启动校验:日志打印 MCP Server 启动成功标识,代表工具服务注册完成,可等待客户端接入。

3.2 WeatherTool

在 tools 目录创建 WeatherTool。至于怎么获取温度不是我们这次的关键,流程搞通才是重要的。并增加日志,方便后面调用的时候查看。

package vip.wayhua.ivy.mcp.tools;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;

@Component
public class WeatherTool {
    private static final Logger log = LoggerFactory.getLogger(WeatherTool.class);

    @Tool(name = "Temperature",
            description = "获取指定城市当前时间的温度")
    public String getTemperature(
            @ToolParam String cityName
    ) {
        log.error("getTemperature->cityName->" + cityName);
        return cityName + "温度值是30度";
    }

    @Tool(description = "获取指定城市的紫外线值")
    public String getUltraviolet(@ToolParam String cityName) {
        log.error("getUltraviolet->cityName->" + cityName);
        return cityName + "紫外线值:103";
    }


}

补充注解规范:

  1. @Tool 的 description 描述必须清晰完整,大模型依靠描述判断何时调用该工具;描述模糊会导致模型不会主动触发工具调用;
  2. @ToolParam 建议补充参数说明,复杂参数可增加枚举、取值范围描述,提升工具调用准确性;
  3. 生产环境替换模拟返回,对接第三方气象 API,增加异常捕获、参数校验逻辑。

3.3 配置 Tools

package vip.wayhua.ivy.mcp.conf;

import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import vip.wayhua.ivy.mcp.tools.WeatherTool;

@Configuration
public class ToolsRegister {

    @Bean
    public ToolCallbackProvider toolList(WeatherTool weatherTool) {

        return MethodToolCallbackProvider.builder().toolObjects(weatherTool).build();
    }
}

只有配置过才可使用。

补充:多工具类场景可连续调用 toolObjects,支持一次性注册多个工具实例;遗漏该 Bean 会导致 MCP 服务无法向外暴露任何工具。

3.4 查看日志

QQ_1784274394228.png 补充日志解读:启动日志会打印所有注册成功的工具名称、入参、描述,可快速核对工具是否全部加载。

四. 调用 Mcp

4.1 demo 增加配置

mcp 中的配置,如下

server:
  port: 8301
spring:
  application:
    name: springai-mcp-server-weather
  ai:
    mcp:
      server:
        # MCP服务器名称
        name:  springai-mcp-server-weather
        version: 0.0.1
        type: SYNC

调用时,也要增加

server:
  port: 8311

logging:   # SpringBoot日志配置
  level:
    # ChatClient 监控日志的等级
    org.springframework.ai.chat.client.advisor: debug

spring:
  ai:
    dashscope:
      # 阿里百炼大模型服务平台 API-Key申请文档
      # https://help.aliyun.com/zh/model-studio/get-api-key
      api-key: sk-b956cd85b6cd472bacb8827be99bdaa9
      chat:
        options:
          model: qwen-max
    # MCP 客户端
    mcp:
      client:
        sse:
          connections:
            # MCP 服务端的名称
            springai-mcp-server-weather:
              url: http://localhost:8301

        # 必须添加以下配置
        toolcallback:
          enabled: true

connections 下面配置 Mcp 服务的名称,对应前面的名称。url 可以直接指定服务 ip 和端口。

补充配置踩坑点:

  1. toolcallback.enabled 必须开启,否则客户端无法拉取远程 MCP 工具列表;
  2. 多 MCP 服务端可在 connections 下新增多个节点,实现多组工具统一接入;
  3. 线上环境 url 替换服务注册中心地址,不硬编码localhost。

4.2 增加调用接口

为了简单,就直接放在 ChatController 中。

  @GetMapping("/mcp/weather/")
    String generation(
            @RequestParam(value = "message",defaultValue = "你有什么工具")
            String message
    ) {
        return this.chatClient
                .prompt(message)
                .call()
                .content();
    }

访问:

http://127.0.0.1:8311/mcp/weather/

QQ_1784274814634.png 你有什么工具,并没有显示 mcp,是因为没有引入。

4.3 ToolCallbackProvider

在 ChatController 中引用 ToolCallbackProvider toolCallbackProvider

    public ChatController(ChatModel chatModel,
                          ChatClient.Builder builder,
                          ToolCallbackProvider toolCallbackProvider) {
        this.chatModel = chatModel;
        this.chatClient = builder
                .defaultToolCallbacks(toolCallbackProvider)
                .build();
    }

补充原理:MCP 客户端自动将远程工具封装为 ToolCallback,通过 defaultToolCallbacks 全局注入 ChatClient,所有对话请求自动携带远程工具列表供大模型选择调用。

4.4 运行

QQ_1784275165675.png 表示成功了,不知道为什么没看到 methods。

补充:日志未打印 methods 属于日志输出粒度问题,不影响工具实际调用,可开启 trace 级日志查看完整工具元数据。

4.5 再次询问你有什么工具

QQ_1784275203820.png

4.6 询问天气

询问天气,就是人为制造调用函数的机会。

QQ_1784275299104.png 查看日志

QQ_1784275320004.png 真实调用就不是我们要讲解的,流程完成。后面会讲如何发布到 nacos,再发现调用(我也不会,要学)。

补充后续拓展方向(当前未落地,后续学习计划):

  1. MCP 服务注册至 Nacos 配置中心,客户端通过服务名动态发现,无需硬编码 IP 端口;
  2. MCP 工具权限管控,不同 AI 客户端隔离可调用工具;
  3. MCP 调用链路监控、超时重试、熔断降级;
  4. 统一 MCP 工具市场,实现工具一键发布、订阅。

五. 小结

实操收获总结

  1. 基础调用层面:掌握 Spring AI Alibaba 对接阿里百炼通义大模型两种调用方式 ChatModel、ChatClient,分清二者封装层级、性能差异、适用场景;实现同步阻塞对话、SSE 流式输出、心跳保活、内存多轮对话记忆完整接口,理解 Advisor 拦截器机制在对话流程中的作用。
  2. MCP 架构层面:厘清 Function Calling 与 MCP 核心区别,完成独立 MCP 服务端搭建、基于 @Tool 注解开发远程工具、工具 Bean 注册、SSE 客户端连接远程 MCP 服务全流程,验证大模型自动识别并远程调用 MCP 工具的完整链路。
  3. 版本与工程层面:搭建多模块 Maven 聚合工程,通过三层 BOM 统一管控 Spring AI、Spring AI Alibaba、Spring Boot 版本,规避版本冲突,梳理新版本 API 改动带来的各类配置、依赖踩坑点。

当前方案存在不足

  1. 对话记忆仅内存存储,服务重启会话丢失,无持久化方案,无法支撑线上用户长期会话;
  2. MCP 服务地址硬编码在配置文件,无服务注册发现机制,多实例部署、服务扩容、IP 变更维护成本高;
  3. 工具均为模拟数据,无真实第三方接口对接,缺少参数校验、异常捕获、超时处理逻辑;
  4. 缺少统一全局异常处理,大模型调用失败、MCP 连接断开、工具执行报错无友好返回;
  5. 无鉴权逻辑,大模型 API 密钥明文配置、MCP 服务无访问权限控制,存在安全风险;
  6. 未实现工具调用日志持久化、调用耗时监控,线上问题排查缺少数据支撑。

后续学习落地计划

  1. 接入 Redis 实现 ChatMemory 持久化,自定义会话过期策略;
  2. 研究 MCP 结合 Nacos 注册中心,实现服务自动发现、动态配置;
  3. 完善工具层封装,增加接口调用异常、参数校验、熔断重试;
  4. 统一全局异常处理器,封装 AI 调用各类异常返回格式;
  5. 增加接口鉴权、密钥加密存储、MCP 服务访问权限校验;
  6. 接入监控组件,记录对话耗时、工具调用次数、失败率指标。

六. 代码

完整聚合工程代码分为父工程、AI 客户端模块、MCP 服务端模块三部分,包含全部 pom 配置、yml 配置、Controller、MCP 工具类、配置类,可直接导入本地运行,仅需替换百炼平台 api-key 即可验证全流程功能。