二、使用Spring AI实现简单聊天功能(实现角色预设、流式和非流式响应)

二、使用Spring AI实现简单聊天功能(实现角色预设、流式和非流式响应)

==================================================================================

==================================================================================

参考资料:

==================================================================================

GitHub - changsongyang/atguigu-springai: 尚硅谷SpringAI实战教程,springai轻松上手大模型应用开发

Spring AI 教程 - Spring AI 教程 - 核心编程 (hxstrive.com)

手把手教你如何使用Spring AI调用DeepSeek API:从SpringBoot启动到存储MySQL数据库_spring-ai-deepseek-spring-boot-starter-CSDN博客

==================================================================================

1、Spring AI的聊天模型

Spring AI的聊天模型API为开发者提供了一条便捷通道,能够将强大的AI驱动的聊天完成功能无缝集成到各类应用中。

借助预先训练的语言模型,它能够依据用户输入生成自然流畅、类人化的回复。

这一API不仅工作机制高效,而且设计理念极为先进,旨在实现简单易用与高度可移植性,

让开发者能以极少的代码改动在不同AI模型间自由切换,充分契合Spring框架一贯秉持的模块化与可互换性原则。

2、ChatClient接口

ChatClient 接口定义了一个与聊天服务交互的客户端。

这个接口主要用于创建聊天客户端对象,设置请求规范,以及发起聊天请求。

2.1、实现简单的对话

用户输入设置用户消息的内容,通过SpringBoot AI封装的方法向 AI 模型发送请求,以字符串形式返回AI 模型的响应。

@RestController
public class ChatController {

    //注入
    private final ChatClient chatClient;

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

    //实现简单对话功能
    @GetMapping("/chat")
    public String chat(@RequestParam(value = "msg", defaultValue = "你是谁")
                       String message) {
        return chatClient.prompt()    //提示词
                .user(message) //用户输入信息
                .call() //请求大模型
                .content(); //返回文本
    }
}

39458eb5-8750-4c80-9f7f-346d1d4b7965

2.2、实现角色预设、流式和非流式响应

配置默认角色

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

@Configuration
public class AiConfig {

    @Bean
    public ChatClient chatClient(ChatClient.Builder builder) {
        return builder.defaultSystem("你是一个聊天助手,请根据用户问题,进行简短的回答!" +
                "你的名字叫老羅。").build();
    }
}

实现接口

@RestController
public class ChatAiController {

    @Autowired
    private ChatClient chatClient;

    //角色预设,使用非流式响应
    @GetMapping("/chatai")
    public String chatAi(@RequestParam(value = "msg") String message) {
        return chatClient.prompt().user(message).call().content();
    }

    //角色预设,使用流式响应
    @GetMapping(value = "/chataiStream", produces = "text/html;charset=UTF-8")
    public Flux<String> chatAiStream(@RequestParam(value = "msg") String message) {
        return chatClient.prompt().user(message).stream().content();
    }
}

d2c78cc9dd6b669dc5aa66a5bef59eb4

非流式输出 call:等待大模型把回答结果全部生成后输出给用户;
流式输出stream:逐个字符输出,一方面符合大模型生成方式的本质,另一方面当模型推理效率不是很高时,流式输出比起全部生成后再输出大大提高用户体验。

3、ChatModel接口

ChatModel接口作为核心,定义了与AI模型交互的基本方法。可以进行下面的操作:

3.1、使用不同大模型返回结果

调用chatModel方法并指定不同于application.yml配置中的LLM大模型返回结果
015c3594-2daa-4ac6-a8c6-5dbc1c3937ba

3.2、动态替换模板中的关键词

使用Prompt Template 提示词模板动态替换模板中的关键词返回结果
e9d3efb0-b842-442d-b752-773da39e0149
b3fa268a-f18f-4589-aca0-524c518dc29c

@RestController
public class ChatModelController {

    @Autowired
    private ChatModel chatModel;

    //提示词操作
    // city:咨询城市
    // name:美食助手名字
    // voice: 饮食习惯
    @GetMapping("/prompt")
    public String prompt(@RequestParam("city") String city,
                         @RequestParam("name") String name,
                         @RequestParam("voice") String voice) {
        //设置用户输入信息
        String userText = """
                给我推荐{0}的至少三种美食
                """;
        UserMessage userMessage = new UserMessage(MessageFormat.format(userText, city));

        //设置系统提示信息
        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(""));
    }

    //String call(String message)
    @GetMapping("/chatModel01")
    public String chatModel01(@RequestParam("msg") String msg) {
        String result = chatModel.call(msg);
        return result;
    }

    //ChatResponse call(Prompt prompt);
    @GetMapping("/chatModel02")
    public String chatModel02(@RequestParam("msg") String msg) {
        ChatResponse chatResponse = chatModel.call(
                new Prompt(
                        msg,
                        OpenAiChatOptions.builder()
                                //可以指定不同于application.yml配置中的LLM大模型
                                .model("deepseek-ai/DeepSeek-V3.2-Exp")
                                .temperature(1.0)
                                .build()
                )
        );
        String content = chatResponse.getResult().getOutput().getText();
        return content;
    }
}
posted @ 2025-11-24 09:59  老羅  阅读(49)  评论(0)    收藏  举报