Главная / Статьи

Предоставьте ИИ-агентам внешнюю память вместо того, чтобы заполнять окно контекста.

Замените агентов-золотых рыб циклом «Читать-Размышлять-Действовать-Писать», работающим с гибридной векторной и графовой памятью, наряду с механизмами консолидации, обрезки данных, оценки и контроля приватности.

Издатель: REACTAPP.TOP11 мин чтения2623 слов

Источники: Your AI Agent’s Memory Problem: The New Architecture You Need

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

Проблема золотой рыбки: почему современные ИИ-агенты забывают

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

+-------------------------------------------------------------+
|                     User Session Ends                       |
|                              |                              |
|                              ▼                              |
|   +-----------------------------------------------------+   |
|   |             Stateless LLM Call Clears               |   |
|   |  - System Prompts: Reset                            |   |
|   |  - Session Context: Erased                          |   |
|   |  - Learned Preferences: Forgotten                   |   |
|   +-----------------------------------------------------+   |
|                              |                              |
|                              ▼                              |
|                   Next Run = Day One Again                  |
+-------------------------------------------------------------+

Иллюзия больших окон контекста

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

  • Рост затрат из-за необходимости перепроцессирования огромных промптов при каждом запросе
  • Задержки — время получения первого токена увеличивается с ростом длины промпта
  • Шум в контексте из-за эффекта «потери информации» при том, что важные факты теряются среди большого объема текста

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

От более большого контекста к более умному контексту

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

Цикл памяти: архитектурный план для когнитивных процессов агентов

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

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

Цикл «Читать-Анализировать-Действовать-Записывать»

Read-Reason-Act-Write (RRAW) делит процесс выполнения на четыре последовательные фазы:

  • Read — перед созданием запроса ищутся в долгосрочных хранилищах соответствующая история, предпочтения и прошлые решения
  • Reason — модель объединяет текущий запрос с полученной информацией для планирования
  • Act — согласно этому плану вызываются инструменты, API или базы данных
  • Write — синтезируются результаты и обратная связь, после чего они индексируются обратно в память

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

Архитектурный поток данных

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

[User Input]
     │
     ▼
[Agent Orchestrator] <─────────────────────────────┐
     │                                             │ (Loopback)
     ├─────────────────► [Memory Retrieval]        │
     │                           │                 │
     ▼                           ▼                 │
[LLM Prompt Assembler] <─── [Context]              │
     │                                             │
     ▼                                             │
[Large Language Model (LLM)]                       │
     │                                             │
     ▼                                             │
[Action Executor]                                  │
     │                                             │
     ▼                                             │
[Memory Writeback Module] ─────────────────────────┘
     │
     ▼
[(Episodic / Semantic / Procedural Stores)]

Три основы агентной памяти

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

  • Эпизодическая память — временно упорядоченные журналы взаимодействий; повествовательная автобиография
  • Семантическая память — устранение дубликатов фактов и связей между сущностями; то, что является истиной в мире
  • Процедурная память — эффективные рабочие процессы и шаблоны использования инструментов; способы выполнения работы
  • Разделение мозга и памяти

    Инженерный прорыв заключается в разделении вычислений (LLM) и состояния (хранилищ). Это позволяет избежать ограничений, связанных с окном контекста, и затрат на постоянную настройку. Хранилище может масштабироваться горизонтально по мере накопления исторических данных, в то время как модель остается ограниченным, в основном безсостоянийным исполнителем. Команды могут менять модели вкладок или схемы графов без переобучения модели чата, а также делять память между пользователями, чтобы рост одного клиента не влиял на работу другого.

    Создание хранилища памяти: гибридная технологическая стек

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

    Векторные базы данных для семантического и эпизодического воспоминания

    Pinecone, Milvus, Weaviate и другие сервисы хранят эмбеддинги событий и документов. Метрики близости, такие как косинусное сходство, позволяют находить связанные воспоминания:

    import numpy as np
    from openai import OpenAI
    
    client = OpenAI()
    
    def get_embedding(text: str) -> list[float]:
        """Generates a 1536-dimensional vector embedding for semantic search."""
        response = client.embeddings.create(
            model="text-embedding-3-small",
            input=text
        )
        return response.data[0].embedding
    
    # Store an episodic memory with its vector representation
    episodic_memory = "Met with Sarah yesterday. She greenlit the budget for Project Titan."
    memory_vector = get_embedding(episodic_memory)
    
    # This vector allows us to find this memory later using natural language queries
    # like 'What did we agree on with Sarah?' even if 'budget' is omitted.
    

    Векторный поиск особенно эффективен при решении открытых вопросов вроде «О чём мы говорили насчёт миграции в облака в прошлом квартале?» Он менее надёжен, когда ответ должен быть точным структурированным фактом — вероятностные аналоги не являются гарантией. Похожесть — подходящий инструмент для задач вроде «Напомните, что мы говорили о миграции», но не для управления заработной платой или правил контроля доступа, где необходимо получить единственно верный результат.

    Базы данных графов для детерминистической картирования знаний

    Запрос «Кто руководит проектом Titan?» может вернуть документ, в котором упоминаются оба имени, но не подтверждается связь между ними. Такие базы данных, как Neo4j, моделируют сущности в виде узлов, а связи — в виде рёбер для обеспечения точности на основе прослеживания путей:

    (Project: Titan) <-[:LEADS]- (Employee: Sarah) -[:REPORTS_to]-> (VP: Marcus)
    

    Агент следует проверенному пути LEADS, вместо того чтобы опираться на оценку похожести.

    Гибкое решение: оркестрированный поиск от векторов к графам

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

    # Real-world query: "Who is the lead on that document-indexing project?"
    
    def hybrid_memory_lookup(user_query: str) -> dict:
        # Step 1: Query Vector DB to find the most contextually relevant project
        query_vector = get_embedding(user_query)
    
        # Mock Vector DB search returning the closest matching entity ID
        matched_project_id = "project_titan_404"  # Found via match on "document-indexing"
    
        # Step 2: Query Graph DB using the strict entity ID to find the exact lead
        # Cypher Query: MATCH (p:Project {id: $id})<-[:LEADS]-(e:Employee) RETURN e.name
        graph_record = mock_neo4j_driver.run(
            "MATCH (p:Project {id: $id})<-[:LEADS]-(e:Employee) RETURN e.name",
            id=matched_project_id
        )
    
        return {
            "project_id": matched_project_id,
            "lead_name": graph_record["e.name"]
        }
    
    # This hybrid flow eliminates vector hallucination by anchoring
    # fuzzy natural language inputs to hard, deterministic graph relationships.
    

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

    От сырых данных к пригодной для использования памяти: консолидационная цепочка

    Запись каждой фразы непосредственно в векторный индекс приводит к увеличению объема памяти и шуму при поиске — стол, заваленный записками с каждой встречи, включая приветствия. Найти решение, принятое три месяца назад, становится невозможным. Без консолидации задержка поиска увеличивается, результаты в формате top-k заполняются приветствиями, а модель начинает использовать устаревшие или противоречивые фрагменты информации. Асинхронная система консолидации преобразует сырые логи в качественные знания:

    [Raw Interaction Data] → [Extraction] → [Synthesis] → [Pruning] → [Long-Term Memory]
    

    Три этапа консолидации памяти

    Консолидацию следует выполнять вне основного пути обработки запросов — с помощью заданий cron или событий окончания сессии — в три этапа:

    1. Извлечение — извлечение фактов, предпочтений и решений из ненужных деталей разговора
    2. Синтез — объединение с существующими долгосрочными записями, устранение конфликтов, обновление устаревших данных
  • Удаление ненужных данных — удаляются мемории с низкой полезностью или временного характера на основе оценки
  • Синтезирование разговоров с структурированными результатами

    Для извлечения и синтеза необходимо генерирование в соответствии с установленной схемой. Модели в стиле Pydantic обеспечивают данные в формате, готовом к сохранению в базе данных:

    import os
    from typing import List
    from pydantic import BaseModel, Field
    from openai import OpenAI
    
    # Define the target structure for consolidated memory
    class MemoryItem(BaseModel):
        fact: str = Field(description="A single, atomic statement of fact about the user or their environment.")
        category: str = Field(description="The functional domain (e.g., tech_stack, preference, constraint).")
        importance: int = Field(description="A subjective importance rating from 1 (low) to 5 (high).")
    
    class ConsolidatedMemory(BaseModel):
        memories: List[MemoryItem]
    
    def synthesize_transcript(transcript: str) -> ConsolidatedMemory:
        """
        Parses a raw transcript and extracts high-signal, deduplicated facts.
        This structured parsing prevents raw noise from polluting the vector store.
        """
        client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
    
        prompt = f"""
        Analyze the following chat transcript between a user and an AI.
        Extract key facts, user preferences, and technical constraints.
        Ignore conversational noise, greetings, and transition phrases.
    
        Transcript:
        {transcript}
        """
    
        # Use structured outputs to guarantee the response matches the Pydantic schema
        completion = client.beta.chat.completions.parse(
            model="gpt-4o-mini",
            messages=[
                {"role": "system", "content": "You are an expert data consolidation engine."},
                {"role": "user", "content": prompt}
            ],
            response_format=ConsolidatedMemory,
        )
    
        return completion.choices[0].message.parsed
    # Example Usage
    raw_chat = """
    User: Hey! I'm starting a new web project. I want to use FastAPI and PostgreSQL.
    AI: That's a great stack! Do you want to use Docker?
    User: Yes, Docker is a must. And remember, I hate using MongoDB, so let's avoid that completely.
    """
    
    structured_output = synthesize_transcript(raw_chat)
    for item in structured_output.memories:
        print(f"[{item.category.upper()}] Fact: {item.fact} (Importance: {item.importance}/5)")
    

    Алгоритмическое удаление ненужных данных и оценка релевантности

    Не каждая синтезированная запись заслуживает сохранения. Оценивайте полезность на основе важности, свежести и частоты использования, например:

    Полезность = (Важность * КоличествоОбращений) / (1 + (КоэффициентУхудшения * ДниСМоментаПоследнегоОбращения))

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

    Практическое применение

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

    • Коллеги-ИИ, которые запоминают структуру кодовой базы, условия API и прошлые решения по дизайну
    • Агенты поддержки, которые помнят информацию о владельцах продукта и настроения клиентов между сессиями
    • Помощники CRM, которые отслеживают нюансы взаимоотношений для более эффективных действий в будущем
  • Помощники в исследованиях, которые обрабатывают литературу и формируют взаимосвязанные гипотезы
  • Выбор способа поиска в зависимости от потребностей: локальное состояние сессии для поддержки пользователя против глубокого структурного контекста для архитектуры кода. Следует избегать использования единого монолитного хранилища данных. Боты, предназначенные для поддержки, часто нуждаются в информации о последних нескольких сессиях и метаданных учетной записи; агенты для написания кода требуют карт репозиториев и краткого описания правил разрешения конфликтов. Размещение этих типов запросов в разных хранилищах или в разных коллекциях с разным сроком хранения позволяет сохранять целостность каждого индекса.

    Ограничения в производственной среде: от прототипа до надежной системы

    Одного подключения к базе данных векторов недостаточно. Распространенной причиной сбоев является память только для записи — сохранение всех логов и ответов инструментов приводит к перегрузке из-за избыточной информации. В производственных средах требуется строгий цикл RRAW с фильтрацией, обработкой данных и периодическим объединением информации; в противном случае шум контекста и смещение векторов берут верх. Показатели наблюдаемости должны включать глубину очереди задач на объединение, частоту удаления данных и пороги оповещений при снижении коэффициента успешных запросов после изменения схемы или способа генерации векторов.

    Количественная оценка ценности памяти с помощью метрик

    Отслеживайте использование памяти как любого другого сервиса:

    • Коэффициент успешных запросов к памяти (MHR) — доля извлеченных фрагментов, которые действительно используются в ответе
    • Оценка качества ответа (RQS) — сравнение ответов, основанных на данных из памяти, и ответов без использования таких данных

    Управление затратами, задержками и конфиденциальностью

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

    import asyncio
    import logging
    from typing import List
    
    logging.basicConfig(level=logging.INFO)
    
    async def fetch_memories_from_db(user_id: str, query: str) -> List[str]:
        # Simulate a vector database retrieval latency
        await asyncio.sleep(0.1)
        return ["User prefers Python for data engineering tasks."]
    
    async def retrieve_memory_safely(
        user_id: str,
        query: str,
        timeout_seconds: float = 0.15
    ) -> List[str]:
        """
        Retrieves memories asynchronously with a strict timeout guardrail.
        This prevents slow vector DB lookups from blocking the main agent response loop.
        """
        try:
            # Enforce a strict latency budget using asyncio.wait_for
            memories = await asyncio.wait_for(
                fetch_memories_from_db(user_id, query),
                timeout=timeout_seconds
            )
            return memories
        except asyncio.TimeoutError:
            logging.warning(f"Memory timeout for user {user_id}. Falling back to empty memory.")
            # Fallback to preserve user experience latency
            return []
    
    # Example execution of the guarded memory retrieval
    if __name__ == "__main__":
        memories = asyncio.run(retrieve_memory_safely("usr_90210", "Get programming language"))
        print(f"Retrieved Memories: {memories}")
    

    Анонимизируйте данные при их поступлении, внедряйте механизмы RBAC, чтобы агент A не мог читать данные агента B, и соблюдайте требования GDPR/CCPA. Никогда не включайте в данные сырые, нередактированные тексты пользователей; выполняйте редактуру персональных данных перед их индексацией.

    Чек-лист операций для первой версии в производстве

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

    Что оптимизирует архитектура

    В этом подходе приоритет отдается способности к эволюции и сохранению состояния перед временной изобретательностью при обработке запросов. ЯЗЫК — это движок во время выполнения; внешняя память представляет собой состояние системы. Структурированный цикл обратной связи позволяет агенту с каждым циклом совершенствовать свой путь — от временного утилитарного инструмента в командной строке к непрерывной производственной системе.

    Это также влияет на стоимость, задержку и релевантность: принудительный поиск в огромном объеме контекста требует значительных ресурсов внимания и токенов. Внешняя память фильтрует этот объем контекста заранее. Настоящая ценность агента определяется не столько размером окна контекста, сколько точностью систем поиска информации, которые питают модель. Команды, вкладывающие средства в гибридную память, процессы консолидации данных, оценку и меры защиты приватности, получают агентов, которые с каждым использованием становятся лучше, а не ухудшаются под влиянием собственной истории. При отсутствии таких мер контроль история превращается в недостаток: более громкие запросы, медленные ответы и пользователи, которые перестают доверять ассистенту, противоречащему самому себе из недели в неделю. Только тщательно спланированное использование внешней памяти позволяет продуктам с агентами накапливать преимущества, а не шум.