Настройки харнеса: модели и бюджеты в одном месте
Статус: действующая модель (v1).
Всё, что генерализовано влияет на работу агентного харнеса, живёт в двух слоях с одним домом на каждый — ничего не выбирается «от балды».
#1. Модельные роли (БД, редактируемые)
Панель супервайзера (GET/PUT /v1/workspace/supervisor), ключи
workspace_setting, каждое имя модели валидируется по реестру провайдеров
при сохранении. Пустая роль = каскад фолбэков ниже.
| Роль | Ключ настройки | Что обслуживает | Каскад при пустой роли |
|---|---|---|---|
| judge | eval.judge.model (есть) |
судейство: оценки, конфликты знаний, area-саммари | выключен |
| vision | supervisor.vision.model (есть) |
картинки, когда основная модель не мультимодальная | основная модель |
| compaction | harness.compaction.model |
карточка состояния при компакции контекста | judge → env-модель |
| title | harness.title.model |
заголовки ранов | judge → env-модель |
| extraction | harness.extraction.model |
извлечение знаний по завершении рана | модель рана → judge → env-модель |
Резолвер — kernel/agent → Activities.HarnessModel (сборка в
cmd/agent-kernel/knowledgeareas.go): слот роли → providerModelClient
(провайдер + ключ) → судья. Дополнительные фолбэкаи — в самих потребителях
(extractionModelClient, evaluationModel, GenerateTitle).
Env-модель по умолчанию (TEMPORALITY_MODEL_BASE_URL / _ID / _API_KEY) —
точка отсчёта для activities.Model (дефолтный aux-клиент) и для
роутинга живых ходов (модель рана → workspace-провайдер → env-fallback).
#Политики агента (per-agent)
Вкладка «Возможности» агента:
| Настройка | Что делает |
|---|---|
Работа с изображениями (capability vision + режим vision_describe) |
Три режима: Пиксели в контексте (по умолчанию) — vision-блоки живут в диалоге, с лимитом ниже; Только описания (vision_describe=true) — любые тулы, возвращающие картинки (view_image, fetch_image, browser), автоматически заменяются текстовым описанием от vision-модели — base64 никогда не попадает в контекст (главный режим для агентов, которым пофиг на пиксели); Выключено (vision=false) — тулы view_image / fetch_image / inspect_image запрещены (DenyTools + фильтр AllowedTools), скриншоты не входят в контекст — только метаданные с пометкой |
× лимит изображений в контексте (vision_keep_images, виден в режиме «Пиксели») |
сколько свежих сообщений со скриншотами держать в контексте; старые vision-блоки вытесняются по мере появления новых (однократная мутация на сообщение, явная пометка, можно вернуть через view_image по пути). 0 = без лимита. Для дизайн-агентов — 2–4 |
тула inspect_image |
точечный осмотр картинки vision-моделью (роль vision) с возвратом текста — доступен во всех режимах кроме «Выключено» и остаётся escape-hatch для «Только описания»: нужен конкретный ответ по пикселям — задай вопрос |
Лимит имеет смысл только при включённом тумблере; выключенный тумблер — жёсткий запрет уровня рантайма, а не рекомендация в промпте.
#2. Бюджеты, таймауты, капы (env + UI-переопределения, единая таблица)
Дом — пакет kernel/harness (Settings, FromEnv, Current); дефолты =
сегодняшние значения. Невалидное значение деградирует до дефолта.
Порядок резолва бюджетных ручек: дефолт → env → сохранённое переопределение
из UI (ключи harness.budgets.<knob> в workspace_setting). Таймауты и
капы картинок — по-прежнему только env.
| Переменная | Дефолт | Что делает |
|---|---|---|
TEMPORALITY_MAX_MODEL_REQUEST_BYTES |
2 МиБ − 32 КиБ | потолок инпута call_model (лимит Temporal limit.blobSize.error = 2 МиБ; выше — честный run.failed вместо TMPRL1103-зависания) |
TEMPORALITY_COMPACTION_TRIGGER_BYTES |
1.2 МиБ | порог компакции контекста (docs/context-compaction.md) |
TEMPORALITY_COMPACTION_CARD_MAX_BYTES |
8 КиБ | размер карточки состояния (едет в каждом следующем запросе) |
TEMPORALITY_COMPACTION_TAIL_BYTES |
256 КиБ | дословный хвост после карточки |
TEMPORALITY_COMPACTION_KEEP_GROUPS_MIN / _MAX |
2 / 8 | сколько целых групп ходов сохранять в хвосте |
TEMPORALITY_COMPACTION_DIGEST_HEAD_BYTES / _TAIL_BYTES |
3584 / 512 | кап одного сообщения в дайджесте для суммаризации |
TEMPORALITY_TOOL_OUTPUT_MAX_BYTES / _TAIL_BYTES |
512 КиБ / 16 КиБ | кап тул-результата в истории (head+tail с пометкой) |
TEMPORALITY_CONTINUE_AS_NEW_BYTES |
128 МиБ | бюджет роста истории одного исполнения: при достижении ран продолжается через ContinueAsNew (docs/context-compaction.md §5) |
TEMPORALITY_IMAGE_ENCODED_MAX_BYTES |
512 КиБ | кап закодированного vision-блока (base64 ×4/3 на проводе) |
TEMPORALITY_IMAGE_MAX_SIDE |
1568 | длинная сторона картинки (тайлы провайдера) |
TEMPORALITY_IMAGE_SOURCE_MAX_BYTES |
5 МиБ | кап исходного файла/загрузки до декодирования |
TEMPORALITY_MODEL_ACTIVITY_TIMEOUT |
20m | потолок kernel.call_model |
TEMPORALITY_TOOL_ACTIVITY_TIMEOUT |
16m | потолок kernel.run_tool (должен перекрывать sandbox-потолок 15m) |
#3. Replay-безопасность
Бюджеты, которые меняют команды workflow (порог компакции, гард
пейлоада, капы истории — они двигают размеры запросов и, следовательно,
решения), пинятся на ран: AgentRun один раз читает снапшот
(kernel.harness_budgets, local activity — паттерн RecordEventLocal) и
работает только с ним. Смена настроек посреди рана не ломает его replay:
решения повторяются идентично. Раны до введения механизма (и тестовые
пробы с нулевым снапшотом) получают harness.DefaultBudgets() — те же
литералы, что зашиты в их истории.
Активити-сторона (кап картинок, карточка, таймауты) читает Current():
результат активити лежит в истории и replay не зависит от окружения.
#4. API
GET /v1/workspace/supervisor отдаёт роли (judge_model, vision_model,
compaction_model, title_model, extraction_model), HAB-коэффициенты,
статус эмбеддингов и эффективный harness-снапшот — одно место, чтобы
видеть, чем харнес реально работает. Для бюджетов ответ дополнительно несёт
harness_defaults (компиляционные дефолты) и harness_saved (ключи с
сохранёнными переопределениями) — UI рисует происхождение значения и кнопку
сброса. PUT принимает роли (compaction_model/title_model/
extraction_model — pointer-семантика: пропущенное поле хранится как есть,
пустая строка сбрасывает роль); валидация имён — по реестру провайдеров.
PUT дополнительно принимает harness — карту бюджетных ручек
(map[string]*int по json-тегам из §2): число сохраняет переопределение,
null сбрасывает ручку обратно на env/дефолт, пропущенный ключ не
трогается. Валидация: известный ключ, значение в пределах потолка ручки
(max_model_request_bytes ≤ 2 МиБ — лимит Temporal, continue_as_new_bytes
≤ 512 МиБ, остальные ≤ 64 МиБ; keep-groups — счётчики ≤ 64), сквозные
проверки keep_groups_min ≤ max и compaction_trigger_bytes ≤ max_model_request_bytes. Ответ — тот же payload, что и GET. Сброс/сохранение
пишется в access audit.
#5. Prompt cache и его инвалидация
Кэш — провайдерский префиксный (KV): prompt_cache_key = TaskID, живёт на
байт-стабильном префиксе сообщений. Мутация старого сообщения инвалидирует
кэш от её позиции до конца; цена пересчёта видна в событиях
(cache_rewritten_bytes). Сводка по механизмам:
| Механизм | Влияние |
|---|---|
| ContinueAsNew | ничего — сообщения переносятся дословно |
| кап тул-вывода | ничего — сообщение стабилизируется один раз |
| компакция | один re-write (маленького) префикса на событие |
окно скриншотов (vision_keep_images) |
один re-write хвоста на вытесненный скриншот; точка мутации ползёт к концу |
| бюджетная элисия картинок | точечно, как окно; редко (за порогом гарда) |
inspect_image |
улучшает — картинки не входят в префикс |
Правило проектирования мутаций: каждое сообщение меняется один раз (детерминированная пометка), и точка мутации — ближе к концу.
#6. Ограничения
- Бюджеты применяются к новым ранам (пин на старте): сохранение переопределения не трогает раны в полёте — это свойство replay-безопасности (§3), а не недостаток. UI-редактирование бюджетов реализовано (§4).
- Таймауты активити и капы картинок — только env (читаются при старте процесса); из интерфейса не редактируются.
- Модельные роли — глобальные на инсталляцию; per-project роли не нужны, пока у проектов есть свои дефолтные модели ранов.