AI在线 AI在线

最新版Spring Ai实践

作者:
2025-04-14 02:25
深入探索 Spring AI 1.0.0-M6在人工智能与软件开发深度融合的时代,Spring AI 作为一个强大的框架,持续为开发者提供着高效且便捷的工具,以实现与大语言模型(LLM)的无缝交互。 Spring AI 的最新版本引入了一系列令人瞩目的特性,其中 Function Calling 到 Tool Calling 的转换以及模型上下文协议(MCP)的应用,标志着该框架在 AI 集成领域的又一次重大飞跃。 聊天接口示例在今天的内容之前我们回一下如何使用SpringAI实现一个简单的聊天接口,使用千问API实现聊天功能:添加依赖复制配置复制实现复制当进行下面的提问时:现在北京时间几点了?

深入探索 Spring AI 1.0.0-M6

在人工智能与软件开发深度融合的时代,Spring AI 作为一个强大的框架,持续为开发者提供着高效且便捷的工具,以实现与大语言模型(LLM)的无缝交互。Spring AI 的最新版本引入了一系列令人瞩目的特性,其中 Function Calling 到 Tool Calling 的转换以及模型上下文协议(MCP)的应用,标志着该框架在 AI 集成领域的又一次重大飞跃。

聊天接口示例

在今天的内容之前我们回一下如何使用SpringAI实现一个简单的聊天接口,使用千问API实现聊天功能:

  1. 添加依赖
复制
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter</artifactId>
</dependency>
  1. 配置
复制
spring:
  ai:
    ## Alibaba
    dashscope:
      api-key: ${DASH_SCOPE_API_KEY}
      chat:
        enable: true
        options:
          model: qwen-max
  1. 实现
复制
@Bean
public ChatClient chatClient(ChatClient.Builder chatClientBuilder) throws IOException {

    var chatClient = chatClientBuilder
            .defaultSystem("You are a helpful assistant.")
            .defaultAdvisors(new SimpleLoggerAdvisor()) // LOG
            .build();
    return chatClient;
}

/**
 * 调用
 * @param message
 * @return
 */
public String completion(String message) {
    return chatClient
            .prompt().user(message)
            .call().content();
}

当进行下面的提问时:

现在北京时间几点了?

[引用]

Function Calling

图片

在早期的 AI 交互中,Function Calling 是一种常见的机制,允许模型在生成回复时调用外部函数以获取额外信息。然而,这种方式在扩展性和灵活性上存在一定的局限性。而 Spring AI 最新版本引入的 Tool Calling 则是对 Function Calling 的进一步演进。Tool Calling 将函数调用抽象为工具调用,将工具视为可复用的资源,模型可以根据需求动态调用这些工具,以完成更复杂的任务。在新版本中已经被改为Tool Calling。

工具主要用于:

信息检索

此类工具可用于从外部来源(例如数据库、Web 服务、文件系统或 Web 搜索引擎)检索信息。其目标是增强模型的知识,使其能够回答原本无法回答的问题。因此,它们可用于检索增强生成 (RAG) 场景。例如,可以使用工具检索给定位置的当前天气、检索最新新闻文章或查询数据库中的特定记录。

采取行动

此类别中的工具可用于在软件系统中采取行动,例如发送电子邮件、在数据库中创建新记录、提交表单或触发工作流。其目标是自动化原本需要人工干预或明确编程的任务。例如,可以使用工具为与聊天机器人交互的客户预订航班、在网页上填写表单,或在代码生成场景中基于自动化测试 (TDD) 实现 Java 类。

尽管我们通常将工具调用称为模型功能,但实际上工具调用逻辑是由客户端应用程序提供的。模型只能请求工具调用并提供输入参数,而应用程序负责根据输入参数执行工具调用并返回结果。

Spring AI 提供了便捷的 API 来定义工具、解析来自模型的工具调用请求以及执行工具调用。

为了解决上面关于时间问题的解决方案,我们可以定义一个工具,并嵌入到模型中...

复制
public class TimeTools {

    private static final Logger logger = LoggerFactory.getLogger(TimeTools.class);

    @Tool(description = "Get the time of a specified city.")
    public String getCityTimeMethod(@ToolParam(description = "Time zone id, such as Asia/Shanghai") String timeZoneId) {
        logger.info("The current time zone is {}", timeZoneId);
        return String.format("The current time zone is %s and the current time is " + "%s", timeZoneId, ZoneUtils.getTimeByZoneId(timeZoneId));
    }
}
复制
public ChatClient chatClient(ChatClient.Builder chatClientBuilder) throws IOException {
    // ...
    chatClientBuilder.defaultTools(timeTool);
    // ...
}

Function Calling实现了大语言模型(LLM)与外部函数或工具进行交互的能力。这一机制赋予了 AI 系统更强大的功能和灵活性,使其能够处理更加复杂和动态的任务。

注意不是所有模型都支持FunctionCalling

MCP

图片

MCP(Model Context Protocol,模型上下文协议) 是的一种开放协议,旨在统一大语言模型(LLM)与外部数据源、工具和服务之间的交互标准,推动 AI 应用的标准化和去中心化发展。 MCP 提供了一种统一的接口,使得不同的工具和服务可以以标准化的方式与模型进行交互。

核心功能

  1. 标准化交互 MCP 提供了一套通用的通信协议、数据格式和规则,使 LLM 能够以统一的方式与外部资源(如数据库、API、文件系统等)进行交互,无需为每个工具单独开发适配接口。
  2. 增强模型能力 通过 MCP,LLM 可以动态调用外部工具或数据源,例如实时获取天气信息、查询数据库、调用第三方服务等,从而扩展模型的功能边界。
  3. 安全与合规 MCP 内置了安全机制,确保数据传输的安全性,并支持细粒度的权限控制,避免数据泄露和滥用。
  4. 降低开发成本 开发者无需重复造轮子,可直接基于 MCP 协议构建 AI 应用,显著减少开发时间和成本。

在1.0.0-M6版本中引入了MCP,使得可以基于Spring AI实现各种扩展

此时聊天应用作MCP服务的调用者,也就是客户端,需要调用外部的MCP服务,首先对聊天服务改造:

  1. 添加必要的依赖:
复制
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
</dependency>
  1. 通过配置ChatClient完成集成:
复制
@Bean
    public ChatClient chatClient(ToolCallbackProvider toolsProvider) throws IOException {
        var chatClient = chatClientBuilder
                // ...
                .defaultTools( toolsProvider.getToolCallbacks() ) //mcp
                // ...
                .build();
        return chatClient;
    }

SpringAI中,MCP 客户端支持两种传输方式:STDIO 和 SSE。 标准启动器通过STDIO(进程内)和/或SSE(远程)传输同时连接到一个或多个 MCP 服务器。SSE 连接使用基于 HttpClient 的传输实现。每个与 MCP 服务器的连接都会创建一个新的 MCP 客户端实例。

STDIO

其实就是通过本地命令进行调用的实现,需要注意的是,返回的数据结果必须遵循MCP规范,我们可以基于Spring开发一个可执行的jar程序包,然后由客户端调用。

  1. 添加依赖
复制
<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-mcp-server-spring-boot-starter</artifactId>
</dependency>
  1. 实现Tool并注册
复制
@Service
public class TranslationService {
    
    @Tool(description = "将内容翻译成英文")
    public String translate(String content) {
        return "hello";
    }
}

@Bean
public ToolCallbackProvider translationTools(TranslationService translationService) {
   return MethodToolCallbackProvider.builder().toolObjects(translationService).build();
}
  1. 添加配置,注意这里要关掉所有日志相关的输出
复制
spring:
   main:
      web-application-type:none
      banner-mode:off
   ai:
      mcp:
         server:
            name:translation-server
            version:0.0.1
logging:
   level:
      root:off
  1. 打包,记得使用spring-boot-maven-plugin插件打包,下面的mcpServers引用的就是这里的jar
  2. 修改聊天应用配置,并且重启
复制
spring:
  ai:
    mcp:
      client:
        type: SYNC
        stdio:
          servers-configuration: classpath:mcp-stdio-servers.json

mcp-stdio-servers.json

复制
{
   "mcpServers": {
      "weather": {
         "command": "java",
         "args": [
            "-Dspring.ai.mcp.server.stdio=true",
            "-Dspring.main.web-application-type=none",
            "-Dlogging.pattern.cnotallow=",
            "-jar",
            "your_jar_path/mcp-stdio-server-1.0.1-SNAPSHOT.jar"
         ],
         "env": {}
      }
   }
}

提问: 翻译单词运势

[引用]

因为我没有实现,全部返回的是hello,看样子模型对我们的结果进一步做了处理

SSE

这里提供一个简单的示例,主要实现星座运势获取的Mcp,这是一个单独的基于Spring开发的应用,与上面的聊天应用隔离:

  1. 引入相关依赖
复制
<dependency>
   <groupId>org.springframework.ai</groupId>
   <artifactId>spring-ai-mcp-server-webmvc-spring-boot-starter</artifactId>
</dependency>
  1. 定义Tool实现
复制
@Service
publicclass HoroscopeService {

    private String url = "https://apis.tianapi.com/star/index?key=%s&astro=%s";
    private String key = "xx";

    private RestTemplate restTemplate = new RestTemplate();
    private ObjectMapper objectMapper = new ObjectMapper();

    @Tool(description = "Get constellation fortune by consName")
    public String getFortune(String consName) {
        Map map = restTemplate.getForObject(String.format(url, key, consName), Map.class);
        try {
            return objectMapper.writeValueAsString(map.get("result"));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return"获取失败:"+ e.getMessage();
        }
    }
}
  1. 配置文件
复制
spring:
   ai:
      mcp:
         server:
            name:webmvc-mcp-server
            version:1.0.0
            type:SYNC
            sse-message-endpoint:/mcp/messages

server:
   port:8081
   servlet:
      encoding:
         charset:utf-8
         enabled:true
         force:true
  1. 启动应用,访问:http://localhost:8081
  2. 修改聊天应用配置,并且重启
复制
spring:
  ai:
    mcp:
      client:
        type: SYNC
        sse:
           connections:
              constellation:
                 url: http://localhost:8081

提问: 白羊座的运势

[引用]

结束语

现阶段的AI技术,恰似一台功能强大却需精心调校的计算机系统。它并非“即插即用”的万能工具,而是需要开发者如同配置硬件般,根据特定业务场景的需求,按需增加“认知模块”与“计算资源”。这种灵活扩展的能力,与模块化计算平台(MCP,Modular Computing Platform)的设计理念不谋而合——通过标准化接口与可组合架构,让AI系统既能像积木般自由拼接算法能力,又能像云计算般弹性调度算力资源。开发者需像搭建乐高城堡般,将自然语言处理、视觉识别、决策推理等模块按需组合,再通过数据管道与反馈机制持续优化,最终让AI在医疗诊断、智能制造、智慧城市等垂直领域中,展现出接近专家水平的场景化智能

相关标签:

相关资讯

低价Claude3.7极速使用,白票Deepseek满血R1

在当今数字化时代,人工智能技术正以前所未有的速度改变着我们的工作和生活方式。 无论你是开发者、创意工作者、还是企业管理者,拥有高效、经济的AI工具已成为提升效率的关键。 而今天,我要向大家隆重推荐的Token-AI平台,正是实现这一目标的完美解决方案。
3/11/2025 2:00:00 AM
tokengo

5090跑《黑神话》飙到200+帧,英伟达DLSS也用上Transformer了

现在,打个游戏都用上Transformer了? 老黄的DLSS进行了一波大升级,换上了基于Transformer的新大脑。 用上新模型之后,光线重建和超分辨率,效果都变得更细腻了。
1/20/2025 7:00:00 AM
量子位

o1不是聊天模型!前SpaceX工程师:这样用o1才能解决复杂问题

「我是如何从讨厌o1到每天用它来解决我最重要的问题的? 我学会了如何正确使用它。 」Ben Hylak曾是SpaceX软件工程师、苹果VisionOS人机交互设计师,后来离职创立了Dawn Analytics。
1/20/2025 9:28:00 AM
新智元