核心说明
向量数据库是 LangChain 构建知识库问答的核心组件,用于存储文档文本的向量嵌入(Embedding),并支持相似性检索(根据查询语句的向量匹配最相关的文本块)。分为「内存向量数据库」(MemoryVectorStore,临时存储)和「持久化向量数据库」(Chroma,永久存储),前者适合测试/临时场景,后者适合生产环境。
一、核心概念
1. 向量嵌入(Embedding)
将文本转换为数值向量(如1536维数组),使计算机能通过「向量距离」衡量文本语义相似度,本文使用阿里通义千问的 text-embedding-v2 模型生成嵌入。
2. 相似性检索
输入查询语句→生成查询向量→计算与库中所有文本向量的距离(如余弦相似度)→返回最相似的N个文本块,是知识库问答的核心逻辑。
二、内存向量数据库(MemoryVectorStore)
核心特点
- 数据存储在内存中,程序重启后丢失;
- 无需额外部署服务,开箱即用;
- 适合快速测试、临时知识库场景。
完整实现代码
typescript
import { TextLoader } from "@langchain/classic/document_loaders/fs/text";
import { RecursiveCharacterTextSplitter } from "@langchain/classic/text_splitter";
import { MemoryVectorStore } from "@langchain/classic/vectorstores/memory";
import { OpenAIEmbeddings } from "@langchain/openai";
// 1. 初始化嵌入模型(阿里通义千问)
const embeddingsModel = new OpenAIEmbeddings({
model: "text-embedding-v2", // 通义千问嵌入模型
configuration: {
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1", // 阿里百炼兼容接口
apiKey: "[你的阿里百炼API Key]", // 替换为有效Key
},
});
// 2. 初始化内存向量数据库
const vectorStore = new MemoryVectorStore(embeddingsModel);
// 3. 加载并分割文档(复用文本加载逻辑)
const loader = new TextLoader("./data/data.txt");
const documents = await loader.load();
// 文本分割器(适配中文语义)
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 25, // 每个文本块最大字符数
chunkOverlap: 5, // 块间重叠字符数(保证上下文连贯)
separators: [",", "。"], // 中文优先分割符
});
const splitDocs = await splitter.splitDocuments(documents);
// 4. 将分割后的文本块存入向量库(自动生成嵌入向量)
await vectorStore.addDocuments(splitDocs);
// 5. 相似性检索(查询+返回Top2最相关文本)
const results = await vectorStore.similaritySearch("李娟的出生于哪里?", 2);
// 输出检索结果
console.log("内存向量库检索结果:");
results.forEach((doc, index) => {
console.log(`第${index+1}条:`, doc.pageContent);
});
/** 输出示例:
内存向量库检索结果:
第1条: 李娟,1979年7月出生于新疆生产建设兵团
第2条: 兵团,籍贯四川乐至,当代女作家
*/
三、持久化向量数据库(Chroma)
核心特点
- 数据持久化存储(磁盘/数据库),程序重启后不丢失;
- 支持独立部署服务,多进程/多实例共享数据;
- 适合生产环境、长期维护的知识库场景。
1. 环境准备
安装Chroma(Python)
bash
# 安装Chroma依赖
pip install chromadb
# 启动Chroma服务(后台运行,端口8000)
chroma run --host 0.0.0.0 --port 8000
安装LangChain-Chroma依赖(Node.js)
bash
pnpm add @langchain/community
2. 完整实现代码
typescript
import { TextLoader } from "@langchain/classic/document_loaders/fs/text";
import { RecursiveCharacterTextSplitter } from "@langchain/classic/text_splitter";
import { Chroma } from "@langchain/community/vectorstores/chroma";
import { OpenAIEmbeddings } from "@langchain/openai";
// 1. 初始化嵌入模型(与内存库一致)
const embeddingsModel = new OpenAIEmbeddings({
model: "text-embedding-v2",
configuration: {
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
apiKey: "[你的阿里百炼API Key]",
},
});
// 2. 初始化Chroma向量数据库(连接远程服务)
const vectorStore = new Chroma(embeddingsModel, {
url: "http://localhost:8000", // Chroma服务地址
collectionName: "langchain_nodejs_demo", // 集合名称(类似数据库表)
});
// 3. 加载并分割文档(与内存库一致)
const loader = new TextLoader("./data/data.txt");
const documents = await loader.load();
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 25,
chunkOverlap: 5,
separators: [",", "。"],
});
const splitDocs = await splitter.splitDocuments(documents);
// 4. 将文本块存入Chroma(自动创建集合+生成嵌入)
await vectorStore.addDocuments(splitDocs);
// 5. 相似性检索
const results = await vectorStore.similaritySearch("李娟的出生于哪里?", 2);
// 输出检索结果
console.log("Chroma向量库检索结果:");
results.forEach((doc, index) => {
console.log(`第${index+1}条:`, doc.pageContent);
});
/** 输出示例:
Chroma向量库检索结果:
第1条: 李娟,1979年7月出生于新疆生产建设兵团
第2条: 兵团,籍贯四川乐至,当代女作家
*/
3. 关键扩展操作
typescript
// 1. 清空集合(删除所有数据)
await vectorStore.delete({ collectionName: "langchain_nodejs_demo" });
// 2. 带分数的相似性检索(返回相似度得分,0-1,越高越相似)
const resultsWithScore = await vectorStore.similaritySearchWithScore("李娟的作品有哪些?", 2);
console.log("带分数的检索结果:");
resultsWithScore.forEach(([doc, score], index) => {
console.log(`第${index+1}条:`, doc.pageContent, `相似度:${score.toFixed(4)}`);
});
// 3. 自定义检索参数(如过滤元数据)
const filteredResults = await vectorStore.similaritySearch(
"李娟的职务",
1,
{ source: "./data/data.txt" } // 仅检索指定来源的文本
);
四、内存/持久化向量库对比
| 维度 | 内存向量库(MemoryVectorStore) | 持久化向量库(Chroma) |
|---|---|---|
| 数据存储 | 内存 | 磁盘/数据库 |
| 持久化 | 程序重启丢失 | 永久保留 |
| 部署成本 | 无(无需额外服务) | 需部署Chroma服务 |
| 性能 | 读写速度快(无网络IO) | 有网络IO,速度略慢 |
| 多实例共享 | 不支持 | 支持(多进程连接同一服务) |
| 适用场景 | 测试、临时知识库 | 生产环境、长期知识库 |
五、核心原理与关键注意事项
1. 核心流程
flowchart TD
A[加载文档] --> B[文本分割为小文本块]
B --> C[嵌入模型生成文本向量]
C --> D[存入向量数据库]
E[用户查询] --> F[生成查询向量]
F --> G[向量库相似性检索]
G --> H[返回最相关文本块]
2. 关键注意事项
- Chroma服务启动 :确保Chroma服务正常运行(
chroma run),否则会报连接错误; - 文本分割参数 :
chunkSize不宜过大(超过嵌入模型上下文)或过小(语义不完整),中文建议20-50字符; - 集合名称管理 :Chroma的
collectionName建议按业务分类(如product_doc、user_manual),避免数据混乱。