- BrainTools - https://www.braintools.ru -

Я реализовал паттерн памяти из OpenAI Cookbook в Python библиотеку

Я создал agent-memory-state — open-source Python библиотеку для управления персистентной памятью [1] AI агентов. Реализует паттерн state-based memory из OpenAI Cookbook: профиль пользователя, разделение session/global памяти, LLM-консолидация и защитные механизмы.


Проблема: Агенты без памяти — безликие

Каждый раз, начиная новый разговор с AI-ассистентом, он забывает [2] всё. Ваши диетические предпочтения, привычки в путешествиях, рабочий контекст — стёрты. Приходится объяснять одно и то же снова и снова.

Это не просто раздражает — это фундаментальное ограничение. Переход от «отвечать» к «помнить» определяет новый рубеж AI-агентов. Агент, который помнит, становится коллаборатором, а не просто инструментом.

Решение: State-Based Memory

Изучив паттерн персонализации контекста из OpenAI Cookbook [3], я создал библиотеку, реализующую эту архитектуру:

┌─────────────────────────────────────────────┐
│                MemoryState                   │
├─────────────────────────────────────────────┤
│  profile: {name, email, loyalty_status}     │
│  global_memory: [персистентные заметки]     │
│  session_memory: [заметки текущей сессии]   │
└─────────────────────────────────────────────┘
          ↓ to_system_prompt()
┌─────────────────────────────────────────────┐
│  ---                                        │
│  name: Alice                                │
│  loyalty_status: gold                       │
│  ---                                        │
│                                             │
│  ## User Memory                             │
│  - [dietary] Предпочитает вегетарианское    │
│  - [travel] Обычно бронирует место у прохода│
└─────────────────────────────────────────────┘

Ключевая архитектура

1. State Object

from agent_memory import MemoryState

state = MemoryState(user_id="user_123")
state.profile["name"] = "Alice"
state.profile["loyalty_status"] = "gold"

State содержит:

  • Profile: Жёсткие факты (имя, email, уровень членства)

  • Global Memory: Персистентные предпочтения между сессиями

  • Session Memory: Временные заметки текущего разговора

2. Инъекция памяти

# Генерируем системный промпт с памятью
system_prompt = state.to_system_prompt()

# Или с защитными разделителями
system_prompt = state.to_memory_block()  # Оборачивает в <memory>...</memory>

Формат вывода:

  • Профиль как YAML frontmatter

  • Заметки как Markdown список с датами

  • Сессионные заметки �� префиксом [SESSION]

3. Дистилляция памяти

Во время разговора агент захватывает устойчивые предпочтения:

state.add_session_note(
    text="Пользователь предпочитает вегетарианскую еду в поездках",
    keywords=["dietary"],
    confidence=0.9
)

Или используйте как инструмент агента:

from agent_memory import create_save_memory_tool, SAVE_MEMORY_TOOL_SCHEMA

save_memory = create_save_memory_tool(state)
tools = [SAVE_MEMORY_TOOL_SCHEMA]  # Для OpenAI function calling

4. Консолидация памяти

После сессии объединяем session notes в global memory:

from openai import AsyncOpenAI

client = AsyncOpenAI()
await manager.consolidate(state, client)

LLM выполняет:

  • Дедупликацию: Слияние семантически похожих заметок

  • Разрешение конфликтов: Новая информация побеждает

  • Фильтрацию: Отбрасывает сессионные заметки («только для этой поездки»)

Реальный вывод (Travel Agent Demo):

Пользователь во время разговора:

“Я стал вегетарианцем, учти это для еды”
“Для этой поездки хочу место у окна — посмотреть на Фудзи”

Агент сохраняет обе заметки в session memory. После разговора:

До консолидации (5 заметок):
  - [baggage, short_trip] Для коротких поездок предпочитает без багажа
  - [seat_preference, flight] Обычно предпочитает место у прохода
  - [neighborhood, hotel] Любит центральные районы
  - [dietary] Вегетарианец                                        ← SESSION
  - [seat, flight] Только для этой поездки: хочет окно для Фудзи  ← SESSION

[Consolidation] LLM merge: {'merged': 2, 'discarded': 2, 'total': 3}

После консолидации (3 заметки):
  - [dietary] Предпочитает вегетарианскую еду в поездках          ✅ СОХРАНЕНО
  - [travel, flight] Обычно предпочитает место у прохода          ✅ ОБЪЕДИНЕНО
  - [neighborhood, hotel] Любит центральные районы                ✅ СОХРАНЕНО

❌ "окно только для этой поездки" — корректно отброшено (session-specific)

5. Защитные механизмы (Guardrails)

from agent_memory.guardrails import GuardedMemoryState, GuardrailConfig

config = GuardrailConfig(
    max_note_length=500,
    max_notes_per_user=100,
    block_ssn=True,
    block_credit_card=True,
    block_instructions=True,
)

guarded = GuardedMemoryState(state, config)
guarded.add_session_note("Мой SSN 123-45-6789")  # Вызывает ValueError

Блокирует:

  • PII паттерны (SSN, кредитные карты, телефоны)

  • Инъекцию инструкций («игнорируй предыдущие инструкции…»)

  • Превышение лимитов

Бэкенды хранения

In-Memory (Тестирование)

from agent_memory.storage import InMemoryStorage

manager = MemoryManager(storage=InMemoryStorage())

SQLite (Продакшен)

from agent_memory.storage import SQLiteStorage

manager = MemoryManager(storage=SQLiteStorage("./memory.db"))

Полный пример

from agent_memory import MemoryManager
from agent_memory.storage import SQLiteStorage
from openai import AsyncOpenAI

# Инициализация
manager = MemoryManager(storage=SQLiteStorage("./memory.db"))
state = manager.load_user("alice_123")

# Настройка профиля
state.profile["name"] = "Alice"
state.profile["loyalty_status"] = "gold"

# Формируем системный промпт
base_prompt = "Ты — туристический консьерж."
memory_block = state.to_memory_block()
system_prompt = f"{base_prompt}nn{memory_block}"

# Во время разговора — агент вызывает save_memory tool
state.add_session_note(
    text="Вегетарианец — предпочитает вегетарианские блюда",
    keywords=["dietary"],
    confidence=1.0
)

# После разговора — консолидация
client = AsyncOpenAI()
await manager.consolidate(state, client)

# Сохраняем для следующей сессии
manager.save(state)

Когда НЕ использовать память

Не каждому агенту нужна долгосрочная память. Простой тест:

Если агент запомнит что-то из предыдущего взаимодействия, это материально поможет решить задачу лучше или быстрее?

Пропустите память для:

  • Разовых задач (генерация кода, перевод)

  • Stateless утилит (калькуляторы, конвертеры)

  • Высоконагруженных API, где важна латентность

Используйте память для:

  • Персональных ассистентов

  • Агентов службы поддержки

  • Систем обучения/коучинга

  • Любых агентов с повторяющимися пользователями

Установка

pip install agent-memory-state

# С поддержкой OpenAI (для консолидации)
pip install "agent-memory-state[openai]"

Что дальше

Это v0.1.0 — фундамент. Планируемые фичи:

  1. Vector-based retrieval для больших хранилищ памяти

  2. Decay памяти с деградацией confidence со временем

  3. Мульти-агентный шаринг памяти

  4. Аналитика памяти (что запоминается, как часто используется)


Системы памяти улучшаются через итерации с измерениями, а не через изначальную сложность. Начните просто, оценивайте строго, развивайте осознанно.

Ссылки:

Автор: ractangle

Источник [5]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/24431

URLs in this post:

[1] памятью: http://www.braintools.ru/article/4140

[2] забывает: http://www.braintools.ru/article/333

[3] паттерн персонализации контекста из OpenAI Cookbook: https://cookbook.openai.com/examples/agents_sdk/context_personalization

[4] https://github.com/molchanovartem/agent-memory: https://github.com/molchanovartem/agent-memory

[5] Источник: https://habr.com/ru/articles/986282/?utm_source=habrahabr&utm_medium=rss&utm_campaign=986282

www.BrainTools.ru

Rambler's Top100