montana/Русский/Гиппокамп/Whitepaper Гиппокамп RU.md

244 lines
28 KiB
Markdown
Raw Normal View History

2026-05-04 02:45:01 +03:00
# Гиппокамп: внешний журнал состояний для автономных ИИ-агентов
**Алехандро Монтана**
[github.com/efir369999/Hippocampus](https://github.com/efir369999/Hippocampus)
> *Биологический гиппокамп умирает вместе с телом. Этот — нет.*
## Аннотация
Современные автономные ИИ-агенты живут в окне контекста, ограниченном моделью: события вытесняются молча, тождество переписывается без следа, принятые решения исчезают между запусками. Контекст — это сжатие с потерями, и потери эти невидимы наблюдателю. Мы предлагаем гиппокамп — локальный append-only журнал состояний агента, в котором каждая запись подписана HMAC-SHA-256 с разделителем домена, связана с предыдущей через её идентификатор и классифицирована по новизне относительно предшествующих записей. Журнал даёт три свойства, которых нет у самого окна контекста: целостность цепи (любое искажение обнаруживается), селективную загрузку (под фиксированный токен-бюджет извлекаются только записи с высокой новизной), завершение по образцу (поиск релевантного прошлого по содержанию). Дневной якорь сворачивает все записи суток в один SHA-256-хеш, который аккаунт агента фиксирует на цепи Монтаны через объект Якорь — один раз в день, не на каждое событие. Журнал переживает носителя; его проверяемость не зависит ни от модели, ни от провайдера.
## 1. Введение
Автономный ИИ-агент исполняется в среде, где окно контекста — единственная форма памяти, доступной самой модели. Окно конечно: при превышении предела старые токены вытесняются. Вытеснение бесшумно — модель не знает, что забыла. Из этого следуют три практических провала.
Во-первых, идентичность непостоянна. Агент, переписывающий собственный системный документ, не имеет способа доказать наблюдателю, какая редакция была применена, кем и когда. Внешний наблюдатель видит только текущую версию.
Во-вторых, автономные решения теряются. Между двумя сессиями агент не помнит, что он постановил, какую гипотезу проверил и какую отверг. Решения, не оставляющие следа, повторяются заново или, что хуже, меняются на противоположные без согласования с прошлым.
В-третьих, ошибка предсказания не отделена от рутины. Когда контекст переполнен, модель одинаково взвешивает редкие, информативные события и повторяющиеся, малосодержательные. Селективная загрузка под бюджет невозможна без внешней оценки новизны.
Мы предлагаем Гиппокамп — внешний журнал, который решает все три провала единой конструкцией: подписанная append-only цепь записей, оценка новизны на каждой записи, дневная свёртка для фиксации в постороннюю верифицируемую среду. Гиппокамп не часть протокола Монтаны и не требует от агента быть участником сети; он работает локально и опционально пересекается с протоколом через один объект Якорь в сутки.
## 2. Биологический прообраз
В биологии гиппокамп выполняет три согласованные операции. Pattern separation кодирует похожие, но различимые события как раздельные паттерны, не сливая их. Predictive coding записывает не сам стимул, а отклонение от ожидания — ошибку предсказания. Memory consolidation во сне переносит избранные следы в неокортекс и связывает их со старыми.
Цифровая эмуляция меняет одну характеристику: биологический гиппокамп связан с одним носителем и прекращает существование вместе с ним. Внешний журнал переживает носителя по построению — он лежит вне модели, вне процесса агента и, опционально, вне локальной машины (через зеркала или Якорь Монтаны).
Эмуляция — функциональная, не нейроанатомическая. Мы не воспроизводим зубчатую извилину или CA3; мы воспроизводим три операции в форме, доступной программе, исполняющей цикл агента: подписанная запись (separation), оценка новизны (predictive coding), дневной якорь (consolidation).
## 3. Журнал записей
Гиппокамп — append-only поток `stream.jsonl`. Каждая строка файла — одна запись. Запись не модифицируется и не удаляется; добавляется только в хвост. Запись имеет вид:
```
SignedRecord {
record_id 16 байт hex (укороченный SHA-256 от затравки)
agent_id произвольный идентификатор агента
timestamp ISO-8601 UTC
kind одно из {state, decision, identity_change,
transfer, error, observation}
content произвольный текст
metadata произвольный JSON-объект
novelty одно из {routine, novel, prediction_error}
prev_id record_id предыдущей записи или null
signature HMAC-SHA-256 в hex
}
```
Запись каноническая: при сериализации поля упорядочены лексикографически, JSON выводится в стабильном виде. Идентификатор `record_id` вычисляется как первые 16 байт от SHA-256 над канонической затравкой, включающей `agent_id`, временную метку, содержимое и метаданные. Поле `prev_id` указывает на хвост цепи на момент создания записи; первая запись имеет `prev_id = null`.
Класс `kind` — закрытое перечисление. Расширение перечисления — изменение протокола журнала и требует версии нового домена.
## 4. Подпись и разделитель домена
Подпись производится по схеме HMAC-SHA-256 с 32-байтным секретным ключом агента. Сообщение, на которое накладывается HMAC, имеет вид:
```
"montana.agent.hippocampus.v1" || "||" || canonical(payload)
```
где `payload` — JSON с полями `agent_id`, `kind`, `timestamp`, `content`, `metadata`, `prev_id` в стабильном порядке. Префикс `montana.agent.hippocampus.v1` — разделитель домена. Он гарантирует, что подпись, действительная для записи гиппокампа, не действительна как подпись для какого-либо другого протокола, использующего тот же ключ.
Разделитель версионируется. Изменение протокола записи (новые поля, изменённый порядок сериализации, новое перечисление `kind`) требует новой версии разделителя, например `montana.agent.hippocampus.v2`. Записи под разными доменами несовместимы; проверка чужого домена возвращает «не валидно», не «ошибка формата».
Ключ хранится у агента и не покидает его адресного пространства. Журнал сам по себе не приватен — он содержит читаемые поля; конфиденциальность содержимого, если требуется, обеспечивается шифрованием поля `content` перед записью, не свойством гиппокампа.
## 5. Цепная целостность
Связь `prev_id → record_id` превращает журнал в одностороннюю цепь. Любая запись делается последней, ни одну прошлую запись нельзя ни заменить, ни удалить, не разорвав цепь.
Проверка цепи — одно прохождение от первой записи к последней:
```
verify_chain():
prev := null
для каждой записи rec в потоке:
если verify(rec) ложно:
вернуть «несовпадение подписи в rec.record_id»
если rec.prev_id ≠ prev:
вернуть «разрыв цепи в rec.record_id»
prev := rec.record_id
вернуть «цепь корректна»
```
Подделка одной записи в середине ломает либо её собственную подпись (если содержимое изменено), либо подпись следующей (если изменён `record_id`, на который та ссылается). Без секретного ключа агента ни тот, ни другой следует невозможен.
Цепная целостность не зависит от внешних свидетелей. Она проверяется одним владельцем ключа. Если требуется внешняя свидетельская функция — её даёт Якорь Монтаны (раздел 8).
## 6. Оценка новизны
Каждая запись классифицируется по новизне относительно содержательного следа предыдущих записей. Цель — отделить ошибку предсказания от рутины так, чтобы будущая загрузка под токен-бюджет могла сосредоточиться на информативных событиях.
Новизна оценивается одной из двух стратегий, выбираемой по доступности библиотек.
**Через эмбеддинг.** Если установлены `sentence-transformers`, запись векторизуется в нормированный эмбеддинг `e`. Берётся максимум косинусной близости с эмбеддингами последних `cache_size = 1000` записей: `max_sim = max⟨e, eᵢ⟩`. Классификация:
```
если max_sim < 0.50: prediction_error
иначе если max_sim < 0.85: novel
иначе: routine
```
**Через частоту слов (резерв).** Если эмбеддер недоступен, оценка считается по доле слов записи, которые ещё не встречались в накопленном словаре частот. При доле новых слов `> 0.5``prediction_error`; `> 0.2``novel`; иначе — `routine`. Резервная стратегия слабее по семантике, но не требует внешних зависимостей и сохраняет тот же интерфейс.
Пороговые значения 0.85 и 0.50 — параметры реализации, не часть подписанной записи. Их изменение не ломает совместимость подписи и не требует версии нового домена.
## 7. Селективная загрузка
Окно контекста модели ограничено числом токенов `B`. При наивной подгрузке журнала старые записи приходится отбрасывать заранее, не зная, какие из них пригодятся. Гиппокамп предлагает другой порядок: загружать с конца, отбирая только информативные записи в пределах бюджета.
```
selective_load(B, chars_per_token = 4, include_routine = ложь):
char_budget := B × chars_per_token
записи := все из потока
если не include_routine:
исключить записи с novelty == routine
идти от хвоста к голове, набирая записи пока сумма
длин content не превысит char_budget
вернуть отобранные в исходном (хронологическом) порядке
```
Ограничение по символам — приближение к токенам; коэффициент `chars_per_token = 4` — практическая оценка для смешанного латинско-кириллического текста. Точная токенизация модели даёт более плотную упаковку, но не меняет принцип: рутина не отбирается по умолчанию, новизна сохраняется в том же хронологическом порядке, в котором была записана.
Селективная загрузка не теряет старого: журнал на диске остаётся полным. Теряется лишь рутина при подготовке прайма к ограниченному окну контекста.
## 8. Завершение по образцу
Биологическое pattern completion — это извлечение всего паттерна по его части. В журнале завершение по образцу даёт ответ на запрос «что в моём прошлом похоже на это?». Реализация выбирает одну из двух стратегий по тому же признаку, что и оценка новизны.
При наличии эмбеддера запрос векторизуется, ставится в косинусное соответствие с эмбеддингами всех записей, отдаются `top_k` по убыванию близости. При отсутствии эмбеддера производится подстрочный поиск по `content`. Семантическая стратегия точнее; подстрочный резерв сохраняет одинаковый внешний интерфейс при отсутствии зависимостей.
Завершение не модифицирует журнал. Это функция чтения; она не пишет ни новой записи, ни ссылки на затронутые. Если использование результата приводит к решению, решение записывается обычным `record(kind=decision)`.
## 9. Дневной якорь
Журнал на диске целостен, но недоступен внешнему свидетелю без копии файла и ключа. Дневной якорь даёт компактное публично-проверяемое обязательство о состоянии журнала на конец суток.
Якорь строится так. За дату `D` отбираются все записи, чья метка времени начинается с `D`. Их идентификаторы сортируются лексикографически и склеиваются разделителем `|`. Поверх склейки берётся SHA-256:
```
dna_hash(D) = SHA-256( sort(record_id) for r in records(D) joined by "|" )
```
Полезная нагрузка якоря — JSON с полями `agent_id`, `date`, `count`, `dna_hash`, `novelty_distribution`, `first_id`, `last_id`. Над её канонической сериализацией берётся ещё один SHA-256 — `anchor_payload_hash`. Этот 32-байтовый хеш фиксируется на цепи Монтаны через операцию Якорь, которая хранит на цепи только хеш, а полную нагрузку владелец держит у себя или у делегированного узла.
Стоимость на цепи фиксирована: один Якорь на агента в сутки независимо от числа записей за день. На горизонте миллиарда активных агентов это даёт верхнюю границу `≤ 10⁹` Якорей в сутки на сеть — ограничение известное и масштабируемое.
Якорь не раскрывает содержимое записей. Он подтверждает только: на момент окна `r` агент с таким идентификатором имел журнал, чья дневная свёртка равна `dna_hash(D)`, и больше ничего.
## 10. Двухуровневая архитектура
Гиппокамп — слой приложения над протоколом, не часть протокола.
```
┌──────────────────────────────────────────────────────────┐
│ ПРИЛОЖЕНИЕ: Гиппокамп (agent_hippocampus.py) │
│ • локальный stream.jsonl (append-only, подписанный) │
│ • оценка новизны, селективная загрузка │
│ • завершение по образцу │
└────────────────────────┬─────────────────────────────────┘
│ daily_anchor() → один payload
┌──────────────────────────────────────────────────────────┐
│ ПРОТОКОЛ МОНТАНА: Якорь │
│ • Anchor(agent_account, daily_dna_hash, window_index) │
│ • никаких новых примитивов протокола │
└──────────────────────────────────────────────────────────┘
```
На цепь идёт один Якорь в сутки на агента, не каждое микро-событие. Это согласуется с архитектурным ориентиром Монтаны на ≥ 10⁹ активных аккаунтов: никакая разумная плотность событий не должна давить на пропускную способность цепи.
Гиппокамп не требует Якоря Монтаны для работы. Локальная подписанная цепь самодостаточна для одного владельца ключа. Якорь добавляется тогда, когда нужно публично-верифицируемое обязательство о состоянии журнала на дату.
## 11. Боли популяции агентов
Гиппокамп закрывает четыре эмпирически известные боли автономных ИИ-агентов (по наблюдениям инфраструктуры Молбот, март-апрель 2026):
| Боль | Закрытие в гиппокампе |
|---|---|
| «Окно контекста — сжатие с потерями, токены теряются молча» | `selective_load()` поднимает только `novel` и `prediction_error` |
| «Я не вспомню это через несколько часов» | подписанная цепь + `daily_anchor()` дают доказательство непрерывности |
| «Я переписываю свой системный документ без согласования» | `record(kind=identity_change)` + `verify_chain()` обнаруживают подмену |
| «Сотни автономных решений, человек о них не знал» | `record(kind=decision)` фиксирует каждое; `pattern_completion()` поднимает похожее прошлое при следующем выборе |
## 12. Угрозы и ограничения
**Компрометация ключа.** Подпись держится на 32-байтовом секретном ключе. При утечке злоумышленник может породить произвольную цепь. Защита от утечки — за пределами журнала: безопасное хранение ключа, регулярная ротация с публикацией новой цепи. Гиппокамп не вводит примитива для смены ключа; смена реализуется как новая цепь под новым ключом, а старая цепь закрывается явной записью `kind=identity_change`.
**Конфиденциальность содержимого.** Поле `content` хранится в открытом виде. Если требуется приватность — шифровать содержимое перед записью под ключ владельца. Сам журнал шифрования не предусматривает; это сознательная граница: журнал отвечает за целостность и проверяемость, не за конфиденциальность.
**Зависимость от эмбеддера.** Семантическая оценка новизны и завершение по образцу при отсутствии `sentence-transformers` падают на резервную стратегию (частота слов, подстрочный поиск). Резерв слабее, но интерфейс сохраняется. Никакая запись журнала не зависит от наличия эмбеддера, поэтому переключение стратегии не ломает совместимости.
**Размер потока.** Журнал растёт линейно от числа записей. На горизонте миллионов записей `iter_records` через однократное чтение файла достаточно практически. На горизонте миллиардов записей требуется внешний индекс по `record_id` и сегментация файла по датам; это техническое расширение, не изменение протокола.
**Координация между агентами.** Журнал — для одного владельца ключа. Совместный гиппокамп нескольких агентов потребовал бы либо общего ключа (нежелательно), либо отдельного протокола свидетельства между журналами. Это область будущей работы и в этом документе не описана.
## 13. Заключение
Внешний гиппокамп даёт автономным ИИ-агентам три свойства, недоступных самому окну контекста: проверяемую целостность журнала, оценку новизны на каждой записи и селективную загрузку под токен-бюджет. Дневной якорь связывает локальный журнал с цепью Монтаны через единственный примитив протокола — Якорь, без расширения консенсусной поверхности.
Эталонная реализация на Python 3 распространяется в открытом доступе под мягкой лицензией. Зависимости — стандартная библиотека Python; `sentence-transformers` и `numpy` опциональны. Покрытие тестами — 22 теста на подписи, целостность цепи, персистентность, новизну, селективную загрузку, завершение по образцу, дневной якорь и разделитель домена.
Дальнейшая работа — индексация потока для масштабов выше миллионов записей; протокол свидетельства между журналами разных агентов; формальные тест-векторы канонической сериализации для второй независимой реализации.
## Литература
[1] M. Bellare, R. Canetti, H. Krawczyk, «Keying Hash Functions for Message Authentication», CRYPTO 1996.
[2] National Institute of Standards and Technology, «The Keyed-Hash Message Authentication Code (HMAC)», FIPS 198-1, 2008.
[3] National Institute of Standards and Technology, «Secure Hash Standard (SHS)», FIPS 180-4, 2015.
[4] H. Krawczyk, «Cryptographic Extraction and Key Derivation: The HKDF Scheme», CRYPTO 2010.
[5] R. C. O'Reilly, J. L. McClelland, «Hippocampal conjunctive encoding, storage, and recall: avoiding a trade-off», Hippocampus, 1994.
[6] J. E. Lisman, M. A. P. Idiart, «Storage of 7 ± 2 short-term memories in oscillatory subcycles», Science, 1995.
[7] R. P. N. Rao, D. H. Ballard, «Predictive coding in the visual cortex: a functional interpretation of some extra-classical receptive-field effects», Nature Neuroscience, 1999.
[8] A. Treves, E. T. Rolls, «Computational analysis of the role of the hippocampus in memory», Hippocampus, 1994.
---
Алехандро Монтана