Обновленная функция индексации

This commit is contained in:
ki.sagidullin
2026-04-01 20:26:19 +05:00
parent 32d5ca97a1
commit 5eeaff5655

View File

@@ -77,7 +77,34 @@ class LocalKnowledgeBase:
print(f"Создана коллекция {self.collection_name}") print(f"Создана коллекция {self.collection_name}")
def load_documents(self, directory_path: str): def load_documents(self, directory_path: str):
"""Загрузка документов из директории (рекурсивно)""" # Кастомные разделители для C++ - в порядке приоритета
cpp_separators = [
# Конец блока - самый важный разделитель
"\n}",
# Конец statement
";",
# Объявления - должны быть отдельными чанками
"\nclass ",
"\nstruct ",
"\nenum ",
"\nnamespace ",
"\ntemplate<",
"\npublic:",
"\nprivate:",
"\nprotected:",
"\nvirtual ",
"\noverride ",
# Функции
"\nvoid ", "\nint ", "\nfloat ", "\ndouble ", "\nbool ", "\nauto ", "\nstd::",
"\nconst ", "\nstatic ", "\nexplicit ",
# Комментарии - тоже разделитель
"\n//",
"\n/*",
"\n*",
# Перенос строки
"\n",
]
loaders = { loaders = {
".pdf": PyPDFLoader, ".pdf": PyPDFLoader,
".txt": lambda path: TextLoader(path, encoding="utf-8"), ".txt": lambda path: TextLoader(path, encoding="utf-8"),
@@ -89,6 +116,7 @@ class LocalKnowledgeBase:
} }
all_documents = [] all_documents = []
files_processed = 0
# Рекурсивный обход с фильтрацией папок # Рекурсивный обход с фильтрацией папок
for root, dirs, files in os.walk(directory_path): for root, dirs, files in os.walk(directory_path):
@@ -102,21 +130,56 @@ class LocalKnowledgeBase:
try: try:
loader = loaders[ext](full_path) loader = loaders[ext](full_path)
documents = loader.load() documents = loader.load()
# Добавляем метаданные о пути к файлу
for doc in documents:
doc.metadata["source"] = full_path
doc.metadata["file_name"] = file_path
doc.metadata["file_ext"] = ext
all_documents.extend(documents) all_documents.extend(documents)
print(f"Загружен {file_path}: {len(documents)} документов") files_processed += 1
print(f"✓ Загружен {file_path}")
except Exception as e: except Exception as e:
print(f"Ошибка загрузки {file_path}: {e}") print(f"Ошибка загрузки {file_path}: {e}")
# Разбиваем на чанки print(f"\n📁 Загружено файлов: {files_processed}")
text_splitter = RecursiveCharacterTextSplitter.from_language( print(f"📄 Всего документов до сплиттинга: {len(all_documents)}")
language=Language.CPP,
chunk_size=500,
chunk_overlap=100,
length_function=len
)
chunks = text_splitter.split_documents(all_documents) # Для C++ файлов используем кастомный сплиттер
print(f"Всего чанков: {len(chunks)}") cpp_files_docs = [d for d in all_documents if d.metadata.get("file_ext") in [".cpp", ".hpp", ".h", ".cc"]]
other_docs = [d for d in all_documents if d.metadata.get("file_ext") not in [".cpp", ".hpp", ".h", ".cc"]]
chunks = []
# Сплиттим C++ с кастомными разделителями
if cpp_files_docs:
print("\n🔧 Сплиттинг C++ файлов...")
cpp_splitter = RecursiveCharacterTextSplitter(
separators=cpp_separators,
chunk_size=800, # Увеличил для C++
chunk_overlap=150, # Больше overlap для контекста
length_function=len,
keep_separator=True, # Сохраняем разделители
)
cpp_chunks = cpp_splitter.split_documents(cpp_files_docs)
chunks.extend(cpp_chunks)
print(f" C++ чанков: {len(cpp_chunks)}")
# Для остальных файлов - стандартный сплиттер
if other_docs:
print("\n📄 Сплиттинг остальных файлов...")
text_splitter = RecursiveCharacterTextSplitter.from_language(
language=Language.CPP,
chunk_size=500,
chunk_overlap=100,
length_function=len
)
other_chunks = text_splitter.split_documents(other_docs)
chunks.extend(other_chunks)
print(f" Остальных чанков: {len(other_chunks)}")
print(f"\n📊 Всего чанков после сплиттинга: {len(chunks)}")
# Создаем эмбеддинги и сохраняем в Qdrant # Создаем эмбеддинги и сохраняем в Qdrant
self._index_documents(chunks) self._index_documents(chunks)