当前位置: 首页 > news >正文

【Spring AI快速上手 (二)】Advisor实现对话上下文管理

一、前言

二、Advisor实现对话上下文管理

        pom.xml

        application.properties

        schema-mysql.sql

        application.yml

         自定义记忆实现

        Redis实现记忆功能

        Mysql实现记忆功能

        Advisor 测试代码


一、前言

 Spring AI详解:【Spring AI详解】开启Java生态的智能应用开发新时代(附不同功能的Spring AI实战项目)-CSDN博客

二、Advisor实现对话上下文管理

pom.xml

Spring AI的上下文管理功能需要依赖多个核心组件:

基础依赖:包括Spring Boot Web、测试等基础框架支持

AI模型集成:阿里云百炼、DeepSeek等大模型接入能力

记忆管理核心:提供ChatMemory接口和基础实现

持久化存储:JDBC和Redis两种存储方案实现

<properties><!-- 设置Java版本为17,Spring AI推荐使用Java 17+ --><java.version>17</java.version><!-- 指定Jedis客户端版本 --><jedis.version>5.2.0</jedis.version>
</properties><!-- 依赖管理配置(BOM模式) -->
<dependencyManagement><dependencies><!-- 1. Spring AI Alibaba BOM --><!-- 功能:管理阿里云AI生态组件的版本(如Dashscope、百炼平台集成等) --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-bom</artifactId><version>1.0.0.2</version><type>pom</type><scope>import</scope></dependency><!-- 2. Spring AI BOM --><!-- 功能:管理Spring AI核心模块版本(ChatClient、RAG、工具调用等) --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.0</version><type>pom</type><scope>import</scope></dependency><!-- 3. Spring Boot BOM --><!-- 功能:管理Spring Boot及其starter组件的版本 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>3.2.5</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><dependencies><!-- 阿里云百炼AI模型集成 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId></dependency><!-- Spring AI 聊天记忆自动配置 (核心) --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-autoconfigure-model-chat-memory</artifactId><!--基础记忆功能支持:- ChatMemory接口自动配置- MessageWindowChatMemory实现- 记忆管理基础架构--></dependency><!-- JDBC记忆存储实现 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId><!--基于数据库的记忆持久化:- 自动创建记忆存储表- 支持主流关系型数据库- 需要配合spring-boot-starter-jdbc使用--></dependency><!-- JDBC核心支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!-- MySQL驱动 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!-- 阿里云Redis记忆存储 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-memory-redis</artifactId><!--基于Redis的高性能记忆存储:- 支持Redis单机/集群模式- 自动序列化/反序列化- 需要配合Jedis客户端--></dependency><!-- Jedis Redis客户端 --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>${jedis.version}</version></dependency><!-- Spring Boot Web支持 --><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><scope>test</scope></dependency>
</dependencies>

application.properties

配置文件定义了应用的基础设置和记忆存储参数:

应用基础配置:应用名称、日志级别等

AI服务配置:API密钥、模型选择等

记忆存储配置:JDBC初始化策略、Schema文件位置等

# 应用基础配置
spring.application.name=chat-client# 阿里云百炼AI配置
spring.ai.dashscope.api-key=${ALI_AI_KEY}
# spring.ai.dashscope.chat.options.model=qwen-plus# 日志级别配置
# 开启SimpleLoggerAdvisor的DEBUG日志
logging.level.org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor=DEBUG# JDBC记忆存储初始化配置
# 启动时自动初始化数据库Schema,可选值:
# always - 总是初始化
# never - 不初始化(需手动建表)
# embedded - 仅嵌入式数据库初始化
spring.ai.chat.memory.repository.jdbc.initialize-schema=always# 指定自定义的Schema初始化SQL文件路径
# 文件内容应包含创建CHAT_MEMORY表的DDL语句
spring.ai.chat.memory.repository.jdbc.schema=classpath:/sql/schema-mysql.sql

schema-mysql.sql

定义了记忆存储的数据库表结构,包含对话ID、内容、类型和时间戳等核心字段

CREATE TABLE IF NOT EXISTS SPRING_AI_CHAT_MEMORY (`conversation_id` VARCHAR(36) NOT NULL,`content` TEXT NOT NULL,`type` VARCHAR(10) NOT NULL,`timestamp` TIMESTAMP NOT NULL,INDEX `SPRING_AI_CHAT_MEMORY_CONVERSATION_ID_TIMESTAMP_IDX` (`conversation_id`, `timestamp`));

application.yml

配置数据源和Redis连接信息

spring:datasource:username: rootpassword: 123456url: jdbc:mysql://localhost:3306/springai?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&driver-class-name: com.mysql.cj.jdbc.Driverai:memory:redis:host: localhostport: 6379timeout:  5000password:

 自定义记忆实现

演示了最简单的上下文管理实现方式 - 手动拼接对话历史

后续交互将历史对话拼接后作为上下文

使用Spring AI提供的标准记忆实现,创建MessageWindowChatMemory

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;@SpringBootTest
public class TestMemory {/*** 测试基础记忆功能 - 手动拼接对话历史* 演示如何通过字符串拼接实现简单记忆** @param chatModel 自动注入的DashScope聊天模型*/@Testpublic void testMemory(@Autowired DashScopeChatModel chatModel) {// 1. 创建基础ChatClientChatClient chatClient = ChatClient.builder(chatModel).build();// 2. 第一次交互String chatHis = "我叫小小";String content = chatClient.prompt().user(chatHis).call().content();System.out.println(content);System.out.println("----------------------------------");// 3. 第二次交互(手动拼接历史)chatHis += content;chatHis += "我叫什么?";content = chatClient.prompt().user(chatHis) // 包含完整对话历史.call().content();System.out.println(content);}/*** 测试ChatMemory实现 - 使用MessageWindowChatMemory* 演示Spring AI提供的标准记忆实现** @param chatModel 自动注入的DashScope聊天模型*/@Testpublic void testMemory2(@Autowired DashScopeChatModel chatModel) {// 1. 创建记忆组件(窗口大小默认为10)ChatMemory chatMemory = MessageWindowChatMemory.builder().build();String conversationId = "xx001"; // 对话唯一标识// 2. 第一次交互UserMessage userMessage1 = new UserMessage("我叫小小");chatMemory.add(conversationId, userMessage1); // 添加用户消息到记忆ChatResponse response1 = chatModel.call(new Prompt(chatMemory.get(conversationId)));chatMemory.add(conversationId, response1.getResult().getOutput()); // 添加AI响应到记忆// 3. 第二次交互UserMessage userMessage2 = new UserMessage("我叫什么?");chatMemory.add(conversationId, userMessage2);ChatResponse response2 = chatModel.call(new Prompt(chatMemory.get(conversationId)));chatMemory.add(conversationId, response2.getResult().getOutput());System.out.println(response2.getResult().getOutput().getText()); // 打印AI响应}// 共享的ChatClient实例ChatClient chatClient;/*** 初始化方法 - 配置带记忆顾问的ChatClient*/@BeforeEachpublic void init(@Autowired ChatClient.Builder builder,@Autowired ChatMemory chatMemory) {// 创建带记忆顾问的ChatClientthis.chatClient = builder.defaultAdvisors(PromptChatMemoryAdvisor.builder(chatMemory).build() // 添加记忆顾问).build();}/*** 测试记忆顾问 - PromptChatMemoryAdvisor* 演示如何通过顾问自动管理对话历史*/@Testpublic void testMemoryAdvisor(@Autowired ChatMemory chatMemory) {// 1. 第一次交互String content = chatClient.prompt().user("我叫小小").call().content();System.out.println(content);System.out.println("----------------------------------");// 2. 第二次交互(自动使用记忆)content = chatClient.prompt().user("我叫什么?").call().content();System.out.println(content);}/*** 测试配置类 - 自定义记忆实现*/@TestConfigurationstatic class Config {/*** 配置消息窗口记忆* @param chatMemoryRepository 记忆存储库* @return 配置好的ChatMemory实例*/@BeanChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {return MessageWindowChatMemory.builder().maxMessages(1) // 只保留最近1条消息.chatMemoryRepository(chatMemoryRepository).build();}}/*** 测试对话ID选项 - 多会话记忆隔离* 演示如何通过不同对话ID隔离记忆*/@Testpublic void testChatOptions() {// 会话1 - 第一次交互String content = chatClient.prompt().user("我叫小小").advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1")).call().content();System.out.println(content);System.out.println("----------------------------------");// 会话1 - 第二次交互(有记忆)content = chatClient.prompt().user("我叫什么?").advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1")).call().content();System.out.println(content);System.out.println("----------------------------------");// 会话2 - 新会话(无记忆)content = chatClient.prompt().user("我叫什么?").advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "2")).call().content();System.out.println(content);}
}

Redis实现记忆功能

Redis基于内存的高性能记忆存储方案

 核心依赖配置

 需要添加spring-ai-alibaba-starter-memory-redis依赖和Jedis客户端依赖

 配置Redis连接参数:主机、端口、超时时间和密码等 

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.alibaba.cloud.ai.memory.redis.RedisChatMemoryRepository;
import com.xushu.springai.cc.ReReadingAdvisor;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@SpringBootTest
public class TestRedisMemory {// 共享的ChatClient实例ChatClient chatClient;/*** 初始化方法 - 配置带Redis记忆的ChatClient* @param chatModel 自动注入的DashScope聊天模型* @param chatMemory 自动注入的ChatMemory实例*/@BeforeEachpublic void init(@Autowired DashScopeChatModel chatModel,@Autowired ChatMemory chatMemory) {// 创建带记忆顾问的ChatClientthis.chatClient = ChatClient.builder(chatModel).defaultAdvisors(PromptChatMemoryAdvisor.builder(chatMemory).build() // 使用Redis记忆).build();}/*** 测试Redis记忆功能 - 多轮对话* 演示如何通过Redis持久化对话记忆*/@Testpublic void testChatOptions() {// 第一轮对话 - 设置用户信息String content = chatClient.prompt().user("你好,我叫小小!") // 用户输入.advisors(new ReReadingAdvisor()) // 添加重读顾问.advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1")) // 设置对话ID.call().content();System.out.println(content);System.out.println("----------------------------------");// 注释说明后续处理流程// MQ 异步处理 ----> 存储向量数据库 ---> 相似性检索// 第二轮对话 - 查询用户信息content = chatClient.prompt().user("我叫什么?") // 基于记忆的查询.advisors(new ReReadingAdvisor()) // 再次添加重读顾问.advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1")) // 相同对话ID.call().content();System.out.println(content);}/*** Redis记忆配置类*/@TestConfigurationstatic class Config {// Redis连接配置@Value("${spring.ai.memory.redis.host}")private String redisHost;@Value("${spring.ai.memory.redis.port}")private int redisPort;@Value("${spring.ai.memory.redis.password}")private String redisPassword;@Value("${spring.ai.memory.redis.timeout}")private int redisTimeout;/*** 配置Redis记忆存储库* @return RedisChatMemoryRepository实例*/@Beanpublic RedisChatMemoryRepository redisChatMemoryRepository() {return RedisChatMemoryRepository.builder().host(redisHost) // Redis主机.port(redisPort) // Redis端口// 若没有设置密码则注释该项// .password(redisPassword) // Redis密码.timeout(redisTimeout) // 连接超时.build();}/*** 配置基于Redis的聊天记忆* @param chatMemoryRepository Redis记忆存储库* @return 配置好的ChatMemory实例*/@BeanChatMemory chatMemory(RedisChatMemoryRepository chatMemoryRepository) {return MessageWindowChatMemory.builder().maxMessages(10) // 保留最近10条消息.chatMemoryRepository(chatMemoryRepository) // 使用Redis存储.build();}}
}

Mysql实现记忆功能

MySQL作为关系型数据库,是稳定可靠的持久化存储方案,适合需要长期保存对话历史的场景

核心依赖配置

添加spring-ai-starter-model-chat-memory-repository-jdbc

依赖配置MySQL数据源连接信息

package com.xushu.springai.cc.memory;import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.xushu.springai.cc.ReReadingAdvisor;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;@SpringBootTest
public class TestJDBCMemory {// 共享的ChatClient实例ChatClient chatClient;/*** 初始化方法 - 配置带JDBC记忆的ChatClient* @param chatModel 自动注入的DashScope聊天模型* @param chatMemory 自动注入的ChatMemory实例*/@BeforeEachpublic void init(@Autowired DashScopeChatModel chatModel,@Autowired ChatMemory chatMemory) {// 创建带记忆顾问的ChatClientthis.chatClient = ChatClient.builder(chatModel).defaultAdvisors(PromptChatMemoryAdvisor.builder(chatMemory).build() // 使用JDBC记忆).build();}/*** 测试JDBC记忆功能 - 多轮对话* 演示如何通过JDBC持久化对话记忆*/@Testpublic void testChatOptions() {// 第一轮对话 - 设置用户信息String content = chatClient.prompt().user("你好,我叫小小!") // 用户输入.advisors(new ReReadingAdvisor()) // 添加重读顾问.advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1")) // 设置对话ID.call().content();System.out.println(content);System.out.println("----------------------------------");// 第二轮对话 - 查询用户信息content = chatClient.prompt().user("我叫什么?") // 基于记忆的查询.advisors(new ReReadingAdvisor()) // 再次添加重读顾问.advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1")) // 相同对话ID.call().content();System.out.println(content);}/*** JDBC记忆配置类*/@TestConfigurationstatic class Config {/*** 配置基于JDBC的聊天记忆* @param chatMemoryRepository JDBC记忆存储库* @return 配置好的ChatMemory实例*/@BeanChatMemory chatMemory(JdbcChatMemoryRepository chatMemoryRepository) {return MessageWindowChatMemory.builder().maxMessages(1) // 保留最近1条消息.chatMemoryRepository(chatMemoryRepository) // 使用JDBC存储.build();}}
}
自定义重读用户输入 Advisor
重读(Re2)技术可以提升大模型的推理能力,以下是实现要点:核心思想:在用户输入后附加"Read the question again: {原问题}"的提示通过重复输入引导模型更深入思考import org.springframework.ai.chat.client.ChatClientRequest;
import org.springframework.ai.chat.client.ChatClientResponse;
import org.springframework.ai.chat.client.advisor.api.*;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import java.util.Map;/*** 重读顾问实现 - 在用户提问前自动添加重读提示* 实现BaseAdvisor接口,提供请求前/后的处理能力*/
public class ReReadingAdvisor implements BaseAdvisor {// 默认的重读提示模板// 使用{re2_input_query}作为占位符,将被实际用户问题替换private static final String DEFAULT_USER_TEXT_ADVISE = """{re2_input_query}Read the question again: {re2_input_query}""";/*** 请求前处理方法 - 修改用户提问* @param chatClientRequest 原始聊天请求* @param advisorChain 顾问链* @return 修改后的聊天请求*/@Overridepublic ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain advisorChain) {// 获取原始用户提示内容String contents = chatClientRequest.prompt().getContents();// 使用PromptTemplate渲染模板,将用户问题插入到重读提示中String re2InputQuery = PromptTemplate.builder().template(DEFAULT_USER_TEXT_ADVISE).build().render(Map.of("re2_input_query", contents));// 构建新的请求,替换原始提示内容ChatClientRequest clientRequest = chatClientRequest.mutate().prompt(Prompt.builder().content(re2InputQuery).build()).build();return clientRequest;}/*** 请求后处理方法 - 本实现不做处理直接返回响应* @param chatClientResponse 聊天响应* @param advisorChain 顾问链* @return 原始响应*/@Overridepublic ChatClientResponse after(ChatClientResponse chatClientResponse, AdvisorChain advisorChain) {return chatClientResponse;}/*** 获取顾问执行顺序* @return 执行顺序(数值越小优先级越高)*/@Overridepublic int getOrder() {return 0; // 最高优先级}
}

Advisor 测试代码

SimpleLoggerAdvisor 日志顾问

SafeGuardAdvisor 安全防护顾问

ReReadingAdvisor 重读顾问

import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;import java.util.List;@SpringBootTest
public class TestAdvisor {/*** 测试日志顾问 - SimpleLoggerAdvisor* 演示如何添加简单的请求/响应日志记录** 日志级别设置:* 在application.properties中添加:* logging.level.org.springframework.ai.chat.client.advisor=DEBUG** @param chatClientBuilder 自动注入的ChatClient构建器*/@Testpublic void testLoggerAdvisor(@Autowired ChatClient.Builder chatClientBuilder) {// 1. 创建ChatClient并添加日志顾问ChatClient chatClient = chatClientBuilder.defaultAdvisors(new SimpleLoggerAdvisor()) // 添加日志顾问.build();// 2. 构建并执行聊天请求String content = chatClient.prompt().user("你好") // 用户消息.call()     // 同步调用.content(); // 获取响应System.out.println(content);}/*** 测试安全防护顾问 - SafeGuardAdvisor* 演示如何拦截包含敏感词的请求** @param chatClientBuilder 自动注入的ChatClient构建器* @param chatMemory 自动注入的聊天记忆组件*/@Testpublic void testAdvisor(@Autowired ChatClient.Builder chatClientBuilder,@Autowired ChatMemory chatMemory) {// 1. 创建ChatClient并添加多个顾问ChatClient chatClient = chatClientBuilder.defaultAdvisors(new SimpleLoggerAdvisor(),    // 日志顾问new SafeGuardAdvisor(List.of("小小")) // 安全顾问,设置敏感词"小小").build();// 2. 构建并执行包含敏感词的请求String content = chatClient.prompt().user("小小是谁") // 包含敏感词的查询.call().content();System.out.println(content);}/*** 测试重读顾问 - ReReadingAdvisor* 演示自定义顾问如何修改用户提问** @param chatClientBuilder 自动注入的ChatClient构建器*/@Testpublic void testReReadingAdvisor(@Autowired ChatClient.Builder chatClientBuilder) {// 1. 创建ChatClient并添加自定义重读顾问ChatClient chatClient = chatClientBuilder.defaultAdvisors(new SimpleLoggerAdvisor(), // 日志顾问new ReReadingAdvisor()     // 自定义重读顾问).build();// 2. 构建并执行请求String content = chatClient.prompt().user("小小是谁") // 原始问题.call().content();System.out.println(content);// 预期效果:AI会收到"小小是谁\nRead the question again: 小小是谁"}
}

上一篇:【Spring AI快速上手 (一)】ChatModel与ChatCilent构建对话-CSDN博客

下一篇:【Spring AI快速上手 (三)】Tool实现业务系统对接-CSDN博客

 实战示例:【Spring AI实战】实现仿DeepSeek页面对话机器人_spring ai flux<string>返回-CSDN博客【Spring AI实战】实现仿DeepSeek页面对话机器人(支持多模态上传)_多模态大模型怎么传图片springai-CSDN博客

有任何问题或建议欢迎评论区留言讨论!

http://www.lryc.cn/news/610188.html

相关文章:

  • 【计算机网络 | 第2篇】计算机网络概述(下)
  • 如何使用 DBeaver 连接 MySQL 数据库
  • 移动端 WebView 视频无法播放怎么办 媒体控件错误排查与修复指南
  • SAP-ABAP:ABAP Open SQL 深度解析:核心特性、性能优化与实践指南
  • 深入剖析Java Stream API性能优化实践指南
  • Mybatis 简单练习,自定义sql关联查询
  • 卸油管链接检测误检率↓76%:陌讯多模态融合算法实战解析
  • Dbeaver数据库的安装和使用(保姆级别)
  • 基于FAISS和Ollama的法律智能对话系统开发实录-【大模型应用班-第5课 RAG技术与应用学习笔记】
  • Ubuntu系统VScode实现opencv(c++)图像一维直方图
  • 机器学习【六】readom forest
  • 微服务配置管理:Spring Cloud Alibaba Nacos 实践
  • 电子电气架构 ---智能电动汽车嵌入式软件开发过程中的block点
  • Nginx服务做负载均衡网关
  • 36.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--缓存Token
  • FPGA学习笔记——简单的乒乓缓存(RAM)
  • 飞算JavaAI需求转SpringBoot项目沉浸式体验
  • android内存作假通杀补丁(4GB作假8GB)
  • labview连接PLC的三种方式
  • 设计模式(一)——抽象工厂模式
  • ES集群规划与调优
  • 进程间通信:管道与共享内存
  • 移动前后端全栈项目
  • 读写分离有那些坑?
  • 16.8 华为昇腾CANN架构深度实战:3大核心引擎解析与性能优化216%秘籍
  • 手搓TCP服务器实现基础IO
  • falsk windows 服务器部署-解决服务器外无法访问
  • javacc学习笔记 02、JavaCC 语法描述文件的格式解析
  • Sklearn 机器学习 数据聚类 肘部法则选择聚类数目
  • 昇思学习营-模型推理和性能优化学习心得