Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Персона

Ядро нейтрально: ни имени, ни рода, ни обращения в коде нет. Всё, что делает ассистента кем-то, задаёт секция persona конфига — а строки своих UI каждый клиент держит у себя. Ядро о клиентах не знает; клиенты знают ядро.

Из чего складывается персона

слойгде живётна что влияет
голос моделиpersona.file (persona.md) у ядрапервые байты системного промпта
обращениеpersona.honorific у ядраправило в [speakers] и якоре атрибуции: «say {honorific} ONLY under a Master marker»; клиенты подставляют в свои строки
имяpersona.name у ядраклиенты подставляют в тайтлы и строки, дефолтная причина chat_attention
строки UIоверлей в конфиге клиентаголос интерфейса поверх нейтрального встроенного каталога

Без секции persona всё работает на брендовых дефолтах: имя «Ева», обращение «Господин», встроенный текст персоны — нейтральный ассистент. Форкеру достаточно задать свои name/honorific; null или пустая строка выключают поле совсем — клиенты уходят на нейтральный бренд, а правило об обращении из промпта пропадает.

GET /v1/persona

{ "name": "Ева", "honorific": "Господин" }

Только идентичность. Клиент подставляет её в собственные строки через подстановки {name} и {honorific}; null — клиент падает на свой нейтральный бренд и обходится без обращения. Старое ядро без ручки (404) читается так же, как null-ы.

Оверлеи клиентов

Каждый клиент шьёт в себя полный нейтральный каталог строк и принимает оверлей — плоский файл «ключ → строка или список строк» — через свой конфиг (где именно — в доке клиента; образец — docs/persona-overlay.example.yaml в каждой клиентской репе). Общий контракт, чтобы один документ персоны порождал согласованные оверлеи:

  • плоские dot-ключи; неймспейс — клиент: web.*, app.*, tui.*, tg.*, common.*;
  • значение — строка или список строк (списки — для ротаций);
  • {placeholders} встроенной строки сохраняются байт-в-байт; всюду доступны {name} и {honorific} — имена и обращения в текст не зашиваются, файл переживает их смену;
  • плюрализация — суффикс-ключами key.one / key.few / key.many (CLDR-категории): переписывается вся тройка или ничего;
  • ключ, которого в оверлее нет, остаётся встроенным — оверлей можно вести по частям.

Генерация оверлеев

scripts/persona-localize.py — из документа персоны и нейтральных каталогов через OpenRouter-совместимый API, по разу на клиента:

OPENROUTER_API_KEY=… python3 scripts/persona-localize.py \
  --persona persona.md \
  --catalog tui/src/eva_tui/locale/builtin.json \
  --reference tui/docs/persona-overlay.example.yaml \
  --model anthropic/claude-sonnet-5 \
  --out tui-overlay.yaml

Каталоги ест как есть (.json/.yaml — плоская карта, .ts — веб, .rs — мост); сам валидирует ключи, плейсхолдеры и полноту счётных троек. --reference подкладывает прежний оверлей эталоном тона, --base-url/EVA_LOCALIZE_BASE_URL — свой апстрим, --dry-run только считает ключи. Результат ревьюится git-диффом в конфиг-репе и уезжает в конфиг соответствующего клиента. Скрипт — оффлайн-инструмент: в рантайме ядро клиентских строк не касается.

NixOS

services.eva-kernel = {
  persona.file = ./persona.md;   # → settings.persona.file
  settings.persona = {
    name = "Ева";
    honorific = "Господин";
  };
};

Персона — не секрет: файл уезжает в мировой стор. Нужен путь вне стора — пишите settings.persona.file строкой. Оверлеи клиентов подключаются в модулях самих клиентов.