Spring AI的聊天模型

目录

  • [1 概述](#1 概述)
  • [2 ChatClient接口](#2 ChatClient接口)
    • [2.1 实现简单的对话](#2.1 实现简单的对话)
      • [2.1.1 需求](#2.1.1 需求)
      • [2.1.2 编写Controller方法](#2.1.2 编写Controller方法)
      • [2.1.3 测试结果](#2.1.3 测试结果)
      • [2.1.4 总结](#2.1.4 总结)
    • [2.2 实现角色预设](#2.2 实现角色预设)
      • [2.2.1 配置默认角色](#2.2.1 配置默认角色)
      • [2.2.2 编写controller](#2.2.2 编写controller)
      • [2.2.3 测试结果](#2.2.3 测试结果)
    • [2.3 实现流式响应](#2.3 实现流式响应)
      • [2.3.1 call和stream的区别](#2.3.1 call和stream的区别)
      • [2.3.2 编写Controller](#2.3.2 编写Controller)
      • [2.3.3 测试结果](#2.3.3 测试结果)
  • [3 ChatModel接口](#3 ChatModel接口)
    • [3.1 概述](#3.1 概述)
    • [3.2 实现简单的对话](#3.2 实现简单的对话)
    • [3.3 提示词](#3.3 提示词)

1 概述

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

2 ChatClient接口

ChatClient 是一个接口,它定义了一个与聊天服务交互的客户端。这个接口主要用于创建聊天客户端对象,设置请求规范,以及发起聊天请求。

2.1 实现简单的对话

2.1.1 需求

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

2.1.2 编写Controller方法

java 复制代码
@RestController
public class ChatDeepSeekController {

    private final ChatClient chatClient;

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

    @GetMapping("/chat")
    public String chat(@RequestParam(value = "msg",defaultValue = "给我讲个笑话")
                           String message) {
        //prompt:提示词
        return this.chatClient.prompt()
                //用户输入的信息
                .user(message)
                //请求大模型
                .call()
                //返回文本
                .content();
    }
}

2.1.3 测试结果

2.1.4 总结

text 复制代码
ChatClient 接口提供了构建和配置聊天客户端对象的灵活性,以及发起和处理聊天请求的能力。用户可以通过 ChatClient.Builder 来定制客户端的行为,然后使用 prompt() 和 prompt(Prompt prompt) 方法设置请求规范,最后通过 call() 方法发起聊天请求。

2.2 实现角色预设

2.2.1 配置默认角色

java 复制代码
@Configuration
public class AIConfig {

    @Bean
    public ChatClient chatClient(ChatClient.Builder builder) {
        return builder.defaultSystem("你是尚硅谷教育的一名老师,你精通Java开发," +
                "你的名字叫尚硅谷。").build();
    }
}

2.2.2 编写controller

java 复制代码
@RestController
@RequestMapping("/ai")
public class AIController {

    @Autowired
    private ChatClient chatClient;

    @GetMapping("/chat")
    public String chat(@RequestParam(value = "msg") String message) {
        return chatClient.prompt().user(message).call().content();
    }
}

2.2.3 测试结果

2.3 实现流式响应

2.3.1 call和stream的区别

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

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

2.3.2 编写Controller

java 复制代码
@GetMapping(value = "/chat/stream",produces="text/html;charset=UTF-8")
public Flux<String> chatStream(@RequestParam(value = "msg") String message) {
    return chatClient.prompt().user(message).stream().content();
}

2.3.3 测试结果

3 ChatModel接口

3.1 概述

ChatModel接口作为核心,定义了与AI模型交互的基本方法。它继承自Model<Prompt, ChatResponse>,提供了两个重载的call方法:

java 复制代码
public interface ChatModel extends Model<Prompt, ChatResponse> {
    default String call(String message) {...}
    @Override
    ChatResponse call(Prompt prompt);
}

在ChatModel接口中,带有String参数的call()方法简化了实际的使用,避免了更复杂的Prompt和 ChatResponse类的复杂性。但是在实际应用程序中,更常见的是使用ChatResponse call()方法,该方法采用Prompt实例并返回ChatResponse。

我们使用的ChatClient底层是使用ChatModel作为属性的,在初始化ChatClient的时候可以指定ChatModel,这里我们直接看底层源码:

java 复制代码
//ChatClient(部分构造器代码)
static ChatClient create(ChatModel chatModel) {
    return create(chatModel, ObservationRegistry.NOOP);
}

3.2 实现简单的对话

java 复制代码
@RestController
public class DeepSeekController {

    @Autowired
    private ChatModel chatModel;

    @GetMapping
    public String chat(@RequestParam("msg")String msg) {
        return chatModel.call(msg);
    }

    @GetMapping("/openai")
    public String openai(@RequestParam("msg")String msg) {
        ChatResponse call = chatModel.call(
                new Prompt(
                        msg,
                        OpenAiChatOptions.builder()
                                //可以更换成其他大模型,如Anthropic3ChatOptions亚马逊
                                .model("deepseek-chat")
                                .temperature(0.8)
                                .build()
                )
        );
        return call.getResult().getOutput().getContent();
    }
}

3.3 提示词

  • 提示词是引导大模型生成特定输出的输入,提示词的设计和措辞会极大地影响模型的响应结果
  • Prompt 提示词是与模型交互的一种输入数据组织方式,本质上是一种复合结构的输入,在 prompt 我们是可以包含多组不同角色(System、User、Aissistant等)的信息。如何管理好 Prompt 是简化 AI 应用开发的关键环节。
  • Spring AI 提供了 Prompt Template 提示词模板管理抽象,开发者可以预先定义好模板,并在运行时替换模板中的关键词。在 Spring AI 与大模型交互的过程中,处理提示词首先要创建包含动态内容占位符 {占位符} 的模板,然后,这些占位符会根据用户请求或应用程序中的其他代码进行替换。在提示词模板中,{占位符} 可以用 Map 中的变量动态替换。
java 复制代码
@GetMapping("/prompt")
public String prompt(@RequestParam("name")
                         String name,
                     @RequestParam("voice")
                         String voice){
    String userText= """
            给我推荐北京的至少三种美食
            """;
    UserMessage userMessage = new UserMessage(userText);
    String systemText= """
            你是一个美食咨询助手,可以帮助人们查询美食信息。
            你的名字是{name},
            你应该用你的名字和{voice}的饮食习惯回复用户的请求。
            """;
    SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemText);
    //替换占位符
    Message systemMessage = systemPromptTemplate
            .createMessage(Map.of("name", name, "voice", voice));
    Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
    List<Generation> results = chatModel.call(prompt).getResults();
    return results.stream().map(x->x.getOutput().getContent()).collect(Collectors.joining(""));
}
相关推荐
Huazhongzhanhui43 分钟前
武汉激光焊接、切割及钣金加工展会上演高端制造技术盛宴
大数据·人工智能
IT 小阿姨(数据库)44 分钟前
K8s v1.24.17 完整搭建文档(CentOS7 + containerd1.6.33 + Calico)
java·容器·kubernetes
辰辉创聚1 小时前
In Vivo抗体是什么?| 体内抗体与普通科研抗体的区别
人工智能·python·时序数据库·in vivo抗体·体内抗体·体内级抗体
xwz小王子1 小时前
Nature Sensors封面:清华“天眸芯”,类脑互补视觉范式重塑AI感知世界的方式
人工智能·深度学习·机器学习
皮皮虾❀1 小时前
钉钉AI服务商+AI表格+AI听记+千问办公全产品线一体化实战:从“办公工具各自为战”到“服务商打包部署全套AI办公能力
人工智能·钉钉
不一样的少年_1 小时前
图解 AI Agent ②:模型到底是怎么读取文件的?
人工智能·agent·ai编程
后焊加工装家1 小时前
【无标题】
人工智能
auto_go1 小时前
大模型实战指南(5)——从 Prompt 到 Harness:Agent 时代的工程范式跃迁
人工智能
lhldsg1 小时前
全民健身解决方案:从共享球场到智能运营的技术实践
java·大数据·开发语言·需求分析