ILCP: Persistent Latent Memory для мультиагентных LLM | β-VAE компрессор | AiManual
AiManual Logo Ai / Manual.
01 Июл 2026 Гайд

Persistent Latent Memory для мультиагентных LLM: метод ILCP с β-VAE компрессором

Разбор метода ILCP для передачи памяти между агентами LLM с помощью β-VAE. Архитектура, пошаговый гайд, типичные ошибки и аналогия с 6G handover.

Реклама
cliv2

Агенты теряют память быстрее, чем вы успеваете сказать "context window exhausted"

Вы запускаете мультиагентную систему. Десять, сто, тысяча AI-агентов. Каждый решает свою подзадачу. Но как передать опыт одного агента другому? Традиционный подход — тащить весь history в следующее окно. Результат? Токены растут экспоненциально, latency падает, агенты "глупеют" на длинном контексте (об этом я писал в статье про coding agent и KV cache quantization). Знакомо?

Выход есть — Persistent Latent Memory. И если вы думаете, что это очередной RAG или векторная база, вы ошибаетесь. Речь о новом методе, представленном на ICML 2026 — Incremental Latent Compression Protocol (ILCP). Он берет β-VAE, скрещивает с gated MLP и создает сжатое скрытое состояние, которое живет вечно. Или пока вы его не перезагрузите.

💡
ILCP не заменяет механизм внимания. Он дополняет его, предоставляя долговременную память поверх текущего контекста. Аналог — долговременная потенциация в нейронауке.

Как работает ILCP? Аналогия с 6G handover

Представьте, что ваш агент — это мобильное устройство, которое перемещается между сотами (другими агентами). В 6G handover передается не весь дамп трафика, а только контекст сессии — закодированный в компактный сигнатурный вектор. ILCP делает то же самое: вместо пересылки гигабайтов текста агент передает латентный вектор фиксированной размерности, полученный через β-VAE.

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

Архитектура ILCP включает три компонента:

  • Энкодер β-VAE — принимает историю взаимодействия агента (конкатенацию предыдущих запросов и ответов, закодированных через эмбеддинги LLM) и выдает параметры гауссова распределения в латентном пространстве.
  • Декодер — восстанавливает приближенный контекст для проверки или повторной инициализации.
  • Gated MLP Memory Manager — принимает текущее латентное состояние и новый контекст (через энкодер), вычисляет обновление через вентильный механизм (как GRU, но в латентном пространстве) и сохраняет новое состояние.

Если вас интересуют альтернативные подходы к памяти, взгляните на MemoryLLM — интерпретируемая память с внешними слоты, или LCME, которая работает быстрее моргания, но для одиночного агента.

Собираем ILCP своими руками (и не ломаем голову)

Теперь к делу. Предположим, вы используете любой LLM на базе трансформера (Qwen3, LLama 4, DeepSeek-V4). ILCP работает как прослойка между агентом и его контекстом. Вот минимальный код на PyTorch для ключевых компонентов.

import torch
import torch.nn as nn
import torch.nn.functional as F

class BetaVAE(nn.Module):
    def __init__(self, input_dim, latent_dim, beta=4.0):
        super().__init__()
        self.beta = beta
        self.encoder = nn.Sequential(
            nn.Linear(input_dim, 512),
            nn.ReLU(),
            nn.Linear(512, latent_dim * 2)  # mean and log_var
        )
        self.decoder = nn.Sequential(
            nn.Linear(latent_dim, 512),
            nn.ReLU(),
            nn.Linear(512, input_dim)
        )

    def encode(self, x):
        h = self.encoder(x)
        mean, log_var = h.chunk(2, dim=-1)
        return mean, log_var

    def reparameterize(self, mean, log_var):
        std = torch.exp(0.5 * log_var)
        eps = torch.randn_like(std)
        return mean + eps * std

    def decode(self, z):
        return self.decoder(z)

    def loss(self, x, recon, mean, log_var):
        recon_loss = F.mse_loss(recon, x, reduction='sum')
        kl_loss = -0.5 * torch.sum(1 + log_var - mean.pow(2) - log_var.exp())
        return recon_loss + self.beta * kl_loss

class GatedMemoryUpdater(nn.Module):
    def __init__(self, latent_dim):
        super().__init__()
        self.update_gate = nn.Linear(latent_dim * 2, latent_dim)
        self.reset_gate = nn.Linear(latent_dim * 2, latent_dim)
        self.candidate = nn.Linear(latent_dim * 2, latent_dim)

    def forward(self, z_prev, x_new_latent):
        combined = torch.cat([z_prev, x_new_latent], dim=-1)
        u = torch.sigmoid(self.update_gate(combined))
        r = torch.sigmoid(self.reset_gate(combined))
        c = torch.tanh(self.candidate(torch.cat([r * z_prev, x_new_latent], dim=-1)))
        z_new = (1 - u) * z_prev + u * c
        return z_new

Не пытайтесь использовать ILCP без предварительного обучения β-VAE на репрезентативных данных. Вы получите шум. Я рекомендую сначала насобирать датасет диалогов агентов, обучить VAE, а потом уже встраивать Memory Manager.

Для обучения β-VAE понадобятся GPU. Рекомендую арендовать A100 на RunPod — у них хорошие цены и быстрый деплой контейнеров.

1 Выбор размерности латентного пространства

Эмпирическое правило: latent_dim = log2(context_length) * 64. Для контекста в 32K токенов — 64 * 15 = 960. Но на практике начинайте с 512 и смотрите на метрики реконструкции.

2 Предобучение β-VAE на логах агентов

Соберите последовательности вида [input_1, output_1, input_2, output_2, ...] длиной в среднем 10 шагов. Каждый шаг — эмбеддинг последнего токена LLM (возьмите hidden states). Обучите VAE с β в диапазоне [1, 10]. Выберите β, при котором качество реконструкции на валидации не падает ниже 95%.

3 Интеграция с LLM агентом

При старте агента инициализируйте z как нулевой вектор. На каждом шаге: получаете ответ от LLM, затем эмбеддинг конкатенации [запрос, ответ] прогоняете через энкодер VAE (получаете x_latent), и обновляете z через GatedMemoryUpdater. Сохраняете z в памяти агента.

4 Передача памяти между агентами

Когда один агент вызывает другого, он передает только свой текущий z (512 чисел float). Принимающий агент использует его как начальное состояние своего Memory Manager. Никакого копирования контекста.

МетодСкорость передачиИнтерпретируемостьТребования к памяти
RAGСредняя (зависит от поиска)ВысокаяВекторное хранилище
MemoryLLMНизкая (слоты внимания)СредняяДополнительная память модели
ILCP (наш метод)Высокая (один вектор)Низкая (латентное пространство не читается)Минимальная (512 floats)

Если ваша система работает на vLLM, изучите 5 техник оптимизации vLLM — они помогут снизить задержки при большом числе агентов.

Типичные грабли и как на них не наступить

Первая и главная ошибка — игнорировать cold start. Если агент только что родился и получил чужой z, он не понимает, что это. Нужно либо передавать вместе с z небольшой текстовый дамп (первые 2-3 шага истории) для контекстной настройки, либо обучать VAE на смешанных данных от разных агентов.

Вторая грабля — затухание памяти. Со временем обновления через gated MLP могут привести к дрейфу z в сторону среднего. Решение — добавлять residual connection и периодически (каждые N шагов) форсировать реконструкцию через декодер для сверки с реальной историей.

Третья — выбор β. Слишком маленькое β (<1) — VAE вырождается в обычный автокодировщик, латентное пространство нерегуляризовано, передача между агентами ломается. Слишком большое β (>10) — агент теряет детали, например, забывает упомянутые пользователем факты. Оптимум обычно лежит в диапазоне 2-6.

Четвертая — отсутствие аугментации данных. Обучайте VAE на синтетических последовательностях с разными стилями диалогов. Иначе модель не обобщит на невиданные сценарии.

💡
ILCP отлично сочетается с техникой Lookahead Sparse Attention из статьи про FlashMemory-DeepSeek-V4 — разреженное внимание для длинного контекста плюс ILCP для долговременной памяти дают агентам почти бесконечную историю.

Когда агентов станет 1000, ILCP спасет от перегрузки контекста — подробнее в гайде по масштабированию LLM.

Готовы пожертвовать интерпретируемостью?

ILCP — это мощный инструмент, но за скорость и компактность вы платите прозрачностью. Вы не сможете заглянуть в латентный вектор и понять, что именно помнит агент. Для многих задач это приемлемо (программирование, планирование, 6G). Но если вам нужна объяснимая память — присмотритесь к MemoryLLM или LCME.

В любом случае, ILCP — один из самых горячих методов на ICML 2026. Внедряйте, тестируйте, но не забывайте про cold start и β. Удачи.

Подписаться на канал