spring-ai-alibaba 1.0.0.2 学习(十)——各种工具调用方式对比
接触过FunctionCallback、ToolCallback、MCP、spring-ai-alibaba的starter-tool-calling包,spring-ai-alibaba的Agent,有没有感觉眼花缭乱?
我们来一起梳理下他们之间到底有什么关系
Spring-ai相关功能
FunctionCallback和ToolCallback
首先是FunctionCallback和ToolCallback概念,这两个都是spring-ai中的概念,FunctionCallback是正式版本之前的名称,从1.0.0版本开始就已经改名为ToolCallback了。ChatClient中也移除了defaultFunctions和functions方法
名称 | 来源 | 版本 |
FunctionCallback | spring-ai | 1.0.0之前(不含) |
ToolCallback | spring-ai | 1.0.0之后(含) |
FunctionToolCallback和MethodToolCallback
FunctionToolCallback和MethodToolCallback都是ToolCallback接口的实现类,注意这里FunctionToolCallback中间多了个Tool,和前文的FunctionCallback并不是同一个概念。
名称 | FunctionToolCallback | MethodToolCallback |
来源 | sping-ai | spring-ai |
接口 | ToolCallback | ToolCallback |
应用对象 | 实现了Function接口的类 | 方法 |
编程式 | 使用FunctionToolCallback.builder | 使用反射获取方法Method后, 使用MethodToolCallback.builder |
声明式 | 使用@Bean注解到装配方法上, 使用ChatClient的toolNames方法 | 使用@Tool注解到方法上, 使用ChatClient的tools方法 |
FunctionToolCallback和MethodToolCallback都有编程式使用方式和声明式使用方式,但过程中使用的类和注解不同。应用对象分别是实现了Function接口的类和方法。
ToolCallback和MCP
ToolCallback和MCP都是对工具的调用,他们之间有区别也有联系。
先来说一下联系,MCP集成进spring-ai框架时,使用的其实就是ToolCallback接口。
以同步模式为例,MCP Client获取到远程的tools信息后,就会将其封装为ToolCallback的实现类SyncMcpToolCallback。使用时将SyncMcpToolCallbackProvider传入ChatClient的toolCallbacks方法即可。
换句话说,MCP底层虽然与传统的ToolCallback(FunctionToolCallback和MethodToolCallback)不同,但是spring-ai框架将其抽象成了ToolCallback的另一种实现。
区别主要在于调用时的入参格式Schema,ToolCallback模式入参格式是静态的,如果要修改则需要修改代码重新部署,而MCP则是动态获取Schema。
ToolCallback | MCP | |
接口 | ToolCallback | ToolCallback |
实现类 | FunctionToolCallback MethodToolCallback | SyncMcpToolCallback AsyncMcpToolCallback |
工具位置 | 一般是本地 | 远程 |
Schema | 静态 | 动态 |
spring-ai-alibaba相关功能
前面是spring-ai相关的能力,接下来我们来看一下spring-ai-alibaba扩展出来的tool-calling包和Agent接口。
tool-calling包和MCP
tool-calling和MCP都能调用远程的工具,但是两者实现方式略有区别
tool-calling是使用FunctionToolCallback的声明式使用方式,实现Function接口,然后通过toolNames方法注册。
而且tool-calling的Schema是定义在tool-calling包中,要修改智能升级tool-calling包。
tool-calling | MCP | |
实现原理 | 基于FunctionToolCallback的声明式 | 基于ToolCallback但自行实现 |
工具位置 | 远程 | 远程 |
工具实现 | jar包 | 远程MCP Server |
Schema | 静态 | 动态 |
Agent和其他
前面的各种工具调用方式都是在本地给大模型增加各种外挂,无论是ToolCallback还是MCP,最终对工具进行调用的都是本地,大模型返回的结果中说需要调用xxx工具,本地进行调用后,将调用结果传递给大模型,然后大模型进行输出。
然而Agent智能体是大模型自带外挂,对工具的调用也不需要再经过本地,发送请求后,大模型直接对工具进行调用,然后返回结果。(ps:在智能体内部其实仍然是请求大模型->返回结果说需要调用xxx工具->智能体调用工具->调用结果传递给大模型->大模型输出的过程)
换一个视角,A服务访问大模型,并使用ToolCallback或MCP对工具进行了调用,然后将整个功能封装为一个接口对外提供服务
那么此时在另一个服务B眼中,A服务就是一个智能体,B服务只需要调用A服务,那么A服务就会访问大模型,调用工具,返回结果
Agent | 其他 | |
发送请求次数 | 1次 | 2次 |
工具调用方 | 智能体 | 本地 |
是否能对工具执行结果进行优化 | 不可以 | 可以 |