偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試官:如何實現(xiàn)大模型的連續(xù)對話?

人工智能
大模型連續(xù)對話功能不同的框架實現(xiàn)也是不同的,以行業(yè)使用最多的 Java AI 框架 Spring AI 和 Spring AI Alibaba 為例,給大家演示一下它們連續(xù)對話是如何實現(xiàn)的。

所有的大模型本身是不進行信息存儲的,也不提供連續(xù)對話功能,所以想要實現(xiàn)連續(xù)對話功能需要開發(fā)者自己寫代碼才能實現(xiàn)。那怎么才能實現(xiàn)大模型的連續(xù)對話功能呢?

大模型連續(xù)對話功能不同的框架實現(xiàn)也是不同的,以行業(yè)使用最多的 Java AI 框架 Spring AI 和 Spring AI Alibaba 為例,給大家演示一下它們連續(xù)對話是如何實現(xiàn)的。

1.SpringAI連續(xù)對話實現(xiàn)

Spring AI 以 MySQL 數(shù)據(jù)庫為例,我們來實現(xiàn)一下它的連續(xù)對話功能。

PS:我們只有先講對話存儲起來,才能實現(xiàn)連續(xù)對話功能,所以我們需要借助數(shù)據(jù)庫存儲來連續(xù)對話。

(1)準備工作

創(chuàng)建表:

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;

添加數(shù)據(jù)庫和 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 執(zhí)行的 SQL
mybatis-plus:
configuration:
    log-impl:org.apache.ibatis.logging.stdout.StdOutImpl
# 配置打印 MyBatis 執(zhí)行的 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 實現(xiàn)類,將對話記錄存儲到 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)代碼調(diào)用

編寫代碼測試歷史對話保存到 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) // 關(guān)鍵:注入記憶管理
        .stream()
        .content();
    }
}

以上程序執(zhí)行結(jié)果如下:

2.SpringAIAlibaba實現(xiàn)連續(xù)對話

Spring AI Alibaba 連續(xù)對話的實現(xiàn)就簡單很多了,因為它內(nèi)置了 MySQL 和 Redis 的連續(xù)對話存儲方式,接下來以 Redis 為例演示 SAA 的連續(xù)對話實現(xiàn),它的實現(xiàn)步驟如下:

  • 添加依賴。
  • 設置配置文件,配置 Redis 連接信息。
  • 添加 Redis 配置類,注入 RedisChatMemoryRepository 對象。
  • 配置 ChatClient 實現(xiàn)連續(xù)對話。

具體實現(xiàn)如下。

(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 對象,實現(xiàn) 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實現(xiàn)連續(xù)對話

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();
    }
}

小結(jié)

通過以上代碼大家也可以看出來,使用 Spring AI 實現(xiàn)連續(xù)對話是比較復雜的,需要自己實現(xiàn)數(shù)據(jù)庫增刪改查的代碼,并且重寫 ChatMemory 才能實現(xiàn)連續(xù)對話功能;而 Spring AI Alibaba 因為內(nèi)置了連續(xù)對話的多種實現(xiàn)(Redis 和其他數(shù)據(jù)庫),所以只需要簡單配置就可以實現(xiàn)了。

責任編輯:姜華 來源: 磊哥和Java
相關(guān)推薦

2024-02-20 14:10:55

系統(tǒng)緩存冗余

2024-09-11 22:51:19

線程通訊Object

2023-11-20 10:09:59

2015-08-13 10:29:12

面試面試官

2024-02-04 10:08:34

2024-12-25 15:44:15

2024-01-26 13:16:00

RabbitMQ延遲隊列docker

2024-04-09 10:40:04

2024-01-19 14:03:59

Redis緩存系統(tǒng)Spring

2024-10-22 16:39:07

2025-04-07 04:25:00

JDBCAPI加載器

2010-08-12 16:28:35

面試官

2021-05-20 08:54:16

Go面向對象

2021-12-15 06:58:13

List 集合LinkedHashS

2024-09-09 15:09:30

2021-05-20 08:34:03

CDN原理網(wǎng)絡

2021-10-26 10:29:45

掃碼登錄功能

2021-05-19 06:07:21

CSS 斜線效果技巧

2022-12-27 08:39:54

MySQL主鍵索引

2022-08-08 13:45:12

Redis面試Hash
點贊
收藏

51CTO技術(shù)棧公眾號