一、向量存储是什么将一段文字通过 Embedding 模型转换成一串数字向量存入向量数据库。搜索时把用户的问题也转成向量和库里所有向量做相似度计算返回最相关的结果。文字 → Embedding模型 → [0.12, 0.87, 0.34, ...] → 存入 Chroma向量代表的是语义而不是字符串匹配。手机和iPhone在向量空间里距离很近即使没有相同的字也能匹配到。二、Document 是独立的每个 Document 在向量化时只看自身内容不知道其他 Document 的存在片段和片段之间没有关联。Document1iPhone17很厉害 → 向量A Document2它搭载了A19处理器 → 向量B Document3它卖10000块 → 向量C三个向量完全独立搜索时各自和用户问题做相似度计算互不影响。后果Document2 和 Document3 里的它失去了指代语义不完整搜索精度下降。正确做法把同一个主题的信息合并成一个 Document 存。// ❌ 错误信息割裂vectorStore.add(List.of(newDocument(id1,iPhone17很厉害,Map.of()),newDocument(id2,它搭载了A19处理器,Map.of()),newDocument(id3,它卖10000块,Map.of())));// ✅ 正确信息完整StringcontentiPhone17很厉害它搭载了A19处理器售价10000块;vectorStore.add(List.of(newDocument(id1,content,Map.of())));三、搜索原理用户提问 → 转成向量 → 和库里每个 Document 的向量计算相似度 → 返回 TopK 个最相关的片段 → 交给大模型综合回答。用户问A19处理器的手机多少钱 ↓ embedding [0.23, 0.91, ...] ↓ 相似度计算 Document1iPhone17搭载A19处理器性能强劲售价10000元 相似度 0.92 ✅ Document2索尼耳机9成新售价500元 相似度 0.11 ❌ ↓ 返回 Document1 给大模型 ↓ 大模型回答iPhone17搭载A19处理器售价10000元四、分片的场景和意义为什么要分片Embedding 模型有 token 上限一般 512~8192 token超出直接报错。即使没超限内容太长会导致向量语义被稀释搜索精度下降。什么时候需要分片内容类型是否需要分片商品标题描述❌ 不需要直接拼一条存长篇商品说明书✅ 需要政策/协议文档✅ 需要聊天记录✅ 按对话轮次分片Spring AI 分片实现BeanpublicTokenTextSplittertextSplitter(){returnnewTokenTextSplitter(800,// 每片最大 token 数400,// 相邻片段重叠 token 数10,// 最小片段长度5000,// 最大片段长度true);}// 使用DocumentdocnewDocument(fullText,Map.of(articleId,articleId));ListDocumentchunkstextSplitter.split(doc);vectorStore.add(chunks);五、重叠的真正意义相邻片段重叠一部分内容目的是让每个片段自身的语义更完整避免关键信息被切断在两片之间。原文iPhone17搭载A19处理器性能非常强劲。售价10000元支持分期付款。 不重叠 片段1iPhone17搭载A19处理器性能非常强劲。 片段2售价10000元支持分期付款。 → 片段2 向量只含价格语义搜A19多少钱时匹配度低 有重叠 片段1iPhone17搭载A19处理器性能非常强劲。 片段2性能非常强劲。售价10000元支持分期付款。 → 片段2 向量混入了性能相关语义和A19多少钱匹配度略高重叠不是银弹提升有限。根本解法是 topK 多取几个片段让大模型综合理解。六、实践建议存入时同一主题的信息拼完整再存不要割裂。StringcontentString.format(商品%s。描述%s。价格%s元。成色%s。,goods.getTitle(),goods.getDescription(),goods.getPrice(),goods.getCondition());vectorStore.add(List.of(newDocument(goods.getId(),content,metadata)));搜索时topK 取 3~5 个把多个片段都交给大模型由大模型综合回答而不是只取第一个。ListDocumentresultsvectorStore.similaritySearch(SearchRequest.builder().query(userQuestion).topK(5).similarityThreshold(0.6).build());// 把 results 里的内容拼成 context 塞给大模型分片配置内容不长的场景无需关心用默认配置即可。只有处理长文档时才需要调整分片大小和重叠比例。