解锁更多精彩,关注公众号:闲人张
本文主要介绍了spring ai的工具调用和结构化输出功能,通过具体的示例来体验整个调用及实现过程,同时对一些使用方法进行总结说明。
前言
目前调用AI的框架语言主要以Python为主,虽然也有一些Java语言实现的,但在使用和功能上仍有一些差距。而Spring做为Java的半壁江山,Spring AI自然也需要体验一下。 一些Java的调用框架:
- langchain4j
- semantic-kernel (依赖了azure-sdk-for-java)
- azure-sdk-for-java
通过官方的架构交互,可以看到主要分为Prompt、ChatClient、ChatResponse
下面来看看Spring AI是如何实现工具调用和结构化输出的。
引入pom
1 | <repositories> |
这里使用azure的api,目前官方的版本是0.8.1,引入后我们可以看到内部也是引用了azure的sdk,目前依赖的版本是1.0.0-beta.7,感兴趣的同学其实也可以直接使用azure的sdk进行调用。
添加模型配置
在yml中添加模型的配置
1 | spring: |
经过以上配置,我们就可以直接使用spring-ai提供的api进行调用了。
工具调用
Spring AI 提供了灵活且用户友好的注册和调用自定义函数的方式。通常,自定义函数需要提供函数 name、 description和函数调用的参数。具体实现只需定义一个Bean,返回java.util.Function。
注册
我们通过一个具体的示例看下,mock一个根据日期获取课程的方法:
1 | public class MockCourseService implements Function<MockCourseService.Request, MockCourseService.Response> { |
可以看到需要实现Function接口,并且提供了两种方式来注册自定义函数。
- 方式一的函数名称为
courseFunctionInfo1
,并且采用了@JsonClassDescription
、@JsonProperty
、@JsonPropertyDescription
、@Description
等注解对函数及其参数进行描述说明 - 方式二的函数名称为
getCourseByDate
,通过spring ai 提供的FunctionCallback
接口注册自定义函数,并使用FunctionCallbackWrapper
包装器来设置函数名称和描述。
调用
我们定义一个接口来调用自定义函数:
1 | @GetMapping("/function") |
可以看到基本上都是一个思路,通过构建Prompt
对象,然后调用chatClient.call(prompt)
即可。通过debug,发现实际是将tool转换OPEN AI function的标准,然后调用openai的api。感兴趣的可以去查看源码以及打开日志来查看具体的调用过程。
运行后可以看到如下输出:
1 | Prompt{messages=[SystemMessage{content='你是一个智能助手,请调用工具回答问题。', properties={}, messageType=SYSTEM}, UserMessage{content='今天星期二有哪些课?', properties={}, messageType=USER}], modelOptions=org.springframework.ai.azure.openai.AzureOpenAiChatOptions@11e70d12} |
结构化输出
spring ai 提供了OutputParser
来支持返回结果的格式化输出,并提供了以下的实现:
下面通过构建一个BeanOutputParser来看下调用的过程:
首先定义一个返回对象
1 | @Data |
可以使用@JsonPropertyDescription
对参数进行描述
调用
借用之前定义的函数,我们让接口返回为定义的对象
1 | @GetMapping("/outputParse") |
可以看到,我们只需要定义一个BeanOutputParser
,然后调用其format
方法,通过对其输出,我们可以看到OutputParser
实际上是将定义的结构化数据转换为了一段Prompt:
1 | Your response should be in JSON format. |
{
"$schema" : "https://json-schema.org/draft/2020-12/schema",
"type" : "object",
"properties" : {
"course" : {
"type" : "array",
"items" : {
"type" : "string"
}
},
"date" : {
"type" : "string",
"description" : "日期"
}
}
}
1
2
查看最终结果可以看到完全是按照我们定义的结构化数据来输出的:
1 | { |
以上就是本篇的全部内容,后续将会对spring ai 其他的功能做更深度的体验,欢迎关注!
解锁更多精彩,关注公众号:闲人张
本文转载自: 掘金