步骤 03 - 流式响应
LLM 的响应可能很长。想象一下让模型生成一个故事。它可能产生数百行文本。
在当前应用程序中,整个响应会在发送到客户端之前被累积。在生成过程中,客户端正在等待响应,服务器正在等待模型完成响应的生成。当然,有一个“…”气泡表明正在进行一些操作,但这并不是最佳的用户体验。
流式传输允许我们在模型生成响应时,将响应分块发送。模型以块(token)的形式发送响应,服务器在接收到这些块时将它们发送给客户端。
此步骤的最终代码位于 step-03
目录中。但是,我们建议您按照以下说明进行操作,并继续扩展您当前的应用程序。
要求 LLM 返回块
第一步是要求 LLM 分块返回响应。最初,我们的 AI 服务是这样的
package dev.langchain4j.quarkus.workshop;
import io.quarkiverse.langchain4j.RegisterAiService;
import jakarta.enterprise.context.SessionScoped;
@SessionScoped
@RegisterAiService
public interface CustomerSupportAgent {
String chat(String userMessage);
}
请注意,chat
方法的返回类型是 String
。 我们将将其更改为 Multi<String>
,以表明响应将被流式传输而不是同步返回。
package dev.langchain4j.quarkus.workshop;
import io.quarkiverse.langchain4j.RegisterAiService;
import io.smallrye.mutiny.Multi;
import jakarta.enterprise.context.SessionScoped;
@SessionScoped
@RegisterAiService
public interface CustomerSupportAgent {
Multi<String> chat(String userMessage);
}
Multi<String>
是字符串流。Multi
是来自 Mutiny 库的类型,它代表一个项目流,可能是无限的。在这种情况下,它将是一个代表 LLM 响应的字符串流,并且它是有限的(幸运的是)。Multi
还有其他特性,例如处理背压的能力,我们将在本次研讨会中不涵盖。
从 WebSocket 提供流
好的,现在我们的 AI 服务返回了一个字符串流。但是,我们需要修改我们的 WebSocket 端点来处理这个流并将其发送给客户端。
目前,我们的 WebSocket 端点是这样的
package dev.langchain4j.quarkus.workshop;
import io.quarkus.websockets.next.OnOpen;
import io.quarkus.websockets.next.OnTextMessage;
import io.quarkus.websockets.next.WebSocket;
@WebSocket(path = "/customer-support-agent")
public class CustomerSupportAgentWebSocket {
private final CustomerSupportAgent customerSupportAgent;
public CustomerSupportAgentWebSocket(CustomerSupportAgent customerSupportAgent) {
this.customerSupportAgent = customerSupportAgent;
}
@OnOpen
public String onOpen() {
return "Welcome to Miles of Smiles! How can I help you today?";
}
@OnTextMessage
public String onTextMessage(String message) {
return customerSupportAgent.chat(message);
}
}
让我们修改 onTextMessage
方法,以便在响应到达时将其发送给客户端。
package dev.langchain4j.quarkus.workshop;
import io.quarkus.websockets.next.OnOpen;
import io.quarkus.websockets.next.OnTextMessage;
import io.quarkus.websockets.next.WebSocket;
import io.smallrye.mutiny.Multi;
@WebSocket(path = "/customer-support-agent")
public class CustomerSupportAgentWebSocket {
private final CustomerSupportAgent customerSupportAgent;
public CustomerSupportAgentWebSocket(CustomerSupportAgent customerSupportAgent) {
this.customerSupportAgent = customerSupportAgent;
}
@OnOpen
public String onOpen() {
return "Welcome to Miles of Smiles! How can I help you today?";
}
@OnTextMessage
public Multi<String> onTextMessage(String message) {
return customerSupportAgent.chat(message);
}
}
就是这样!现在响应将在到达时流式传输到客户端。这是因为 Quarkus 本地理解返回类型是 Multi
,并且知道如何处理它。
测试流式传输
要测试流式传输,您可以使用与之前相同的聊天界面。应用程序应仍处于运行状态。返回浏览器,刷新页面,然后开始聊天。如果您问简单的问题,您可能不会注意到区别。
问一些诸如此类的问题
您将看到响应在到达时被显示出来。
现在让我们切换到 下一步!