一文搞懂向量数据库:告别MySQL关键词检索,看懂RAG必备核心底座|Langchain4j+Milvus实战落地
哈喽各位后端小伙伴👋,Langchain4j系列第三篇干货如约而至!
前面我们搞定了大模型流式返回、ChatMemory多轮对话记忆+会话隔离,现在AI项目还剩下两个绕不开的痛点:
-
大模型幻觉严重:回答胡编乱造,不知道公司内部业务文档、私有知识库内容
-
上下文窗口有限:无法把几十万字内部文档全部塞进Prompt,Token直接爆表
解决这两个问题的核心方案就是RAG检索增强生成,而RAG架构最核心的底层组件,就是今天要讲的:向量数据库。
本文全程避开复杂高数公式,用后端能听懂的大白话讲解,同时附上SpringBoot+Langchain4j+Milvus完整实战代码、全局配置类、RAG完整链路,看完直接可以接入自己的AI项目。
一、有MySQL了,为什么还要向量数据库?
1. 传统MySQL关键词检索的致命短板
我们平时用MySQL做like %关键词%模糊查询,只认字面,不认语义。
举个业务真实例子:
-
库存文档内容:账号冻结如何解除限制
-
用户提问:我的账号被封禁了怎么办
👉 MySQL查询结果:查不到任何数据
原因:冻结和封禁字面完全不一样,MySQL无法识别两者语义相同。
2. 向量数据库的核心能力:语义检索
向量数据库不比对文字是否一样,比对文字的含义是否一样。
上面的例子,向量数据库可以精准匹配两条内容,因为语义完全一致。
一句话总结区别: MySQL:找长得一样的文字(精确/模糊匹配) 向量数据库:找意思一样的文字(语义相似度匹配)
二、向量、嵌入向量、向量相似度
1. 什么是向量(Embedding)
大模型里的向量,本质就是一串数字数组。
嵌入模型(Embedding模型)可以把任意文本,转换成固定长度的多维数字向量:
-
账号冻结如何解除限制 → [0.12,0.35,0.88,......]
-
我的账号被封禁了怎么办 → [0.13,0.34,0.87,......]
意思越相近的文本,生成出来的数字向量越接近。
2. 什么是向量相似度计算
向量数据库内置算法(余弦相似度、欧氏距离),自动计算两个向量之间的距离:
-
向量距离越小 → 文本语义越相似
-
向量距离越大 → 文本语义差距越大
3. 完整RAG工作流程(必背)
理解了向量,就能看懂整个私有知识库RAG流程:
-
文档切片:把内部PDF、Word、网页长文档,切分成小块文本
-
向量化:调用Embedding模型,把每一块文本转为向量
-
入库存储:向量+原文存入向量数据库
-
用户提问:用户输入问题,同样转为向量
-
相似检索:向量数据库快速召回相似度最高的知识库原文
-
增强Prompt:把检索到的真实文档+用户问题一起发给大模型
-
精准回答:大模型基于私有文档回答,彻底杜绝幻觉
三、主流向量数据库选型对比
|
向量库 |
特点 |
适用场景 |
|---|---|---|
|
Milvus |
开源、高性能、支持海量数据、企业级首选 |
线上生产环境、千万级文档知识库(本文实战选用) |
|
Chroma |
轻量、开箱即用、部署简单 |
本地测试、个人项目、小体量知识库 |
|
FAISS |
Meta开源,检索速度极快,无持久化 |
临时检索、内存向量计算,不适合线上持久化 |
|
RedisVector |
依托Redis,无需额外部署服务 |
中小体量项目,不想额外部署中间件 |
生产环境无脑选 Milvus,目前Langchain4j生态适配最好、社区最活跃、并发和检索性能拉满。
四、项目环境准备
1. 依赖引入(整合Langchain4j+Milvus)
<!-- Langchain4j 核心依赖 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.14.0</version>
</dependency>
<!-- 百炼/通义大模型 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-dashscope-spring-boot-starter</artifactId>
<version>1.14.0</version>
</dependency>
<!-- Milvus向量数据库适配 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-milvus</artifactId>
<version>1.14.0</version>
</dependency>
2. yml配置文件
spring:
application:
name: langchain4j-vector-demo
# 阿里百炼大模型配置
langchain4j:
dashscope:
chat-model:
api-key: 你的百炼key
model-name: qwen-turbo
# 嵌入模型:专门用来生成文本向量
embedding-model:
api-key: 你的百炼key
model-name: text-embedding-v3
# Milvus向量数据库连接配置
milvus:
host: 127.0.0.1
port: 19530
database-name: default
# 知识库集合名称(类似MySQL的表)
collection-name: ai_knowledge_base
五、全局Milvus向量数据库配置类
统一封装向量库客户端、向量存储仓库、相似度检索参数,业务层无需关心底层连接细节。
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.milvus.MilvusEmbeddingStore;
import io.milvus.client.MilvusServiceClient;
import io.milvus.param.ConnectParam;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Milvus向量数据库全局配置类
* 对接Langchain4j,统一管理向量存储、向量检索
*/
@Configuration
@ConfigurationProperties(prefix = "milvus")
@Data
public class MilvusVectorConfig {
private String host;
private Integer port;
private String databaseName;
private String collectionName;
/**
* 构建Milvus客户端连接
*/
@Bean
public MilvusServiceClient milvusServiceClient() {
return new MilvusServiceClient(
ConnectParam.newBuilder()
.withHost(host)
.withPort(port)
.withDatabaseName(databaseName)
.build()
);
}
/**
* 构建Langchain4j专属向量存储器
* 自动完成:向量新增、向量相似度检索、文档删除
*/
@Bean
public MilvusEmbeddingStore milvusEmbeddingStore(MilvusServiceClient client, EmbeddingModel embeddingModel) {
return MilvusEmbeddingStore.builder()
.milvusClient(client)
.collectionName(collectionName)
// 检索返回top3相似度最高的文档片段
.defaultSearchParams("{\"nprobe\": 128}")
.dimension(1024) // text-embedding-v3向量维度固定1024
.autoFlushOnInsert(true) // 新增数据自动刷新,立刻可检索
.build();
}
}
六、核心业务代码:文档入库 + 语义检索 + RAG问答
1. 封装通用向量知识库Service
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.DocumentSplitter;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
import dev.langchain4j.store.embedding.EmbeddingSearchResult;
import dev.langchain4j.store.embedding.milvus.MilvusEmbeddingStore;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 向量知识库服务:文档向量化入库、语义检索、RAG问答
*/
@Service
@RequiredArgsConstructor
public class VectorKnowledgeService {
// 向量存储器
private final MilvusEmbeddingStore milvusEmbeddingStore;
// 嵌入模型:文本转向量
private final EmbeddingModel embeddingModel;
/**
* 1. 上传文档并向量化入库
* @param content 原始文档全文
*/
public void importDocument(String content) {
// 1. 构建文档
Document document = Document.from(content);
// 2. 文档切片:长文本切割,避免单次向量过长,重叠部分保证上下文连贯
DocumentSplitter splitter = DocumentSplitters.recursive(500, 100);
List<TextSegment> segments = splitter.split(document);
// 3. 批量向量化并存入Milvus向量数据库
milvusEmbeddingStore.addAll(segments, embeddingModel);
}
/**
* 2. 根据用户问题,语义检索相关知识库内容
* @param question 用户提问
* @return 匹配到的私有文档内容
*/
public String searchSimilarKnowledge(String question) {
// 构建检索请求:查询top3最相似内容,相似度阈值0.7,过滤低相关内容
EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
.query(question)
.maxResults(3)
.minScore(0.7)
.build();
// 执行向量检索
EmbeddingSearchResult<TextSegment> result = milvusEmbeddingStore.search(request, embeddingModel);
// 拼接检索到的上下文
return result.matches().stream()
.map(match -> match.embedded().text())
.reduce("", String::concat);
}
/**
* 3. 清空当前知识库集合
*/
public void clearKnowledge() {
milvusEmbeddingStore.clear();
}
}
2. RAG问答Service(结合大模型回答问题)
import dev.langchain4j.model.chat.ChatLanguageModel;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class RagChatService {
private final ChatLanguageModel chatLanguageModel;
private final VectorKnowledgeService vectorKnowledgeService;
/**
* RAG增强问答:基于私有知识库回答问题
*/
public String ragChat(String question) {
// 第一步:向量数据库检索私有知识库上下文
String context = vectorKnowledgeService.searchSimilarKnowledge(question);
// 第二步:拼接Prompt,约束大模型只能基于知识库回答
String prompt = String.format("""
请严格基于下面给出的【知识库上下文】回答用户问题,禁止编造内容。
如果上下文没有相关信息,请直接回答:暂无相关信息,不要胡说八道。
【知识库上下文】:%s
【用户问题】:%s
""", context, question);
// 第三步:调用大模型生成答案
return chatLanguageModel.chat(prompt);
}
}
3. 对外Controller接口
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/ai/vector")
@RequiredArgsConstructor
public class VectorController {
private final VectorKnowledgeService vectorKnowledgeService;
private final RagChatService ragChatService;
// 文档入库接口
@GetMapping("/import")
public String importDoc(@RequestParam String content) {
vectorKnowledgeService.importDocument(content);
return "文档向量化入库成功";
}
// RAG知识库问答接口
@GetMapping("/rag/chat")
public String ragChat(@RequestParam String question) {
return ragChatService.ragChat(question);
}
// 清空知识库
@GetMapping("/clear")
public String clear() {
vectorKnowledgeService.clearKnowledge();
return "向量知识库清空成功";
}
}
七、接口测试流程(直观感受向量检索效果)
第一步:导入私有知识库文档
调用接口导入内容:账号被封禁/冻结,可前往个人中心-安全设置提交申诉,1-3个工作日完成审核解封
第二步:语义提问(字面完全不匹配)
提问:账号被封了怎么解决?
返回结果
账号被封禁/冻结,可前往个人中心-安全设置提交申诉,1-3个工作日完成审核解封。
✅ 向量数据库成功识别语义,字面不一样但意思一致,精准召回文档,MySQL完全做不到。
八、向量数据库常见开发踩坑总结
-
向量维度必须和Embedding模型一致:百炼text-embedding-v3固定1024维,写错直接检索报错
-
合理设置相似度阈值:建议0.65-0.75,过低会召回无关垃圾文档,过高召回内容太少
-
文档必须切片:不要直接把上万字文档直接入库,切片可以提升检索精准度,降低向量生成成本
-
topN不要设置过大:一般取top3-top5即可,过多上下文会浪费Token、降低回答速度
-
向量库和ChatMemory结合使用:RAG知识库检索 + 对话记忆,实现带历史上下文的私有知识库问答
-
禁止大模型裸答:生产环境必须拼接检索上下文,从根源杜绝幻觉
九、MySQL、ES、向量数据库三者横向对比
|
数据库 |
检索能力 |
能否语义检索 |
AI知识库适配度 |
|---|---|---|---|
|
MySQL |
精确匹配、关键词模糊匹配 |
❌ 不支持 |
极差,不适合AI语义搜索 |
|
ElasticSearch |
分词关键词检索 |
半支持,依赖分词,无法深度语义理解 |
一般,适合传统全文搜索,不适合大模型RAG |
|
Milvus向量库 |
向量相似度检索 |
✅ 原生深度语义理解 |
满分,RAG架构官方标配 |
十、博主总结
-
向量数据库不是用来替代MySQL,二者各司其职:MySQL存业务结构化数据,向量库存文本向量做语义检索
-
RAG核心逻辑:向量检索兜底真实数据,大模型负责语言组织,完美解决大模型幻觉
-
结合本系列前两篇:流式输出 + ChatMemory会话记忆 + 向量知识库RAG,即可搭建一套完整企业级AI对话系统
-
本文全套代码基于Langchain4j原生API开发,无第三方封装,可直接上线生产
更多推荐



所有评论(0)