it编程 > 编程语言 > Java

Spring AI使用tool Calling和MCP的示例详解

4人参与 2025-07-26 Java

深入探索 spring ai

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.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程序包,然后由客户端调用。

<dependency>
  <groupid>org.springframework.ai</groupid>
  <artifactid>spring-ai-mcp-server-spring-boot-starter</artifactid>
</dependency> 
@service
public class translationservice {
    @tool(description = "将内容翻译成英文")
    public string translate(string content) {
        return "hello";
    }
}
@bean
public toolcallbackprovider weathertools(translationservice translationservice) {
   return methodtoolcallbackprovider.builder().toolobjects(translationservice).build();
}
spring:
   main:
      web-application-type: none
      banner-mode: off
   ai:
      mcp:
         server:
            name: translation-server
            version: 0.0.1
logging:
   level:
      root: off 
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.console=",
            "-jar",
            "your_jar_path/mcp-stdio-server-1.0.1-snapshot.jar"
         ],
         "env": {}
      }
   }
}

提问: 翻译单词运势

回答: 看起来在处理您的请求时发生了一些混淆。单词"运势"的正确英文翻译应为 “fortune” 而非 “hello”。如果您需要关于星座运势的信息,请告诉我您的星座名称。如果是其他类型的运势,请提供更多的细节。

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

sse

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

<dependency>
   <groupid>org.springframework.ai</groupid>
   <artifactid>spring-ai-mcp-server-webmvc-spring-boot-starter</artifactid>
</dependency>
  1. 定义tool实现
@service
public class 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();
        }
    }
}
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 
spring:
  ai:
    mcp:
      client:
        type: sync
        sse:
           connections:
              constellation:
                 url: http://localhost:8081

提问: 白羊座的运势

回答: 今天白羊座的运势如下: - 综合指数:80% - 爱情指数:70% - 工作指数:55% - 财运指数:65% - 健康指数:80% - 幸运颜色:蓝色 - 幸运数字:5 - 贵人星座:射手座 今日概述:今天你可能会忍不住向另一半抱怨工作上遇到的问题,但这样也会给对方带来困扰。在感情中,要注意不要过多地向对方发泄负面情绪,而应该把温暖和幸福带给他们。

结束语

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

到此这篇关于spring ai使用tool calling和mcp的示例详解的文章就介绍到这了,更多相关spring ai tool calling和mcp内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

Java应对高并发的思路和最佳实践

07-26

Java快速转C#的简明教程

07-26

Java使用StopWatch输出执行耗时的方法详解

07-26

Java Thread中join方法使用举例详解

07-26

springboot使用外置的Servlet容器步骤

07-26

vscode 登录ssh如何记住密码直接登录设置

07-26

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论