Теперь проекты для индексации хранятся отдельно
This commit is contained in:
@@ -65,8 +65,11 @@ class AgenticRAGInterface:
|
|||||||
self.conversation_history = []
|
self.conversation_history = []
|
||||||
return "История очищена", ""
|
return "История очищена", ""
|
||||||
|
|
||||||
def index_documents(self, folder_path: str):
|
def index_documents(self, project_name: str, folder_path: str):
|
||||||
"""Индексация документов из указанной папки"""
|
"""Индексация документов из указанной папки для проекта"""
|
||||||
|
if not project_name:
|
||||||
|
return "❌ Укажите имя проекта", ""
|
||||||
|
|
||||||
if not folder_path:
|
if not folder_path:
|
||||||
return "❌ Укажите путь к папке", ""
|
return "❌ Укажите путь к папке", ""
|
||||||
|
|
||||||
@@ -77,17 +80,28 @@ class AgenticRAGInterface:
|
|||||||
return f"❌ Указанный путь не является папкой: {folder_path}", ""
|
return f"❌ Указанный путь не является папкой: {folder_path}", ""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Переключаемся на проект (создаст новую коллекцию)
|
||||||
|
self.kb.set_project(project_name)
|
||||||
|
|
||||||
|
# Индексируем документы
|
||||||
chunks = self.kb.load_documents(folder_path)
|
chunks = self.kb.load_documents(folder_path)
|
||||||
return f"✅ Успешно! Индексировано чанков: {len(chunks)}", folder_path
|
return f"✅ Проект '{project_name}': индексировано чанков: {len(chunks)}", folder_path
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"❌ Ошибка при индексации: {str(e)}", ""
|
return f"❌ Ошибка при индексации: {str(e)}", ""
|
||||||
|
|
||||||
# Инициализируем базу
|
def switch_project(self, project_name: str):
|
||||||
kb = LocalKnowledgeBase()
|
"""Переключиться на другой проект"""
|
||||||
# Загружаем документы (если есть)
|
if not project_name:
|
||||||
if os.path.exists("./documents"):
|
return "❌ Укажите имя проекта", ""
|
||||||
kb.load_documents("./documents")
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.kb.set_project(project_name)
|
||||||
|
return f"✅ Переключено на проект: {project_name}", project_name
|
||||||
|
except Exception as e:
|
||||||
|
return f"❌ Ошибка: {str(e)}", ""
|
||||||
|
|
||||||
|
# Инициализируем базу
|
||||||
|
kb = LocalKnowledgeBase(project_name="default")
|
||||||
|
|
||||||
# Создаем интерфейс
|
# Создаем интерфейс
|
||||||
interface = AgenticRAGInterface(create_agent_graph(), kb)
|
interface = AgenticRAGInterface(create_agent_graph(), kb)
|
||||||
@@ -141,9 +155,28 @@ def create_gradio_interface():
|
|||||||
label="Примеры запросов"
|
label="Примеры запросов"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Секция управления проектами
|
||||||
|
gr.Markdown("---")
|
||||||
|
gr.Markdown("### 📂 Управление проектами")
|
||||||
|
|
||||||
|
with gr.Row():
|
||||||
|
with gr.Column(scale=2):
|
||||||
|
project_input = gr.Textbox(
|
||||||
|
label="Имя проекта",
|
||||||
|
placeholder="my_cpp_project",
|
||||||
|
lines=1
|
||||||
|
)
|
||||||
|
switch_btn = gr.Button("🔄 Переключить", variant="secondary")
|
||||||
|
with gr.Column(scale=1):
|
||||||
|
project_status = gr.Textbox(
|
||||||
|
label="Текущий проект",
|
||||||
|
lines=1,
|
||||||
|
interactive=False
|
||||||
|
)
|
||||||
|
|
||||||
# Секция индексации документов
|
# Секция индексации документов
|
||||||
gr.Markdown("---")
|
gr.Markdown("---")
|
||||||
gr.Markdown("### 📂 Индексация документов")
|
gr.Markdown("### 📥 Индексация документов")
|
||||||
|
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
with gr.Column(scale=3):
|
with gr.Column(scale=3):
|
||||||
@@ -153,7 +186,7 @@ def create_gradio_interface():
|
|||||||
lines=1
|
lines=1
|
||||||
)
|
)
|
||||||
with gr.Column(scale=1):
|
with gr.Column(scale=1):
|
||||||
index_btn = gr.Button("📥 Индексировать", variant="secondary")
|
index_btn = gr.Button("📥 Индексировать", variant="primary")
|
||||||
|
|
||||||
status_output = gr.Textbox(
|
status_output = gr.Textbox(
|
||||||
label="Статус индексации",
|
label="Статус индексации",
|
||||||
@@ -180,10 +213,17 @@ def create_gradio_interface():
|
|||||||
outputs=[answer_output, history_output]
|
outputs=[answer_output, history_output]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Обработчик переключения проекта
|
||||||
|
switch_btn.click(
|
||||||
|
fn=interface.switch_project,
|
||||||
|
inputs=[project_input],
|
||||||
|
outputs=[project_status, project_input]
|
||||||
|
)
|
||||||
|
|
||||||
# Обработчик индексации
|
# Обработчик индексации
|
||||||
index_btn.click(
|
index_btn.click(
|
||||||
fn=interface.index_documents,
|
fn=interface.index_documents,
|
||||||
inputs=[folder_input],
|
inputs=[project_input, folder_input],
|
||||||
outputs=[status_output, folder_input]
|
outputs=[status_output, folder_input]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -18,21 +18,48 @@ def should_skip(path: str) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
class LocalKnowledgeBase:
|
class LocalKnowledgeBase:
|
||||||
def __init__(self, collection_name="documents", persist_dir="./qdrant_data"):
|
def __init__(self, project_name: str = "default", persist_dir="./qdrant_data"):
|
||||||
# Инициализируем клиент Qdrant
|
# Инициализируем клиент Qdrant
|
||||||
self.client = QdrantClient(
|
self.client = QdrantClient(
|
||||||
path=persist_dir, prefer_grpc=True # Локальное хранение
|
path=persist_dir, prefer_grpc=True # Локальное хранение
|
||||||
)
|
)
|
||||||
|
|
||||||
self.collection_name = collection_name
|
self.persist_dir = persist_dir
|
||||||
|
self.set_project(project_name)
|
||||||
|
|
||||||
# Инициализация эмбеддингов
|
# Инициализация эмбеддингов
|
||||||
self.embeddings = OllamaEmbeddings(
|
self.embeddings = OllamaEmbeddings(
|
||||||
model="nomic-embed-text", # Хорошие локальные эмбеддинги
|
model="nomic-embed-text", # Хорошие локальные эмбеддинги
|
||||||
)
|
)
|
||||||
|
|
||||||
# Создаем коллекцию если её нет
|
def set_project(self, project_name: str):
|
||||||
|
"""Переключиться на проект (создать/выбрать коллекцию)"""
|
||||||
|
# Очищаем имя от недопустимых символов
|
||||||
|
safe_name = "".join(c for c in project_name if c.isalnum() or c in "-_")
|
||||||
|
self.collection_name = safe_name
|
||||||
self._create_collection()
|
self._create_collection()
|
||||||
|
print(f"Переключено на проект: {self.collection_name}")
|
||||||
|
|
||||||
|
def get_current_project(self) -> str:
|
||||||
|
"""Получить имя текущего проекта"""
|
||||||
|
return self.collection_name
|
||||||
|
|
||||||
|
def list_projects(self) -> list:
|
||||||
|
"""Список всех проектов (коллекций)"""
|
||||||
|
try:
|
||||||
|
collections = self.client.get_collections()
|
||||||
|
return [c.name for c in collections.collections]
|
||||||
|
except:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def delete_project(self, project_name: str = None):
|
||||||
|
"""Удалить проект (коллекцию)"""
|
||||||
|
name = project_name or self.collection_name
|
||||||
|
try:
|
||||||
|
self.client.delete_collection(collection_name=name)
|
||||||
|
print(f"Удалена коллекция: {name}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Не удалось удалить коллекцию {name}: {e}")
|
||||||
|
|
||||||
def _create_collection(self):
|
def _create_collection(self):
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user