Files
Agent/agentic_rag_interface.py

231 lines
9.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import gradio as gr
import asyncio
import os
from typing import List
from agent_core import create_agent_graph
from local_knowledge_base import LocalKnowledgeBase
from langchain_core.messages import HumanMessage
class AgenticRAGInterface:
def __init__(self, agent_graph, knowledge_base):
self.agent = agent_graph
self.kb = knowledge_base
self.conversation_history = []
def process_query(self, query: str, use_rag: bool):
"""Обработка запроса пользователя"""
# Добавляем сообщение в историю
self.conversation_history.append({"role": "user", "content": query})
# Если нужен RAG, ищем в базе знаний
context = ""
if use_rag:
search_results = self.kb.search(query)
if search_results:
context = "\n".join([f"[{i+1}] {res['text'][:200]}..."
for i, res in enumerate(search_results)])
# Подготавливаем состояние
initial_state = {
"messages": [HumanMessage(content=query)],
"knowledge_base": context,
"needs_search": use_rag,
"current_step": "start",
"final_answer": None
}
# Запускаем агента
try:
result = self.agent.invoke(initial_state)
answer = result.get("final_answer", "Не удалось получить ответ")
# Добавляем ответ в историю
self.conversation_history.append({"role": "assistant", "content": answer})
# Форматируем историю для отображения
history_text = self._format_history()
return answer, history_text
except Exception as e:
error_msg = f"Ошибка: {str(e)}"
return error_msg, self._format_history()
def _format_history(self):
"""Форматирование истории разговора"""
formatted = []
for msg in self.conversation_history[-10:]: # Последние 10 сообщений
role = "👤 Пользователь" if msg["role"] == "user" else "🤖 Ассистент"
formatted.append(f"{role}: {msg['content']}")
return "\n\n".join(formatted)
def clear_history(self):
"""Очистка истории"""
self.conversation_history = []
return "История очищена", ""
def index_documents(self, project_name: str, folder_path: str):
"""Индексация документов из указанной папки для проекта"""
if not project_name:
return "❌ Укажите имя проекта", ""
if not folder_path:
return "❌ Укажите путь к папке", ""
if not os.path.exists(folder_path):
return f"❌ Папка не существует: {folder_path}", ""
if not os.path.isdir(folder_path):
return f"❌ Указанный путь не является папкой: {folder_path}", ""
try:
# Переключаемся на проект (создаст новую коллекцию)
self.kb.set_project(project_name)
# Индексируем документы
chunks = self.kb.load_documents(folder_path)
return f"✅ Проект '{project_name}': индексировано чанков: {len(chunks)}", folder_path
except Exception as e:
return f"❌ Ошибка при индексации: {str(e)}", ""
def switch_project(self, project_name: str):
"""Переключиться на другой проект"""
if not project_name:
return "❌ Укажите имя проекта", ""
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)
# Создаем Gradio интерфейс
def create_gradio_interface():
with gr.Blocks(title="Локальный Agentic RAG", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# 🤖 Локальный Agentic RAG Система
Полностью автономный AI-агент с базой знаний. Работает без интернета!
""")
with gr.Row():
with gr.Column(scale=2):
query_input = gr.Textbox(
label="Ваш запрос",
placeholder="Задайте вопрос или дайте задание...",
lines=3
)
rag_toggle = gr.Checkbox(
label="Использовать базу знаний (RAG)",
value=True
)
submit_btn = gr.Button("Отправить", variant="primary")
clear_btn = gr.Button("Очистить историю")
with gr.Column(scale=3):
answer_output = gr.Textbox(
label="Ответ агента",
lines=8,
interactive=False
)
history_output = gr.Textbox(
label="История разговора",
lines=12,
interactive=False
)
# Примеры запросов
gr.Examples(
examples=[
["Объясни концепцию machine learning простыми словами", True],
["Посчитай: (15 * 4) + (120 / 3)", False],
["Найди информацию о нейронных сетях в базе знаний", True],
["Спланируй изучение Python на месяц", False]
],
inputs=[query_input, rag_toggle],
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("### 📥 Индексация документов")
with gr.Row():
with gr.Column(scale=3):
folder_input = gr.Textbox(
label="Путь к папке с файлами",
placeholder="./documents или /home/user/my_project",
lines=1
)
with gr.Column(scale=1):
index_btn = gr.Button("📥 Индексировать", variant="primary")
status_output = gr.Textbox(
label="Статус индексации",
lines=2,
interactive=False
)
# Обработчики событий
submit_btn.click(
fn=interface.process_query,
inputs=[query_input, rag_toggle],
outputs=[answer_output, history_output]
)
clear_btn.click(
fn=interface.clear_history,
inputs=[],
outputs=[answer_output, history_output]
)
query_input.submit(
fn=interface.process_query,
inputs=[query_input, rag_toggle],
outputs=[answer_output, history_output]
)
# Обработчик переключения проекта
switch_btn.click(
fn=interface.switch_project,
inputs=[project_input],
outputs=[project_status, project_input]
)
# Обработчик индексации
index_btn.click(
fn=interface.index_documents,
inputs=[project_input, folder_input],
outputs=[status_output, folder_input]
)
return demo