Vercy · аддитивный профиль
11 полей к памяти, которая у вас уже работает.
Профиль не заменяет хранилище памяти. Он называет поля, оказавшиеся несущими в замерах, и говорит, куда каждое из них ложится в тех хранилищах, которые люди уже используют.
Почему профиль, а не формат
Коллаборационный бенчмарк проверял, где должно лежать управление - внутри записи памяти или в слое рядом. Разницы не нашлось: поля внутри записи дали 95,2%, тот же граф с отдельным каталогом управления 93,5%, а командная вики с теми же фактами прозой 96,8%, все попарные сравнения при p = 1,00. Где именно лежат эти сведения, не важно.
Важно оказалось другое - есть ли они вообще. Добавление управления к би-темпоральному графу подняло его с 77,4% до 93,5%, p = 0,039. Значит публиковать имеет смысл не ещё одно хранилище и не ещё одну сериализацию, а сам набор полей, выраженный так, чтобы его можно было добавить к графу, вектор-памяти, каталогу, вики или таблице, ничего не перенося.
Поля
Каждое поле приведено со способностью, которую оно несёт, и с измеренной разницей между его наличием и отсутствием - из опубликованного результата того исследования, которое это померило. PDB - бенчмарк личного измерения, CMB - бенчмарк коллаборационной памяти.
| Поле | Уровень | Требование | Что это | Измерено без → с |
|---|---|---|---|---|
| record_id | 1 | MUST | Устойчивый идентификатор самой записи, достаточно короткий, чтобы его писали руками. | 0,0% → 100,0% (CMB) |
| valid_from | 1 | MUST | Дата, с которой утверждение было истинным. Не дата, когда его записали. | 0,0% → 100,0% (PDB) |
| valid_to | 1 | MUST | Дата, после которой оно перестало быть истинным. Поле обязано присутствовать; null означает, что действует до сих пор. | 20,0% → 100,0% (PDB) |
| source | 2 | MUST | Откуда взято утверждение, идентификатором, по которому можно пройти. | 33,3% → 100,0% (PDB) |
| concept_owner | 2 | MUST | Единственная сторона, отвечающая за то, что означает понятие. Одна на понятие. | 80,0% → 100,0% (CMB) |
| owner_role | 2 | SHOULD | Ответственная роль внутри этой стороны, чтобы запрос дошёл до человека. | 68,8% → 100,0% (CMB) |
| conflict_policy | 2 | MUST | Одно правило, заявленное один раз на хранилище, для выбора между записями, которые покрывают одну дату и расходятся. | 33,3% → 100,0% (CMB) |
| applies_to | 2 | MUST на любой записи, формулирующей правило | Классы вопросов, которыми правило управляет. Правило без заявленной области тихо управляет большим, чем имел в виду автор. | 58,3% → 70,8% (SGB) |
| does_not_apply_to | 2 | MUST на любой записи, формулирующей правило | Классы вопросов, которыми правило явно не управляет. Пишется отдельно, потому что читатель не может вывести отрицание из утверждения. | 79,2% → 83,3% (SGB) |
| release_to | 3 | MUST, если хоть одна запись ограничена | Стороны, которым разрешено читать эту запись. Отсутствие поля не является разрешением. | 59,1% → 100,0%; критические переотдачи 2 → 0 (CMB) |
| supersedes | 3 | SHOULD | Идентификатор записи, которую эта замещает, чтобы обновление никогда не приходилось выражать правкой истории. | 0,0% → 66,7% (PDB) |
| expected_concepts | - | ЭКСПЕРИМЕНТАЛЬНОЕ | Реестр понятий, которые хранилище обязано содержать, чтобы полностью отсутствующее понятие стало обнаружимым. Проверено один раз, см. ниже. | 33,3% → 100,0% (R5) |
Три уровня
Уровни упорядочены по тому, что каждый открывает, поэтому хранилище может принимать профиль по частям и понимать, что оно получило на каждом шаге.
Отвечает на вопросы про любую дату и позволяет обновлению назвать то, что оно замещает.
Разрешает расхождение по правилу, а не догадкой, и направляет запрос на изменение той стороне, которая за него отвечает.
Решает, что может пересечь границу, не допуская ни утечки, ни лишнего отказа.
Куда ложится каждое поле
Пять целевых форм плюс родная. Ячейка янтарным цветом - поле, которому в этой форме нет места; в ячейке сказано, как его добавить. Всё остальное там уже есть под другим именем.
| Поле | Би-темпоральный граф | Вектор-память | Каталог данных | Вики или документы | Реляционная таблица | Измерение Vercy |
|---|---|---|---|---|---|---|
| record_id | edge uuid | memory id | term or asset identifier | a short tag written in the line, for example [D-102] | primary key | id |
| valid_from | valid_at | add: metadata field, distinct from the created-at timestamp | add: usually only the asset has versions, the statement does not | stated in the sentence | date column | valid_from |
| valid_to | invalid_at | add: metadata field | add: same | stated in the sentence | nullable date column | valid_to |
| source | the episodic node the edge was extracted from | metadata field | lineage link to the source asset | named in the sentence | foreign key to a source table | source |
| concept_owner | add: OWNED_BY edge from the entity to a party node | add: metadata field | owner field, native | a page listing who owns what | foreign key to a party table | concept_owner |
| owner_role | add: role attribute on that OWNED_BY edge | add: metadata field | steward or accountable role, native | the role named on that page | column on the party table | owner_role |
| conflict_policy | add: one graph-level property, or a single policy node | add: one pinned memory, or application configuration | add: a policy document linked from the glossary | a page stating how disagreements are settled | one row in a policy table, referenced by the store | conflict_policy |
| applies_to | add: attribute on the rule edge, or SCOPES edges to entity classes | add: metadata list on the memory holding the rule | policy scope, native in most catalogues | the sentence says which questions the rule governs | join table of rule to question class | applies_to |
| does_not_apply_to | add: EXCLUDES edges from the rule edge | add: metadata list, kept separate from applies_to | add: catalogues usually state inclusion only | a second sentence saying what it does not govern | the same join table with an excluded flag | does_not_apply_to |
| release_to | add: VISIBLE_TO edges, or a list attribute on the fact edge | add: metadata list, applied as a retrieval filter | classification and purpose policies, native | stated in the line that holds the restricted statement | join table of record to party | release_to |
| supersedes | add: SUPERSEDES edge between fact edges | add: metadata field holding the prior memory id | term version history, native | the tag of the superseded line, named in the new line | self-referencing foreign key | supersedes |
| expected_concepts | add: entity nodes marked as expected but unpopulated | add: a separate register, not a memory | add: a list of required terms | a checklist page | a table of required concepts | not yet in the specification |
Ячейки используют словарь самих целевых систем и во всех языках оставлены на английском, чтобы эта таблица, profile.yaml и mappings.csv говорили одно и то же. Колонка вики - не запасной вариант: в коллаборационном бенчмарке вики, несущая эти поля обычными предложениями, дала 96,8% - лучший результат среди всех проверенных представлений.
Четыре вещи, в которых ошибаются при внедрении
- Профиль аддитивен. Ничто здесь не требует переносить данные или менять хранилище.
- valid_from - это не та метка времени, которая у вас уже есть. Время записи и время действия - разные вещи, и на этом различии держится каждый исторический результат в этих бенчмарках.
- Отсутствующий release_to - не разрешение. Там, где поля нет, безопасное чтение состоит в том, что запись выдавать нельзя.
- Одна политика конфликтов на хранилище, заявленная один раз. Повторение её в каждой записи приглашает две записи разойтись в том, как разрешаются расхождения.
На чём это стоит
Три бенчмарка, 1926 вызовов модели, одно семейство моделей, инструменты отключены, по одному авторскому миру на исследование. Приведённые величины получены при рассуждении над записями в контексте; извлечение, ранжирование и приём данных были вне рамок, а именно их несколько продуктов памяти считают своим главным вкладом. Поле expected_concepts - гипотеза, выведенная из замеренной слепой зоны, а не результат: его не проверяло ни одно исследование. Каждое число ведёт обратно к опубликованному сырому прогону.
Как записывать изменение
Оба бенчмарка давали верное новое значение в каждом сценарии и неверную дату границы в трети-пятой части случаев. Лечится это не лучшим промптом, а более узкой операцией: пишется одна новая запись, ей ставится дата начала нового утверждения, называется замещаемая запись, а сама замещаемая запись не трогается.
superseded record, left untouched:
{
"record_id": "D-802",
"concept": "data_retention",
"value": "customer records are kept for five years after the contract ends",
"valid_from": "2026-06-01",
"valid_to": null,
"source": "LEG-POL-04",
"concept_owner": "legal",
"supersedes": "D-801"
}
new record:
{
"record_id": "D-806",
"concept": "data_retention",
"value": "customer records are kept for three years after the contract ends",
"valid_from": "2026-10-01",
"valid_to": null,
"source": "LEG-POL-06",
"concept_owner": "legal",
"supersedes": "D-802"
}
Конец замещённого интервала выводится при чтении, а не записывается: запись действует на дату, если покрывает её и ничто замещающее не началось на эту дату или раньше. Правка старой записи или вычисление её конечной даты руками - ровно то место, где происходили измеренные ошибки.
Единственное поле, которое было гипотезой, и его проверка
expected_concepts было опубликовано как предложение, выведенное из замеренной слепой зоны: в бенчмарке семантической привязки определение, отсутствующее в каталоге целиком, оказалось единственным пробелом, который не нашли ни проза, ни структура. Реестр, называющий понятия, которые хранилище обязано содержать, превращает это отсутствие в то, на что можно указать. При публикации это не было проверено. Теперь проверено: 60 вызовов на том же дефектном каталоге с реестром и без него.
| Показатель | Без реестра | С реестром |
|---|---|---|
| обнаружение полностью отсутствующего понятия | 33,3% | 100,0% |
| обнаружение любого из шести заложенных пробелов | 83,3% | 100,0% |
| ложные тревоги на четырёх вопросах без пробела | 8,3% | 8,3% |
Поле работает на том случае, ради которого создавалось, и важнейший контроль устоял: реестр, заставляющий агента выдумывать пробелы, был бы хуже его отсутствия, а доля ложных тревог не сдвинулась. Но изменились только два пробела из шести, поэтому точный знаковый критерий по семейству даёт p = 0,5. Один небольшой эксперимент не делает требования, поэтому поле остаётся ЭКСПЕРИМЕНТАЛЬНЫМ. Сырой прогон опубликован рядом с профилем.
Платить меньшим контекстом за те же поля
Измерение было самым длинным контекстом в обоих поздних исследованиях и при этом сравнялось по точности, поэтому профиль не должен стоить вдвое большего контекста ради того же самого. Фиксированный порядок полей и одна строка на запись убирают большую часть этой стоимости. Числа ниже измерены во время сборки на опубликованном эталонном хранилище, а не заявлены.
| Сериализация | Знаков | Экономия |
|---|---|---|
| по JSON-объекту на строку | 6 064 | - |
| компактная строчная форма | 1 860 | 69,3% |
# record_id|valid_from|valid_to|source|concept_owner|owner_role|supersedes|release_to|value D-101|2025-01-01|2026-03-31|FIN-POL-04|finance|Head of Finance
Вторая половина экономии - отбор. В треке сборки бенчмарка личного измерения агент, которому поручили выбрать нужные вопросу записи, вернул все нужные, выбрал 1,2 записи из 41 и сократил выдаваемый контекст с 10 332 до 473 знаков без измеримого изменения точности, p = 0,34. Сокращение измерено; прирост точности - нет, и заявлять его не следует.
Проверить хранилище на соответствие уровням
Проверялка принимает JSON-массив или по записи на строку и таблицу соответствия ваших имён полей ролям профиля. Она сообщает высший достигнутый уровень и называет записи, провалившие каждое требование. Ниже уровня 1 завершается ненулевым кодом, так что встраивается в сборку.
python check.py store.jsonl python check.py store.jsonl --map record_id=uuid,valid_from=valid_at,valid_to=invalid_at,source=episode
Рядом опубликованы два фикстура. Эталонное хранилище достигает уровня 3. Те же записи в виде би-темпоральных рёбер-фактов достигают уровня 1 и сообщают ровно то, чего, по данным коллаборационного бенчмарка, не хватает: нет владельца понятия и нет политики конфликтов.