Вступ: чому ШІ-агентам потрібна пам'ять
Великі мовні моделі за своєю природою — без стану. Кожен виклик API починається з чистого аркуша: модель не пам'ятає, хто ви, що обговорювали вчора, і які рішення вже ухвалили. Для простих чат-ботів це ще якось прийнятно. Але коли ви будуєте ШІ-агента — автономну систему, що виконує складні багатокрокові завдання — відсутність пам'яті стає по-справжньому критичною проблемою.
Уявіть менеджера проєктів, який щоранку забуває всіх членів команди, дедлайни та прийняті рішення. Ось саме так і працює ШІ-агент без системи пам'яті. Повторювані запитання, втрачений контекст, неспроможність навчатися на власному досвіді — і все це щоразу з нуля.
У 2026 році пам'ять для ШІ-агентів — це вже не «було б непогано», а обов'язковий компонент продакшн-систем. За даними дослідження Mem0, правильно реалізована пам'ять дає +26% точності порівняно з підходами без пам'яті, зменшує споживання токенів на 90% і знижує латентність відповідей (p95) на 91%. Цифри, чесно кажучи, вражають.
У цій статті ми розберемо архітектуру пам'яті для ШІ-агентів, порівняємо фреймворки Mem0, LangGraph та Zep, і — що найважливіше — напишемо робочий код на Python, який можна взяти й використати у своєму проєкті.
Типи пам'яті ШІ-агентів
Перш ніж писати код, варто розібратися, які типи пам'яті існують і навіщо кожен із них потрібен. Архітектура пам'яті ШІ-агента дуже нагадує людську — з короткостроковою, довгостроковою та процедурною пам'яттю. Аналогія не ідеальна, але досить точна для практичних цілей.
Короткострокова пам'ять (Short-Term Memory)
Це інформація, доступна в контекстному вікні LLM: поточна розмова, системний промпт, останні повідомлення. Короткострокова пам'ять обмежена розміром контекстного вікна моделі — від 4К до 200К+ токенів залежно від моделі. Коли вікно переповнюється, старі повідомлення просто зникають.
Є важливий нюанс: моделі найбільше уваги приділяють початку та кінцю контексту. Інформація посередині часто ігнорується — це відоме явище «Lost in the Middle». Тому критичні дані краще розміщувати на початку (системний промпт) або ближче до кінця (останній запит).
Семантична пам'ять (Semantic Memory)
Зберігає факти та знання: «Користувач — вегетаріанець», «Проєкт використовує PostgreSQL 16», «Клієнт у часовому поясі UTC+2». По суті, це узагальнена інформація, витягнута з різних взаємодій. Реалізується через векторні бази даних із семантичним пошуком або графи знань.
Епізодична пам'ять (Episodic Memory)
Зберігає конкретні події та взаємодії: «12 лютого користувач повідомив про баг у формі оплати», «Минулого тижня ми обговорили міграцію на Kubernetes». Це часові послідовності подій з контекстом — дозволяє агенту відстежувати, як змінювались рішення з часом.
Процедурна пам'ять (Procedural Memory)
Зберігає навички та патерни поведінки: як правильно деплоїти на продакшн, яку структуру промптів використовувати, які кроки виконувати при code review. Реалізується через шаблони промптів, правила та збережені робочі процеси. Якщо семантична пам'ять — це «що я знаю», то процедурна — «що я вмію робити».
Архітектура системи пам'яті
Типова архітектура пам'яті для продакшн ШІ-агента складається з кількох шарів. Ось як це виглядає схематично:
┌─────────────────────────────────────────────┐
│ LLM (Claude, GPT) │
│ Контекстне вікно (STM) │
└──────────────────┬──────────────────────────┘
│
┌────────▼────────┐
│ Memory Manager │
│ (Mem0 / Zep) │
└───┬─────┬───┬───┘
│ │ │
┌────────▼─┐ ┌─▼───▼──────┐ ┌──────────┐
│ Vector DB│ │ Graph DB │ │ Key-Value│
│ (Qdrant) │ │ (Neo4j) │ │ (Redis) │
│ Semantic │ │ Relations │ │ Sessions │
└──────────┘ └────────────┘ └──────────┘
Memory Manager — це центральний компонент, і саме він вирішує чотири ключові питання:
- Що зберігати: не всі повідомлення варті збереження. «Хм, дай подумати» — ні, «Я вегетаріанець» — так.
- Як зберігати: факти йдуть у семантичну пам'ять (вектори), події — в епізодичну (з часовими мітками), зв'язки — в граф знань.
- Коли витягувати: під час кожного нового запиту система шукає релевантні спогади і вставляє їх у контекст.
- Як оновлювати: «Користувач переїхав з Києва до Львова» — стара інформація повинна бути оновлена, а не дубльована.
Практична реалізація з Mem0
Mem0 — мабуть, найпопулярніший фреймворк для управління пам'яттю ШІ-агентів у 2026 році. Він автоматично витягує ключову інформацію з розмов, зберігає її у векторній базі та забезпечує семантичний пошук по накопичених спогадах. Отже, давайте подивимось, як це працює на практиці.
Встановлення та базове налаштування
# Встановлення
pip install mem0ai
# Для self-hosted варіанту з Qdrant
pip install mem0ai qdrant-client
Створення агента з пам'яттю
Ось мінімальний, але цілком робочий приклад — агент, який використовує Mem0 для запам'ятовування та згадування інформації про користувача:
from openai import OpenAI
from mem0 import Memory
# Ініціалізація клієнта та пам'яті
client = OpenAI()
memory = Memory()
def chat_with_memory(message: str, user_id: str) -> str:
"""Чат з контекстом довгострокової пам'яті."""
# 1. Витягуємо релевантні спогади
memories = memory.search(query=message, user_id=user_id, limit=5)
memory_context = "\n".join(
f"- {m['memory']}" for m in memories.get("results", [])
)
# 2. Формуємо системний промпт з пам'яттю
system_prompt = f"""Ти — корисний ШІ-асистент з довгостроковою пам'яттю.
Ось що ти пам'ятаєш про цього користувача:
{memory_context if memory_context else "Поки що нічого не відомо."}
Використовуй ці знання для персоналізації відповідей.
Не згадуй прямо, що маєш "пам'ять" — просто природно використовуй цю інформацію."""
# 3. Генеруємо відповідь
response = client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": message}
]
)
assistant_reply = response.choices[0].message.content
# 4. Зберігаємо нову інформацію в пам'ять
memory.add(
messages=[
{"role": "user", "content": message},
{"role": "assistant", "content": assistant_reply}
],
user_id=user_id
)
return assistant_reply
# Використання
print(chat_with_memory("Привіт! Мене звати Олексій, я працюю DevOps-інженером.", "user_oleksiy"))
# Mem0 автоматично витягне: ім'я = Олексій, професія = DevOps-інженер
print(chat_with_memory("Які інструменти порекомендуєш для моніторингу?", "user_oleksiy"))
# Mem0 підтягне збережений контекст про DevOps і дасть персоналізовану відповідь
Зверніть увагу на крок 4 — Mem0 сам аналізує розмову і вирішує, які факти варто зберегти. Вам не потрібно вручну вказувати, що саме запам'ятовувати. Це, на мій погляд, одна з найсильніших сторін фреймворку.
Self-hosted конфігурація з Qdrant
Для повного контролю над даними (а це важливо, якщо ви працюєте з чутливою інформацією) можна налаштувати Mem0 з власною векторною базою:
from mem0 import Memory
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333,
"collection_name": "agent_memories"
}
},
"embedder": {
"provider": "openai",
"config": {
"model": "text-embedding-3-small"
}
},
"llm": {
"provider": "anthropic",
"config": {
"model": "claude-sonnet-4-6",
"temperature": 0.1
}
}
}
memory = Memory.from_config(config)
# Додавання спогадів
memory.add(
"Наш проєкт використовує Python 3.12, FastAPI та PostgreSQL 16. "
"Деплоїмо через GitHub Actions у Kubernetes кластер на AWS EKS.",
user_id="team_project",
metadata={"category": "tech_stack", "project": "main_api"}
)
# Пошук з метаданими
results = memory.search(
query="яку базу даних ми використовуємо?",
user_id="team_project",
limit=3
)
for r in results["results"]:
print(f"Пам'ять: {r['memory']}")
print(f"Релевантність: {r['score']:.3f}")
print()
Управління пам'яттю в LangGraph
Якщо ви вже будуєте агентів на LangGraph, хороша новина — у вас є вбудовані механізми для роботи з пам'яттю. А саме: checkpointers для збереження стану графа та LangMem для довгострокової пам'яті.
Checkpointers: стан між викликами
Checkpointer зберігає знімок стану графа після кожного вузла. Це дозволяє агенту «пам'ятати» попередні кроки в межах одного потоку (thread). По суті — це спосіб не втрачати контекст між окремими викликами:
from langgraph.graph import StateGraph, START, END, MessagesState
from langgraph.checkpoint.memory import MemorySaver
from langchain_anthropic import ChatAnthropic
model = ChatAnthropic(model="claude-sonnet-4-6")
def call_model(state: MessagesState):
response = model.invoke(state["messages"])
return {"messages": [response]}
# Побудова графа
builder = StateGraph(MessagesState)
builder.add_node("agent", call_model)
builder.add_edge(START, "agent")
builder.add_edge("agent", END)
# Компіляція з checkpointer — тепер граф пам'ятає стан
memory = MemorySaver()
graph = builder.compile(checkpointer=memory)
# Перше повідомлення
config = {"configurable": {"thread_id": "conversation_1"}}
result = graph.invoke(
{"messages": [{"role": "user", "content": "Привіт, мене звати Марія"}]},
config
)
# Друге повідомлення — агент пам'ятає контекст
result = graph.invoke(
{"messages": [{"role": "user", "content": "Як мене звати?"}]},
config
)
# Відповідь: "Вас звати Марія!"
Важливо: MemorySaver зберігає дані в оперативній пам'яті і підходить лише для розробки. Для продакшну використовуйте PostgresSaver або RedisSaver:
# Продакшн-варіант із PostgreSQL
from langgraph.checkpoint.postgres import PostgresSaver
DB_URI = "postgresql://user:password@localhost:5432/agent_memory"
checkpointer = PostgresSaver.from_conn_string(DB_URI)
graph = builder.compile(checkpointer=checkpointer)
LangMem: довгострокова пам'ять для LangGraph
LangMem додає шар довгострокової пам'яті поверх checkpointers. Він зберігає спогади як JSON-документи у структурованому сховищі LangGraph і дозволяє агенту явно керувати своєю пам'яттю через виклики інструментів. Тобто агент сам вирішує — що зберігати, а що ні:
from langgraph.store.memory import InMemoryStore
from langmem import create_manage_memory_tool, create_search_memory_tool
# Створення сховища
store = InMemoryStore(
index={
"dims": 1536,
"embed": "openai:text-embedding-3-small"
}
)
# Створення інструментів пам'яті для агента
manage_memory = create_manage_memory_tool(namespace=("memories", "{user_id}"))
search_memory = create_search_memory_tool(namespace=("memories", "{user_id}"))
# Тепер агент може самостійно вирішувати, що зберігати:
# - manage_memory(content="Користувач працює з Kubernetes")
# - search_memory(query="технологічний стек користувача")
Векторні бази даних для пам'яті агентів
Векторна база даних — це основа семантичної пам'яті. Вона зберігає ембедінги (числові представлення тексту) та забезпечує швидкий пошук за семантичною подібністю, а не за точним збігом ключових слів. Простіше кажучи, ви питаєте «яку БД ми використовуємо?», а система знаходить запис «Проєкт працює на PostgreSQL 16» — навіть без прямого збігу слів.
Вибір векторної бази у 2026
| База даних | Найкраще для | Латентність (100М векторів) | Self-hosted |
|---|---|---|---|
| Qdrant | Продакшн з фільтрацією | <50 мс | Так |
| Chroma | Прототипи та MVP | Не для масштабу | Так |
| Milvus | Мільярди векторів | <50 мс | Так |
| pgvector | Якщо вже є PostgreSQL | ~100 мс | Так |
| Pinecone | Повністю керований сервіс | <50 мс | Ні (SaaS) |
Чесно кажучи, якщо у вас немає конкретних вимог — починайте з Qdrant. Він швидкий, добре документований і прекрасно працює як self-hosted рішення. Chroma підійде для швидкого прототипування, а pgvector — якщо ви вже «живете» в екосистемі PostgreSQL і не хочете додавати ще одну базу.
Приклад: семантична пам'ять з Qdrant
А тепер — повноцінний приклад роботи з Qdrant для побудови семантичної пам'яті агента:
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
from openai import OpenAI
import uuid
# Ініціалізація
qdrant = QdrantClient(host="localhost", port=6333)
openai_client = OpenAI()
COLLECTION_NAME = "agent_memories"
EMBEDDING_MODEL = "text-embedding-3-small"
EMBEDDING_DIM = 1536
# Створення колекції
qdrant.create_collection(
collection_name=COLLECTION_NAME,
vectors_config=VectorParams(
size=EMBEDDING_DIM,
distance=Distance.COSINE
)
)
def get_embedding(text: str) -> list[float]:
"""Отримання ембедінгу тексту."""
response = openai_client.embeddings.create(
model=EMBEDDING_MODEL,
input=text
)
return response.data[0].embedding
def store_memory(text: str, user_id: str, category: str = "general"):
"""Збереження спогаду у векторну базу."""
embedding = get_embedding(text)
point = PointStruct(
id=str(uuid.uuid4()),
vector=embedding,
payload={
"text": text,
"user_id": user_id,
"category": category,
"timestamp": "2026-03-02T12:00:00Z"
}
)
qdrant.upsert(collection_name=COLLECTION_NAME, points=[point])
def recall_memories(query: str, user_id: str, limit: int = 5) -> list[dict]:
"""Семантичний пошук релевантних спогадів."""
query_embedding = get_embedding(query)
results = qdrant.search(
collection_name=COLLECTION_NAME,
query_vector=query_embedding,
query_filter={
"must": [{"key": "user_id", "match": {"value": user_id}}]
},
limit=limit
)
return [
{"text": r.payload["text"], "score": r.score, "category": r.payload["category"]}
for r in results
]
# Збереження
store_memory("Проєкт migrated з Django на FastAPI у січні 2026", "team_alpha", "architecture")
store_memory("Використовуємо Redis для кешування та Celery для черг завдань", "team_alpha", "tech_stack")
store_memory("SLA для API — 99.9%, максимальний час відповіді 200мс", "team_alpha", "requirements")
# Пошук
memories = recall_memories("який фреймворк ми використовуємо?", "team_alpha")
for m in memories:
print(f"[{m['score']:.3f}] {m['text']}")
Порівняння фреймворків пам'яті: Mem0 vs Zep vs LangMem
Вибір правильного фреймворку залежить від вашого стеку, масштабу та конкретних вимог. Тож давайте розберемо кожне рішення окремо, а потім зведемо в таблицю.
Mem0: універсальне рішення
- Підхід: автоматичне витягування фактів із розмов + векторний пошук + опціональний граф знань
- Переваги: найшвидша латентність, інтеграції з OpenAI/Claude/LangGraph/CrewAI, SOC 2 compliance, можна як self-hosted, так і в хмарі
- Бенчмарки: +26% точності, 90% економії токенів
- Недоліки: графові можливості лише на платних планах, не найкращий варіант для складних причинно-наслідкових зв'язків
- Коли обирати: персоналізовані продукти, чат-боти з пам'яттю, будь-який фреймворк
Zep: для складних зв'язків
- Підхід: темпоральний граф знань із відстеженням змін фактів у часі
- Переваги: найкращий для розуміння зв'язків між сутностями, автоматична темпоральна інвалідація (старі факти позначаються як застарілі), SDK для Python/TypeScript/Go
- Бенчмарки: J-score 76.60 — найвищий серед конкурентів на момент написання
- Недоліки: більша складність налаштування, відсутність валідації вхідних даних, вища вартість
- Коли обирати: ентерпрайз-рішення з потребою в моделюванні зв'язків та часових змін
LangMem: для екосистеми LangGraph
- Підхід: інструменти пам'яті, інтегровані в робочі процеси LangGraph — агент сам вирішує, що зберігати
- Переваги: безкоштовний та відкритий, повний контроль над логікою пам'яті, нативна інтеграція з LangGraph
- Недоліки: висока латентність пошуку (p50: ~18 с — і це серйозно), немає графу знань, потребує LangGraph
- Коли обирати: прототипи та MVP на LangGraph, коли потрібен повний контроль над усім
Порівняльна таблиця
| Критерій | Mem0 | Zep | LangMem |
|---|---|---|---|
| Граф знань | Так (Pro+) | Так (ядро) | Ні |
| Латентність | Дуже низька | Помірна (~1.3 с) | Висока (~18 с) |
| Прив'язка до фреймворку | Ні | Ні | LangGraph |
| Self-hosted | Так | Community Ed. | Тільки self-hosted |
| Ціна | Freemium | Платні тарифи | Безкоштовно |
| Автоматичне витягування | Так | Так | Ні (агент керує) |
Патерни та найкращі практики
Побудувати систему пам'яті — це півсправи. Не менш важливо дотримуватися перевірених практик, щоб вона працювала ефективно та надійно в продакшні.
1. Розділяйте типи пам'яті за namespace
Не змішуйте всі спогади в одному сховищі — це дуже швидко стає хаосом. Використовуйте окремі простори імен для різних типів інформації:
# Розділення за типами
memory.add(content, user_id=user_id, metadata={"type": "preference"}) # Вподобання
memory.add(content, user_id=user_id, metadata={"type": "fact"}) # Факти
memory.add(content, user_id=user_id, metadata={"type": "interaction"}) # Історія подій
2. Реалізуйте стратегію забування
Не вся інформація однаково цінна з часом. Епізодичні спогади (конкретні події) втрачають актуальність швидше, ніж семантичні (факти). Варто реалізувати TTL (Time-to-Live) або механізм поступового зменшення ваги для старих спогадів:
from datetime import datetime, timedelta
def decay_score(original_score: float, created_at: datetime, half_life_days: int = 30) -> float:
"""Зменшення релевантності спогаду з часом."""
age = (datetime.utcnow() - created_at).days
decay_factor = 0.5 ** (age / half_life_days)
return original_score * decay_factor
Цей простий підхід із «напіввременем розпаду» працює напрочуд добре — спогади поступово втрачають вагу, але ніколи не зникають повністю.
3. Уникайте дублювання
Якщо користувач повідомляє «Я живу у Києві» двічі, система повинна оновити існуючий запис, а не створювати новий. Mem0 робить це автоматично, але для кастомних рішень потрібна перевірка на дублікати перед вставкою. Інакше через місяць у вас буде десяток записів «живу у Києві» з різними датами.
4. Дотримуйтесь GDPR та правил конфіденційності
Система пам'яті зберігає персональні дані — і це серйозна відповідальність. Обов'язково реалізуйте:
- Право на видалення:
memory.delete_all(user_id="user_123") - Право на доступ:
memory.get_all(user_id="user_123") - Шифрування збережених даних
- Аудит-логи доступу до пам'яті
Про це легко забути на етапі прототипування, але виправляти потім — набагато дорожче.
5. Гібридний пошук для точності
Чистий векторний пошук не завжди достатній. Комбінуйте семантичний пошук із фільтрацією за метаданими — це помітно покращує результати:
# Спочатку фільтр за структурованими полями, потім семантичний пошук
results = memory.search(
query="яку базу даних використовуємо?",
user_id="team_alpha",
filters={"category": "tech_stack"}, # Звужуємо область пошуку
limit=5
)
Повний приклад: DevOps-асистент з пам'яттю
Тепер зберемо все разом у повноцінному прикладі. Ось ШІ-асистент для DevOps-команди, який пам'ятає технічний стек, прийняті рішення та інциденти. Це саме той тип агента, де пам'ять дає найбільший ефект:
from openai import OpenAI
from mem0 import Memory
class DevOpsAssistant:
"""ШІ-асистент для DevOps з довгостроковою пам'яттю."""
def __init__(self, team_id: str):
self.team_id = team_id
self.client = OpenAI()
self.memory = Memory.from_config({
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333,
"collection_name": f"devops_{team_id}"
}
}
})
def _build_context(self, query: str) -> str:
"""Побудова контексту з релевантних спогадів."""
memories = self.memory.search(query=query, user_id=self.team_id, limit=7)
if not memories.get("results"):
return "Поки що немає збереженої інформації про цю тему."
context_parts = []
for m in memories["results"]:
context_parts.append(f"- {m['memory']}")
return "\n".join(context_parts)
def chat(self, message: str) -> str:
"""Обробка повідомлення з контекстом пам'яті."""
context = self._build_context(message)
response = self.client.chat.completions.create(
model="gpt-4.1",
messages=[
{
"role": "system",
"content": f"""Ти — DevOps-асистент команди.
Ось що ти знаєш про інфраструктуру та проєкти команди:
{context}
Давай конкретні технічні поради, враховуючи відомий стек."""
},
{"role": "user", "content": message}
]
)
reply = response.choices[0].message.content
# Автоматичне збереження нової інформації
self.memory.add(
messages=[
{"role": "user", "content": message},
{"role": "assistant", "content": reply}
],
user_id=self.team_id
)
return reply
def remember(self, fact: str, category: str = "general"):
"""Явне збереження факту в пам'ять."""
self.memory.add(
fact,
user_id=self.team_id,
metadata={"category": category}
)
def forget_all(self):
"""Видалення всієї пам'яті (GDPR compliance)."""
self.memory.delete_all(user_id=self.team_id)
# Використання
assistant = DevOpsAssistant(team_id="alpha")
# Наповнення початкового контексту
assistant.remember("Продакшн кластер: AWS EKS, 3 node groups, Kubernetes 1.29", "infrastructure")
assistant.remember("CI/CD: GitHub Actions, деплой через ArgoCD, GitOps підхід", "ci_cd")
assistant.remember("Моніторинг: Prometheus + Grafana, алерти через PagerDuty", "monitoring")
assistant.remember("Інцидент 15.02.2026: OOM у payment-service через memory leak в Redis connection pool", "incidents")
# Тепер асистент знає контекст команди
print(assistant.chat("У нас знову проблеми з пам'яттю в payment-service. Що порадиш?"))
# Асистент пам'ятає попередній інцидент і дасть контекстну пораду
Часті запитання (FAQ)
Чим відрізняється пам'ять ШІ-агента від RAG?
RAG (Retrieval-Augmented Generation) — це метод доповнення промпту зовнішніми знаннями з документів або баз даних. Пам'ять агента — ширше поняття, яке включає RAG як один з механізмів. Окрім пошуку по документах, пам'ять агента охоплює збереження контексту розмов, навчання на взаємодіях із користувачем, відстеження змін у часі та процедурні навички.
Якщо коротко: RAG відповідає на питання «що написано в документах?», а пам'ять агента — «що я знаю про цього користувача і цю ситуацію?».
Скільки спогадів може зберігати система пам'яті?
Сучасні векторні бази даних (Milvus, Qdrant) масштабуються до мільярдів векторів із латентністю пошуку менше 50 мс. Практичне обмеження — не кількість спогадів, а якість їх фільтрації. При великих обсягах важливо використовувати правильну стратегію індексування: HNSW для до 100К записів, IVF-PQ для мільйонів. І не забувайте про метадатну фільтрацію — вона суттєво прискорює пошук.
Чи безпечно зберігати дані користувачів у пам'яті агента?
Системи пам'яті зберігають персональні дані, тому підпадають під дію GDPR, CCPA та інших законів про конфіденційність. Обов'язково реалізуйте шифрування даних at rest та in transit, механізми видалення на вимогу користувача, обмеження доступу (RBAC) і аудит-логи. Фреймворки як Mem0 (SOC 2 та HIPAA compliant) і Zep підтримують ці вимоги з коробки — це одна з причин обирати готове рішення замість повністю кастомного.
Який фреймворк пам'яті обрати для нового проєкту?
Якщо ви будуєте MVP або прототип — починайте з Mem0: він простий у налаштуванні, працює з будь-яким фреймворком і має безкоштовний тариф. Для ентерпрайз-рішень із складними зв'язками між сутностями — Zep. Якщо ваш проєкт побудований на LangGraph і вам потрібен повний контроль — LangMem.
Головне правило: обирайте рішення під реальні потреби, а не під максимальну кількість функцій. Я бачив багато проєктів, де починали з Zep «бо крутіший», а потім мігрували на Mem0, бо не потрібна була половина можливостей.
Чи можна комбінувати різні типи пам'яті в одному агенті?
Так, і це навіть рекомендований підхід для продакшн-систем. Типова архітектура комбінує: короткострокову пам'ять через контекстне вікно LLM (LangGraph checkpointers), семантичну пам'ять через векторну базу (Mem0 або Qdrant) та структуровані знання через граф (Zep або Neo4j). Кожен шар відповідає за свій тип інформації, а Memory Manager координує їхню роботу.