265 lines
9.2 KiB
Markdown
265 lines
9.2 KiB
Markdown
# 🧠 Система памяти 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*
|