面试官:如何实现大模型的连续对话?

大模型连续对话功能不同的框架实现也是不同的,以行业使用最多的 Java AI 框架 Spring AI 和 Spring AI Alibaba 为例,给大家演示一下它们连续对话是如何实现的。

所有的大模型本身是不进行信息存储的,也不提供连续对话功能,所以想要实现连续对话功能需要开发者自己写代码才能实现。那怎么才能实现大模型的连续对话功能呢?

大模型连续对话功能不同的框架实现也是不同的,以行业使用最多的 Java AI 框架 Spring AI 和 Spring AI Alibaba 为例,给大家演示一下它们连续对话是如何实现的。

1.SpringAI连续对话实现

Spring AI 以 MySQL 数据库为例,我们来实现一下它的连续对话功能。

PS:我们只有先讲对话存储起来,才能实现连续对话功能,所以我们需要借助数据库存储来连续对话。

(1)准备工作

创建表:

CREATE TABLE chat_message (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  conversation_id VARCHAR(255) NOT NULL,
  role VARCHAR(50) NOT NULL,
  context TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

添加数据库和 MyBatisPlus 依赖: 

<dependency>
  <groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.11</version>
</dependency>

<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>

 设置配置文件:

spring:
  datasource:
    url:jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=utf8
    username:root
    password:12345678
    driver-class-name:com.mysql.cj.jdbc.Driver
# 配置打印 MyBatis 执行的 SQL
mybatis-plus:
configuration:
    log-impl:org.apache.ibatis.logging.stdout.StdOutImpl
# 配置打印 MyBatis 执行的 SQL
logging:
level:
    com:
      ai:
        deepseek:debug

编写实体类: 

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Date;

@Getter
@Setter
@TableName("chat_message")
publicclass ChatMessageDO implements Serializable {

    privatestaticfinallong serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    private String conversationId;

    private String role;

    private String context;

    private Date createdAt;
}

编写 Mapper: 

import com.ai.chat.entity.ChatMessageDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface ChatMessageMapper extends BaseMapper<ChatMessageDO> {
}
(2)自定义ChatMemory类

自定义的 ChatMemory 实现类,将对话记录存储到 MySQL:

import com.ai.deepseek.entity.ChatMessageDO;
import com.ai.deepseek.mapper.ChatMessageMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

@Component
publicclass MySQLChatMemory implements ChatMemory {
    @Autowired
    private ChatMessageMapper repository;

    @Override
    public void add(String conversationId, Message message) {
        ChatMessageDO entity = new ChatMessageDO();
        entity.setConversationId(conversationId);
        entity.setRole(message.getMessageType().name());
        entity.setContext(message.getText());
        repository.insert(entity);
    }

    @Override
    public void add(String conversationId, List<Message> messages) {
        messages.forEach(message -> add(conversationId, message));
    }

    @Override
    public List<Message> get(String conversationId, int lastN) {
        LambdaQueryWrapper<ChatMessageDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessageDO::getConversationId, conversationId);
        // queryWrapper.orderByDesc(ChatMessageDO::getId);
        return repository.selectList(queryWrapper)
        .stream()
        .limit(lastN)
        .map(e -> new UserMessage(e.getContext()))
        .collect(Collectors.toList());
    }

    @Override
    public void clear(String conversationId) {
        LambdaQueryWrapper<ChatMessageDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessageDO::getConversationId, conversationId);
        repository.delete(queryWrapper);
    }
}
(3)代码调用

编写代码测试历史对话保存到 MySQL 的功能:

 

import com.ai.deepseek.component.MySQLChatMemory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

@RestController
@RequestMapping("/multi")
publicclass MultiChatController {

    @Autowired
    private ChatClient chatClient;
    @Autowired
    private MySQLChatMemory chatMemory;

    @RequestMapping("/chat")
    public Flux<String> chat(@RequestParam("msg") String msg,
                             @RequestParam(defaultValue = "default") String sessionId) {
        // 添加MessageChatMemoryAdvisor,自动管理上下文
        MessageChatMemoryAdvisor advisor =
        new MessageChatMemoryAdvisor(chatMemory, sessionId, 10); // 保留最近5条历史
        return chatClient.prompt()
        .user(msg)
        .advisors(advisor) // 关键:注入记忆管理
        .stream()
        .content();
    }
}

以上程序执行结果如下:

2.SpringAIAlibaba实现连续对话

Spring AI Alibaba 连续对话的实现就简单很多了,因为它内置了 MySQL 和 Redis 的连续对话存储方式,接下来以 Redis 为例演示 SAA 的连续对话实现,它的实现步骤如下:

  • 添加依赖。
  • 设置配置文件,配置 Redis 连接信息。
  • 添加 Redis 配置类,注入 RedisChatMemoryRepository 对象。
  • 配置 ChatClient 实现连续对话。

具体实现如下。

(1)添加依赖
<dependency>
  <groupId>com.alibaba.cloud.ai</groupId>
  <artifactId>spring-ai-alibaba-starter-memory-redis</artifactId>
</dependency>
(2)设置配置文件

设置配置文件,配置 Redis 连接信息:

spring:
  ai:
    memory:
      redis:
        host: localhost
        port: 6379
        timeout: 5000
(3)添加Redis配置类

添加 Redis 配置类,注入 RedisChatMemoryRepository 对象,实现 Redis 自定义存储器注入:

import com.alibaba.cloud.ai.memory.redis.RedisChatMemoryRepository;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
publicclass RedisMemoryConfig {

    @Value("${spring.ai.memory.redis.host}")
    private String redisHost;
    @Value("${spring.ai.memory.redis.port}")
    privateint redisPort;
    //    @Value("${spring.ai.memory.redis.password}")
    //    private String redisPassword;
    @Value("${spring.ai.memory.redis.timeout}")
    privateint redisTimeout;

    @Bean
    public RedisChatMemoryRepository redisChatMemoryRepository() {
        return RedisChatMemoryRepository.builder()
        .host(redisHost)
        .port(redisPort)
        // 若没有设置密码则注释该项
        //           .password(redisPassword)
        .timeout(redisTimeout)
        .build();
    }
}

(4)配置ChatClient实现连续对话 

import com.alibaba.cloud.ai.memory.redis.RedisChatMemoryRepository;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

importstatic org.springframework.ai.chat.memory.ChatMemory.CONVERSATION_ID;

@RestController
@RequestMapping("/redis")
publicclass RedisMemoryController {

    privatefinal ChatClient chatClient;
    privatefinalint MAXMESSAGES = 10;
    privatefinal MessageWindowChatMemory messageWindowChatMemory;

    public RedisMemoryController(ChatModel dashscopeChatModel,
                                 RedisChatMemoryRepository redisChatMemoryRepository) {
        this.messageWindowChatMemory = MessageWindowChatMemory.builder()
        .chatMemoryRepository(redisChatMemoryRepository)
        .maxMessages(MAXMESSAGES)
        .build();

        this.chatClient = ChatClient.builder(dashscopeChatModel)
        .defaultAdvisors(
            MessageChatMemoryAdvisor.builder(messageWindowChatMemory)
            .build()
        )
        .build();
    }

    @GetMapping("/call")
    public String call(String msg, String cid) {
        return chatClient.prompt(msg)
        .advisors(
            a -> a.param(CONVERSATION_ID, cid)
        )
        .call().content();
    }
}

小结

通过以上代码大家也可以看出来,使用 Spring AI 实现连续对话是比较复杂的,需要自己实现数据库增删改查的代码,并且重写 ChatMemory 才能实现连续对话功能;而 Spring AI Alibaba 因为内置了连续对话的多种实现(Redis 和其他数据库),所以只需要简单配置就可以实现了。

 

 

 

 

 如何系统的去学习大模型LLM ?

大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业?”“谁的饭碗又将不保了?”等问题热议不断。

事实上,抢你饭碗的不是AI,而是会利用AI的人。

科大讯飞、阿里、华为等巨头公司发布AI产品后,很多中小企业也陆续进场!超高年薪,挖掘AI大模型人才! 如今大厂老板们,也更倾向于会AI的人,普通程序员,还有应对的机会吗?

与其焦虑……

不如成为「掌握AI工具的技术人」,毕竟AI时代,谁先尝试,谁就能占得先机!

但是LLM相关的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习成本和门槛很高。

针对所有自学遇到困难的同学们,我帮大家系统梳理大模型学习脉络,将这份 LLM大模型资料 分享出来:包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程

一、LLM大模型经典书籍

AI大模型已经成为了当今科技领域的一大热点,那以下这些大模型书籍就是非常不错的学习资源。

在这里插入图片描述

二、640套LLM大模型报告合集

这套包含640份报告的合集,涵盖了大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(几乎涵盖所有行业)

在这里插入图片描述

 三、LLM大模型系列视频教程

在这里插入图片描述

四、LLM大模型开源教程(LLaLA/Meta/chatglm/chatgpt)

在这里插入图片描述

LLM大模型学习路线 

阶段1:AI大模型时代的基础理解
  • 目标:了解AI大模型的基本概念、发展历程和核心原理。

  • 内容

  • L1.1 人工智能简述与大模型起源
  • L1.2 大模型与通用人工智能
  • L1.3 GPT模型的发展历程
  • L1.4 模型工程
  • L1.4.1 知识大模型
  • L1.4.2 生产大模型
  • L1.4.3 模型工程方法论
  • L1.4.4 模型工程实践
  • L1.5 GPT应用案例
阶段2:AI大模型API应用开发工程
  • 目标:掌握AI大模型API的使用和开发,以及相关的编程技能。

  • 内容

  • L2.1 API接口
  • L2.1.1 OpenAI API接口
  • L2.1.2 Python接口接入
  • L2.1.3 BOT工具类框架
  • L2.1.4 代码示例
  • L2.2 Prompt框架
  • L2.3 流水线工程
  • L2.4 总结与展望
阶段3:AI大模型应用架构实践
  • 目标:深入理解AI大模型的应用架构,并能够进行私有化部署。

  • 内容

  • L3.1 Agent模型框架
  • L3.2 MetaGPT
  • L3.3 ChatGLM
  • L3.4 LLAMA
  • L3.5 其他大模型介绍
阶段4:AI大模型私有化部署
  • 目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。

  • 内容

  • L4.1 模型私有化部署概述
  • L4.2 模型私有化部署的关键技术
  • L4.3 模型私有化部署的实施步骤
  • L4.4 模型私有化部署的应用场景

这份 LLM大模型资料 包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程等, 😝有需要的小伙伴,可以 下方小卡片领取🆓↓↓↓ 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值