之前刷短视频刷到了 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));
}
}
調用結果如下