Реализация памяти для агента

Мы уже изучили, как передавать контекст между запросами — через Redis, файлы и сессии. Это помогает LLM "помнить" предыдущие сообщения в рамках диалога. Но что, если агенту нужно помнить больше, чем просто историю чата? Например, прогресс пользователя в курсе, его предпочтения или состояние системы?

Контекст — это то, что видит модель. А вот память — это то, что хранит сам сервер. Это его внутреннее состояние, независимое от LLM. Именно память позволяет агенту быть по-настоящему "умным" — помнить важное, игнорировать мусор и действовать осмысленно.

Без памяти агент каждый раз начинает с чистого листа. С памятью — он становится помощником, который знает, кто вы, что вы делали и что вам нужно.

Типы памяти у ИИ-агента

Память у агента — не единый блок. Как и у человека, она бывает разной. Мы выделяем три основных типа:

  • Краткосрочная (сессионная) — хранит данные в течение одной сессии. Например, текущий диалог, состояние формы, временные настройки.
  • Долгосрочная — сохраняет информацию между сессиями. Например, прогресс обучения, предпочтения пользователя, история действий.
  • Метапамять — хранит служебные данные: идентификаторы сессий, настройки агента, флаги состояния.

💡 Контекст и память — это разные вещи.
Контекст — это часть промпта, который передаётся в LLM.
Память — это данные, которые хранит сервер и использует по необходимости.
Мы храним в памяти, а в контекст передаём только релевантное.

Практика: реализуем память на TypeScript

Мы создадим агента-помощника по курсам, который будет помнить, какие темы пользователь уже прошёл. Это особенно актуально, учитывая ваш стартап по генерации персональных курсов.

Будем использовать:

  • Redis — для хранения сессионной памяти и прогресса
  • Асинхронные операции — чтобы не блокировать сервер
  • TTL (Time To Live) — чтобы данные автоматически удалялись

Шаг 1: Подключение Redis

Убедитесь, что Redis запущен локально. Установить его можно через Docker:

docker run -d -p 6379:6379 --name redis redis:alpine

Установите пакет redis:

npm install redis

Шаг 2: Клиент Redis с TTL

Создадим файл memory.ts:

import { createClient } from 'redis';

// Подключение к Redis
const client = createClient({
  url: process.env.REDIS_URL || 'redis://localhost:6379'
});

client.on('error', (err) => console.log('Redis Client Error', err));

await client.connect();

// Сохранение прогресса пользователя
async function saveProgress(userId: string, topic: string) {
  const key = `progress:${userId}`;
  const progress = await client.get(key);
  const topics = progress ? JSON.parse(progress) : [];

  if (!topics.includes(topic)) {
    topics.push(topic);
    // Устанавливаем TTL: 30 дней
    await client.setEx(key, 2592000, JSON.stringify(topics));
  }
}

// Получение прогресса
async function getProgress(userId: string): Promise<string[]> {
  const key = `progress:${userId}`;
  const progress = await client.get(key);
  return progress ? JSON.parse(progress) : [];
}

⚠️ Всегда используйте process.env для хранения URL Redis. Это безопасно и гибко.

Шаг 3: Использование в обработчике запроса

// Пример обработки завершения темы
app.post('/topic/completed', async (req, res) => {
  const { userId, topic } = req.body;

  try {
    await saveProgress(userId, topic);
    res.json({ success: true, message: `Тема "${topic}" сохранена в прогрессе` });
  } catch (err) {
    res.status(500).json({ error: 'Не удалось сохранить прогресс' });
  }
});

Асинхронные операции: почему это важно

Redis работает по сети. Операции чтения и записи — асинхронные. Если не использовать async/await, сервер может:

  • Блокироваться
  • Потерять соединение
  • Вернуть устаревшие данные

Правильный подход:

await saveProgress(userId, topic); // ✅ Дожидаемся завершения

Ошибочный подход:

saveProgress(userId, topic); // ❌ Не дожидаемся — возможна потеря данных

Асинхронность — не просто синтаксис. Это гарантия надёжности.

Упражнение: добавьте сохранение прогресса

Ваша задача — реализовать функцию, которая:

  1. Принимает userId и topic через POST-запрос
  2. Проверяет, не завершал ли пользователь уже эту тему
  3. Добавляет тему в прогресс, если её ещё нет
  4. Возвращает обновлённый список тем

Используйте код выше как основу. Проверьте работу через curl или Postman.

💡 Подсказка: добавьте логирование, чтобы отслеживать, что происходит:

console.log(`Прогресс для ${userId}:`, topics);

Долгосрочная память: краткое упоминание

В 2026 году всё чаще используется векторное хранилище для долгосрочной памяти. Например, Qdrant или Milvus Lite. Они позволяют:

  • Хранить большие объёмы знаний
  • Искать по смыслу, а не по точному совпадению
  • Интегрироваться с RAG (Retrieval-Augmented Generation)

Но это — тема будущих уроков. Сейчас важно освоить базу: сессионная память + Redis + асинхронность.

Почему это работает

Когда агент помнит прогресс, он может:

  • Не предлагать уже пройденные темы
  • Строить персонализированные рекомендации
  • Экономить токены, не дублируя информацию

Это не просто "запоминание". Это основа интеллектуального поведения.

Что дальше?

Теперь, когда агент умеет помнить, пришло время научить его действовать. В следующей теме — инструменты (tools). Мы создадим функции, которые агент сможет вызывать: получать данные, генерировать PDF, работать с API.

Представьте: агент, который не только помнит, что вы прошли тему "Контекст", но и может сгенерировать вам чек-лист по MCP — по команде.

Готовы превратить память в действия? В следующей теме — это станет реальностью.