Lana49's picture
Upload 13 files
417b2ea verified
import streamlit as st
from pathlib import Path
import sys
sys.path.insert(0, str(Path(__file__).parent))
from core.qa_engine import QASystem
from core.formula_engine import FormulaEngine
from utils.config import RAW_DIR, PROCESSED_DIR
# Настройка страницы
st.set_page_config(
page_title="Инженерный чат-бот",
page_icon="🏗️",
layout="wide"
)
# Инициализация QA системы
if 'qa_system' not in st.session_state:
st.session_state.qa_system = QASystem(use_llm=False)
index_path = PROCESSED_DIR / "qa_index"
if index_path.exists():
st.session_state.qa_system.load_index(index_path)
# Инициализация Formula Engine
if 'formula_engine' not in st.session_state:
st.session_state.formula_engine = FormulaEngine()
# Инициализация сообщений чата
if 'messages' not in st.session_state:
st.session_state.messages = [
{
"role": "assistant",
"content": """🏗️ **Здравствуйте!** Я инженерный помощник по строительной документации.
📖 **База знаний:** СП 61.13330.2012 «Тепловая изоляция оборудования и трубопроводов»
**Что я умею:**
• 📖 Отвечать на вопросы по документации
• 📐 Рассчитывать толщину изоляции
• 🌡️ Определять тепловые потери
• 📊 Находить материалы и нормативы
**💡 Примеры вопросов:**
• Какие материалы для тепловой изоляции?
• Как рассчитать толщину изоляции?
• Рассчитай толщину при температуре 150°C
• Какая температура на поверхности изоляции?
• Какие нормативы регулируют изоляцию?
**Задайте свой вопрос!**"""
}
]
qa_system = st.session_state.qa_system
formula_engine = st.session_state.formula_engine
# Заголовок
st.title("🏗️ Инженерный помощник по строительной документации")
st.caption("📄 База знаний: СП 61.13330.2012 «Тепловая изоляция оборудования и трубопроводов»")
# Боковая панель
with st.sidebar:
st.header("📚 О системе")
st.markdown("""
**База знаний:**
- СП 61.13330.2012
- Тепловая изоляция
- 93 714 символов
- 460 предложений
**Что я умею:**
- ✅ Отвечать на вопросы
- ✅ Рассчитывать толщину
- ✅ Определять теплопотери
- ✅ Находить нормативы
""")
st.divider()
# Статус системы
if qa_system.is_ready:
st.success(f"✅ База знаний готова\n📄 {qa_system.index.ntotal} фрагментов")
else:
st.warning("⚠️ База знаний не загружена")
if st.button("📚 Индексировать документы"):
with st.spinner("Индексация..."):
success = qa_system.index_documents(RAW_DIR)
if success:
index_path = PROCESSED_DIR / "qa_index"
index_path.mkdir(parents=True, exist_ok=True)
qa_system.save_index(index_path)
st.success(f"✅ Проиндексировано {qa_system.index.ntotal} фрагментов")
st.rerun()
else:
st.error("❌ Не найдено документов для индексации")
st.divider()
# Доступные формулы
st.subheader("📐 Доступные формулы")
formulas = formula_engine.get_available_formulas()
for f in formulas:
with st.expander(f"📖 {f['name'][:25]}"):
st.write(f"`{f['expression']}`")
st.caption(f['description'][:50])
st.divider()
# Кнопка очистки истории
if st.button("🗑️ Очистить историю", use_container_width=True):
st.session_state.messages = [st.session_state.messages[0]]
st.rerun()
# Отображение чата
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Поле ввода вопроса
if prompt := st.chat_input("Задайте вопрос по строительной документации..."):
# Добавляем вопрос пользователя
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# Генерируем ответ
with st.chat_message("assistant"):
with st.spinner("🔍 Анализирую..."):
# Проверяем, расчетный ли вопрос
is_calc = any(word in prompt.lower() for word in
['рассчитай', 'вычисли', 'толщин', 'температур', 'потери', 'формул'])
if is_calc:
result = formula_engine.answer_calculation(prompt)
response = result['answer']
else:
search_result = qa_system.answer(prompt)
response = search_result['answer']
# Добавляем источники, если есть
if search_result.get('sources'):
response += "\n\n---\n📚 **Источники:**\n"
for src in search_result['sources'][:2]:
response += f"\n• {src['doc_name']} (релевантность: {src['score']:.2f})"
st.markdown(response)
# Сохраняем ответ
st.session_state.messages.append({"role": "assistant", "content": response})
# Подвал
st.divider()
st.caption("💡 Совет: для расчетов указывайте температуру (например, 'при 150°C')")