rag-kb-system / src /lib /vector-store.ts
duqing2026's picture
对接语雀 token,同步所有文档,并同样布局展示页面和交互功能,并未实现对话知识库功能
2c10495
import { LocalEmbeddings } from "./local-embeddings";
import { HNSWLib } from "@langchain/community/vectorstores/hnswlib";
import path from "path";
import fs from "fs";
import { Embeddings } from "@langchain/core/embeddings";
export const getEmbeddings = () => {
console.log("[VectorStore] Initializing Local Embeddings (Xenova/all-MiniLM-L6-v2)...");
return new LocalEmbeddings();
};
const VECTOR_STORE_PATH = path.join(process.cwd(), "vector_store");
export const indexExists = () => {
return fs.existsSync(path.join(VECTOR_STORE_PATH, "hnswlib.index"));
};
export const getVectorStore = async (embeddings?: Embeddings) => {
const finalEmbeddings = embeddings || getEmbeddings();
if (fs.existsSync(path.join(VECTOR_STORE_PATH, "hnswlib.index"))) {
return HNSWLib.load(VECTOR_STORE_PATH, finalEmbeddings);
}
// Return a new empty store if it doesn't exist
// Requires initial document to initialize, so we might need to handle this
// But usually, we only call getVectorStore for retrieval, so it SHOULD exist.
// For ingestion, we use `HNSWLib.fromDocuments`.
throw new Error("Vector store not initialized. Upload some documents first.");
};
export const getVectorStoreForIngest = async () => {
const embeddings = getEmbeddings();
if (fs.existsSync(path.join(VECTOR_STORE_PATH, "hnswlib.index"))) {
return HNSWLib.load(VECTOR_STORE_PATH, embeddings);
}
return null; // Return null to signal creating a new one
};
export const saveVectorStore = async (store: HNSWLib) => {
await store.save(VECTOR_STORE_PATH);
};