文章目錄
- 1 AI框架
- 1.1 Spring AI 簡介
- 1.2 Spring AI 使用
- 1.2.1 pom.xml
- 1.2.2 可實現的功能
- 1.3 Spring Cloud Alibaba AI
- 1.4 Spring Cloud Alibaba AI 實踐操作
- 1.4.1 pom.xml
- 1.4.2 配置文件
- 1.4.3 對接文本模型
- 1.4.4 文生圖模型
- 1.4.5 語音合成模型
1 AI框架
1.1 Spring AI 簡介
在軟件開發的世界中,Java一直是企業級應用的主力軍。而Spring框架,尤其是Spring Boot,以其生態系統的豐富性,為開發者提供了無與倫比的便利。現在,Spring Boot正邁向一個新的紀元——人工智-能的時代。
Spring AI
項目的推出,不僅標志著Spring生態的進一步擴展,也為廣大Java開發者開啟了一個全新的編程領域。
Spring AI
是從著名的 Python
項目LangChain和LlamaIndex中汲取靈感,它不是這些項目的直接移植,它的成立信念是,下一波生成式人工智能應用程序將不僅適用于 Python 開發人員,而且將在許多編程語言中無處不在。
Spring AI
功能,可以看Spring推出的官方文檔:https://spring.io/projects/spring-ai
我們可以從Spring AI
的官網描述中,總結出Spring AI的幾個核心的關鍵詞:
- 提供抽象能力
- 簡化AI應用的開發
- 模型與向量支持
- AI集成與自動配置
Spring AI
簡化了我們構建大型復雜的AI應用的過程,當然如果你的項目僅僅是需要調用一個AI接口,那其實直接調用官方SDK反而更方便。
Spring AI提供的功能如下:
- SQL類過濾器API: 提供類似SQL的元數據過濾器API,實現跨供應商的一致性。
- Spring Boot集成: 專為Spring Boot設計的自動配置和啟動器,讓AI集成變得輕而易舉。
- API可移植性,支持所有主要的模型提供商,如OpenAI,Microsoft,Amazon,Google和Huggingface。支持的模型類型包括聊天和文本到圖像。
- 跨 AI 提供商的可移植 API,用于聊天和嵌入模型。支持同步和流 API 選項。還支持下拉以訪問特定于模型的功能。
- 將 AI 模型輸出映射到 POJO。
- 支持所有主要的向量數據庫,例如 Azure Vector Search、Chroma、Milvus、Neo4j、PostgreSQL/PGVector、PineCone、Qdrant、Redis 和 Weaviate。
- 跨 Vector Store 提供程序的可移植 API,包括新穎的類似 SQL 的元數據過濾器 API,該 API 也是可移植的。
- AI 模型和矢量存儲的 Spring Boot stater。
- 用于數據工程的 ETL 框架
1.2 Spring AI 使用
1.2.1 pom.xml
添加Maven存儲庫: 在項目的pom.xml中添加Spring Milestone
和Snapshot
存儲庫。
<repositories><!-- Spring Milestone Repository for milestones --><repository><id>spring-milestones</id><url>https://repo.spring.io/milestone</url></repository><!-- Spring Snapshot Repository for snapshots --><repository><id>spring-snapshots</id><url>https://repo.spring.io/snapshot</url></repository>
</repositories>
注意
:在集成 Spring AI 或其他較新的 Spring 生態系統組件時,添加 Spring Milestone
和 Snapshot
存儲庫是為了確保能夠訪問到最新的開發版本、里程碑版本和快照版本。這些版本可能尚未發布到 Maven Central
這樣的穩定倉庫,但包含了最新的特性、修復和改進
導入Spring AI BOM: 使用Spring AI BOM定義,可以確保你使用的是測試過的、兼容的庫版本。
<dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>0.8.1-SNAPSHOT</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
添加AI功能: 根據你的需求,添加相關的AI模塊依賴項到pom.xml。
<dependencies><!-- 示例:添加OpenAI的支持 --><dependency><groupId>org.springframework.experimental.ai</groupId><artifactId>spring-ai-openai</artifactId></dependency>
</dependencies>
1.2.2 可實現的功能
可實現的功能:
生成式AI
:利用Spring AI,你可以通過簡單的API調用,實現文本的生成、翻譯、摘要等功能。矢量數據庫
:當你需要對文本數據進行語義搜索時,Spring AI提供的矢量數據庫支持使得相關操作變得簡單高-效。AI繪畫
:對于需要將文本轉換為圖像的應用場景,Spring AI的繪畫功能可以無縫集成到你的應用中。
1.3 Spring Cloud Alibaba AI
原始的Spring AI
并沒有國內相關大模型的接入,對國內開發者不太友好。
總的來說,Spring Cloud Alibaba AI
目前基于 Spring AI 0.8.1
版本 API
完成通義系列大模型的接入。
在當前最新版本中,Spring Cloud Alibaba AI
主要完成了幾種常見生成式模型的適配,包括對話、文生圖、文生語音等,開發者可以使用 Spring Cloud Alibaba AI
開發基于通義的聊天、圖片或語音生成 AI 應用,框架還提供 OutParser、Prompt Template、Stuff 等實用能力。
Spring Cloud Alibaba AI
官方還提供了包括聊天對話、文生圖、文生語音等多種應用的開發示例,具體可以前往官網查看:https://sca.aliyun.com
1.4 Spring Cloud Alibaba AI 實踐操作
首先新建一個Maven項目,JDK選的是17版本。
1.4.1 pom.xml
Maven文件需要引入spring-cloud-alibaba-dependencies
和spring-cloud-starter-alibaba-ai
兩個依賴。
<dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2023.0.1.0</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-ai</artifactId></dependency>
</dependencies>
1.4.2 配置文件
配置阿里云通義千問的Api-Key,沒有的讀者可以從官網上申請。
server:port: 8080
spring:application:name: alibaba-spring-ai-democloud:ai:tongyi:api-key: 你的api-key
1.4.3 對接文本模型
我們首先測試如何對接文本大模型。
新建一個控制器類:新建/simple接口,用來測試基本QA。
@RestController
@RequestMapping("/ai")
@CrossOrigin
public class TongYiController {@Autowired@Qualifier("tongYiSimpleServiceImpl")private TongYiService tongYiSimpleService;@GetMapping("/simple")public String completion(@RequestParam(value = "message", defaultValue = "AI時代下Java開發者該何去何從?")String message) {return tongYiSimpleService.completion(message);}
}
新建一個TongyiService服務類:
public interface TongYiService {/*** 基本問答*/String completion(String message);/*** 文生圖*/ImageResponse genImg(String imgPrompt);/*** 語音合成*/String genAudio(String text);}
具體的實現類如下:由 Spring AI
自動注入 ChatClient、StreamingChatClient,ChatClient
屏蔽底層通義大模型交互細節,后者用于流式調用。
對于QA而言,僅僅通過client.call(prompt)
一行代碼就可以完成對模型的調用。
@Service
@Slf4j
public class TongYiSimpleServiceImpl extends AbstractTongYiServiceImpl {/*** 自動注入ChatClient、StreamingChatClient,屏蔽模型調用細節*/private final ChatClient chatClient;private final StreamingChatClient streamingChatClient;@Autowiredpublic TongYiSimpleServiceImpl(ChatClient chatClient, StreamingChatClient streamingChatClient) {this.chatClient = chatClient;this.streamingChatClient = streamingChatClient;}/*** 具體實現:*/@Overridepublic String completion(String message) {Prompt prompt = new Prompt(new UserMessage(message));return chatClient.call(prompt).getResult().getOutput().getContent();}
}
我們發送一個請求,prompt是AI時代下Java開發者該何去何從?測試結果如下:
1.4.4 文生圖模型
這里只給出service的代碼,其它代碼同上面的文本問答。
可以看到,只需要實例化一個imagePrompt,再調用模型即可。
@Slf4j
@Service
public class TongYiImagesServiceImpl extends AbstractTongYiServiceImpl {private static final Logger logger = LoggerFactory.getLogger(TongYiService.class);private final ImageClient imageClient;@Autowiredpublic TongYiImagesServiceImpl(ImageClient client) {this.imageClient = client;}@Overridepublic ImageResponse genImg(String imgPrompt) {var prompt = new ImagePrompt(imgPrompt);return imageClient.call(prompt);}
}
測試的prompt是:Painting a boy coding in front of the desk, with his dog.,測試結果如下,效果還是很不錯的:
1.4.5 語音合成模型
@Slf4j
@Service
public class TongYiAudioSimpleServiceImpl extends AbstractTongYiServiceImpl {private static final Logger logger = LoggerFactory.getLogger(TongYiService.class);private final SpeechClient speechClient;@Autowiredpublic TongYiAudioSimpleServiceImpl(SpeechClient client) {this.speechClient = client;}@Overridepublic String genAudio(String text) {logger.info("gen audio prompt is: {}", text);var resWAV = speechClient.call(text);// save的代碼省略,就是將音頻保存到本地而已return save(resWAV, SpeechSynthesisAudioFormat.WAV.getValue());}
}
測試結果也是成功的: