Skip to content

Короткая память

Рабочий контекст этого разговора на этом ходу — сообщения, которые LLM реально видит, в пределах токенового бюджета модели. Это не то же самое, что две другие «памяти»:

  • Короткая память (эта страница) — живое окно разговора + running summary. Ограниченная, на ход.
  • Память — семантический поиск по всем прошлым чатам (долгосрочная, pgvector).
  • Прочные факты — то, что агент решил запомнить (agent/memory, в стиле MEMORY).

Ограничение: эфемерный мозг

Наш мозг — это запуск api на каждый ход: stateless, скейлится под трафик. Поэтому короткая память не может жить в процессе между ходами. Два следствия:

  1. Рабочий контекст регидратируется из Postgres каждый ход (из чата как источника записи).
  2. Результат компактизации нужно персистить — running summary, хранимый на чате, — чтобы следующий эфемерный ход не пересчитывал его заново.

(Внутри одного длинного хода — например, час управления worker'ом — окно растёт in-process, пока этот инстанс мозга жив; в конце хода оно персистится.)

Сборка контекста (на ход)

Context engine оркестратора собирает промпт заново каждый ход:

[ system prompt ]          ← snapshot на чате → держит prefix cache модели тёплым
[ running summary ]        ← структурированный rolling-summary старых ходов, ограждён "reference-only"
[ tail window ]            ← самые свежие сообщения ДОСЛОВНО, в пределах token budget хвоста
[ retrieved long-memory ]  ← попадания pgvector, ограждены <memory-context> (вычищаются из вывода)
[ new user message ]
+ tools = MCP-тулсет (brain-MCP · worker-MCP · connector-MCP) — не в истории

Пайплайн компактизации

Бюджет = контекстное окно модели − резерв под ответ. Когда окно за бюджетом:

  1. Дешёвый пре-пасс (без LLM): ужать старые tool results до однострочных сводок, дедуп одинаковых, выкинуть устаревшие скриншоты/картинки. Часто одного этого достаточно.
  2. Защитить голову и хвост: оставить system prompt + первый ход и свежий хвост (по token budget, а не по числу сообщений) дословно.
  3. Memory-flush хук: перед суммаризацией вытащить прочные факты в agent/memory, чтобы компактизация никогда не теряла их молча.
  4. Суммаризировать середину дешёвой вспомогательной моделью (через system/llm) в структурированную сводку — resolved · pending · active task — и смержить её в предыдущую сводку.
  5. Анти-трэш: пропустить компактизацию, если недавние проходы сэкономили мало; затем персистить новую сводку.

Где на самом деле живёт сводка

Не в колонках у треда, а строкой в самом треде, вида kind = summary. Окно режется по самой свежей такой строке, поэтому модель читает пересказ и всё, что после него, а строки до неё остаются там, куда человек может прокрутить.

Хранение строкой, а не полем, даёт две вещи, которых колонка дать не могла:

  • Граница видна. Сжатый разговор и подменённый различаются линией, которую читатель видит, а «начать заново» — это та же линия, поставленная сознательно.
  • Это идемпотентно. Id строки выводится из сообщения, за которым она идёт, поэтому повтор — или две вкладки разом — пишут одну строку, а не две.

Где это живёт

АспектSlice
сообщения + строка-сводка (источник окна)agent/chat
context engine + цикл ходаagent/orchestrator
дешёвая вспомогательная модель для сводокsystem/llm
долгосрочная + прочная памятьagent/memory

Короткая память — это не новое хранилище, а производная сборка над agent/chat плюс небольшое поле сводки. Именно это и делает её подходящей для эфемерного мозга: каждый ход api регидратирует окно из Postgres, компактизирует при необходимости, персистит сводку и снова становится stateless.

См. также

  • Хранилище — чат как источник записи, из которого строится окно.
  • Память — долгосрочный поиск (короткая память ≠ долгая память).
  • Runtime-модель — где находится цикл хода.
  • Реализация — построение context engine.