🚀 Узнайте про внедрение AI-driven SDLC в вашу команду
/10 мин /Команда AI4DEV

Архитектура памяти ИИ-агентов

Разбираем трехуровневую архитектуру долговременной памяти для ИИ-агентов: онтологию POLE+O, контракты Pydantic, дедупликацию эмбеддингов, единую СУБД, RRF-поиск и протокол MCP.

Архитектура памяти ИИ-агентов

Перезапуск терминала удаляет рабочий контекст: ИИ-агент мгновенно теряет нить диалога, принятые стандарты кодовой базы и структуру модулей проекта. Разработчик вынужден заново объяснять модели контекст репозитория и принятый код-стайл.

Попытки решить эту проблему обычным векторным поиском (когда документацию просто делят на фрагменты и ищут ближайшие векторы) быстро упираются в тупик. Механизм косинусного расстояния сопоставляет семантически близкие фразы, но игнорирует причинно-следственные цепочки и целостную иерархию компонентов. Если же позволить языковой модели строить произвольный граф знаний без строгих ограничений, база быстро заполняется дубликатами и выдуманными связями. Долговременная память агента требует выверенной архитектуры.

Трехуровневая модель памяти

Оперативная память
(Текущая сессия, контекстное окно LLM)

Журнал рассуждений
(Промежуточные выводы, вызовы инструментов, аудит решений)

Долговременная память
(Граф фактов, профиль пользователя, правила кодовой базы)

Пирамида памяти

Организуем память агента в виде трехуровневой пирамиды:

  1. Оперативная память (Working Memory). Верхний уровень содержит контекст текущей рабочей сессии. Сюда входят последние сообщения диалога, активные системные промпты и непосредственные ответы инструментов. Данные хранятся только пока открыта сессия в консоли.
  2. Журнал рассуждений (Reasoning Log). Промежуточный уровень записывает рассуждения модели. В журнал попадают промежуточные выводы, аргументы вызова инструментов (tool calls) и результаты выполнения тестов. Журнал обеспечивает воспроизводимость: инженер всегда может восстановить ход мыслей агента и выяснить, на каком шаге алгоритм принял неверное решение.
  3. Долговременная память (Long-Term Memory). Это валидированный граф знаний о людях, репозиториях, технологическом стеке и предпочтениях разработчика сохраняется между сессиями.

Онтология и контракт

Без формализованной онтологии большая языковая модель создает десятки синонимичных связей и мусорных сущностей.

В основу графа закладываем классическую модель сущностей POLE+O:

  • Person (Человек): разработчики, авторы коммитов, тимлиды.
  • Organization (Организация): команды, компании, внешние поставщики.
  • Location (Место): виртуальные пути, URL-эндпоинты, пути к модулям в репозитории.
  • Event (Событие): инциденты, релизы, мержи pull request.
  • Object (Предмет): микросервисы, библиотеки, конфигурационные файлы.

Для агента стандартную онтологию дополняют два специфических типа записей:

  • Атомарные факты. Автономные утверждения прямого действия (например: «сервис billing использует Go 1.24»). Они не требуют сложных связей с соседними вершинами графа, сохраняются обособленно и извлекаются по семантическому сходству.
  • Предпочтения пользователя. Типизированные записи с требованиями к стеку, соглашениями о форматировании и персональными ограничениями (например: «не использовать any в TypeScript»).

Контракт фиксируется в кодовой базе схемами – через Pydantic в Python или Zod в TypeScript:

from enum import Enum
from typing import List, Optional
from pydantic import BaseModel, Field

class EntityType(str, Enum):
    PERSON = "person"
    ORGANIZATION = "organization"
    LOCATION = "location"
    EVENT = "event"
    OBJECT = "object"
    ATOMIC_FACT = "atomic_fact"
    USER_PREFERENCE = "user_preference"

class ExtractedEntity(BaseModel):
    name: str = Field(description="Каноническое название сущности")
    entity_type: EntityType
    properties: dict = Field(default_factory=dict)

class KnowledgeRelation(BaseModel):
    source_entity: str
    target_entity: str
    relation_type: str = Field(description="Тип связи: DEPENDS_ON, AUTHORED_BY, APPLIES_TO")
    weight: float = Field(ge=0.0, le=1.0, default=1.0)

class IngestionPayload(BaseModel):
    entities: List[ExtractedEntity]
    relations: List[KnowledgeRelation]

Модель физически не запишет в базу лишнее поле или выдуманный тип связи: парсер отсечет невалидный JSON еще до выполнения запроса.

Конвейер сохранения

Превращаем исходный текст в проверенные знания через многоступенчатый конвейер. Ошибка слияния записей способна связать разные сущности и нарушить логику рассуждений агента.

Ошибка

Успех

>= 95%

85% – 95%

< 85%

Необработанный текст

Чанкинг (512 токенов, overlap 64)

Извлечение (LLM)

Валидация схемы

Отбраковка / Re-ask

Нормализация имён

Косинусное сходство векторов

Автоматическое слияние

Метка дубликата (Human-in-the-loop)

Создание новой сущности

Единая СУБД

Этапы обработки конвейера:

  1. Параллельный чанкинг. Документ разбивается на фрагменты (на практике хорошо зарекомендовал себя размер в 512 токенов с перекрытием в 64 токена). Каждый блок анализируется моделью независимо, что позволяет распараллелить извлечение сущностей по потокам.
  2. Валидация схемы. Ответ модели проверяется валидатором. При нарушении типов или выходе за рамки перечисления EntityType запись отбрасывается либо отправляется на повторный запрос с указанием ошибки.
  3. Нормализация названий. Вариативные написания приводятся к общему знаменателю (например, строки «FastAPI», «fastapi-framework» и «FastAPI lib» сводятся к каноническому имени FastAPI).
  4. Векторная дедупликация. Вектор новой записи сопоставляется с уже сохраненными фактами по косинусному расстоянию эмбеддингов.

Конвейер выбирает действие по шкале косинусного сходства (конкретные пороги калибруются под выбранную модель эмбеддингов, типовой практический ориентир):

Сходство векторовДействие конвейераИнженерное обоснование
>= 95%Автоматическое слияниеЗаписи с высокой вероятностью дублируют одну сущность (синонимы, опечатки).
85% - 95%Создание записи с флагом дубликатаПограничная зона: решение передается инженеру во избежание ошибочного слияния разных сущностей со схожими именами.
< 85%Создание новой сущностиСистема считает сущность оригинальной и добавляет в граф как отдельный узел.

Единая база данных

Храним документы, векторы и граф связей в одной СУБД. Классическая архитектура с тремя отдельными сервисами (векторная база, графовая СУБД Neo4j и файловое хранилище) неизбежно приводит к рассинхронизации связей при сетевых сбоях или падении одного из компонентов.

Для надежной работы выбирают единую СУБД общего назначения — например, PostgreSQL с расширением pgvector или MongoDB:

  • Тексты документов. Исходные фрагменты файлов хранятся в неизменном виде.
  • Векторные эмбеддинги. Векторы хранятся в соседнем поле той же таблицы и индексируются через HNSW.
  • Ребра графа. Связи между узлами хранятся в виде списка смежности (таблица триплетов subject -> predicate -> object).

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

import hashlib

def generate_entity_id(user_id: str, entity_type: str, canonical_name: str) -> str:
    seed = f"{user_id}:{entity_type.lower()}:{canonical_name.strip().lower()}"
    return hashlib.sha256(seed.encode("utf-8")).hexdigest()

Идентификаторы формируются детерминированно из хэша связки пользователя, типа и канонического имени. Запись становится идемпотентной: повторный прогон индексации не создает дубликатов и не повреждает существующие ребра.

Способы поиска

Извлекаем контекст тремя путями под разные типы инженерных задач.

Факты и зависимости

Масштабный рефакторинг

Точные метаданные

Запрос агента

Тип задачи

Гибридный поиск: BM25 + Vector Search

Ранжирование по RRF

Поиск по связям графа

Контекст: факты + окружение

Глубокий поиск: подграф на 3 шага

Генерация мини-вики со ссылками

Оглавление + навигация по ссылкам

Параметризованный SQL-запрос

Табличные данные

Гибридный поиск и RRF

Стандартный запрос запускает параллельно два механизма: поиск по ключевым словам (BM25) и векторный поиск по косинусному расстоянию.

У текстового и векторного поиска разные шкалы релевантности: их баллы нельзя просто сложить. Вместо развертывания тяжелой нейросети-реранкера (cross-encoder), требующей вычислительных ресурсов GPU и создающей задержку в сотни миллисекунд, применяют формулу Reciprocal Rank Fusion (RRF), предложенную Кормаком и коллегами (SIGIR 2009):

RRF_Score(d) = Σ [ 1 / (k + rank_m(d)) ]

Алгоритм делит единицу на сумму ранга документа и константы сглаживания k (обычно 60), после чего складывает полученные дроби для обоих списков. Окончательный порядок определяется без привязки к абсолютным оценкам релевантности.

Отобрав топ-10 кандидатов, алгоритм проходит по связям графа на два шага вглубь. Модель получает не оторванные цитаты, а целевой фрагмент вместе со связанным контекстом: зависимостями, автором и правилами проектирования.

Глубокий поиск

Комплексные задачи (например, переработка архитектуры модуля) требуют широкого контекста, но выгрузка полного графа в промпт перегружает контекстное окно модели: она теряет фокус и рассеивает внимание.

В этом сценарии система выделяет локальный подграф на три шага в глубину:

  1. Целевой модуль.
  2. Внутренние компоненты и внешние сервисы модуля.
  3. Библиотечные зависимости и конфигурационные параметры.

Извлеченный подграф форматируется в локальную базу взаимосвязанных заметок с гиперссылками (в виде markdown-вики). Агент получает общее оглавление и стартовую страницу. Дальнейшее исследование графа модель ведет автономно через вызовы инструментов, открывая только нужные узлы по мере рассуждения.

Параметризованные запросы

Когда агенту требуется строгая выборка (например, найти все микросервисы на Go с версией выше 1.23), векторный поиск не нужен. Модель формирует прямой SQL-запрос к типизированным полям базы данных. Ответ возвращается мгновенно, без текстового шума и случайных выдумок модели.

Сравнение поисковых механизмов:

Метод выборкиМеханизм работыНазначение
Гибридный поиск (RRF)Параллельный BM25 + эмбеддинги со сведением рангов и обходом на 2 шагаТочечный поиск релевантных фактов и их прямого окружения без нейросетей-реранкеров.
Глубокий поиск (подграф-вики)Выгрузка связей на 3 шага вглубь в виде гипертекстовых заметокАрхитектурные задачи и масштабный рефакторинг с навигацией по ссылкам через инструменты.
Параметризованный запросСтруктурированная фильтрация по фиксированным полям и типам данныхТочные выборки метаданных без привлечения векторных расстояний.

Интеграция через MCP

Подключаем сервис памяти к консольным агентам через протокол Model Context Protocol. Это исключает жесткую привязку логики памяти к конкретному инструменту вроде Claude Code или Cursor.

Сервер памяти предоставляет внешнему агенту безопасный набор инструментов:

  • search_memory(query: str, tags: list[str]) — гибридный поиск по базе фактов;
  • get_subgraph(entity_id: str, depth: int) — исследование связей выбранной сущности;
  • remember_fact(fact: str, entity_type: str) — отправка нового знания на конвейер сохранения.
Фоновый процесс обученияЕдиная СУБДСервер памяти (MCP)Консольный агент (Claude Code)Фоновый процесс обученияЕдиная СУБДСервер памяти (MCP)Консольный агент (Claude Code)Контур непрерывного обученияРазработчикЗавершение рабочей сессии / задачи1Задача выполнена, PR отправлен2Чтение лога рассуждений и изменений кодовой базы3Вызов remember_fact (новые соглашения, архитектура)4Валидация схемы, дедупликация и запись5Старт новой сессии на следующий день6search_memory (контекст проекта)7Гибридная выборка + граф8Актуальные правила и факты9Разработчик

Система учится на лету: фоновый процесс разбирает завершенные сессии и коммиты. Принятые архитектурные решения и новые правила оформления кода автоматически отправляются в долговременную память.

Неконтролируемое накопление фактов превращает память в свалку устаревших инструкций. Архитектура должна включать фоновые циклы консолидации (по аналогии с фазой сна) и регулярную очистку базы от конфликтующих правил и временных сессионных заметок.

Варианты реализации

Выбираем стек под масштаб проекта и требования к безопасности данных:

  1. Собственное ядро на основе СУБД. Стек на базе PostgreSQL + pgvector или MongoDB. Подходит для команд с высокими требованиями к корпоративной безопасности данных, где хранилище развертывается во внутреннем контуре, с полным контролем над схемами и триплетами.
  2. Локальные автономные движки. Решения, работающие прямо на машине разработчика без внешних зависимостей. Примером служит Mnemosyne — встраиваемый движок на SQLite со встроенным графом фактов, сессионным сжатием и готовым интерфейсом MCP. Для встраивания в существующий Python-код подходят библиотеки Graphiti и mem0.
  3. Облачные платформы памяти. Специализированные SaaS- и фреймворк-сервисы вроде Zep или Cognee. Предоставляют готовые конвейеры чанкинга, автоматическую дедупликацию и векторные индексы из коробки через удаленный API.

Сравнение вариантов реализации:

ВариантРешенияПреимуществаНедостатки
Собственное ядроPostgreSQL (pgvector), MongoDBПолный контроль схемы, транзакционность, нахождение данных в периметре.Требует самостоятельной реализации обхода графа и алгоритма RRF.
Локальные движкиMnemosyne, Graphiti, mem0Автономная работа на локальном диске, нулевая задержка сети, встроенный MCP.Ограничены вычислительными ресурсами рабочей машины инженера.
Облачные платформыZep, CogneeРазвертывание за несколько минут, готовые конвейеры чистки и реранкинга.Передача исходного кода во внешний контур, зависимость от доступности стороннего API.

Источники

  1. Model Context Protocol Specification — спецификация открытого протокола взаимодействия агентов с внешними источниками данных.
  2. pgvector: Open-source vector similarity search for PostgreSQL — расширение векторного поиска для PostgreSQL.
  3. Pydantic Documentation — валидация контрактов данных и сериализация структурированных схем.
  4. Cormack, Clarke, Buettcher: Reciprocal Rank Fusion Outperforms Indri and trec_eval — статья с описанием формулы ранжирования RRF (ACM SIGIR 2009).
Поделиться статьей:

Читайте также

Карта компетенций AI-инженера и пошаговый план входа в специальность
/7 мин

Карта компетенций AI-инженера и пошаговый план входа в специальность

Разбираем реальные требования рынка к AI-инженеру на основе десятка собеседований: разделение ролей, карта ключевых технических навыков и пошаговый план перехода из классической разработки.