基于Spring AI Alibaba 的RAG智能问答系统

项目概述

这是一个基于 Spring AI Alibaba 框架和 Redis 向量存储实现的 RAG 智能问答系统。系统通过用户提出的相关问题在向量数据库中检索相检索相关文档片段并结合大语言模型生成回答,提供更准确的信息查询服务。

技术栈

  • 核心框架: Spring Boot
  • AI 能力: Spring AI Alibaba (集成阿里云 DashScope)
  • 向量存储: Redis Vector Store
  • 检索增强生成: RAG 架构

功能特性

  • 基于用户问题检索最相关的文档片段
  • 结合检索结果和语言模型生成准确回答
  • 当知识库中没有相关信息时,明确告知用户 “我无法回答您的问题”
  • 确保回答不超出知识库范围,避免幻觉
#redis向量数据库需要是redis-stack-server 版本,否则不支持。这里采用docker启动
docker run -d --name my-redis -p 6379:6379 redis/redis-stack-server 

项目结构

src/main/java/com/ai/rag/qa/springaialibabaragqa/
├── assistant/            # AI 辅助类
│   └── AiAssistant.java     # 核心聊天逻辑实现
├── config/                 # 配置类
│   └── RedisConfig.java     # Redis 向量存储配置
├── controller/             # 控制器
│   └── UserChatController.java # REST API 
src/main/resources/
│   ├── application.properties          # 系统配置文件
│   └── rag/                           # RAG知识库文档
│       └── question.txt             # 智能问答对话组
└── src/test/                  #测试类中有加载知识库文档并向量化文档存储到向量数据库中方法

核心代码

创建只能助手组件,提供提示词模板

@Component
public class AiAssistant {

    private final ChatClient dashScopeChatClient;

    private final String DEFAULT_SYSTEM_PROMPT = "你是一个答疑机器人,你的任务是根据下述给定的已知信息回答用户的问题 已知信息: {context}\n" +
//            "    用户问题: {question}\n" +
            "    如果已知信息不包含用户问题的答案,或者已知信息不足以回答用户的问题,请直接回复“我无法回答您的问题”.\n" +
            "    请不要输出已知信息中不包含的信息或者答案。\n" +
            "    请用中文回答用户问题";

    public AiAssistant(ChatModel chatModel) {
        this.dashScopeChatClient = ChatClient.builder(chatModel).defaultSystem(DEFAULT_SYSTEM_PROMPT).build();
    }

    public String chat(String message, List<Document> context){
        SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(DEFAULT_SYSTEM_PROMPT);
        Message systemMessage = systemPromptTemplate.createMessage(Map.of("context", context));
        UserMessage userMessage = new UserMessage( message);

        return this.dashScopeChatClient
                .prompt(new Prompt(List.of(systemMessage, userMessage)))
                .call().content();
    }
}

redis 向量数据库配置


@Configuration
public class RedisConfig {


    @Value("${spring.data.redis.host}")
    private String host;

    @Value("${spring.data.redis.port}")
    private int port;

    @Value("${spring.ai.vector-store.redis.index-name}")
    private String indexName;

    @Value("${spring.ai.vectorstore.redis.prefix}")
    private String prefix;


    @Bean
    public JedisPooled jedisPooled() {
        return new JedisPooled(host, port);
    }

    @Bean
    @Qualifier("redisVectorStore")
    public RedisVectorStore redisVectorStore(JedisPooled jedisPooled, EmbeddingModel embeddingModel) {
        return RedisVectorStore.builder(jedisPooled, embeddingModel)
                .indexName(indexName)
                .prefix(prefix)
                .initializeSchema(true)
                .build();
    }
}

controller层的对话调用

@RestController
public class UserChatController {

    @Resource
    private AiAssistant aiAssistant;

    @Resource
    private RedisVectorStore redisVectorStore;

    @GetMapping("/chatQuery")
    public String chatQuery(@RequestParam String query) {
//        构建请求,获取相似度前三的文档
        SearchRequest.Builder searchRequest = SearchRequest.builder().query(query).topK(3);
        List<Document> documents = redisVectorStore.similaritySearch(searchRequest.build());
        return aiAssistant.chat(query, documents);
    }

}

项目存储前置要求,将知识库文档向量化后存储到向量数据库中

    @Test
    public void importData(){
        Resource resource = new PathMatchingResourcePatternResolver().getResource("classpath:rag/question.txt");
        TextReader textReader = new TextReader(resource);
        List<Document> read = textReader.read();
        List<Document> split = new TokenTextSplitter().builder().withChunkSize(400).withMinChunkSizeChars(0).build().split(read);
        redisVectorStore.doAdd(split);

    }

源代码访问地址:基于Spring AI Alibaba 的RAG智能问答系统

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐