Spaces:
Runtime error
Runtime error
| 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')") |