自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java智能之Spring AI:五分鐘打造智能聊天模型的利器

開發(fā) 前端 人工智能
通過本文的介紹,我們深入了解了Spring AI項(xiàng)目的優(yōu)勢和特性,以及在實(shí)際應(yīng)用中的快速實(shí)戰(zhàn)示例。Spring AI作為一個高度抽象化的人工智能應(yīng)用程序開發(fā)框架,為開發(fā)者提供了便捷的模型支持、靈活的功能模塊交換和優(yōu)化能力。

前言

盡管Python最近成為了編程語言的首選,但是Java在人工智能領(lǐng)域的地位同樣不可撼動,得益于強(qiáng)大的Spring框架。隨著人工智能技術(shù)的快速發(fā)展,我們正處于一個創(chuàng)新不斷涌現(xiàn)的時代。從智能語音助手到復(fù)雜的自然語言處理系統(tǒng),人工智能已經(jīng)成為了現(xiàn)代生活和工作中不可或缺的一部分。在這樣的背景下,Spring AI 項(xiàng)目迎來了發(fā)展的機(jī)遇。盡管該項(xiàng)目汲取了Python項(xiàng)目如LangChain和LlamaIndex的靈感,但Spring AI并不是簡單的移植。該項(xiàng)目的初衷在于推進(jìn)生成式人工智能應(yīng)用程序的發(fā)展,使其不再局限于Python開發(fā)者。

Spring AI 的核心理念是提供高度抽象化的組件,作為開發(fā)AI應(yīng)用程序的基礎(chǔ)。這些抽象化組件具備多種實(shí)現(xiàn),使得開發(fā)者能夠以最少的代碼改動便捷地交換和優(yōu)化功能模塊。

具體而言,Spring AI 提供了支持多種主流模型提供商的功能,包括OpenAI、Microsoft、Amazon、Google和Hugging Face。支持的模型類型涵蓋了從聊天機(jī)器人到文本生成、圖像處理、語音識別等多個領(lǐng)域。而其跨模型提供商的可移植API設(shè)計(jì),不僅支持同步和流式接口,還提供了針對特定模型功能的靈活選項(xiàng)。

此外,Spring AI 還支持將AI模型輸出映射為POJO,以及與主流矢量數(shù)據(jù)庫提供商(如Apache Cassandra、Azure Vector Search、MongoDB Atlas等)無縫集成的能力。其功能不僅局限于模型本身,還包括了數(shù)據(jù)工程中的ETL框架和各種便利的函數(shù)調(diào)用,使得開發(fā)AI應(yīng)用程序變得更加高效和可靠。

快速實(shí)戰(zhàn)

本期實(shí)戰(zhàn)是我們的第一篇,旨在通過快速展示Spring AI項(xiàng)目,讓大家了解它的優(yōu)點(diǎn)和特性。為了方便大家使用,我還將本期的源代碼提交到了倉庫中,并加入了swagger-ui的API調(diào)用界面,使得使用起來更加便捷。如果你對此感興趣,歡迎前往查看star。同時,我也會持續(xù)維護(hù)這個項(xiàng)目,確保它始終保持活躍。

倉庫地址:https://github.com/StudiousXiaoYu/spring-ai-demo

項(xiàng)目生成

當(dāng)我們開始時,首先需要創(chuàng)建一個項(xiàng)目結(jié)構(gòu)。我們可以前往官方網(wǎng)站,快速生成Spring AI的依賴并創(chuàng)建項(xiàng)目。

圖片圖片

聊天模型

在大型模型中,聊天模型扮演著至關(guān)重要的角色。那么,SpringAI是如何對其進(jìn)行封裝的呢?本期主要著重展示如何有效利用Spring AI的ChatClient,特別是在本示例中應(yīng)用Spring AI的智能聊天模型。

日志級別

在這個過程中,如果想要查看請求的細(xì)節(jié)日志,務(wù)必將日志級別調(diào)整至DEBUG,具體操作如下:

圖片圖片

image

模型配置

當(dāng)我們使用一個模型時,必須首先在項(xiàng)目中加入相關(guān)的依賴,加入依賴后還需要在配置文件中填寫相應(yīng)的配置信息。

圖片圖片

注入model

那么模型可以自動注入,我們可以直接使用它。在本期演示中,我們將展示三種自定義模型的注入方式,具體如下:

private final ChatClient myChatClientWithSystem;

    private final ChatClient myChatClientWithParam;

    /**
     * 可以選擇自動注入、也可以在方法內(nèi)自定義,此客戶端無系統(tǒng)文本
     */
    private final ChatClient chatClient;

    public MyController(ChatClient.Builder chatClientBuilder, MyChatClientWithSystem myChatClient, MyChatClientWithParam myChatClientWithParam) {
        this.chatClient = chatClientBuilder.build();
        this.myChatClientWithSystem = myChatClient.client();
        this.myChatClientWithParam = myChatClientWithParam.client();
    }

好的,讓我來解釋一下這三種情況:

  1. chatClient:這是默認(rèn)的自動注入的ChatClient,不需要任何條件。
  2. myChatClientWithParam:這是一個注入系統(tǒng)文本并帶有參數(shù)的ChatClient。
  3. myChatClientWithSystem:這是一個注入帶有系統(tǒng)文本的ChatClient。

好的,第一種情況不需要處理,我們只需要通過配置類簡單配置下面兩種ChatClient。

@Configuration
class Config {

    @Bean
    MyChatClientWithSystem myChatClientWithSystem(ChatClient.Builder builder) {
        MyChatClientWithSystem build = MyChatClientWithSystem.builder()
                .client(builder.defaultSystem("你是努力的小雨,一名 Java 服務(wù)端碼農(nóng),潛心研究著 AI 技術(shù)的奧秘。我熱愛技術(shù)交流與分享,對開源社區(qū)充滿熱情。身兼掘金優(yōu)秀作者、騰訊云內(nèi)容共創(chuàng)官、阿里云專家博主、華為云云享專家等多重身份。")
                .build()).build();
        return build;
    }

    @Bean
    MyChatClientWithParam myChatClientWithParam(ChatClient.Builder builder) {
        MyChatClientWithParam build = MyChatClientWithParam.builder()
                .client(builder.defaultSystem("你是{user}。")
                        .build()).build();
        return build;
    }
}

簡單文本回答

首先,讓我們先來討論一些簡單的問答。

@GetMapping("/ai")
    String generationByText(String userInput) {
        return this.chatClient.prompt()
            .user(userInput)
            .call()
            .content();
    }

在這段簡練代碼中,已經(jīng)實(shí)現(xiàn)了各種封裝和交互,為了更好地演示,我們來展示一下:

圖片圖片

封裝回答實(shí)體對象

大家都知道Java是一種面向?qū)ο蟮木幊陶Z言,因此在加入人工智能技術(shù)時,為了滿足業(yè)務(wù)需求,將對象納入其中是不可或缺的。那么,如何讓人工智能的回答能夠被Spring框架自動封裝到對象中呢?讓我們來探討一下:

定義一個對象記錄類:一個記錄類(Record Class)的定義,名為 ActorFilms。用于封裝相關(guān)字段記錄類自動實(shí)現(xiàn)了 toString()、equals()、hashCode() 和 getter 方法,使得對象的字符串表示、相等性比較和哈希計(jì)算變得簡單。你可以直接使用 actorFilms.toString()、actorFilms.equals(anotherActorFilms) 和 actorFilms.hashCode()。

public record ActorFilms(String actor, List<String> movies) {
}
@GetMapping("/ai-Entity")
    ActorFilms generationByEntity() {
        ActorFilms actorFilms = chatClient.prompt()
                .user("Generate the filmography for a random actor.")
                .call()
                .entity(ActorFilms.class);
        return actorFilms;
    }

可以看到,只需簡單地將entity設(shè)置為ActorFilms。接下來,我們需要檢查返回的對象是否符合預(yù)期。

圖片圖片

當(dāng)用戶輸入信息后,系統(tǒng)返回一個實(shí)體類型的回答。這種實(shí)體類型的回答之所以能夠被封裝,是因?yàn)樵诎l(fā)送信息時,系統(tǒng)不僅僅發(fā)送了用戶輸入的文本,還在其后添加了額外的信息。Generate the filmography for a random actor.\r\nYour response should be in JSON format.\r\nDo not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation.\r\nDo not include markdown code blocks in your response.\r\nRemove the ```json markdown from the output.\r\nHere is the JSON Schema instance your output must adhere to:\r\n```{\r\n \"$schema\" : \"https://json-schema.org/draft/2020-12/schema\",\r\n \"type\" : \"object\",\r\n \"properties\" : {\r\n \"actor\" : {\r\n \"type\" : \"string\"\r\n },\r\n \"movies\" : {\r\n \"type\" : \"array\",\r\n \"items\" : {\r\n \"type\" : \"string\"\r\n }\r\n }\r\n }\r\n}```\r\n因此,當(dāng)后續(xù)返回的數(shù)據(jù)為大型模型時,例如{"actor": "Emily Blunt", "movies": ["Edge of Tomorrow", "A Quiet Place", "The Devil Wears Prada", "Sicario", "Mary Poppins Returns"]},這樣一來Spring就可以幫我將其自動封裝起來了。

封裝回答列表實(shí)體對象

當(dāng)我們需要返回一個列表而不是一個對象時,可以輕松地利用Spring AI的封裝功能來實(shí)現(xiàn)。讓我們來看看如何操作:

@GetMapping("/ai-EntityList")
    List<ActorFilms> generationByEntityList() {
        List<ActorFilms> actorFilms = chatClient.prompt()
                .user("Generate the filmography of 5 movies for Tom Hanks and Bill Murray.")
                .call()
                .entity(new ParameterizedTypeReference<List<ActorFilms>>() {
                });
        return actorFilms;
    }

直接使用ParameterizedTypeReference對象即可。為了讓Spring能夠自動封裝返回結(jié)果,發(fā)送信息時也包含了返回格式信息作為提示。現(xiàn)在我們來查看演示的結(jié)果。

圖片圖片

流式回答

在前面展示的示例中,大型模型一次性完成回答并將其全部輸出給用戶。然而,前端無法實(shí)現(xiàn)打字機(jī)效果,因此我們決定采用流式回答的方式來進(jìn)行演示。

@GetMapping("/ai-streamWithParam")
    Flux<String> generationByStreamWithParam() {
        var converter = new BeanOutputConverter<>(new ParameterizedTypeReference<List<ActorFilms>>() {
        });

        Flux<String> flux = this.chatClient.prompt()
                .user(u -> u.text("""
                            Generate the filmography for a random actor.
                            {format}
                          """)
                        .param("format", converter.getFormat()))
                .stream()
                .content();

        String content = flux.collectList().block().stream().collect(Collectors.joining());

        List<ActorFilms> actorFilms = converter.convert(content);
        log.info("actorFilms: {}", actorFilms);
        return flux;
    }

為了演示用戶信息中的參數(shù)傳遞,我對流式回答進(jìn)行了一個阻塞操作。如果不需要的話,可以將其刪除。另外,由于我需要封裝一個列表對象,所以進(jìn)行了阻塞操作。實(shí)際上,這與上面提到的一樣,即在問答中直接定義了大模型返回的格式。好的,我們來看一下返回結(jié)果。

圖片圖片

帶有系統(tǒng)信息的client

這次我們將演示客戶端的配置。在對話中,我們知道有三種身份標(biāo)識:system、user、assistant。至今,我們尚未展示系統(tǒng)身份標(biāo)識,但之前我們已經(jīng)定義了系統(tǒng)形式的客戶端。因此,這次我們將直接使用它:

@GetMapping("/ai-withSystemClient")
    Map<String, String> generationByTextWithSystemClient(String message) {
        return Map.of("completion", myChatClientWithSystem.prompt().user(message).call().content());
    }

這段代碼非常簡單,只需使用ChatClient即可。用戶輸入后,會返回一個Map類型的回答,其中key為"completion",對應(yīng)的value為回答內(nèi)容。讓我們一起來看一下結(jié)果吧。

圖片圖片

可以看出,實(shí)際上他已經(jīng)將我的system信息包含在內(nèi)了。

帶有參數(shù)信息的client

當(dāng)您需要演示帶有參數(shù)的情況時,您可以考慮以下方法:在用戶輸入后,返回一個Map類型的回答,其中包含鍵值對,鍵為"completion",值為相應(yīng)的回答。在實(shí)際業(yè)務(wù)場景中,參數(shù)是不可避免的,因此這種演示方式可以更好地展示人工智能的適用性。讓我們繼續(xù)探討這一點(diǎn):

@GetMapping("/ai-withParamClient")
    Map<String, String> generationByTextWithParamClient(String message, String user) {
        return Map.of("completion", myChatClientWithParam.prompt().system(sp ->sp.param("user",user)).user(message).call().content());
    }

這里也是很簡單的一句話,所以我們看下效果:

圖片圖片

如果您對回答感到困惑,我們可以查看后臺傳輸日志,以了解傳輸?shù)膮?shù)詳情。

圖片圖片

可以注意到,實(shí)際上我們已經(jīng)成功將參數(shù)設(shè)置完成。

聊天歷史

在最后一個主要的業(yè)務(wù)場景中,每個人都會有自己的聊天記錄。我們不能一直進(jìn)行無狀態(tài)的對話,這樣會顯得很不智能。因此,必須要有聊天記錄的功能。雖然Spring AI尚未完全確定如何封裝這部分功能,但已經(jīng)提供了一個簡單的對象類供我們調(diào)用。讓我們來看一下:

@GetMapping("/ai-chatMemory")
    String generationByChatMemory(HttpServletRequest request, String userInput) {
        String sessionId = request.getSession().getId();
        chatMemory.add(sessionId, new UserMessage(userInput));
        String content = this.chatClient.prompt()
                .advisors(new MessageChatMemoryAdvisor(chatMemory))
                .user(userInput)
                .call()
                .content();
        chatMemory.add(sessionId, new AssistantMessage(content));
        return content;
    }

實(shí)際上,在這種情況下,我們需要自行創(chuàng)建并維護(hù)一個聊天歷史對象。因此,每次進(jìn)行聊天前和聊天后,我們都應(yīng)該將所需的信息添加到該對象中,然后直接使用它。讓我們來看一下這種做法的效果:

圖片圖片

圖片圖片

可以看到,實(shí)際上在這里已經(jīng)將歷史記錄一并呈現(xiàn)了出來。

總結(jié)

通過本文的介紹,我們深入了解了Spring AI項(xiàng)目的優(yōu)勢和特性,以及在實(shí)際應(yīng)用中的快速實(shí)戰(zhàn)示例。Spring AI作為一個高度抽象化的人工智能應(yīng)用程序開發(fā)框架,為開發(fā)者提供了便捷的模型支持、靈活的功能模塊交換和優(yōu)化能力。它不僅能將AI模型輸出映射為POJO,還能與主流矢量數(shù)據(jù)庫提供商無縫集成,從而顯著提升開發(fā)AI應(yīng)用程序的效率和可靠性。

與Python相比,Java在企業(yè)級應(yīng)用和大型系統(tǒng)中具有顯著優(yōu)勢。Java語言的靜態(tài)類型和嚴(yán)格的編譯時檢查使得代碼更加健壯和易于維護(hù),尤其適合需要高度可靠性和長期支持的項(xiàng)目。同時,Java生態(tài)系統(tǒng)的成熟度和廣泛應(yīng)用確保了開發(fā)者可以輕松找到豐富的庫和工具支持,加速開發(fā)周期并降低項(xiàng)目風(fēng)險。

責(zé)任編輯:武曉燕 來源: 靈墨AI探索室
相關(guān)推薦

2022-12-16 09:55:50

網(wǎng)絡(luò)架構(gòu)OSI

2025-02-25 07:49:36

智能體數(shù)據(jù)庫DeepSeek

2015-08-06 17:17:33

swoole聊天室

2023-07-31 11:37:05

經(jīng)營分析模型

2023-08-06 07:00:59

Openstack網(wǎng)絡(luò)

2009-11-16 10:53:30

Oracle Hint

2024-12-11 07:00:00

面向?qū)ο?/a>代碼

2025-03-13 06:22:59

2020-06-16 08:47:53

磁盤

2023-07-31 08:55:15

AI技術(shù)網(wǎng)絡(luò)暴力

2021-02-11 08:08:09

Spring Boot配置架構(gòu)

2024-06-25 12:25:12

LangChain路由鏈

2024-06-19 10:41:06

2024-01-26 10:19:00

AI模型

2023-07-16 18:46:30

2024-08-27 13:54:44

2021-06-07 09:51:22

原型模式序列化

2009-10-22 16:18:19

Oracle表空間

2009-11-05 14:53:54

Visual Stud

2021-10-19 07:27:08

HTTP代理網(wǎng)絡(luò)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號