之前刷短视频刷到了 spring 框架竟然出了 AI 模块,这我身为一个 Java 程序员竟然不知道,赶紧去官网看一下再找点教程试一试。
现在spring AI 的版本是0.8.1,但也已经有正式版 1.0 的 SNAPSHOT 了,所以 API 基本不会有大的变动。总而言之,现在的版本是可用的,且不用担心兼容性。
初始化#
你可以使用 idea 快速初始化一个 spring ai 项目
但请注意,JDK 版本最少 >=17,spring boot 版本 > 3
你也可以
通过 https://start.spring.io/ 创建一个包含 Spring AI 的初始项目:
上图所示,我们添加最常见的 OpenAI 依赖,Spring AI 主要添加了下面的 BOM:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>0.8.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
还有我们选择的 OpenAI:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
快速开始#
准备#
接下来需要提供模型的接口地址,以 OpenAI 为例
事实上 base-url 可以被省略,默认就是官方的地址
如果你使用官方的 api 接口,那你很有可能也需要为程序添加代理
System.setProperty("https.proxyHost", "localhost");
System.setProperty("https.proxyPort", "7890");
客户端对象#
如果你已经在配置文件配置了信息,那么你可以直接初始化对象
private final OpenAiChatClient chatClient;
另一种方法是在代码里创建
var openAiApi = new OpenAiApi("https://api.openai.com", "sk-xxxxx");
OpenAiChatClient chatClient = new OpenAiChatClient(openAiApi, OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo-1106")
.withTemperature(0.4F)
.build());
使用代码的好处是可以很灵活的自定义对象,withModel("gpt-3.5-turbo-1106")
指定了使用哪种模型,默认是 gpt-3.5-turbo 。withTemperature(0.4F)
指定了模型的随机属性(Temperature 默认值为 0.8,值越大,回复内容越赋有多样性、创造性、随机性;设为 0 - 根据事实回答,希望得到精准答案应该降低该参数;日常聊天建议 0.5-0.8。)
不过,你依然可以在配置文件里面指定这些参数,可以查看 官方文档里面的 Configuration Properties
提示词#
很好,已经有了对象,那是否可以调用了?事实上的确可以直接调用。
可以看到,call 方法接收 2 种不同的参数
prompt 是提示词,类似于模型的人设,大多数情况下,我们都需要给模型赋予这个值。
那又为什么直接传 message 也能调用呢?
源码可以看到,还是用 prompt 包了一层的
创建 Prompt 也很简单:
private static Prompt getPrompt(String message) {
String systemPrompt = "{prompt}";
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
Message userMessage = new UserMessage(message);
Message systemMessage = systemPromptTemplate.createMessage(MapUtil.of("prompt", "you are a helpful AI assistant"));
return new Prompt(List.of(userMessage, systemMessage));
}
这里其实也是把 message 包了一层,不过多了一个 systemMessage ,类似于模型的人设。
事实上,Prompt 的种类很多,玩法也很多样,不仅仅是提示词,同样也是多轮对话的关键。
下面是完整的代码
/**
* @author lza
* @date 2024/04/11-11:37
**/
@RestController
@RequestMapping("ai")
@RequiredArgsConstructor
@CrossOrigin
public class OpenAIController {
private final OpenAiChatClient chatClient;
@GetMapping("chat/{message}")
public String opChat(@PathVariable String message) {
Prompt prompt = getPrompt(message);
List<Generation> response = chatClient.call(prompt).getResults();
StringBuilder result = new StringBuilder();
for (Generation generation : response) {
String content = generation.getOutput().getContent();
result.append(content);
}
return result.toString();
}
private static Prompt getPrompt(String message) {
String systemPrompt = "{prompt}";
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
Message userMessage = new UserMessage(message);
Message systemMessage = systemPromptTemplate.createMessage(MapUtil.of("prompt", "you are a helpful AI assistant"));
return new Prompt(List.of(userMessage, systemMessage));
}
}
调用结果如下