LangChain4j 项目实战--4:硅谷小智(实现流式输出)

一、核心目标

将基于 LangChain4j 的小芝(Xiaozhi)项目从 "一次性返回大模型结果" 改为 "通义千问流式输出",实现后端逐段向前端推送回答内容。

二、关键改动步骤

1. 添加流式输出核心依赖

xml

复制代码
<!-- 流式输出核心依赖:Spring WebFlux(响应式编程) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- LangChain4j 对 Reactor 响应式框架的适配,支持流式返回 -->
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-reactor</artifactId>
</dependency>
  • 说明:WebFlux 提供 Flux(流式响应)核心类,langchain4j-reactor 是 LangChain4j 对接响应式框架的桥梁,二者缺一不可。

2. 配置通义千问流式大模型

application.properties 中添加流式模型配置:

properties

复制代码
# 通义千问流式模型配置
langchain4j.community.dashscope.streaming-chat-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.community.dashscope.streaming-chat-model.model-name=qwen-plus
  • 关键参数:
    • api-key:通义千问 API 密钥(需替换为自己的有效密钥);
    • model-name:指定流式模型(如 qwen-plus 为通义千问增强版,支持流式输出);
    • 前缀 streaming-chat-model:明确指定使用 "流式聊天模型",区别于普通一次性模型。

3. 修改 AI 服务接口(XiaozhiAgent)

复制代码
@AiService(
    wiringMode = EXPLICIT,
    // 核心改动:从普通 chatModel 改为流式 streamingChatModel
    streamingChatModel = "qwenStreamingChatModel",
    chatMemoryProvider = "chatMemoryProviderXiaozhi",
    tools = "appointmentTools",
    contentRetriever = "contentRetrieverXiaozhiPincone")
public interface XiaozhiAgent {
    @SystemMessage(fromResource = "zhaozhi-prompt-template.txt")
    // 核心改动:返回值从 String 改为 Flux<String>(流式字符串序列)
    Flux<String> chat(@MemoryId Long memoryId, @UserMessage String userMessage);
}
  • 核心改动点:
    1. @AiService 注解中:chatModelstreamingChatModel,指定使用流式模型;
    2. 方法返回值:StringFlux<String>Flux 代表 "0 到 N 个元素的流式序列",对应大模型逐段返回的结果。

4. 修改 Controller 接口

复制代码
@Operation(summary = "对话")
// 核心改动:添加 produces 声明返回流式文本,指定 UTF-8 避免中文乱码
@PostMapping(value = "/chat", produces = "text/stream;charset=utf-8")
// 核心改动:返回值同步改为 Flux<String>,承接流式结果
public Flux<String> chat(@RequestBody ChatForm chatForm) {
    return xiaozhiAgent.chat(chatForm.getMemoryId(), chatForm.getMessage());
}
  • 核心改动点:
    1. produces = "text/stream;charset=utf-8":告诉前端响应为流式文本,同时指定编码;
    2. 返回值改为 Flux<String>,将 AI 服务的流式结果透传给前端。

5. 前端环境准备(辅助步骤)

  • 安装 Node.js(推荐 v18.17.1):前端需基于 Node.js 运行,用于接收 / 展示流式数据(如通过 EventSource 接收 SSE 流)。

三、关键注意事项

  1. 编码问题:produces 中必须加 charset=utf-8,否则前端接收中文会乱码;
  2. 模型兼容性:确保配置的 model-name(如 qwen-plus)支持流式输出;
  3. 前端对接:需用 SSE(EventSource)或支持流式的请求库(如 Axios)接收后端推送的流式数据。

四、核心逻辑总结

  1. 依赖层:引入 WebFlux + LangChain4j-Reactor 支撑响应式流式返回;
  2. 配置层:指定通义千问流式模型的 API 密钥和模型名称;
  3. 接口层:将 AI 服务和 Controller 的返回值改为 Flux<String>,并指定流式模型 / 响应类型;
  4. 最终效果:后端逐段推送通义千问的回答内容,前端实时接收并展示
相关推荐
茶本无香5 小时前
设计模式之十六:状态模式(State Pattern)详解 -优雅地管理对象状态,告别繁琐的条件判断
java·设计模式·状态模式
木斯佳1 天前
前端八股文面经大全:字节跳动前端一面(2025-10-09)·面经深度解析
前端·状态模式
山北雨夜漫步3 天前
点评Day06 剩下的卡拉米,我不都写,只写一些新奇的
状态模式
木斯佳4 天前
前端八股文面经大全:京东零售前端实习一面(2026-1-20)·面经深度解析
前端·状态模式·零售
木斯佳4 天前
前端八股文面经大全:字节前端一面(2026-2-1)·面经深度解析
前端·状态模式
前端不太难5 天前
Flutter 页面切换后为什么会“状态丢失”或“状态常驻”?
flutter·状态模式
前端不太难5 天前
从零写一个完整的原生鸿蒙 App
华为·状态模式·harmonyos
木斯佳5 天前
前端八股文面经大全:小红书前端一面(2026-2-3)·面经深度解析
前端·状态模式
geovindu5 天前
python: State Pattern
python·状态模式