最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring AI源碼分析流式回答(最新推薦)

 更新時(shí)間:2024年11月14日 11:53:36   作者:努力的小雨  
本文我們將重點(diǎn)講解流式響應(yīng)的概念與實(shí)現(xiàn),畢竟,AI的流式回答功能與其交互體驗(yàn)密切相關(guān),是提升用戶滿意度的重要組成部分,我們將通過代碼示例來展示這一過程,幫助您更清晰地理解如何在實(shí)際應(yīng)用中進(jìn)行操作,感興趣的朋友一起看看吧

在上一章節(jié)中,我們深入分析了Spring AI的阻塞式請(qǐng)求與響應(yīng)機(jī)制,并探討了如何增強(qiáng)其記憶能力。今天,我們將重點(diǎn)講解流式響應(yīng)的概念與實(shí)現(xiàn)。畢竟,AI的流式回答功能與其交互體驗(yàn)密切相關(guān),是提升用戶滿意度的重要組成部分。

基本用法

基本用法非常簡(jiǎn)單,只需增加一個(gè) stream 方法即可實(shí)現(xiàn)所需功能。接下來,我們將通過代碼示例來展示這一過程,幫助您更清晰地理解如何在實(shí)際應(yīng)用中進(jìn)行操作。請(qǐng)看以下代碼:

@GetMapping(value = "/ai-stream",produces = MediaType.APPLICATION_OCTET_STREAM_VALUE + ";charset=UTF-8")
Flux<String> generationByStream(@RequestParam("userInput") String userInput) {
    Flux<String> output = chatClient.prompt()
            .user(userInput)
            .stream()
            .content();
    return output;
}

在我們?cè)黾?nbsp;stream 方法之后,返回的對(duì)象類型將不再是原來的阻塞式 CallResponseSpec,而是轉(zhuǎn)換為非阻塞的 StreamResponseSpec。與此同時(shí),返回的數(shù)據(jù)類型也由之前的 String 變更為 Flux。

在深入探討其具體應(yīng)用之前,首先讓我來介紹一下 Flux 的概念與特性。

Spring WebFlux的處理器實(shí)現(xiàn)

首先,在 WebFlux 中,處理器已經(jīng)實(shí)現(xiàn)了非阻塞式的功能。這意味著,只要我們的代碼返回一個(gè) Flux 對(duì)象,就能輕松實(shí)現(xiàn)響應(yīng)功能。通過這種方式,應(yīng)用程序能夠高效地處理并發(fā)請(qǐng)求,而不會(huì)因阻塞操作而影響整體性能。

    @Override
    public Mono<Void> handle(ServerWebExchange exchange) {
        if (this.handlerMappings == null) {
            return createNotFoundError();
        }
        if (CorsUtils.isPreFlightRequest(exchange.getRequest())) {
            return handlePreFlight(exchange);
        }
        return Flux.fromIterable(this.handlerMappings)
                .concatMap(mapping -> mapping.getHandler(exchange))
                .next()
                .switchIfEmpty(createNotFoundError())
                .onErrorResume(ex -> handleResultMono(exchange, Mono.error(ex)))
                .flatMap(handler -> handleRequestWith(exchange, handler));
    }

這里簡(jiǎn)單介紹一下 Spring WebFlux,雖然這不是我們的重點(diǎn),但了解其基本概念還是很有幫助的。Spring WebFlux 是 Spring 框架的一部分,專為構(gòu)建反應(yīng)式應(yīng)用而設(shè)計(jì)。它支持異步和非阻塞的編程模型,使得處理高并發(fā)請(qǐng)求變得更加高效。以下是 WebFlux 的幾個(gè)關(guān)鍵特性:

  • 反應(yīng)式編程:WebFlux 基于反應(yīng)式編程模型,使用 Mono 和 Flux 類型來處理數(shù)據(jù)流。Mono 表示零或一個(gè)元素,而 Flux 則表示零個(gè)或多個(gè)元素。這種模型使得我們可以輕松處理異步數(shù)據(jù)流,從而提高代碼的可讀性和可維護(hù)性。
  • 非阻塞 I/O:WebFlux 通過非阻塞的 I/O 操作(如 Netty 或 Servlet 3.1+ 容器)來實(shí)現(xiàn)高效的資源利用。與傳統(tǒng)的阻塞 I/O 不同,WebFlux 在等待響應(yīng)時(shí)能夠釋放線程,這樣一來,就可以顯著提高應(yīng)用的并發(fā)能力,支持更多的同時(shí)請(qǐng)求而不增加線程開銷。

了解這些特性將為后續(xù)的非阻塞式響應(yīng)設(shè)計(jì)奠定基礎(chǔ),幫助我們更好地利用 WebFlux 的能力來提升應(yīng)用性能。

源碼分析

現(xiàn)在我們來詳細(xì)看看我們的 content 是如何操作的。接下來的代碼示例將展示具體的實(shí)現(xiàn)方式,幫助我們理解在 WebFlux 中如何處理數(shù)據(jù)流和響應(yīng):

public Flux<String> content() {
    return doGetFluxChatResponse(this.request).map(r -> {
        if (r.getResult() == null || r.getResult().getOutput() == null
                || r.getResult().getOutput().getContent() == null) {
            return "";
        }
        return r.getResult().getOutput().getContent();
    }).filter(StringUtils::hasLength);
}

這里的實(shí)現(xiàn)相對(duì)簡(jiǎn)單,主要是傳入了一個(gè)函數(shù)。接下來,我們將深入分析 doGetFluxChatResponse 的代碼實(shí)現(xiàn),以便更好地理解其具體邏輯和運(yùn)作方式:

private Flux<ChatResponse> doGetFluxChatResponse2(DefaultChatClientRequestSpec inputRequest) {
//此處省略重復(fù)代碼
    var fluxChatResponse = this.chatModel.stream(prompt);
//此處省略重復(fù)代碼
    return advisedResponse;
}

這里的代碼邏輯與阻塞回答基本相同,唯一的不同之處在于它調(diào)用了 chatModel.stream(prompt) 方法。接下來,我們將深入探討 chatModel.stream(prompt) 方法的具體實(shí)現(xiàn)和其背后的設(shè)計(jì)思路:

public Flux<ChatResponse> stream(Prompt prompt) {
        return Flux.deferContextual(contextView -> {
        //此處省略重復(fù)代碼
            Flux<OpenAiApi.ChatCompletionChunk> completionChunks = this.openAiApi.chatCompletionStream(request,
                    getAdditionalHttpHeaders(prompt));
//此處省略重復(fù)代碼
            Flux<ChatResponse> chatResponse = completionChunks.map(this::chunkToChatCompletion)
                .switchMap(chatCompletion -> Mono.just(chatCompletion).map(chatCompletion2 -> {
//此處省略重復(fù)代碼
                        return new ChatResponse(generations, from(chatCompletion2, null));
                    }
                }));
//此處省略重復(fù)代碼
            return new MessageAggregator().aggregate(flux, observationContext::setResponse);
        });
    }

同樣的邏輯在這里就不再贅述,我們將重點(diǎn)關(guān)注其中的區(qū)別。在這一部分,我們使用了 chatCompletionStream,而且與之前不同的是,這里不再使用 retryTemplate,而是引入了 webClient,這是一個(gè)能夠接收事件流的工具類。

public Flux<ChatCompletionChunk> chatCompletionStream(ChatCompletionRequest chatRequest,
        MultiValueMap<String, String> additionalHttpHeader) {
    Assert.notNull(chatRequest, "The request body can not be null.");
    Assert.isTrue(chatRequest.stream(), "Request must set the stream property to true.");
    AtomicBoolean isInsideTool = new AtomicBoolean(false);
    return this.webClient.post()
        .uri(this.completionsPath)
        .headers(headers -> headers.addAll(additionalHttpHeader))
        .body(Mono.just(chatRequest), ChatCompletionRequest.class)
        .retrieve()
        .bodyToFlux(String.class)
        // cancels the flux stream after the "[DONE]" is received.
        .takeUntil(SSE_DONE_PREDICATE)
        // filters out the "[DONE]" message.
        .filter(SSE_DONE_PREDICATE.negate())
        .map(content -> ModelOptionsUtils.jsonToObject(content, ChatCompletionChunk.class))
//此處省略一堆代碼

這段代碼的主要目的是通過 webClient 向指定路徑發(fā)起一個(gè) POST 請(qǐng)求,同時(shí)設(shè)置合適的請(qǐng)求頭和請(qǐng)求體。在獲取響應(yīng)數(shù)據(jù)時(shí),使用了事件流的方式(通過 bodyToFlux 方法)來接收響應(yīng)內(nèi)容,并對(duì)數(shù)據(jù)進(jìn)行過濾和轉(zhuǎn)換,最終將其轉(zhuǎn)化為 ChatCompletionChunk 對(duì)象。

盡管其余的業(yè)務(wù)邏輯與之前相似,但有一點(diǎn)顯著的區(qū)別,即整個(gè)流程的返回類型以及與 OpenAI API 的調(diào)用方式都是非阻塞式的。

總結(jié)

在當(dāng)今的數(shù)字時(shí)代,流式響應(yīng)機(jī)制不僅提升了系統(tǒng)的性能,還在用戶體驗(yàn)上扮演了關(guān)鍵角色。通過引入 Flux 類型,Spring WebFlux 的設(shè)計(jì)理念使得應(yīng)用能夠以非阻塞的方式處理并發(fā)請(qǐng)求,從而有效利用資源并減少響應(yīng)延遲。

我們終于全面講解了Spring AI的基本操作,包括阻塞式回答、流式回答以及記憶增強(qiáng)功能。這些內(nèi)容為我們深入理解其工作機(jī)制奠定了基礎(chǔ)。接下來,我們將繼續(xù)深入探索源碼,重點(diǎn)分析回調(diào)函數(shù)、實(shí)體類映射等重要功能。

這將幫助我們更好地理解Spring AI的內(nèi)部運(yùn)作原理,并為進(jìn)一步的優(yōu)化和定制化提供指導(dǎo)。

到此這篇關(guān)于深入探索Spring AI:源碼分析流式回答的文章就介紹到這了,更多相關(guān)Spring AI流式回答內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java基礎(chǔ)之?dāng)?shù)組詳解

    Java基礎(chǔ)之?dāng)?shù)組詳解

    這篇文章主要介紹了Java基礎(chǔ)之?dāng)?shù)組詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-04-04
  • 使用controller傳boolean形式值

    使用controller傳boolean形式值

    這篇文章主要介紹了使用controller傳boolean形式值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java Aop實(shí)現(xiàn)自動(dòng)填充字段值示例

    java Aop實(shí)現(xiàn)自動(dòng)填充字段值示例

    這篇文章主要為大家介紹了Aop實(shí)現(xiàn)自動(dòng)填充字段值示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Ribbon負(fù)載均衡算法原理與使用介紹

    Ribbon負(fù)載均衡算法原理與使用介紹

    在微服務(wù)中,對(duì)服務(wù)進(jìn)行拆分之后,必然會(huì)帶來微服務(wù)之間的通信需求,而每個(gè)微服務(wù)為了保證高可用性,又會(huì)去部署集群,那么面對(duì)一個(gè)集群微服務(wù)進(jìn)行通信的時(shí)候,如何進(jìn)行負(fù)載均衡也是必然需要考慮的問題
    2022-09-09
  • 實(shí)例講解Java的MyBatis框架對(duì)MySQL中數(shù)據(jù)的關(guān)聯(lián)查詢

    實(shí)例講解Java的MyBatis框架對(duì)MySQL中數(shù)據(jù)的關(guān)聯(lián)查詢

    這里我們來以實(shí)例講解Java的MyBatis框架對(duì)MySQL中數(shù)據(jù)的關(guān)聯(lián)查詢,包括一對(duì)多、多對(duì)一的關(guān)聯(lián)查詢以及自身關(guān)聯(lián)映射的方法等,需要的朋友可以參考下
    2016-06-06
  • java中的十個(gè)大類總結(jié)

    java中的十個(gè)大類總結(jié)

    java.lang.string字符串類將是無(wú)可爭(zhēng)議的冠軍在任何一天的普及和不可以否認(rèn)。這是最后一個(gè)類,用來創(chuàng)建操作不可變字符串字面值
    2013-10-10
  • 分析java并發(fā)中的wait notify notifyAll

    分析java并發(fā)中的wait notify notifyAll

    一個(gè)線程修改一個(gè)對(duì)象的值,而另一個(gè)線程則感知到了變化,然后進(jìn)行相應(yīng)的操作,這就是wait()、notify()和notifyAll()方法的本質(zhì)。本文將詳細(xì)來介紹它們概念實(shí)現(xiàn)以及區(qū)別
    2021-06-06
  • SpringBoot中的Mybatis依賴問題

    SpringBoot中的Mybatis依賴問題

    這篇文章主要介紹了SpringBoot中的Mybatis依賴問題,包括pom導(dǎo)入依賴和相關(guān)實(shí)例代碼講解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • MyBatis-Plus插件機(jī)制及通用Service新功能

    MyBatis-Plus插件機(jī)制及通用Service新功能

    這篇文章主要介紹了MyBatis-Plus插件機(jī)制以及通用Service、新功能,本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • 三級(jí)聯(lián)動(dòng)省市ajax的代碼

    三級(jí)聯(lián)動(dòng)省市ajax的代碼

    這篇文章主要為大家詳細(xì)介紹了ajax實(shí)現(xiàn)省市三級(jí)聯(lián)動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助
    2021-07-07

最新評(píng)論

盐边县| 久治县| 台北县| 东辽县| 信宜市| 马关县| 扶绥县| 武定县| 青铜峡市| 泸州市| 栾川县| 福建省| 建水县| 微博| 罗甸县| 喀什市| 扬中市| 宁强县| 枣阳市| 永城市| 延川县| 中超| 武城县| 嵩明县| 托克逊县| 红原县| 碌曲县| 东丽区| 郑州市| 怀来县| 平遥县| 景德镇市| 临潭县| 疏附县| 九龙坡区| 贵南县| 瑞昌市| 祁东县| 卓尼县| 巢湖市| 高阳县|