Solon v3.2.0

chat - 调用之两种 http 流式输出

</> markdown

http 流式输出(主要是指文本流式输出),需要使用响应式接口和支持流输出的 mime 申明。常见的有两种文本流式输出:

1、使用 sse(Server Sent Event)

输出的格式:以 sse 消息块为单位,以"空行"为识别间隔。

示例代码:

@Produces(MimeType.TEXT_EVENT_STREAM_UTF8_VALUE)
@Mapping("case1")
public Flux<SseEvent> case1(String prompt) throws IOException {
    return Flux.from(chatModel.prompt(prompt).stream())
            .map(resp -> resp.getMessage())
            .map(msg -> new SseEvent().data(msg.getContent()));
}

输出效果如下(sse 消息块有多个属性,data 为必选,其它为可选):

data:{"role":"ASSISTANT","content":"xxx"}

data:{"role":"ASSISTANT","content":"yyy"}

2、使用 ndjosn(Newline-Delimited JSON))

输出的格式:以 json 消息块为单位,以"换行符"为识别间隔。

@Produces(MimeType.APPLICATION_X_NDJSON_UTF8_VALUE)
@Mapping("case2")
public Flux<AssistantMessage> case2(String prompt) throws IOException {
    return Flux.from(chatModel.prompt(prompt).stream())
            .map(resp -> resp.getMessage());
}

输出效果如下:

{"role":"ASSISTANT","content":"xxx"}
{"role":"ASSISTANT","content":"yyy"}

3、补充

上面讲的是作为 server 以流式输出。solon-net-httputils 则提供了,作为客户端接收流式输出的能力:

  • 在服务端使用 HttpUtils 请求文本流,并直接返回到客户端
@Produces(MimeType.APPLICATION_X_NDJSON_UTF8_VALUE)
@Mapping("case3")
public Publisher<String> case3(String prompt) throws IOException {
    return HttpUtils.http("http://localhost:8080/stream")
                .execAsTextStream("GET");
}
  • 使用 HttpUtils 获取 ServerSentEvnet (简称:sse)文本流
Publisher<ServerSentEvent> publisher = HttpUtils.http("http://localhost:8080/sse")
                .execAsEventStream("GET");