# 🧠 Система памяти Telegram бота ## ✅ Реализовано сохранение контекста разговора Система памяти обеспечивает сохранение контекста диалога между перезапусками бота. --- ## 🏗️ Архитектура памяти ### Уровни памяти: 1. **STM (Short-Term Memory)** — краткосрочная память - Последние 5 сообщений в полном объёме - Хранится в `state.ai_chat_history` (оперативная память) - Загружается из БД при первом сообщении после перезапуска 2. **LTM (Long-Term Memory)** — долгосрочная память - Сообщения 5-20 в сжатом виде (первые 50 символов) - Хранится в SQLite (`memory.db`) - Загружается по мере необходимости 3. **RAG (Retrieval-Augmented Generation)** — векторный поиск - Семантический поиск по всем сообщениям - Хранится в ChromaDB (`vector_db/`) - Используется для релевантного контекста 4. **Факты** — извлечённые знания о пользователе - Личные данные (имя, город, профессия) - Технические предпочтения (языки, инструменты) - Проекты и директории - Хранится в SQLite (`memory.db`) --- ## 📁 Базы данных | Файл | Назначение | Технология | |------|-----------|------------| | `memory.db` | История сообщений, факты, сессии | SQLite | | `vector_db/` | Векторные эмбеддинги для RAG-поиска | ChromaDB | | `chroma.sqlite3` | Метаданные ChromaDB | SQLite | --- ## 🔄 Как работает сохранение контекста ### 1. При отправке сообщения пользователем: ```python # В handle_text_message (bot.py) if not state_manager.is_history_loaded(user_id): load_history_to_state(user_id, state, state_manager) ``` ### 2. При обработке ИИ-запроса: ```python # В handle_ai_task (bot.py) save_message(user_id, "user", text) # Сохранение в SQLite + ChromaDB state.ai_chat_history.append(f"User: {text}") # STM ``` ### 3. При получении ответа ИИ: ```python save_message(user_id, "assistant", full_output) # Сохранение в SQLite + ChromaDB state.ai_chat_history.append(f"Assistant: {full_output[:500]}") # STM ``` ### 4. Автоматическое извлечение фактов: Каждые 5 сообщений ИИ анализирует диалог и извлекает факты: - Имя пользователя - Город проживания - Профессия - Технологии - Предпочтения --- ## 📊 Форматирование контекста для ИИ Контекст формируется с градиентной памятью: ``` 📋 ПРОФИЛЬ ПОЛЬЗОВАТЕЛЯ: [personal]: - Пользователя зовут Владимир - Живёт в городе Ангарск [technical]: - Использует Python - Работает с Telegram API 💬 STM (ПОСЛЕДНИЕ СООБЩЕНИЯ): Пользователь: Привет! Как дела? Assistant: Отлично! Чем могу помочь? ... 🕰️ LTM (БОЛЕЕ СТАРЫЕ СООБЩЕНИЯ — КРАТКО): Пользователь: Интересуюсь Python asyncio... Assistant: asyncio — это библиотека для... ... 🔍 RAG (РЕЛЕВАНТНЫЕ СООБЩЕНИЯ ПО ЗАПРОСУ): [0.85] Пользователь: Я работаю системным администратором... [0.72] Assistant: Для автоматизации используйте Python... ================================================== 🧠 ПАМЯТЬ: STM чётко → LTM размыто → RAG глубоко ================================================== ``` --- ## 🛠️ Компоненты системы памяти ### `memory_system.py` - `SQLiteMemoryStorage` — хранение сообщений и фактов - `MemoryManager` — управление памятью - `Fact` — модель факта - `Message` — модель сообщения - `DialogSession` — модель сессии ### `vector_memory.py` - `VectorMemoryStorage` — ChromaDB хранилище - `HybridMemoryManager` — гибридная память (SQLite + Vector) - `load_history_to_state()` — загрузка истории в state - `save_message()` — сохранение сообщения - `get_context()` — получение контекста с градиентной памятью ### `bot.py` - `handle_text_message()` — загрузка истории при первом сообщении - `handle_ai_task()` — обработка ИИ-запросов с памятью --- ## 🧪 Тестирование Запуск тестов системы памяти: ```bash cd /home/mirivlad/telegram-bot python test_memory.py ``` ### Тесты: 1. ✅ Сохранение сообщений в SQLite 2. ✅ Сохранение сообщений в ChromaDB 3. ✅ Загрузка истории из БД в состояние 4. ✅ RAG-поиск по векторной базе 5. ✅ Извлечение фактов 6. ✅ Градиентная память (STM → LTM → RAG) --- ## 🔧 Настройки ### Размеры памяти: ```python # В vector_memory.py stm_size = 5 # Размер краткосрочной памяти (сообщения) ltm_size = 15 # Размер долгосрочной памяти (сообщения) max_messages = 20 # Максимум сообщений в истории ``` ### Модель эмбеддингов: ```python # В vector_memory.py model_name = "all-MiniLM-L6-v2" # 384 измерения, 90MB ``` ### Порог извлечения фактов: ```python # В bot.py state.messages_since_fact_extract >= 5 # Каждые 5 сообщений ``` --- ## 📈 Мониторинг Получить статистику памяти: ```python from vector_memory import get_memory_stats stats = get_memory_stats(user_id) # { # 'total_sessions': 10, # 'total_messages': 250, # 'total_facts': 15, # 'hybrid_mode': True, # 'vector_documents': 393, # 'vector_model': 'all-MiniLM-L6-v2' # } ``` --- ## ⚠️ Важные замечания 1. **История загружается один раз** — при первом сообщении после перезапуска бота 2. **Флаг `is_history_loaded`** — предотвращает повторную загрузку 3. **Автосохранение** — каждое сообщение сохраняется в БД немедленно 4. **RAG-поиск** — используется для релевантного контекста по запросу 5. **Компактификация** — при превышении лимита токенов запускается сжатие истории --- ## 🔄 Восстановление контекста после перезапуска ### До исправления: - ❌ `state.ai_chat_history` сбрасывался при перезапуске - ❌ Бот «забывал» предыдущие сообщения - ❌ Контекст терялся ### После исправления: - ✅ История загружается из SQLite при первом сообщении - ✅ `state.ai_chat_history` восстанавливается из БД - ✅ RAG-поиск работает по всем сообщениям - ✅ Факты извлекаются и сохраняются - ✅ Контекст сохраняется между перезапусками --- ## 📝 Пример использования ```python # Сохранение сообщения from vector_memory import save_message save_message(user_id=123, role="user", content="Меня зовут Владимир") save_message(user_id=123, role="assistant", content="Привет, Владимир!") # Загрузка истории from vector_memory import load_history_to_state from bot.models.user_state import UserState, StateManager state = UserState() state_manager = StateManager() load_history_to_state(user_id=123, state, state_manager) # Получение контекста с градиентной памятью from vector_memory import get_context context = get_context(user_id=123, query="Python", stm_size=5, ltm_size=15) print(context) # RAG-поиск from vector_memory import search_memory results = search_memory(user_id=123, query="asyncio", limit=5) for msg, score in results: print(f"[{score:.2f}] {msg.role}: {msg.content}") ``` --- *Документация для разработчиков Telegram CLI Bot* *Версия: 0.8.0*