SpringAI之聊天模型sse

我爱海鲸 2025-07-10 12:42:17 暂无标签

简介java、jdk17、springboot3.5、流式、非流式

链接上一篇文章:http://www.haijin.xyz/article/842

1、Spring AI的聊天模型API为开发者提供了一条便捷通道,能够将强大的AI驱动的聊天完成功能无缝集成到各类应用中。借助预先训练的语言模型,如广为人知的GPT,它能够依据用户输入生成自然流畅、类人化的回复。这一API不仅工作机制高效,而且设计理念极为先进,旨在实现简单易用与高度可移植性,让开发者能以极少的代码改动在不同AI模型间自由切换,充分契合Spring框架一贯秉持的模块化与可互换性原则。

2、结果输出:

(1)非流式输出 call:等待大模型把回答结果全部生成后输出给用户;

(2)流式输出stream:逐个字符输出,一方面符合大模型生成方式的本质,另一方面当模型推理效率不是很高时,流式输出比起全部生成后再输出大大提高用户体验。

3、项目截图:

1、ChatClientConfig:

package xyz.haijin.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ai.chat.client.ChatClient;

@Configuration
public class ChatClientConfig {
    @Bean
    public ChatClient chatClient(ChatClient.Builder builder) {
        // 设置默认 system prompt,作为角色设定
        return builder.defaultSystem("我叫haijin,90后,是一名java程序员").build();
    }
} 

2、ChatAiController:

package xyz.haijin.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import java.util.Base64;
import java.nio.charset.StandardCharsets;

@RestController
public class ChatAiController {

    private final ChatClient chatClient;

    public ChatAiController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    // 非流式接口
    @GetMapping("/chat/call")
    public String call(@RequestParam(value = "msg", defaultValue = "你是谁") String msg) {
        return chatClient.prompt().user(msg).call().content();
    }

    // 流式接口,返回标准 SSE
    @GetMapping(value = "/chat/stream",produces = "text/html;charset=UTF-8")
    public Flux<String> chatAiStream(@RequestParam(value = "msg") String message) {
        return chatClient.prompt().user(message).stream().content();
    }
} 

3、ChatController:

package xyz.haijin.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ChatController {

    private final ChatClient chatClient;

    public ChatController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    @GetMapping("/chat")
    public String chat(@RequestParam(value = "msg", defaultValue = "你是谁") String msg) {
        // ChatClient 是 Spring AI 推荐的通用 LLM 客户端,兼容多种模型
        return chatClient.prompt().user(msg).call().content();
    }
} 

4、ChatModelController:

package xyz.haijin.controller;

import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.model.Generation;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.ai.deepseek.DeepSeekChatOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
public class ChatModelController {

    @Autowired
    private ChatModel chatModel;

    //提示词操作
    // name:名字
    // voice: 习惯
    @GetMapping("/prompt")
    public String prompt(@RequestParam("name")
                             String name,
                         @RequestParam("voice")
                             String voice) {
        //设置用户输入信息
        String userText = """
            给我推荐北京的至少三种美食
            """;
        UserMessage userMessage = new UserMessage(userText);

        //设置系统提示信息
        String systemText= """
            你是一个美食咨询助手,可以帮助人们查询美食信息。
            你的名字是{name},
            你应该用你的名字和{voice}的饮食习惯回复用户的请求。
            """;
        //使用Prompt Template 设置信息
        SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemText);

        //替换占位符
        Message systemMessage =
                systemPromptTemplate
                        .createMessage(Map.of("name", name, "voice", voice));

        //使用Prompt封装
        Prompt prompt = new Prompt(List.of(userMessage,systemMessage));

        //调用chatModel方法
        ChatResponse response = chatModel.call(prompt);
        List<Generation> results = response.getResults();
        return
                results.stream().map(x->x.getOutput().getText())
                        .collect(Collectors.joining(""));
    }

    //ChatResponse call(Prompt prompt);
    @GetMapping("/chatModel02")
    public String chatModel02(@RequestParam("msg") String msg) {
        ChatResponse chatResponse = chatModel.call(
                new Prompt(
                        msg,
                        DeepSeekChatOptions.builder()
                                .model("deepseek-chat")
                                .temperature(0.8)
                                .build()
                )
        );
        String content = chatResponse.getResult().getOutput().getText();
        return content;
    }
}

5、SpringAiHelloApplication:

package xyz.haijin;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringAiHelloApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringAiHelloApplication.class, args);
    }
} 

6、测试:

 

你好:我的2025