Spring AI与MCP客户端集成:Java开发指南与实践

本文介绍了在Java中通过Spring AI和原生SDK集成MCP客户端的方法,简化大模型工具调用,并对比了两种方式的优劣。

原文标题:MCP客户端调用看这一篇就够了(Java版)

原文作者:阿里云开发者

冷月清谈:

本文深入探讨了在Java环境中使用MCP(模型上下文协议)客户端的两种主要方法:通过Spring AI框架和使用原生SDK。MCP旨在统一大模型工具调用的规范,解决客户端和服务端对接方式不一致的问题。文章详细介绍了如何利用Spring AI简化MCP客户端的配置和调用过程,包括引入依赖、配置LLM接口(如OpenAI),以及配置SSE和Stdio两种类型的MCP服务。同时,文章也介绍了如何使用原生MCP SDK进行更底层的控制和开发,包括获取MCP服务中的资源和发起调用。此外,还分享了使用过程中遇到的常见问题和解决方法。文章最后对比了框架和原生SDK的优劣,建议平台级研发更多采用原生方式以实现更灵活的控制和定制化。

怜星夜思:

1、在使用Spring AI集成MCP客户端时,如果需要动态地为不同的用户或会话绑定不同的MCP工具,应该如何实现?文章中提到的“助理平台”场景下,这种动态绑定具体有哪些应用场景?
2、文章提到了Spring-AI-Alibaba项目对Spring AI的扩展,使其更适合集团内部技术栈。那么,对于非阿里集团的开发者,这些扩展是否具有参考价值?在什么情况下,非阿里集团的开发者也应该考虑使用Spring-AI-Alibaba?
3、文章对比了使用框架和原生SDK进行MCP客户端开发的优劣,并建议平台级研发更多采用原生方式。那么,对于一个从零开始构建的AI平台,在技术选型上,应该如何平衡开发效率和灵活性?是否有更折中的方案?

原文内容

如果没有MCP

MCP协议的初衷是希望能将大模型的工具调用来做统一,对于 MCP 的原理介绍的文章已经随处可见,相信大家都有自己的见解,这里简单介绍一些没有MCP之前的痛点问题,帮助大家理解为何需要MCP。

1.客户端:每个工具暴露出来的对接方式都不一样,客户端为了去对接各类工具,需要做很多开发,比如getWeather工具是一个http服务,getLocation是一个HSF服务,并且两种入参,出参的数据结构都不一样,那这时候的对接开发成本就会很高;

2.服务端:A平台Agent和B平台Agent所需要服务的约定不一致,同一个服务需要考虑客户端的约定,开发两套接口,开发成本和维护成本都较高;

因此,MCP的出现约定了在AI开发领域客户端和服务端的对接规范,当然未来也许会有更好用的协议也会替代MCP成为一种新的规范。

大模型调用MCP姿势

框架篇

Spring-AI
引包

这里使用最新的M7版本(此前M6版本中的MCP包里面有部分问题,会将SSE类型的服务端url做改写,导致某些SSE服务调用报错 ,社区在M7版本中已经做了依赖升级)。

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-client</artifactId>
    <version>1.0.0-M7</version>
</dependency>
配置LLM接口
Spring-AI支持的LLM类型有很多,基本涵盖了各个平台的LLM接口规范,具体可以参考官方文档中介绍[1]。

我们平常用OpenAI的规范多一些,并且Idealab中也提供了开放接口,这里我们采用OpenAI接口作为chatModel,当然大家也可自行封装自己的API为OpenAI规范,如Whale上部署的模型也都是支持OpenAI协议的。

#配置chatModel的域名,这里我们使用的idealab
spring.ai.openai.base-url=https://idealab.alibaba-inc.com
#配置chat的ak
spring.ai.openai.api-key=脱敏
#配置chant的接口路径
spring.ai.openai.chat.completions-path=api/openai/v1/chat/completions
#配置模型
spring.ai.openai.chat.options.model=gpt-4o-0513-global
#其他参数配置
spring.ai.openai.chat.options.temperature=0.1

模型配置完以后开始注册我们的chatModel:

@Configuration
publicclassChatClientConfig {
    @Autowired
    private ToolCallbackProvider tools;
    @Autowired
    OpenAiChatModel chatModel;
    @Bean
    public CommandLineRunner predefinedQuestions(
            ConfigurableApplicationContext context) {
        return args -> {
            // 构建ChatClient,此时不注入任何工具
            var chatClient = ChatClient.builder(chatModel)
                    .build();
            String userInput = "帮我将这个网页内容进行抓取 https://www.shuaijiao.cn/news/view/68320.html";
            System.out.println("\n>>> QUESTION: " + userInput);
            System.out.println("\n>>> ASSISTANT: " + chatClient.prompt().user(userInput).call().content());

            context.close();
        };
    }

此时我们先不配置chatModel的工具,只是作为一个最基本的LLM利用Spring-AI配置化框架进行调用看看效果。

此时的回答就是没有任何工具的一个最基础的LLM能力,接下来我们开始为这个chatModel上添加MCP工具,利用框架去直接让大模型调用MCP服务。

配置MCP服务

上述配置chatClient的过程中我们发现,使用框架提供的能力去调用LLM的API比我们自己去写客户端对接API来的方便。

而调用MCP的过程,使用框架的提效会更明显,直接给chatClient注入工具即可,不用我们去手动写functionCall的组装,以及获取到结果后再去调用对应服务。

1.服务端为SSE方式提供

a.设置配置文件

spring.ai.mcp.client.name=ai-demo
spring.ai.mcp.client.type=SYNC
spring.ai.mcp.client.toolcallback.enabled=true
spring.ai.mcp.client.request-timeout=30000
spring.ai.mcp.client.enabled=true
# 配置mcp的服务端sse地址,这里选用了一个开源的抓取网站内容的工具
spring.ai.mcp.client.sse.connections.server1.url=https://mcp-09724909-442f-4b85.api-inference.modelscope.cn

b.给chatModel注入工具

运行结果:

此时可以发现,我们的chatModel不再是一个原生的LLM接口,已经可以根据用户意图来自主调用我们的MCP工具。

当然我们也可以看出,利用Spring-AI做MCP调用是非常简单,只需配置好LLM的调用接口和MCP工具地址即可。

作为Demo此时没有任何问题,但如果作为工程实现,比如我们要去做一个助理平台,这时候其实每个助理所绑定的MCP工具是动态的,而非像上述这样在应用启动时初始化好的Bean,这种场景也是可以实现的,Spring-AI也支持在调用过程中动态封装工具,这些工具可以是MCP,也可以是程序中的Bean,或者是某些HTTP、RCP接口等。

2.服务端为stdio方式提供

a.配置Properties

Stdio和SSE配置的区别是将调用方式由显示的服务地址换成npm、java、python等脚本命令直接执行的远程包或本地包。

这里采用本地配置文件的方式去配置Stdio,即spring.ai.mcp.client.stdio.servers-configuration=classpath:/mcp-servers-config.json。

spring.ai.mcp.client.name=ai-demo
#spring.ai.mcp.client.type=SYNC
spring.ai.mcp.client.toolcallback.enabled=true
spring.ai.mcp.client.request-timeout=30000
spring.ai.mcp.client.enabled=true
spring.ai.mcp.client.stdio.servers-configuration=classpath:/mcp-servers-config.json

b.配置config.json

这里注入了两个比较经典的MCP服务,百度地图和新闻热点服务:

{
  "mcpServers": {
    "baidu-map": {
      "command": "npx",
      "args": [
        "-y",
        "@baidumap/mcp-server-baidu-map"
      ],
      "env": {
        "BAIDU_MAP_API_KEY": "Qr0GV6v4krVPlIJkupyPpi63d1zXh0Ko"
      }
    },
    "mcp-server-hotnews": {
      "command": "npx",
      "args": [
        "-y",
        "@wopal/mcp-server-hotnews"
      ]
    }
  } 
}

c.给chatModel注入工具

@Configuration
publicclassChatClientConfig {
    @Autowired
    private ToolCallbackProvider tools;
    @Autowired
    OpenAiChatModel chatModel;
    @Bean
    public CommandLineRunner predefinedQuestions(
            ConfigurableApplicationContext context) {
        return args -> {
            // 构建ChatClient,注入mcp工具
            var chatClient = ChatClient.builder(chatModel).defaultTools(tools.getToolCallbacks())
                    .build();

            // 使用ChatClient与LLM交互
            String userInput = “帮我查找今天的知乎热帖”;
            System.out.println(“\n>>> QUESTION: " + userInput);
            System.out.println(”\n>>> ASSISTANT: " + chatClient.prompt().user(userInput).call().content());

            context.close();
        };
    }
}

d.让LLM自主选择工具调用

用户输入为热点查询的提问时:

用户输入为地点检索时:

通过上述例子可以发现,我们在初始化时配置了两个MCP服务,LLM可以根据用户不同提问来自行选择不同的工具去调用,方式也比较简单。

Spring-AI-Alibaba

上述介绍了Spring-AI框架对于MCP调用的支持和使用方式,但在集团内部,Spring-AI-Alibaba项目在此基础上也做了很多封装,更适合集团技术栈和内部中间件的无缝衔接,以及基于Spring-AI项目扩展了很多example项目可以参阅学习。如:Stramable HTTP 方式的MCP调用、OpenManus的实现等等,可以帮助开发者最更上层的封装调用[2]。

基于Spring-AI-Alibaba做MCP客户端的实现与Spring-AI框架基本相似,一些差一点主要有:

1.引入依赖时,在Spring-AI-MCP客户端包的基础上,需要新增com.alibaba.cloud.ai的依赖,如下所示:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-client</artifactId>
    <version>1.0.0-M7</version>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter</artifactId>
    <version>1.0.0-M6.1</version>
</dependency>

2.配置chatModel时,Spring-AI-Alibaba支持百炼平台上的模型及API,即

spring:
  ai:
    dashscope:
      # 配置通义千问API密钥
      api-key: ${DASH_SCOPE_API_KEY}

3.支持Stramable HTTP 模式的MCP调用,配置方式与Spring-AI的SSE客户端配置方式一致,但Spring-AI-Alibaba底层是自主实现了Stramable HTTP的get和post请求并集成在了Spring-AI框架中,具体可参考[3]。

自研篇

io.modelcontextprotocol.sdk+functionCall

通过上述介绍,我们发现既然框架层面已经为我们封装好了很规范的MCP调用方式,通过简单配置即可实现MCP客户端,本章节将介绍原生的MCP SDK调用方式,对于平台类研发可能更有帮助。

1. 引入依赖

<dependency>
    <groupId>io.modelcontextprotocol.sdk</groupId>
    <artifactId>mcp</artifactId>
    <version>0.9.0</version>
</dependency>
2. 获取该MCP服务中的所资源(方法、入参、描述等)
private McpSyncClient mcpClient;

    privatestaticfinal String sseServerUrl = “https://mcp-09724909-442f-4b85.api-inference.modelscope.cn”;

    @PostConstruct
    publicvoidinit(){
        try {
            McpClientTransport transport = new HttpClientSseClientTransport(sseServerUrl);
            mcpClient = McpClient.sync(transport)
                    .requestTimeout(Duration.ofSeconds(20L))
                    .capabilities(ClientCapabilities.builder()
                                          .roots(true)
                                          .sampling()
                                          .build())
                    .build();
            mcpClient.initialize();
        } catch (Exception e) {
            thrownew RuntimeException(“初始化MCP客户端对象失败”, e);
        }
    }

    @PreDestroy
    publicvoiddestroy(){
        if (mcpClient != null) {
            mcpClient.closeGracefully();
        }
    }

    @Bean
    public String getToolList(){
        ListToolsResult toolsResult = mcpClient.listTools();
        for (Tool tool:toolsResult.tools()) {
            System.out.println(tool.name());
            System.out.println(tool.description());
            System.out.println(tool.inputSchema());
        }
        return null;
    }

即初始化构建了MCP客户端和实例关闭动作,通过listTools即可得到该MCP-Server中的所有资源,如下示例:

其中inputSchema即用来作为functionCall中tools中的对象,获取到该描述后,我们就可以在调用functionCall的时候这样填写tools中每个方法中的properties。

3. McpSyncClient来发起调用
@Bean
    public String getToolList(){
        ListToolsResult toolsResult = mcpClient.listTools();
        for (Tool tool:toolsResult.tools()) {
            System.out.println(tool.name());
            System.out.println(tool.description());
            System.out.println(tool.inputSchema());

            Map<String, Object> schemaMap = new HashMap<>();
            schemaMap.put(“type”, “object”);
            Map<String, Object> properties = new HashMap<>();
            if (tool.inputSchema().properties() != null) {
                tool.inputSchema().properties().forEach((key, value) -> {
                    properties.put(key, value);
                });
            }
            schemaMap.put(“properties”, properties);

            if (tool.inputSchema().required() != null && !tool.inputSchema().required().isEmpty()) {
                schemaMap.put(“required”, tool.inputSchema().required());
            }
            Map<String,Object> parameters = new HashMap<>();
            parameters.put(“url”,“https://www.shuaijiao.cn/news/view/68320.html”);
            CallToolResult toolResult = mcpClient.callTool(new CallToolRequest(“fetch”, parameters));
            System.out.println(extractTextContent(toolResult));

        }
        return null;
    }

    private String extractTextContent(CallToolResult toolResult){
        StringBuilder resultText = new StringBuilder();
        toolResult.content().forEach(content -> {
            if (content instanceof TextContent) {
                resultText.append(((TextContent) content).text());
            }
        });
        return resultText.toString();
    }

上述示例中,通过mock了一个parameters作为functionCall返回的格式,传给CallToolRequest中,并且显示的指定调用的方法是fetch方法,运行结果如下:

通过上述过程发现,其实调用MCP的SDK去做封装和开发也是比较简单的,只需调用资源获取接口,拿到工具列表传给functionCall,并且将LLM分析出的结果拿到后来调用MCP的call方法即可。

踩坑记录

1. 1.0.0-M6版本SSE方式报错Caused by: java.lang.IllegalStateException: Multiple tools with the same name

解决方式:在启动类上排除SseHttpClientTransportAutoConfiguration 即可。(换成1.0.0-M7版本后没有出现)。

2. SSE方式不带/SSE的时候报错 服务找不到,本质原因是地址url被改写

解决方式:Spring-AI的话升级1.0.0-M6到1.0.0-M7版本,并且单独引入io.modelcontextprotocol.sdk 0.9的版本。

3. 启动时报错MCP服务连接超时

试了很久发现,本身一些MCP服务是做了IP安全证书等等,localhost本身ping不通,可尝试换一些公开可访问的url尝试,如本文示例中的fetch网页内容的url。

思考

本文针对框架和原生SDK的调用都做了总结,那如何选型,或者说如何取舍两种不同技术路线来支撑平台型研发呢?

如果我们自己开发一套这样的流程,其中包括意图识别、工具描述获取、functionCall入参拼接、LLM调用结果获取、工具调用、上下文记忆配置......岂不是需要投入很多的人力成本?甚至说是Spring-AI-Alibaba开源的openManus,如果我们自己开发工作量可想而知,从使用者的视角出发,采用框架固然可以很快的构建出自己的个人超级Agent,但从平台开发视角出发,我们仍然需要调用底层sdk去更好的服务上层,比如现在很多的AI助理平台中,一个Agent不仅仅是支持调用工具,还支持其他Agent的嵌套调用、如RAG知识检索、工作流调用等等,如果采用框架来开发。

一方面需要很大的成本将自己平台的调用姿势对接成框架底层的调用,如将平台某个Agent关联的其他Agent及工具都要抽象成适合框架的工具,才能发起调用;另一方面,框架调用会屏蔽很多处理细节,比如一次规划中到底使用了哪些工具、当前执行到哪个工具,此工具的输出是什么等等,都是需要展示给用户的,框架层面难以将很多个性化的细节一一暴露给用户。

因此面向AI平台研发工程,个人觉得还是需要用原生的方式去打磨平台能力,一些如openMauns等复杂流程,如果在框架中后续暴露出接口,可以结合框架做调用,而不是完全依赖框架。

总结

本文针对MCP客户端的开发,详细介绍了如何通过Spring-AI框架和原生SDK调用MCP服务,并对使用过程中遇到的一些问题进行了记录。整体来说,框架调用简单快捷,适合快速构建应用;而原生SDK则提供更灵活的控制,适合平台级开发。

本文所实践的示例仅基于一次调用过程,但MCP真正发挥其“链接模型和数据”意义可能需要体现在规划反思类场景中,最近也在做此类场景的研发模式探索,大致上有几个方向:1. 提示词中做规划打标,每次结束后重新思考需要调用什么工具  2. 规划本身作为一个工具去每次调用 3. Spring-AI-Alibaba发布的openManus开源代码的设计。后续将在新的文章中做分享。

参考资料

[1]https://docs.spring.io/spring-ai/reference/api/index.html

[2]https://java2ai.com/docs/1.0.0-M6.1/overview/?spm=0.29160081.0.0.79fa20f6jEvcRH

[3]https://java2ai.com/blog/spring-ai-alibaba-mcp-streamable-http/?spm=0.29160081.0.0.1cb05b624WFIFp#%E9%9B%86%E6%88%90%E5%88%B0-spring-ai-%E6%A1%86%E6%9E%B6

[4]https://java2ai.com/docs/1.0.0-M6.1/overview/?spm=0.29160081.0.0.1cb05b624WFIFp

[5]https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html#_standard_mcp_client

[6]https://github.com/springaialibaba/spring-ai-alibaba-examples/blob/main/spring-ai-alibaba-mcp-example/starter-example/client/starter-default-client/pom.xml

[7]https://bailian.console.aliyun.com/?spm=5176.29015046.0.0.1dd4778bb93yqh&tab=app#/app-market

[8]https://openlm.alibaba-inc.com/web/workbench/chatOs/public-tools?projectName=alsc_eleme_iic&pathname=%2Fpublic-tools

[9]https://java2ai.com/mcp/?spm=0.29160081.0.0.1cb05b624WFIFp

OpenLake大数据&AI一体化解决方案


本方案是基于开放可控数据湖仓构建的大数据/搜索/AI一体化解决方案。通过元数据管理平台DLF管理结构化和半/非结构化数据,提供湖仓数据表和文件的安全访问及IO加速。支持多引擎对接和平权协同计算,通过DataWorks统一开发,并保障大规模任务调度。    


点击阅读原文查看详情。

Spring-AI-Alibaba,听起来就很“重”。小公司或者个人开发者,还是先用Spring AI把基本功能搞定再说吧。除非你们公司以后打算全面拥抱阿里云,那可以提前研究一下。

不过,学习一下总是没错的。看看人家是怎么解决问题的,说不定以后能用上。万一哪天被阿里收购了呢?(手动狗头)

我觉得动态绑定MCP工具这块儿,关键在于如何管理这些“工具”。如果把每个工具都看作一个服务,那是不是可以用服务注册发现那一套东西来管理?比如每个用户登录的时候,根据他的角色,从注册中心拉取对应的工具列表,然后动态地注册到Spring容器里。

“助理平台”场景下,有个很实际的应用就是角色权限控制。想象一下,一个客服助理和一个销售助理,他们需要的工具肯定不一样。客服可能需要查询订单状态、退款申请之类的工具,销售可能需要客户信息、销售预测之类的工具。动态绑定就能保证他们只能访问自己需要的工具,避免误操作。

针对动态绑定MCP工具的问题,可以考虑以下方案:

1. 基于用户/会话的配置: 为每个用户或会话维护一个MCP工具列表,存储在数据库或者缓存中。在发起请求时,根据当前用户/会话的ID动态加载对应的工具列表,并将其注入到ChatClient中。

2. 使用Spring Bean的动态注册: 利用BeanDefinitionRegistry,在运行时动态注册ToolCallback的Bean。这种方式需要更深入地理解Spring的Bean管理机制,但可以实现更灵活的工具配置。

3. 自定义ToolCallbackProvider: 实现一个自定义的ToolCallbackProvider,该Provider可以根据用户/会话信息动态地返回不同的ToolCallback列表。然后在ChatClient构建时使用这个自定义的Provider。

在“助理平台”场景下,动态绑定的应用场景包括:

* 权限控制: 不同用户可能有不同的工具使用权限,动态绑定可以确保用户只能访问其有权使用的工具。
* 个性化定制: 不同用户可以根据自己的需求定制助理的功能,例如,某些用户可能需要更多的金融分析工具,而另一些用户可能需要更多的营销工具。
* AB测试: 可以动态地为一部分用户绑定新的工具,观察其使用情况,以便评估新工具的有效性。

我觉得Spring-AI-Alibaba的参考价值主要在于它的一些最佳实践。毕竟是大厂内部用的东西,肯定解决了很多实际问题,踩过不少坑。比如那个Streamable HTTP,如果你的应用对性能要求很高,那就可以好好研究一下它的实现。

至于是否使用,我觉得主要看你的项目是否和阿里的技术栈有交集。如果没有,那可能直接使用的价值不大,但可以学习它的设计思路和实现方式,应用到自己的项目中。

说实话,从零开始搞AI平台,除非你是大厂,否则还是别想太多“灵活性”了。先活下来再说!

我的建议是,能用开源的就用开源的,能用框架的就用框架的。不要重复造轮子,把精力放在解决实际问题上。

等平台做大了,用户多了,钱也多了,再考虑“灵活性”的事情。到时候,可以招几个大牛,专门负责底层架构的优化和重构。

我觉得这个问题没有标准答案,完全取决于你的资源目标。如果你的团队人手不足,时间紧迫,那就老老实实用框架,快速上线。如果你的团队技术实力雄厚,追求极致的性能和灵活性,那就选择原生SDK。

更折中的方案,我觉得是先用框架,再逐步重构。先用框架把基本功能实现,跑起来,收集用户反馈。然后,根据用户的实际需求,逐步用原生SDK重构一些关键模块。这样,既能保证开发效率,又能逐步提高平台的灵活性。

从零开始构建AI平台,在技术选型上平衡开发效率和灵活性,我认为可以采取以下策略:

1. 分阶段实施: 初期为了快速验证MVP,可以使用Spring AI这样的框架,快速搭建MCP客户端,实现基本功能。后期,随着平台功能的不断丰富和对灵活性的要求越来越高,可以逐步将核心模块迁移到原生SDK。

2. 采用“框架+SDK”混合模式: 对于一些通用的、标准化的功能,可以使用框架来简化开发。对于一些需要高度定制化的功能,可以使用原生SDK来实现。

3. 构建自己的抽象层: 在框架和原生SDK之上,构建一个自己的抽象层,封装底层的实现细节。这样,即使底层技术发生变化,上层应用也可以保持稳定。

4. 领域驱动设计(DDD): 使用DDD的思想,将平台划分为多个领域,每个领域可以选择最适合自己的技术方案。例如,对于工具管理领域,可以使用原生SDK来实现更灵活的工具注册和发现机制;对于任务调度领域,可以使用框架来简化任务的编排和管理。

更折中的方案:

* 基于框架进行扩展: 如果框架提供了扩展点,可以在框架的基础上进行二次开发,实现定制化的功能。例如,可以自定义ToolCallbackProvider,实现动态工具绑定。
* 使用DSL(领域特定语言): 定义一套自己的DSL,用于描述AI任务的流程和工具的调用。然后,使用DSL引擎来执行这些任务。这样,既可以提高开发效率,又可以保证灵活性。

谢邀,刚从厕所出来。

动态工具绑定,我觉着可以搞个“工具市场”,用户自己选购。有点像手机应用商店,每个工具都是一个“应用”,用户可以根据自己的需求安装/卸载。平台负责管理这些工具,提供统一的API接口。

至于应用场景,那可太多了!比如,可以根据用户的使用习惯,推荐一些常用的工具;或者搞一些“组合套餐”,把几个常用的工具打包在一起,优惠出售。

不过,这种模式下,安全问题很重要。要确保用户安装的工具不会对系统造成危害,也不能泄露用户的隐私数据。

Spring-AI-Alibaba项目虽然是针对阿里集团内部技术栈做的扩展,但其中的一些设计思想和实现方式对于非阿里集团的开发者仍然具有一定的参考价值。

1. Streamable HTTP 方式的MCP调用: 这种方式可以提高数据传输效率,降低延迟,尤其是在处理大量数据或者实时性要求高的场景下。非阿里集团的开发者可以借鉴其实现,优化自己的MCP调用。

2. OpenManus的实现: OpenManus是一个工作流引擎,可以用于编排和管理复杂的AI任务。非阿里集团的开发者可以学习其设计思想,构建自己的AI工作流平台。

3. 对百炼平台模型的支持:如果你的项目也使用了类似的云服务平台提供的LLM,可以参考Spring-AI-Alibaba的配置方式,快速集成到你的项目中。

在以下情况下,非阿里集团的开发者也可以考虑使用Spring-AI-Alibaba:

* 项目需要与阿里集团的某些服务进行集成:例如,需要调用阿里云的某些API或者使用阿里集团的某些数据。
* 项目中需要实现类似OpenManus的工作流引擎:可以基于Spring-AI-Alibaba的代码进行二次开发。
* 对Spring AI框架有深入的了解,并且希望学习和借鉴阿里集团在AI领域的实践经验:可以阅读Spring-AI-Alibaba的源码,了解其设计思想和实现方式。