前言
在当今技术飞速发展的时代,大模型(Large Language Models, LLMs)已经成为热门话题,应用场景涵盖了自然语言处理、图像生成、智能客服等各个领域。特别是像GPT这样的生成式AI模型,正被越来越多的企业引入到自己的业务系统中。然而,面对如此庞大的模型和复杂的请求,如何实现实时、流式地获取模型响应成为了一个关键问题。
本文将向大家介绍如何通过流式调用接口技术,将大模型的能力快速接入到现有的系统中,实现实时返回的效果。我们将结合text/event-stream
和WebFlux
响应式编程,展示如何高效调用第三方大模型API,并将数据流式返回给前端。
前置知识
1. text/event-stream
流式调用
text/event-stream
是一种轻量级的服务器推送技术,通过 HTTP 协议实现服务端向客户端发送实时更新消息。它允许服务器在一个持久连接上连续发送事件,而无需客户端反复轮询,这对于调用大模型等长时间处理任务非常适合。
典型格式:
vbnet
http
Content-Type: text/event-stream
data: { "response": "数据流..." }
data: { "response": "更多数据..." }
2. WebFlux 响应式编程
WebFlux 是 Spring 5 中引入的一种异步、非阻塞的响应式编程框架,旨在支持高并发的请求处理。通过 WebFlux 提供的响应式编程模型,我们可以轻松实现流式数据处理和返回。在流式调用大模型时,WebFlux 可以帮助我们在不阻塞主线程的情况下流畅地处理请求和响应。
实现方式
下面我们将通过一个具体的示例,展示如何快速实现大模型的流式调用接口。
1. 引入依赖
首先,在Spring Boot
项目中,我们需要引入 WebFlux 相关依赖。编辑 pom.xml
文件:
xml
xml
复制代码
<dependencies>
<!-- WebFlux 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- 其他相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
2. 实现 WebClient 调用第三方接口
接下来,我们使用 WebFlux 中的 WebClient
调用大模型接口,获取流式返回的数据。
arduino
java
复制代码
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
@Service
public class LargeModelService {
private final WebClient webClient;
public LargeModelService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://api.large-model.com").build();
}
public Flux<String> getModelResponse(String input) {
return webClient.post()
.uri("/model/stream")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue("{"input": "" + input + ""}")
.accept(MediaType.TEXT_EVENT_STREAM)
.retrieve()
.bodyToFlux(String.class);
}
}
关键点:
WebClient
是 WebFlux 提供的非阻塞客户端,用于调用第三方接口。- 使用
text/event-stream
格式接受服务器返回的流式数据。 bodyToFlux(String.class)
表示将返回的数据作为流式数据(Flux<String>
)进行处理。
3. 返回数据到前端
为了将流式数据返回给前端,我们可以通过 Controller
进行封装。
kotlin
java
复制代码
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
@RestController
public class LargeModelController {
private final LargeModelService largeModelService;
public LargeModelController(LargeModelService largeModelService) {
this.largeModelService = largeModelService;
}
@GetMapping(value = "/model/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamModelResponse(@RequestParam String input) {
return largeModelService.getModelResponse(input);
}
}
关键点:
- 通过
@GetMapping
将请求映射到/model/stream
接口上。 produces = MediaType.TEXT_EVENT_STREAM_VALUE
确保返回的数据是text/event-stream
格式的流式数据。Flux<String>
用于将流式响应传递给前端,前端可以逐步接收和展示模型的输出。这里不能使用Mono,否则你会发现你调用你自己接口的时候会等到第三方接口的流全部都返回了,然后你才会像你的前端返回接口
4. 前端处理流式数据
前端通过 EventSource
接口接收流式数据,并实时展示。