Долгоживущие агенты Local LLM: проблемы дублирования, потери состояния и решения на 2026 | AiManual
AiManual Logo Ai / Manual.
03 Фев 2026 Гайд

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

Практическое руководство по управлению состоянием, побочными эффектами и консистентностью в долгоживущих локальных LLM-агентах. Реальные проблемы и решения.

Он уже отправлял это письмо. Три раза

Представьте: ваш агент мониторит тикеты в Jira. Новый баг-репорт - он создает задачу, назначает на разработчика, отправляет уведомление в Slack. Через час тот же тикет появляется снова (система глючит). Агент создает еще одну задачу. И еще. И еще. Разработчик получает 5 одинаковых писем. Команда в панике.

Это не гипотетический сценарий. Это понедельник для каждого, кто запускал долгоживущих агентов на локальных LLM в 2025 году.

Главный парадокс 2026: чем умнее агент, тем глупее он себя ведет в долгоживущих сессиях. GPT-4o, Claude 3.5 Sonnet, локальные Mixtral 8x22B - все они страдают амнезией операций.

Почему state management - это не просто "сохрани контекст"

Когда говорят "управление состоянием агента", 90% разработчиков думают о сохранении истории диалога. Вот и первая ошибка.

История диалога - это то, что агент ВИДИТ. Состояние операций - это то, что агент СДЕЛАЛ. Разница колоссальная.

  • Агент может помнить, что обсуждал отправку письма (контекст)
  • И забыть, что уже отправил его (состояние операции)
  • Или помнить отправку, но не помнить ID созданной задачи в Jira
  • Или помнить ID, но не знать, что задача уже выполнена другим агентом

Это не баг LLM. Это фундаментальное несоответствие между дискретными вызовами модели и непрерывным workflow.

Три призрака долгоживущих агентов

1 Призрак дублирования: когда одна операция выполняется N раз

Классика. Агент анализирует почту каждые 5 минут. Видит письмо от клиента. Создает тикет. Через 5 минут видит то же письмо (оно еще в inbox). Создает еще тикет.

Почему это происходит? Потому что проверка "уже обработано" требует:

# Наивный подход (не работает)
if "обработать письмо" in история_диалога:
    пропустить()

Но агент может сформулировать задачу по-разному: "создать тикет для клиента X", "обработать запрос от email@example.com", "добавить задачу по письму про баг".

💡
Решение: хеш-сигнатура операции. Берем исходные данные (письмо), цель операции (create_ticket), параметры (client_id, priority) - вычисляем хеш. Храним в KV-хранилище с TTL.

2 Призрак рассинхронизации: когда состояние мира изменилось без ведома агента

Агент создал задачу в Jira с ID=123. Запланировал проверку через час. За это время задачу вручную закрыли. Агент проверяет - видит статус "закрыта". Но в его ментальной модели задача все еще "в работе".

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

Эта проблема напрямую связана с эпистемической асимметрией - агенту не хватает контекста изменений.

3 Призрак каскадных отказов: когда одна ошибка ломает всю цепочку

Агент должен: 1) получить данные из API, 2) обработать, 3) сохранить в БД, 4) отправить уведомление.

Шаг 3 падает (коннект к БД потерян). Агент фиксирует ошибку. Но что происходит с шагами 1 и 2? Они уже выполнены. Данные в памяти. При перезапуске агент начнет с шага 1... и получит те же данные (дублирование).

Или хуже: агент попытается откатить изменения, но не знает как - потому что откат не прописан в его skills.

Архитектурные антидоты: как проектировать агентов, которые помнят

Operation Registry - реестр операций вместо истории чата

Забудьте о сохранении простого контекста. Нужен структурированный журнал операций:

Поле Зачем нужно Пример
operation_id Уникальный ID операции (UUID) op_abc123
input_signature Хеш входящих данных для дедупликации sha256(email+timestamp)
external_ids ID во внешних системах (Jira, Slack) {"jira": "PROJ-123", "slack": "C123ABC"}
state_machine Текущее состояние в workflow {"step": 3, "status": "failed", "retries": 2}
compensation_actions Как откатить операцию при ошибке ["delete_jira_issue", "revoke_slack_message"]

Это не просто логи. Это единственный источник правды о том, что агент СДЕЛАЛ в мире.

Сквозные транзакции с сагой-паттерном

Для мультишаговых операций нужна сага - последовательность компенсируемых транзакций. В 2026 для этого есть готовые решения:

# Псевдокод саги для обработки тикета
saga = SagaBuilder()\.add_step(
    name="create_jira_issue",
    execute=create_issue,
    compensate=delete_issue  # Функция отката
)\.add_step(
    name="notify_slack",
    execute=send_slack_message,
    compensate=delete_message
)\.add_step(
    name="schedule_followup",
    execute=add_calendar_event,
    compensate=remove_event
)\.build()

# При ошибке на шаге 2, автоматически выполняются
# compensate шага 2, затем шага 1

Сагу нужно сохранять в Operation Registry после КАЖДОГО шага. При перезапуске агент может восстановить состояние и решить: продолжить, откатить или перезапустить с определенного шага.

Event Sourcing для агентов: переосмысление подхода

Вместо того чтобы спрашивать агента "что ты помнишь?", мы даем ему поток событий:

# Восстановление контекста агента при перезапуске
events = event_store.get_events(
    agent_id="support_bot",
    since=last_checkpoint
)

# Агент получает не историю диалога, а факты:
# 1. 2026-02-03 10:00: Создана задача PROJ-456
# 2. 2026-02-03 10:05: Задаче назначен статус "In Progress"
# 3. 2026-02-03 10:30: Пользователь добавил комментарий
# 4. 2026-02-03 11:00: Задача закрыта (вручную)

# Теперь агент понимает реальное состояние мира

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

Практическая реализация: от теории к продакшену

1 Выбираем правильные инструменты (2026 edition)

Для локальных агентов в 2026 нужно:

  • База состояний: Redis с модулем RedisJSON или PostgreSQL с jsonb. Ключевое - быстрый lookup по input_signature.
  • Очередь операций: RabbitMQ с persistent messages или Apache Kafka. Обязательно с подтверждением доставки.
  • Модель: Любая из LLM с поддержкой Tool Calling, но с важным дополнением - она должна уметь работать с operation registry как с контекстом.

Важно: Не храните состояние в памяти процесса. Любой restart = потеря всего. Используйте внешние хранилища с атомарными операциями.

2 Пишем детерминированные skills с идемпотентностью

Каждый skill (инструмент агента) должен быть идемпотентным. Вызов с теми же параметрами = тот же результат, без побочных эффектов.

# ПЛОХО: создает дубликаты
def create_jira_issue(title, description):
    return jira_client.create_issue(title, description)

# ХОРОШО: проверяет существование сначала
def create_jira_issue(title, description, dedupe_hash):
    # Проверяем по хешу в operation registry
    existing = registry.find_by_signature(dedupe_hash)
    if existing:
        return existing.external_ids["jira"]
    
    # Создаем с reference на dedupe_hash
    issue = jira_client.create_issue(
        title,
        description,
        custom_fields={"dedupe_hash": dedupe_hash}
    )
    
    # Сразу сохраняем в registry
    registry.record_operation(
        op_type="create_jira_issue",
        signature=dedupe_hash,
        external_ids={"jira": issue.key}
    )
    
    return issue.key

3 Реализуем health checks и самовосстановление

Долгоживущий агент должен регулярно проверять:

  1. Консистентность: все ли операции в registry имеют корректный статус в внешних системах?
  2. Зависшие операции: есть ли операции в статусе "in_progress" старше таймаута?
  3. Дубликаты: не появились ли операции с одинаковым signature?

При обнаружении проблем - агент либо сам исправляет (компенсирует дубликаты), либо эскалирует человеку.

Чего НЕ делать: самые частые ошибки 2025 года

Ошибка 1: Доверять LLM отслеживанию состояния. Модель может галлюцинировать о выполненных операциях. Все external calls должны проверяться через registry.

Ошибка 2: Использовать реляционные БД для operation registry. JOIN-ы убивают производительность. Нужны документ-ориентированные БД или специализированные solutions вроде Temporal.io.

Ошибка 3: Забывать про cleanup. Operation registry растет бесконечно. Нужны политики архивации: удалять успешные операции старше 30 дней, оставляя только metadata.

Связь с другими проблемами агентов

Управление состоянием - не изолированная проблема. Она напрямую влияет на:

  • Отладку - без четкого operation registry невозможно понять, что пошло не так
  • Тестирование - тесты должны проверять не только вызов функции, но и запись в registry
  • Мультиагентные системы - когда несколько агентов работают над одним workflow, им нужен shared operation registry
  • Надежность skills - skill без компенсации и дедупликации опасен для продакшена

Что будет в 2027? Прогноз от практика

Сейчас мы вручную пишем operation registry и саги. Это сложно. Ошибкоопасно.

К 2027 появятся:

  1. State-aware LLM frameworks: Библиотеки, где состояние - first-class citizen. Не нужно придумывать велосипеды.
  2. Автоматическая генерация compensation logic: LLM будет анализировать код skill и генерировать функции отката.
  3. Кросс-агентные consistency protocols: Как distributed consensus (Raft, Paxos), но для агентов.
  4. Визуальные debuggers для state flow: Инструменты типа Jaeger, но для трейсинга состояния агентов.

Но пока этого нет - приходится строить надежность самим. Мой совет: начните с простого operation registry на Redis. Добавьте deduplication по хешу. Реализуйте хотя бы один skill с компенсацией.

Потому что агент, который трижды отправляет одно письмо - это смешно. Агент, который трижды списывает деньги с карты - это уже уголовное дело.

💡
Бонусный совет: Всегда добавляйте human-in-the-loop для операций с financial или legal impact. Даже самый надежный агент может ошибиться. А операция "перевод 10000$" не имеет функции компенсации в реальном мире.