Я пишу локальный runtime JIN для диагностики поведения LLM, а также как эксперимент по имплементации долговременной памяти.

Изначально проект задумывался как альтернатива тому, что уже существует в большом количестве и постоянно обсуждается: RAG, пересылке всей пачки сообщений туда‑сюда и так далее

Поэтому первый MVP был простым: строка ввода, чистый чат с WebSocket‑стримингом и локальная модель.

Сейчас JIN выглядит так:


L1: память как состояние текущего разговора

Чтобы модель не забывала разговор, я дал ей первый слой памяти. После каждого ответа происходило сжатие текущего «вопрос — ответ» в смысловую запись. Что‑то вроде записок и полароидных снимков Леонарда из фильма Memento, только теперь записки генерирует LLM для следующего шага.

Так в JIN появился L1 memory summarizer.

Этот слой получает контекст и возвращает обновлённый блок памяти. И это уже давало осмысленное продолжение диалога на некоторое время. Лог чата всё ещё нигде не сохранялся.

User message
  ↓
Brain / Service model
  ↓
Assistant response
  ↓
L1 memory summarizer
  ↓
Runtime memory update
  ↓
Next prompt

Пример L1-памяти:

session status: Session started on 2026-06-08 at 18:03 UTC (trace: 0.50)
user_request: User asked JIN to draw a house ("привет, нарисуй домик"). (trace: 0.50)
active topics: ASCII art generation (House drawing). (trace: 0.50)
last_jin_response: Provided an ASCII representation of a small house and greeted the user. (trace: 0.50)

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

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


Проблема: факты, извлечённые L1, не описывают поведение

Допустим, пользователь пишет:

Привет
Привет
Привет

Можно сохранить:

last_user_message: Привет
user_fact: User initiated conversation
current_concern: Establishing initial topic

И такая реакция будет на каждый новый «Привет», а большего из L1 не выжать.

Так появился L2 memory summarizer

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

Пример слепка L2:

possible pattern: Iterative content generation requests for diverse objects
observed_behavior: User initiates a session by requesting an ASCII art drawing of one object (House), then sequentially continues the request by naming additional, unrelated objects (Cup, Frog, Bird, Fire). Occurrences: 5; last_seen_snapshot: 5; evidence summary: Sequential generation requests for House, Cup, Frog, Bird, and Fire in ASCII art format; confidence: high.
likely_intent: User is testing JIN's ability to maintain context and execute multiple, distinct creative tasks sequentially within a single session.
scope: Current session/test sequence (ASCII Art Generation).

L3 memory summarizer: слепки сессий

При явной просьбе пользователя в диалоге JIN инициирует сохранение текущей сессии. Запускается цепочка запросов:

L1 — (иногда L2) — L3

После чего в localStorage появляются две записи:

  • Последний активный слепок L1

  • Слепок сессии L3

Пример слепка сессии L3:

session_status: Completed ASCII Art Generation Sequence
project_focus: Contextual object generation and maintenance via ASCII art.
durable_fact: Successfully generated a sequence of five distinct objects using ASCII art within this session.
generated_objects: House, Cup, Frog, Bird, Fire
sequence_of_generation:
1. Initial request for a house (привет, нарисуй домик).
2. Continuation with a cup ("а теперь чашку").
3. Addition of a frog ("лягушку").
4. Inclusion of a bird.
5. Final object generated was fire.
session_conclusion: User explicitly requested to save the session state after completing the sequence, marking the end of the current task cycle.

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


Итоговая схема памяти на данный момент:

  • L1 (Runtime Memory): хранит текущее состояние, защищает важные факты durable‑ключами

  • L2 (Pattern Memory): анализ динамики, ловит повторы, стресс‑тесты, смены тем и прочие паттерны

  • L3 (Session Memory): хранит итоги текущей сессии, которые могут переезжать в соседние вкладки

Помимо слоёв памяти, в проекте уже реализованы веб‑поиск и другие actions, которые запускает сам JIN. В дальнейшем будут добавляться фичи, позволяющие комфортно диагностировать поведение LLM. Например, подсветка текста в блоке think, явно указывающая на источник давления (context / session / runtime) и превью конкретных цитат из правил или памяти.

Репозиторий проекта: https://github.com/makeitdouble/jin_core/