一、LLMs流式输出介绍

流式输出(Streaming Output)是大语言模型(LLMs)中一种重要的交互方式,它允许模型将生成的文本逐步返回给用户,而不是等待整个响应完成后再一次性返回。

二、流式输出的工作原理

  1. 分块生成:模型不是一次性生成完整回答,而是逐词或逐句生成

  2. 即时传输:每生成一部分内容就立即发送给客户端

  3. 持续处理:客户端可以即时显示或处理接收到的部分结果

三、流式输出的优势

1、用户体验提升

  • 降低等待焦虑:用户不需要长时间等待就能看到部分结果

  • 更自然的交互:模拟人类对话的逐步响应方式

  • 响应感知:用户可以早期判断响应方向是否正确

2、技术优势

  • 降低延迟:首个令牌(Token)的响应时间(TTFB)大幅缩短

  • 内存效率:不需要缓存完整响应再发送

  • 中断能力:用户可以在中途停止不想要的响应。

四、流式输出的应用场景

  1. 聊天应用:模拟真人对话体验

  2. 代码生成:逐步显示生成的代码

  3. 长文写作:分段显示生成内容

  4. 实时翻译:边听边翻译的场景

  5. 教育应用:逐步解释复杂概念

五、流式输出的技术挑战与解决方案

挑战 解决方案
连接稳定性 心跳机制、自动重连
部分响应处理 客户端状态管理
错误处理 错误边界设计、重试机制
前后端协调 定义明确的数据协议

六、流式与一次性输出的对比

特性 流式输出 一次性输出
响应时间 快(首个令牌) 慢(完整响应)
内存占用
用户体验 更优 一般
实现复杂度 较高 较低
适用场景 交互式应用 批处理任务

流式输出已成为现代LLM应用的标准功能,它能显著提升用户体验,特别是在需要长时间生成内容的场景中。

七、流式输出的实现

下面使用Langchain4j+阿里千问来实现:

1、引入依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>langchain4j</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>langchain4j_springboot</name>
    <description>langchain4j_springboot</description>
    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <spring-boot.version>3.4.3</spring-boot.version>
        <langchain4j.version>1.0.0-beta1</langchain4j.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
        </dependency>
       <dependency>
               <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>dev.langchain4j</groupId>
                <artifactId>langchain4j-community-bom</artifactId>
                <version>${langchain4j.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

 这里重点说一下需要引入webflux实现流式响应输出:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

2、在application.properties配置流式输出所需要的信息

langchain4j.community.dashscope.streaming-chat-model.api-key=配置key
langchain4j.community.dashscope.streaming-chat-model.model-name=qwq-32b

3、编码实现:

package com.example.langchain4j.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import dev.langchain4j.community.model.dashscope.QwenChatModel;
import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

/**
 * @author: 
 * @Desc:
 * @create: 2025-07-13 12:40
 **/
@RestController
@RequestMapping("/ai")
public class ChatController {

    @Autowired
    private QwenStreamingChatModel streamingChatModel;
    
	//须指定produces为stream输出,编码为utf-8,否则会乱码
    @RequestMapping(value = "/stream", produces = "text/stream;charset=UTF-8")
    public Flux<String> stream(@RequestParam(value="message",defaultValue = "你是谁") String message){
        Flux<String> flux = Flux.create(sink -> {
            streamingChatModel.chat(message, new StreamingChatResponseHandler() {
                @Override
                public void onPartialResponse(String partialResponse) {
                    sink.next(partialResponse);
                }

                @Override
                public void onCompleteResponse(ChatResponse chatResponse) {
                    sink.complete();
                }

                @Override
                public void onError(Throwable throwable) {
                    sink.error(throwable);
                }
            });
        });

        return flux;
    }

}

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐