智能聊天机器人-基于Spring AI实现

发布于:2025-08-31 ⋅ 阅读:(23) ⋅ 点赞:(0)

项目背景

随着⼈⼯智能技术的快速发展和⼤模型开源趋势的兴起,智能聊天机器⼈在客服、知识问答、⽣活助⼿ 等领域得到了⼴泛应⽤,我们接下来模仿这些应用实现一个智能的聊天机器人

核心功能

1.对话

  • 支持用户和机器人之间的对话
  • 实时响应用户的输入,进行回答

2.多轮对话

  • 能够理解和处理多轮对话,保持上下文的连续性
  • 支持基于上下文的智能应答

3.历史记录

  • 自动保存用户和机器人之间的对话历史
  • 支持用户查看历史的对话内容

页面设计

我们通过ollama搭建本地的大模型

首先添加本项目所需要的依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>1.0.0-M6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

配置.yml文件

spring:
  application:
    name: spring-ai-chatRobot
  ai:
#    ollama
    ollama:
      base-url: http://127.0.0.1:11434
      chat:
        model: deepseek-r1:1.5b
logging:
  pattern:
    console: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
    file: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
  level:
    org.springframework.ai.chat.client.advisor: debug  # 只针对 Spring AI 的 advisor

写出启动类

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

对话功能

定义请求的内容

@Bean
    public ChatClient chatClient(OllamaChatModel ollamaChatModel, ChatMemory chatMemory){
        return ChatClient.builder(ollamaChatModel)
                .defaultSystem("你的名字是小瑞,你是一个智能聊天机器人")
                .defaultAdvisors(new SimpleLoggerAdvisor(), new MessageChatMemoryAdvisor(chatMemory))
                .build();
    }
  @RequestMapping(value = "/stream",produces = "text/html;charset=utf-8")
    public Flux<String> stream(@RequestParam String prompt,String chatId){

        if (prompt == null || prompt.trim().isEmpty()) {
            return Flux.just(" message 参数不能为空!");
        }
        memoryChatHistoryRepository.save(prompt, chatId);
        return chatClient.prompt()
                .user(prompt)
                .advisors(spec -> spec.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY, chatId))
                .stream()
                .content();
    }
}

对话记忆(ChatMemory)

⼤型语⾔模型是⽆状态的,也就是它们不会保留有关以前交互的信息.当开发⼈员希望在多个交 互中维护上下⽂或状态时,这可能是⼀个限制.为了解决这个问题,SpringAI提供了对话内存功能,定义 了ChatMemory接⼝,允许开发⼈员在与⼤型语⾔模型的多次交互中存储和检索信息.

定义ChatMemory将其注入到ChatClient中

@Bean
    public ChatMemory chatMemory(){
        return new InMemoryChatMemory();
    }

向模型发送请求时,传递ChatId

历史对话

我们需要定义一个实体类表示历史对话

@Data
public class ChatInfo {

    private String title;
    private String chatId;

    public ChatInfo(String title, String chatId) {
        this.title = title==null?"无标题" : title.length()>15?title.substring(0,15):title;
        this.chatId = chatId;
    }
}

实现存储,查询全文,删除三个方法

用LinkedHashMap是因为历史记录是有序的,

private Map<String,String> chatInfos=new LinkedHashMap<>();

模仿ChatMemory中的方法,实现存储,查询全文,删除三个方法

public interface ChatHistoryRepository {

    void save(String prompt,String chatId);

    List<ChatInfo> getChats();

    void clearByChatId(String chatId);
}
@Repository
public class MemoryChatHistoryRepository implements ChatHistoryRepository{

//    用LinkedHashMap<>是因为是有序的
    private Map<String,String> chatInfos=new LinkedHashMap<>();


    @Override
    public void save(String title, String chatId) {
        chatInfos.put(chatId, title);
    }

    @Override
    public List<ChatInfo> getChats() {
        return chatInfos.entrySet().stream()
                .map(entry->new ChatInfo(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());
    }

    @Override
    public void clearByChatId(String chatId) {
        chatInfos.remove(chatId);
    }
}

注入实现的方法对象

    @Autowired
    private MemoryChatHistoryRepository memoryChatHistoryRepository;

存储会话

获得会话列表

定义接口

//    获得会话列表
@RequestMapping("/getChatIds")
    public List<ChatInfo> getChatIds(){
        return memoryChatHistoryRepository.getChats();
    }

获取会话记录

定义接口

根据会话的Id,获得记录

//  活得会话记录
@RequestMapping("/getChatHistory")
    public List<MessageVo> getChatHistory(String chatId){
        List<Message> messages = chatMemory.get(chatId, 20);
        return messages.stream().map(MessageVo::new).collect(Collectors.toList());
    }

为了让前端处理起来更加的简单,我们用VO统一成固定的格式

@Data
public class MessageVo {

    private String role;
    private String content;

    public MessageVo(Message message){
        switch (message.getMessageType()){
            case USER -> {this.role = "user"; break;}
            case ASSISTANT -> {this.role = "assistant"; break;}
            case SYSTEM -> {this.role = "system"; break;}
            case TOOL -> {this.role = "tool"; break;}
        }
        this.content = message.getText();
        }


}

删除会话记录

定义接口

//    删除会话记录
@RequestMapping("/deleteChat")
    public boolean clearChat(String chatId){
        try {
            memoryChatHistoryRepository.clearByChatId(chatId);
            chatMemory.clear(chatId);
        }catch (Exception e){
            return false;
        }
        return true;
    }

将Ollama切换到DeepSeek

添加依赖和修改.yml文件

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
        </dependency>
    openai:
      api-key: sk-493d502eee42490f92d3015479aa8f47
      base-url: https://api.deepseek.com
      chat:
        options:
          model: deepseek-chat
          temperature: 0.7

定义ChatClient

    @Bean
    public ChatClient chatClient(OpenAiChatModel openAiChatModel, ChatMemory chatMemory){
        return ChatClient.builder(openAiChatModel)
                .defaultSystem("你的名字小瑞,是一个智能机器人")
                .defaultAdvisors(new SimpleLoggerAdvisor(), new MessageChatMemoryAdvisor(chatMemory))
                .build();
    }

希望能对大家有所帮助!!!!!


网站公告

今日签到

点亮在社区的每一天
去签到