Описание изменений
This commit is contained in:
134
backend/services/vectorStore.js
Normal file
134
backend/services/vectorStore.js
Normal file
@@ -0,0 +1,134 @@
|
||||
const { HNSWLib } = require("@langchain/community/vectorstores/hnswlib");
|
||||
const { OllamaEmbeddings } = require("@langchain/ollama");
|
||||
const { DirectoryLoader } = require("langchain/document_loaders/fs/directory");
|
||||
const { TextLoader } = require("langchain/document_loaders/fs/text");
|
||||
const { RecursiveCharacterTextSplitter } = require("langchain/text_splitter");
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Путь к директории с документами
|
||||
const DOCS_DIR = path.join(__dirname, '../data/documents');
|
||||
// Путь к директории для хранения векторного индекса
|
||||
const VECTOR_STORE_DIR = path.join(__dirname, '../data/vector_store');
|
||||
|
||||
// Создаем директории, если они не существуют
|
||||
if (!fs.existsSync(DOCS_DIR)) {
|
||||
fs.mkdirSync(DOCS_DIR, { recursive: true });
|
||||
console.log(`Создана директория для документов: ${DOCS_DIR}`);
|
||||
}
|
||||
|
||||
if (!fs.existsSync(VECTOR_STORE_DIR)) {
|
||||
fs.mkdirSync(VECTOR_STORE_DIR, { recursive: true });
|
||||
console.log(`Создана директория для векторного хранилища: ${VECTOR_STORE_DIR}`);
|
||||
}
|
||||
|
||||
// Глобальная переменная для хранения экземпляра векторного хранилища
|
||||
let vectorStore = null;
|
||||
|
||||
// Функция для инициализации векторного хранилища
|
||||
async function initializeVectorStore() {
|
||||
try {
|
||||
console.log('Инициализация векторного хранилища...');
|
||||
|
||||
// Проверяем, существует ли директория с документами
|
||||
if (!fs.existsSync(DOCS_DIR)) {
|
||||
console.warn(`Директория с документами не найдена: ${DOCS_DIR}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Проверяем, есть ли документы в директории
|
||||
const files = fs.readdirSync(DOCS_DIR);
|
||||
if (files.length === 0) {
|
||||
console.warn(`В директории с документами нет файлов: ${DOCS_DIR}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log(`Найдено ${files.length} файлов в директории с документами`);
|
||||
|
||||
// Загружаем документы из директории
|
||||
const loader = new DirectoryLoader(
|
||||
DOCS_DIR,
|
||||
{
|
||||
".txt": (path) => new TextLoader(path),
|
||||
".md": (path) => new TextLoader(path),
|
||||
}
|
||||
);
|
||||
|
||||
console.log('Загрузка документов...');
|
||||
const docs = await loader.load();
|
||||
console.log(`Загружено ${docs.length} документов`);
|
||||
|
||||
if (docs.length === 0) {
|
||||
console.warn('Не удалось загрузить документы');
|
||||
return null;
|
||||
}
|
||||
|
||||
// Разбиваем документы на чанки
|
||||
const textSplitter = new RecursiveCharacterTextSplitter({
|
||||
chunkSize: 1000,
|
||||
chunkOverlap: 200,
|
||||
});
|
||||
|
||||
console.log('Разбиение документов на чанки...');
|
||||
const splitDocs = await textSplitter.splitDocuments(docs);
|
||||
console.log(`Документы разбиты на ${splitDocs.length} чанков`);
|
||||
|
||||
// Создаем эмбеддинги с помощью Ollama
|
||||
console.log('Создание эмбеддингов...');
|
||||
const embeddings = new OllamaEmbeddings({
|
||||
model: "mistral",
|
||||
baseUrl: "http://localhost:11434",
|
||||
});
|
||||
|
||||
// Проверяем, существует ли уже векторное хранилище
|
||||
if (fs.existsSync(path.join(VECTOR_STORE_DIR, 'hnswlib.index'))) {
|
||||
console.log('Загрузка существующего векторного хранилища...');
|
||||
try {
|
||||
vectorStore = await HNSWLib.load(
|
||||
VECTOR_STORE_DIR,
|
||||
embeddings
|
||||
);
|
||||
console.log('Векторное хранилище успешно загружено');
|
||||
return vectorStore;
|
||||
} catch (error) {
|
||||
console.error('Ошибка при загрузке векторного хранилища:', error);
|
||||
console.log('Создание нового векторного хранилища...');
|
||||
}
|
||||
}
|
||||
|
||||
// Создаем новое векторное хранилище
|
||||
console.log('Создание нового векторного хранилища...');
|
||||
vectorStore = await HNSWLib.fromDocuments(
|
||||
splitDocs,
|
||||
embeddings
|
||||
);
|
||||
|
||||
// Сохраняем векторное хранилище
|
||||
console.log('Сохранение векторного хранилища...');
|
||||
await vectorStore.save(VECTOR_STORE_DIR);
|
||||
console.log('Векторное хранилище успешно сохранено');
|
||||
|
||||
return vectorStore;
|
||||
} catch (error) {
|
||||
console.error('Ошибка при инициализации векторного хранилища:', error);
|
||||
console.log('Приложение продолжит работу без векторного хранилища');
|
||||
// Возвращаем заглушку вместо реального хранилища
|
||||
return {
|
||||
addDocuments: async () => console.log('Векторное хранилище недоступно: addDocuments'),
|
||||
similaritySearch: async () => {
|
||||
console.log('Векторное хранилище недоступно: similaritySearch');
|
||||
return [];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Функция для получения экземпляра векторного хранилища
|
||||
async function getVectorStore() {
|
||||
if (!vectorStore) {
|
||||
vectorStore = await initializeVectorStore();
|
||||
}
|
||||
return vectorStore;
|
||||
}
|
||||
|
||||
module.exports = { initializeVectorStore, getVectorStore };
|
||||
Reference in New Issue
Block a user