《SpringBoot整合智谱清言大模型实战:流式AI问答接口开发指南(附完整代码)》

303 阅读2分钟

一、背景与场景

1.1 为什么需要流式AI问答?

  • 传统问答接口痛点

    • 响应延迟高:用户需要等待完整答案生成
    • 交互体验差:无法实现「打字机效果」
    • 资源浪费:长文本生成时占用大量内存
  • 流式传输优势

    • 首包响应时间低至300ms
    • 支持实时交互,提升用户体验
    • 节省服务器资源,降低内存占用

1.2 技术选型

技术栈选型理由
SpringBoot快速构建RESTful API,生态丰富
智谱清言国产大模型,API稳定,支持流式响应
SSE(Server-Sent Events)轻量级流式传输协议,兼容性好

二、快速开始

1.在pom.xml文件中引入依赖。

<dependency>
    <groupId>cn.bigmodel.openapi</groupId>
    <artifactId>oapi-java-sdk</artifactId>
    <version>release-V4-2.3.2</version>
</dependency>

2.我们需要在智谱清言开放平台注册个人账号,并获取apikey

# AI 配置
ai:
  apiKey: 你的秘钥

三、核心实现

  1. 配置类封装
@Configuration
@ConfigurationProperties(prefix = "ai")
@Data
public class AiConfig {

    private String apiKey;

    @Bean
    public ClientV4 getClientV4() {
        return new ClientV4.Builder(apiKey).build();
    }
}

4.AI服务层封装

@Component
public class AiManager {

    @Resource
    private ClientV4 clientV4;

    // 温度参数控制
    private static final float STABLE_TEMPERATURE = 0.05f; // 稳定输出
    private static final float UNSTABLE_TEMPERATURE = 0.99f; // 创造性输出

    /**
     * 流式请求(核心方法)
     */
    public Flowable<ModelData> doStreamRequest(List<ChatMessage> messages, Float temperature) {
        ChatCompletionRequest request = ChatCompletionRequest.builder()
                .model(Constants.ModelChatGLM4Flash)
                .stream(Boolean.TRUE)
                .temperature(temperature)
                .messages(messages)
                .build();
        
        try {
            return clientV4.invokeModelApi(request).getFlowable();
        } catch (Exception e) {
            throw new BusinessException("AI服务调用失败", e);
        }
    }
}

5.流式控制器实现

@RestController
@RequestMapping("/ai")
public class AIController {

    @Resource
    private AiManager aiManager;

    private static final String AI_PROMPT = """
        你是一位资深教授,擅长解决学术问题...
        <!--技能模块-->
        {具体提示词内容}
        """;


@GetMapping("/ai_generate/sse")
public SseEmitter aiGenerateQuestionSSE(QuestionAddRequest aiGenerateQuestionRequest, HttpServletRequest request) throws Exception {
    ThrowUtils.throwIf(aiGenerateQuestionRequest == null, ErrorCode.PARAMS_ERROR);
    // 获取参数
    String userMessage = aiGenerateQuestionRequest.getQuestion();

    // 封装 Prompt
    // 建立 SSE 连接对象,0 表示永不超时
    SseEmitter sseEmitter = new SseEmitter(0L);

    // AI 生成,SSE 流式返回
    Flowable<ModelData> modelDataFlowable = aiManager.doStreamRequest(AI_INTERACTION_MESSAGE, userMessage, null);

    // 默认全局线程池
    Scheduler scheduler = Schedulers.single();

    StringBuilder stringBuilder = new StringBuilder();

    modelDataFlowable
            .observeOn(scheduler)
            .map(modelData -> modelData.getChoices().get(0).getDelta().getContent())
            .doOnNext(content -> {
                stringBuilder.append(content);
                sseEmitter.send(SseEmitter.event().name("message").data(content));
                stringBuilder.setLength(0);
            })
            .doOnError((e) -> log.error("sse error", e))
            .doOnComplete(sseEmitter::complete)
            .subscribe();
    return sseEmitter;
}

四、参考说明

  • 智谱清言官方文档API Reference
  • Spring官方文档SSE支持
  • 技术参考:本文部分实现参考了程序员鱼皮的API设计实践,特此致谢