9.2 KiB
9.2 KiB
🧠 Система памяти Telegram бота
✅ Реализовано сохранение контекста разговора
Система памяти обеспечивает сохранение контекста диалога между перезапусками бота.
🏗️ Архитектура памяти
Уровни памяти:
-
STM (Short-Term Memory) — краткосрочная память
- Последние 5 сообщений в полном объёме
- Хранится в
state.ai_chat_history(оперативная память) - Загружается из БД при первом сообщении после перезапуска
-
LTM (Long-Term Memory) — долгосрочная память
- Сообщения 5-20 в сжатом виде (первые 50 символов)
- Хранится в SQLite (
memory.db) - Загружается по мере необходимости
-
RAG (Retrieval-Augmented Generation) — векторный поиск
- Семантический поиск по всем сообщениям
- Хранится в ChromaDB (
vector_db/) - Используется для релевантного контекста
-
Факты — извлечённые знания о пользователе
- Личные данные (имя, город, профессия)
- Технические предпочтения (языки, инструменты)
- Проекты и директории
- Хранится в SQLite (
memory.db)
📁 Базы данных
| Файл | Назначение | Технология |
|---|---|---|
memory.db |
История сообщений, факты, сессии | SQLite |
vector_db/ |
Векторные эмбеддинги для RAG-поиска | ChromaDB |
chroma.sqlite3 |
Метаданные ChromaDB | SQLite |
🔄 Как работает сохранение контекста
1. При отправке сообщения пользователем:
# В handle_text_message (bot.py)
if not state_manager.is_history_loaded(user_id):
load_history_to_state(user_id, state, state_manager)
2. При обработке ИИ-запроса:
# В handle_ai_task (bot.py)
save_message(user_id, "user", text) # Сохранение в SQLite + ChromaDB
state.ai_chat_history.append(f"User: {text}") # STM
3. При получении ответа ИИ:
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()— загрузка истории в statesave_message()— сохранение сообщенияget_context()— получение контекста с градиентной памятью
bot.py
handle_text_message()— загрузка истории при первом сообщенииhandle_ai_task()— обработка ИИ-запросов с памятью
🧪 Тестирование
Запуск тестов системы памяти:
cd /home/mirivlad/telegram-bot
python test_memory.py
Тесты:
- ✅ Сохранение сообщений в SQLite
- ✅ Сохранение сообщений в ChromaDB
- ✅ Загрузка истории из БД в состояние
- ✅ RAG-поиск по векторной базе
- ✅ Извлечение фактов
- ✅ Градиентная память (STM → LTM → RAG)
🔧 Настройки
Размеры памяти:
# В vector_memory.py
stm_size = 5 # Размер краткосрочной памяти (сообщения)
ltm_size = 15 # Размер долгосрочной памяти (сообщения)
max_messages = 20 # Максимум сообщений в истории
Модель эмбеддингов:
# В vector_memory.py
model_name = "all-MiniLM-L6-v2" # 384 измерения, 90MB
Порог извлечения фактов:
# В bot.py
state.messages_since_fact_extract >= 5 # Каждые 5 сообщений
📈 Мониторинг
Получить статистику памяти:
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'
# }
⚠️ Важные замечания
- История загружается один раз — при первом сообщении после перезапуска бота
- Флаг
is_history_loaded— предотвращает повторную загрузку - Автосохранение — каждое сообщение сохраняется в БД немедленно
- RAG-поиск — используется для релевантного контекста по запросу
- Компактификация — при превышении лимита токенов запускается сжатие истории
🔄 Восстановление контекста после перезапуска
До исправления:
- ❌
state.ai_chat_historyсбрасывался при перезапуске - ❌ Бот «забывал» предыдущие сообщения
- ❌ Контекст терялся
После исправления:
- ✅ История загружается из SQLite при первом сообщении
- ✅
state.ai_chat_historyвосстанавливается из БД - ✅ RAG-поиск работает по всем сообщениям
- ✅ Факты извлекаются и сохраняются
- ✅ Контекст сохраняется между перезапусками
📝 Пример использования
# Сохранение сообщения
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