RAG 向量存储原理总结

一、向量存储是什么

将一段文字通过 Embedding 模型转换成一串数字(向量),存入向量数据库。搜索时把用户的问题也转成向量,和库里所有向量做相似度计算,返回最相关的结果。

复制代码
文字 → Embedding模型 → [0.12, 0.87, 0.34, ...] → 存入 Chroma

向量代表的是语义,而不是字符串匹配。"手机"和"iPhone"在向量空间里距离很近,即使没有相同的字也能匹配到。


二、Document 是独立的

每个 Document 在向量化时只看自身内容,不知道其他 Document 的存在,片段和片段之间没有关联。

复制代码
Document1:"iPhone17很厉害"            → 向量A
Document2:"它搭载了A19处理器"          → 向量B
Document3:"它卖10000块"               → 向量C

三个向量完全独立,搜索时各自和用户问题做相似度计算,互不影响。

后果: Document2 和 Document3 里的"它"失去了指代,语义不完整,搜索精度下降。

正确做法: 把同一个主题的信息合并成一个 Document 存。

java 复制代码
// ❌ 错误:信息割裂
vectorStore.add(List.of(
    new Document("id1", "iPhone17很厉害", Map.of()),
    new Document("id2", "它搭载了A19处理器", Map.of()),
    new Document("id3", "它卖10000块", Map.of())
));

// ✅ 正确:信息完整
String content = "iPhone17很厉害,它搭载了A19处理器,售价10000块";
vectorStore.add(List.of(new Document("id1", content, Map.of())));

三、搜索原理

用户提问 → 转成向量 → 和库里每个 Document 的向量计算相似度 → 返回 TopK 个最相关的片段 → 交给大模型综合回答。

复制代码
用户问:"A19处理器的手机多少钱"
        ↓ embedding
    [0.23, 0.91, ...]
        ↓ 相似度计算
Document1:"iPhone17搭载A19处理器,性能强劲,售价10000元"   相似度 0.92 ✅
Document2:"索尼耳机,9成新,售价500元"                    相似度 0.11 ❌
        ↓
返回 Document1 给大模型
        ↓
大模型回答:"iPhone17搭载A19处理器,售价10000元"

四、分片的场景和意义

为什么要分片

Embedding 模型有 token 上限(一般 512~8192 token),超出直接报错。即使没超限,内容太长会导致向量语义被稀释,搜索精度下降。

什么时候需要分片

内容类型 是否需要分片
商品标题+描述 ❌ 不需要,直接拼一条存
长篇商品说明书 ✅ 需要
政策/协议文档 ✅ 需要
聊天记录 ✅ 按对话轮次分片

Spring AI 分片实现

java 复制代码
@Bean
public TokenTextSplitter textSplitter() {
    return new TokenTextSplitter(
        800,   // 每片最大 token 数
        400,   // 相邻片段重叠 token 数
        10,    // 最小片段长度
        5000,  // 最大片段长度
        true
    );
}

// 使用
Document doc = new Document(fullText, Map.of("articleId", articleId));
List<Document> chunks = textSplitter.split(doc);
vectorStore.add(chunks);

五、重叠的真正意义

相邻片段重叠一部分内容,目的是让每个片段自身的语义更完整,避免关键信息被切断在两片之间。

复制代码
原文:iPhone17搭载A19处理器,性能非常强劲。售价10000元,支持分期付款。

不重叠:
片段1:"iPhone17搭载A19处理器,性能非常强劲。"
片段2:"售价10000元,支持分期付款。"
→ 片段2 向量只含价格语义,搜"A19多少钱"时匹配度低

有重叠:
片段1:"iPhone17搭载A19处理器,性能非常强劲。"
片段2:"性能非常强劲。售价10000元,支持分期付款。"
→ 片段2 向量混入了性能相关语义,和"A19多少钱"匹配度略高

重叠不是银弹,提升有限。根本解法是 topK 多取几个片段,让大模型综合理解。


六、实践建议

存入时: 同一主题的信息拼完整再存,不要割裂。

java 复制代码
String content = String.format(
    "商品:%s。描述:%s。价格:%s元。成色:%s。",
    goods.getTitle(), goods.getDescription(),
    goods.getPrice(), goods.getCondition()
);
vectorStore.add(List.of(new Document(goods.getId(), content, metadata)));

搜索时: topK 取 3~5 个,把多个片段都交给大模型,由大模型综合回答,而不是只取第一个。

java 复制代码
List<Document> results = vectorStore.similaritySearch(
    SearchRequest.builder()
        .query(userQuestion)
        .topK(5)
        .similarityThreshold(0.6)
        .build()
);
// 把 results 里的内容拼成 context 塞给大模型

分片配置: 内容不长的场景无需关心,用默认配置即可。只有处理长文档时才需要调整分片大小和重叠比例。

相关推荐
周航宇JoeZhou9 小时前
JB3-9-SpringAI(二)
java·ai·agent·多智能体·调度·智能体·观察
Tbisnic9 小时前
AI大模型学习第十一天:技术选型、安全防护与金融实战
python·学习·ai·大模型·提示词工程
AI工具挖掘机9 小时前
Codex 桌面版上手:从安装到自己开发首个小游戏,0 基础快速入门,手把手教学
经验分享·ai·ai编程
凉菜凉凉10 小时前
AI时代,被抛弃的前端
前端·ai
不吃青椒!12 小时前
LangGraph 流式事件处理:从实战到体系
ai·langchain·状态模式
DS随心转插件13 小时前
AI 导出鸭实测:Markdown TO Word 本地化转换能力深度评测,多角度拆解本地化转换真实表现
人工智能·ai·word·wps·deepseek·ai导出鸭
财经资讯数据_灵砚智能13 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年6月10日
大数据·人工智能·python·ai·信息可视化·自然语言处理·灵砚智能
OpenAnolis小助手14 小时前
如何利用 AI Agent 实现热补丁的自动化生成
人工智能·安全·ai·操作系统·agent·龙蜥
DS随心转插件14 小时前
AI 导出鸭实操教程:Markdown 转 Word 高效协作与隐私交付实战指南
人工智能·ai·word·豆包·deepseek·ai导出鸭
xiami_world15 小时前
私有化部署协同白板选型指南:从Docker容器化到信创全栈适配的架构实践
运维·人工智能·docker·ai·持续部署